1cfcc706cSMiquel Raynal /*
2cfcc706cSMiquel Raynal * Overview:
3cfcc706cSMiquel Raynal * This is the generic MTD driver for NAND flash devices. It should be
4cfcc706cSMiquel Raynal * capable of working with almost all NAND chips currently available.
5cfcc706cSMiquel Raynal *
6cfcc706cSMiquel Raynal * Additional technical information is available on
7cfcc706cSMiquel Raynal * http://www.linux-mtd.infradead.org/doc/nand.html
8cfcc706cSMiquel Raynal *
9cfcc706cSMiquel Raynal * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
10cfcc706cSMiquel Raynal * 2002-2006 Thomas Gleixner (tglx@linutronix.de)
11cfcc706cSMiquel Raynal *
12cfcc706cSMiquel Raynal * Credits:
13cfcc706cSMiquel Raynal * David Woodhouse for adding multichip support
14cfcc706cSMiquel Raynal *
15cfcc706cSMiquel Raynal * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
16cfcc706cSMiquel Raynal * rework for 2K page size chips
17cfcc706cSMiquel Raynal *
18cfcc706cSMiquel Raynal * TODO:
19cfcc706cSMiquel Raynal * Enable cached programming for 2k page size chips
20cfcc706cSMiquel Raynal * Check, if mtd->ecctype should be set to MTD_ECC_HW
21cfcc706cSMiquel Raynal * if we have HW ECC support.
22cfcc706cSMiquel Raynal * BBT table is not serialized, has to be fixed
23cfcc706cSMiquel Raynal *
24cfcc706cSMiquel Raynal * This program is free software; you can redistribute it and/or modify
25cfcc706cSMiquel Raynal * it under the terms of the GNU General Public License version 2 as
26cfcc706cSMiquel Raynal * published by the Free Software Foundation.
27cfcc706cSMiquel Raynal *
28cfcc706cSMiquel Raynal */
29cfcc706cSMiquel Raynal
30cfcc706cSMiquel Raynal #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31cfcc706cSMiquel Raynal #include <common.h>
32cfcc706cSMiquel Raynal #if CONFIG_IS_ENABLED(OF_CONTROL)
33cfcc706cSMiquel Raynal #include <fdtdec.h>
34cfcc706cSMiquel Raynal #endif
35cfcc706cSMiquel Raynal #include <malloc.h>
36cfcc706cSMiquel Raynal #include <watchdog.h>
37cfcc706cSMiquel Raynal #include <linux/err.h>
38cfcc706cSMiquel Raynal #include <linux/compat.h>
39cfcc706cSMiquel Raynal #include <linux/mtd/mtd.h>
40cfcc706cSMiquel Raynal #include <linux/mtd/rawnand.h>
41cfcc706cSMiquel Raynal #include <linux/mtd/nand_ecc.h>
42cfcc706cSMiquel Raynal #include <linux/mtd/nand_bch.h>
43cfcc706cSMiquel Raynal #ifdef CONFIG_MTD_PARTITIONS
44cfcc706cSMiquel Raynal #include <linux/mtd/partitions.h>
45cfcc706cSMiquel Raynal #endif
46cfcc706cSMiquel Raynal #include <asm/io.h>
47cfcc706cSMiquel Raynal #include <linux/errno.h>
48cfcc706cSMiquel Raynal
49cfcc706cSMiquel Raynal /* Define default oob placement schemes for large and small page devices */
50*0cc120e3SGregory CLEMENT #ifndef CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT
51cfcc706cSMiquel Raynal static struct nand_ecclayout nand_oob_8 = {
52cfcc706cSMiquel Raynal .eccbytes = 3,
53cfcc706cSMiquel Raynal .eccpos = {0, 1, 2},
54cfcc706cSMiquel Raynal .oobfree = {
55cfcc706cSMiquel Raynal {.offset = 3,
56cfcc706cSMiquel Raynal .length = 2},
57cfcc706cSMiquel Raynal {.offset = 6,
58cfcc706cSMiquel Raynal .length = 2} }
59cfcc706cSMiquel Raynal };
60cfcc706cSMiquel Raynal
61cfcc706cSMiquel Raynal static struct nand_ecclayout nand_oob_16 = {
62cfcc706cSMiquel Raynal .eccbytes = 6,
63cfcc706cSMiquel Raynal .eccpos = {0, 1, 2, 3, 6, 7},
64cfcc706cSMiquel Raynal .oobfree = {
65cfcc706cSMiquel Raynal {.offset = 8,
66cfcc706cSMiquel Raynal . length = 8} }
67cfcc706cSMiquel Raynal };
68cfcc706cSMiquel Raynal
69cfcc706cSMiquel Raynal static struct nand_ecclayout nand_oob_64 = {
70cfcc706cSMiquel Raynal .eccbytes = 24,
71cfcc706cSMiquel Raynal .eccpos = {
72cfcc706cSMiquel Raynal 40, 41, 42, 43, 44, 45, 46, 47,
73cfcc706cSMiquel Raynal 48, 49, 50, 51, 52, 53, 54, 55,
74cfcc706cSMiquel Raynal 56, 57, 58, 59, 60, 61, 62, 63},
75cfcc706cSMiquel Raynal .oobfree = {
76cfcc706cSMiquel Raynal {.offset = 2,
77cfcc706cSMiquel Raynal .length = 38} }
78cfcc706cSMiquel Raynal };
79cfcc706cSMiquel Raynal
80cfcc706cSMiquel Raynal static struct nand_ecclayout nand_oob_128 = {
81cfcc706cSMiquel Raynal .eccbytes = 48,
82cfcc706cSMiquel Raynal .eccpos = {
83cfcc706cSMiquel Raynal 80, 81, 82, 83, 84, 85, 86, 87,
84cfcc706cSMiquel Raynal 88, 89, 90, 91, 92, 93, 94, 95,
85cfcc706cSMiquel Raynal 96, 97, 98, 99, 100, 101, 102, 103,
86cfcc706cSMiquel Raynal 104, 105, 106, 107, 108, 109, 110, 111,
87cfcc706cSMiquel Raynal 112, 113, 114, 115, 116, 117, 118, 119,
88cfcc706cSMiquel Raynal 120, 121, 122, 123, 124, 125, 126, 127},
89cfcc706cSMiquel Raynal .oobfree = {
90cfcc706cSMiquel Raynal {.offset = 2,
91cfcc706cSMiquel Raynal .length = 78} }
92cfcc706cSMiquel Raynal };
9350c9e2f7SStefan Agner #endif
94cfcc706cSMiquel Raynal
95cfcc706cSMiquel Raynal static int nand_get_device(struct mtd_info *mtd, int new_state);
96cfcc706cSMiquel Raynal
97cfcc706cSMiquel Raynal static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
98cfcc706cSMiquel Raynal struct mtd_oob_ops *ops);
99cfcc706cSMiquel Raynal
100cfcc706cSMiquel Raynal /*
101cfcc706cSMiquel Raynal * For devices which display every fart in the system on a separate LED. Is
102cfcc706cSMiquel Raynal * compiled away when LED support is disabled.
103cfcc706cSMiquel Raynal */
104cfcc706cSMiquel Raynal DEFINE_LED_TRIGGER(nand_led_trigger);
105cfcc706cSMiquel Raynal
check_offs_len(struct mtd_info * mtd,loff_t ofs,uint64_t len)106cfcc706cSMiquel Raynal static int check_offs_len(struct mtd_info *mtd,
107cfcc706cSMiquel Raynal loff_t ofs, uint64_t len)
108cfcc706cSMiquel Raynal {
109cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
110cfcc706cSMiquel Raynal int ret = 0;
111cfcc706cSMiquel Raynal
112cfcc706cSMiquel Raynal /* Start address must align on block boundary */
113cfcc706cSMiquel Raynal if (ofs & ((1ULL << chip->phys_erase_shift) - 1)) {
114cfcc706cSMiquel Raynal pr_debug("%s: unaligned address\n", __func__);
115cfcc706cSMiquel Raynal ret = -EINVAL;
116cfcc706cSMiquel Raynal }
117cfcc706cSMiquel Raynal
118cfcc706cSMiquel Raynal /* Length must align on block boundary */
119cfcc706cSMiquel Raynal if (len & ((1ULL << chip->phys_erase_shift) - 1)) {
120cfcc706cSMiquel Raynal pr_debug("%s: length not block aligned\n", __func__);
121cfcc706cSMiquel Raynal ret = -EINVAL;
122cfcc706cSMiquel Raynal }
123cfcc706cSMiquel Raynal
124cfcc706cSMiquel Raynal return ret;
125cfcc706cSMiquel Raynal }
126cfcc706cSMiquel Raynal
127cfcc706cSMiquel Raynal /**
128cfcc706cSMiquel Raynal * nand_release_device - [GENERIC] release chip
129cfcc706cSMiquel Raynal * @mtd: MTD device structure
130cfcc706cSMiquel Raynal *
131cfcc706cSMiquel Raynal * Release chip lock and wake up anyone waiting on the device.
132cfcc706cSMiquel Raynal */
nand_release_device(struct mtd_info * mtd)133cfcc706cSMiquel Raynal static void nand_release_device(struct mtd_info *mtd)
134cfcc706cSMiquel Raynal {
135cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
136cfcc706cSMiquel Raynal
137cfcc706cSMiquel Raynal /* De-select the NAND device */
138cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
139cfcc706cSMiquel Raynal }
140cfcc706cSMiquel Raynal
141cfcc706cSMiquel Raynal /**
142cfcc706cSMiquel Raynal * nand_read_byte - [DEFAULT] read one byte from the chip
143cfcc706cSMiquel Raynal * @mtd: MTD device structure
144cfcc706cSMiquel Raynal *
145cfcc706cSMiquel Raynal * Default read function for 8bit buswidth
146cfcc706cSMiquel Raynal */
nand_read_byte(struct mtd_info * mtd)147cfcc706cSMiquel Raynal uint8_t nand_read_byte(struct mtd_info *mtd)
148cfcc706cSMiquel Raynal {
149cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
150cfcc706cSMiquel Raynal return readb(chip->IO_ADDR_R);
151cfcc706cSMiquel Raynal }
152cfcc706cSMiquel Raynal
153cfcc706cSMiquel Raynal /**
154cfcc706cSMiquel Raynal * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
155cfcc706cSMiquel Raynal * @mtd: MTD device structure
156cfcc706cSMiquel Raynal *
157cfcc706cSMiquel Raynal * Default read function for 16bit buswidth with endianness conversion.
158cfcc706cSMiquel Raynal *
159cfcc706cSMiquel Raynal */
nand_read_byte16(struct mtd_info * mtd)160cfcc706cSMiquel Raynal static uint8_t nand_read_byte16(struct mtd_info *mtd)
161cfcc706cSMiquel Raynal {
162cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
163cfcc706cSMiquel Raynal return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R));
164cfcc706cSMiquel Raynal }
165cfcc706cSMiquel Raynal
166cfcc706cSMiquel Raynal /**
167cfcc706cSMiquel Raynal * nand_read_word - [DEFAULT] read one word from the chip
168cfcc706cSMiquel Raynal * @mtd: MTD device structure
169cfcc706cSMiquel Raynal *
170cfcc706cSMiquel Raynal * Default read function for 16bit buswidth without endianness conversion.
171cfcc706cSMiquel Raynal */
nand_read_word(struct mtd_info * mtd)172cfcc706cSMiquel Raynal static u16 nand_read_word(struct mtd_info *mtd)
173cfcc706cSMiquel Raynal {
174cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
175cfcc706cSMiquel Raynal return readw(chip->IO_ADDR_R);
176cfcc706cSMiquel Raynal }
177cfcc706cSMiquel Raynal
178cfcc706cSMiquel Raynal /**
179cfcc706cSMiquel Raynal * nand_select_chip - [DEFAULT] control CE line
180cfcc706cSMiquel Raynal * @mtd: MTD device structure
181cfcc706cSMiquel Raynal * @chipnr: chipnumber to select, -1 for deselect
182cfcc706cSMiquel Raynal *
183cfcc706cSMiquel Raynal * Default select function for 1 chip devices.
184cfcc706cSMiquel Raynal */
nand_select_chip(struct mtd_info * mtd,int chipnr)185cfcc706cSMiquel Raynal static void nand_select_chip(struct mtd_info *mtd, int chipnr)
186cfcc706cSMiquel Raynal {
187cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
188cfcc706cSMiquel Raynal
189cfcc706cSMiquel Raynal switch (chipnr) {
190cfcc706cSMiquel Raynal case -1:
191cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
192cfcc706cSMiquel Raynal break;
193cfcc706cSMiquel Raynal case 0:
194cfcc706cSMiquel Raynal break;
195cfcc706cSMiquel Raynal
196cfcc706cSMiquel Raynal default:
197cfcc706cSMiquel Raynal BUG();
198cfcc706cSMiquel Raynal }
199cfcc706cSMiquel Raynal }
200cfcc706cSMiquel Raynal
201cfcc706cSMiquel Raynal /**
202cfcc706cSMiquel Raynal * nand_write_byte - [DEFAULT] write single byte to chip
203cfcc706cSMiquel Raynal * @mtd: MTD device structure
204cfcc706cSMiquel Raynal * @byte: value to write
205cfcc706cSMiquel Raynal *
206cfcc706cSMiquel Raynal * Default function to write a byte to I/O[7:0]
207cfcc706cSMiquel Raynal */
nand_write_byte(struct mtd_info * mtd,uint8_t byte)208cfcc706cSMiquel Raynal static void nand_write_byte(struct mtd_info *mtd, uint8_t byte)
209cfcc706cSMiquel Raynal {
210cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
211cfcc706cSMiquel Raynal
212cfcc706cSMiquel Raynal chip->write_buf(mtd, &byte, 1);
213cfcc706cSMiquel Raynal }
214cfcc706cSMiquel Raynal
215cfcc706cSMiquel Raynal /**
216cfcc706cSMiquel Raynal * nand_write_byte16 - [DEFAULT] write single byte to a chip with width 16
217cfcc706cSMiquel Raynal * @mtd: MTD device structure
218cfcc706cSMiquel Raynal * @byte: value to write
219cfcc706cSMiquel Raynal *
220cfcc706cSMiquel Raynal * Default function to write a byte to I/O[7:0] on a 16-bit wide chip.
221cfcc706cSMiquel Raynal */
nand_write_byte16(struct mtd_info * mtd,uint8_t byte)222cfcc706cSMiquel Raynal static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
223cfcc706cSMiquel Raynal {
224cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
225cfcc706cSMiquel Raynal uint16_t word = byte;
226cfcc706cSMiquel Raynal
227cfcc706cSMiquel Raynal /*
228cfcc706cSMiquel Raynal * It's not entirely clear what should happen to I/O[15:8] when writing
229cfcc706cSMiquel Raynal * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads:
230cfcc706cSMiquel Raynal *
231cfcc706cSMiquel Raynal * When the host supports a 16-bit bus width, only data is
232cfcc706cSMiquel Raynal * transferred at the 16-bit width. All address and command line
233cfcc706cSMiquel Raynal * transfers shall use only the lower 8-bits of the data bus. During
234cfcc706cSMiquel Raynal * command transfers, the host may place any value on the upper
235cfcc706cSMiquel Raynal * 8-bits of the data bus. During address transfers, the host shall
236cfcc706cSMiquel Raynal * set the upper 8-bits of the data bus to 00h.
237cfcc706cSMiquel Raynal *
238cfcc706cSMiquel Raynal * One user of the write_byte callback is nand_onfi_set_features. The
239cfcc706cSMiquel Raynal * four parameters are specified to be written to I/O[7:0], but this is
240cfcc706cSMiquel Raynal * neither an address nor a command transfer. Let's assume a 0 on the
241cfcc706cSMiquel Raynal * upper I/O lines is OK.
242cfcc706cSMiquel Raynal */
243cfcc706cSMiquel Raynal chip->write_buf(mtd, (uint8_t *)&word, 2);
244cfcc706cSMiquel Raynal }
245cfcc706cSMiquel Raynal
iowrite8_rep(void * addr,const uint8_t * buf,int len)246cfcc706cSMiquel Raynal static void iowrite8_rep(void *addr, const uint8_t *buf, int len)
247cfcc706cSMiquel Raynal {
248cfcc706cSMiquel Raynal int i;
249cfcc706cSMiquel Raynal
250cfcc706cSMiquel Raynal for (i = 0; i < len; i++)
251cfcc706cSMiquel Raynal writeb(buf[i], addr);
252cfcc706cSMiquel Raynal }
ioread8_rep(void * addr,uint8_t * buf,int len)253cfcc706cSMiquel Raynal static void ioread8_rep(void *addr, uint8_t *buf, int len)
254cfcc706cSMiquel Raynal {
255cfcc706cSMiquel Raynal int i;
256cfcc706cSMiquel Raynal
257cfcc706cSMiquel Raynal for (i = 0; i < len; i++)
258cfcc706cSMiquel Raynal buf[i] = readb(addr);
259cfcc706cSMiquel Raynal }
260cfcc706cSMiquel Raynal
ioread16_rep(void * addr,void * buf,int len)261cfcc706cSMiquel Raynal static void ioread16_rep(void *addr, void *buf, int len)
262cfcc706cSMiquel Raynal {
263cfcc706cSMiquel Raynal int i;
264cfcc706cSMiquel Raynal u16 *p = (u16 *) buf;
265cfcc706cSMiquel Raynal
266cfcc706cSMiquel Raynal for (i = 0; i < len; i++)
267cfcc706cSMiquel Raynal p[i] = readw(addr);
268cfcc706cSMiquel Raynal }
269cfcc706cSMiquel Raynal
iowrite16_rep(void * addr,void * buf,int len)270cfcc706cSMiquel Raynal static void iowrite16_rep(void *addr, void *buf, int len)
271cfcc706cSMiquel Raynal {
272cfcc706cSMiquel Raynal int i;
273cfcc706cSMiquel Raynal u16 *p = (u16 *) buf;
274cfcc706cSMiquel Raynal
275cfcc706cSMiquel Raynal for (i = 0; i < len; i++)
276cfcc706cSMiquel Raynal writew(p[i], addr);
277cfcc706cSMiquel Raynal }
278cfcc706cSMiquel Raynal
279cfcc706cSMiquel Raynal /**
280cfcc706cSMiquel Raynal * nand_write_buf - [DEFAULT] write buffer to chip
281cfcc706cSMiquel Raynal * @mtd: MTD device structure
282cfcc706cSMiquel Raynal * @buf: data buffer
283cfcc706cSMiquel Raynal * @len: number of bytes to write
284cfcc706cSMiquel Raynal *
285cfcc706cSMiquel Raynal * Default write function for 8bit buswidth.
286cfcc706cSMiquel Raynal */
nand_write_buf(struct mtd_info * mtd,const uint8_t * buf,int len)287cfcc706cSMiquel Raynal void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
288cfcc706cSMiquel Raynal {
289cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
290cfcc706cSMiquel Raynal
291cfcc706cSMiquel Raynal iowrite8_rep(chip->IO_ADDR_W, buf, len);
292cfcc706cSMiquel Raynal }
293cfcc706cSMiquel Raynal
294cfcc706cSMiquel Raynal /**
295cfcc706cSMiquel Raynal * nand_read_buf - [DEFAULT] read chip data into buffer
296cfcc706cSMiquel Raynal * @mtd: MTD device structure
297cfcc706cSMiquel Raynal * @buf: buffer to store date
298cfcc706cSMiquel Raynal * @len: number of bytes to read
299cfcc706cSMiquel Raynal *
300cfcc706cSMiquel Raynal * Default read function for 8bit buswidth.
301cfcc706cSMiquel Raynal */
nand_read_buf(struct mtd_info * mtd,uint8_t * buf,int len)302cfcc706cSMiquel Raynal void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
303cfcc706cSMiquel Raynal {
304cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
305cfcc706cSMiquel Raynal
306cfcc706cSMiquel Raynal ioread8_rep(chip->IO_ADDR_R, buf, len);
307cfcc706cSMiquel Raynal }
308cfcc706cSMiquel Raynal
309cfcc706cSMiquel Raynal /**
310cfcc706cSMiquel Raynal * nand_write_buf16 - [DEFAULT] write buffer to chip
311cfcc706cSMiquel Raynal * @mtd: MTD device structure
312cfcc706cSMiquel Raynal * @buf: data buffer
313cfcc706cSMiquel Raynal * @len: number of bytes to write
314cfcc706cSMiquel Raynal *
315cfcc706cSMiquel Raynal * Default write function for 16bit buswidth.
316cfcc706cSMiquel Raynal */
nand_write_buf16(struct mtd_info * mtd,const uint8_t * buf,int len)317cfcc706cSMiquel Raynal void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
318cfcc706cSMiquel Raynal {
319cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
320cfcc706cSMiquel Raynal u16 *p = (u16 *) buf;
321cfcc706cSMiquel Raynal
322cfcc706cSMiquel Raynal iowrite16_rep(chip->IO_ADDR_W, p, len >> 1);
323cfcc706cSMiquel Raynal }
324cfcc706cSMiquel Raynal
325cfcc706cSMiquel Raynal /**
326cfcc706cSMiquel Raynal * nand_read_buf16 - [DEFAULT] read chip data into buffer
327cfcc706cSMiquel Raynal * @mtd: MTD device structure
328cfcc706cSMiquel Raynal * @buf: buffer to store date
329cfcc706cSMiquel Raynal * @len: number of bytes to read
330cfcc706cSMiquel Raynal *
331cfcc706cSMiquel Raynal * Default read function for 16bit buswidth.
332cfcc706cSMiquel Raynal */
nand_read_buf16(struct mtd_info * mtd,uint8_t * buf,int len)333cfcc706cSMiquel Raynal void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
334cfcc706cSMiquel Raynal {
335cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
336cfcc706cSMiquel Raynal u16 *p = (u16 *) buf;
337cfcc706cSMiquel Raynal
338cfcc706cSMiquel Raynal ioread16_rep(chip->IO_ADDR_R, p, len >> 1);
339cfcc706cSMiquel Raynal }
340cfcc706cSMiquel Raynal
341cfcc706cSMiquel Raynal /**
342cfcc706cSMiquel Raynal * nand_block_bad - [DEFAULT] Read bad block marker from the chip
343cfcc706cSMiquel Raynal * @mtd: MTD device structure
344cfcc706cSMiquel Raynal * @ofs: offset from device start
345cfcc706cSMiquel Raynal *
346cfcc706cSMiquel Raynal * Check, if the block is bad.
347cfcc706cSMiquel Raynal */
nand_block_bad(struct mtd_info * mtd,loff_t ofs)348cfcc706cSMiquel Raynal static int nand_block_bad(struct mtd_info *mtd, loff_t ofs)
349cfcc706cSMiquel Raynal {
350cfcc706cSMiquel Raynal int page, res = 0, i = 0;
351cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
352cfcc706cSMiquel Raynal u16 bad;
353cfcc706cSMiquel Raynal
354cfcc706cSMiquel Raynal if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
355cfcc706cSMiquel Raynal ofs += mtd->erasesize - mtd->writesize;
356cfcc706cSMiquel Raynal
357cfcc706cSMiquel Raynal page = (int)(ofs >> chip->page_shift) & chip->pagemask;
358cfcc706cSMiquel Raynal
359cfcc706cSMiquel Raynal do {
360cfcc706cSMiquel Raynal if (chip->options & NAND_BUSWIDTH_16) {
361cfcc706cSMiquel Raynal chip->cmdfunc(mtd, NAND_CMD_READOOB,
362cfcc706cSMiquel Raynal chip->badblockpos & 0xFE, page);
363cfcc706cSMiquel Raynal bad = cpu_to_le16(chip->read_word(mtd));
364cfcc706cSMiquel Raynal if (chip->badblockpos & 0x1)
365cfcc706cSMiquel Raynal bad >>= 8;
366cfcc706cSMiquel Raynal else
367cfcc706cSMiquel Raynal bad &= 0xFF;
368cfcc706cSMiquel Raynal } else {
369cfcc706cSMiquel Raynal chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos,
370cfcc706cSMiquel Raynal page);
371cfcc706cSMiquel Raynal bad = chip->read_byte(mtd);
372cfcc706cSMiquel Raynal }
373cfcc706cSMiquel Raynal
374cfcc706cSMiquel Raynal if (likely(chip->badblockbits == 8))
375cfcc706cSMiquel Raynal res = bad != 0xFF;
376cfcc706cSMiquel Raynal else
377cfcc706cSMiquel Raynal res = hweight8(bad) < chip->badblockbits;
378cfcc706cSMiquel Raynal ofs += mtd->writesize;
379cfcc706cSMiquel Raynal page = (int)(ofs >> chip->page_shift) & chip->pagemask;
380cfcc706cSMiquel Raynal i++;
381cfcc706cSMiquel Raynal } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));
382cfcc706cSMiquel Raynal
383cfcc706cSMiquel Raynal return res;
384cfcc706cSMiquel Raynal }
385cfcc706cSMiquel Raynal
386cfcc706cSMiquel Raynal /**
387cfcc706cSMiquel Raynal * nand_default_block_markbad - [DEFAULT] mark a block bad via bad block marker
388cfcc706cSMiquel Raynal * @mtd: MTD device structure
389cfcc706cSMiquel Raynal * @ofs: offset from device start
390cfcc706cSMiquel Raynal *
391cfcc706cSMiquel Raynal * This is the default implementation, which can be overridden by a hardware
392cfcc706cSMiquel Raynal * specific driver. It provides the details for writing a bad block marker to a
393cfcc706cSMiquel Raynal * block.
394cfcc706cSMiquel Raynal */
nand_default_block_markbad(struct mtd_info * mtd,loff_t ofs)395cfcc706cSMiquel Raynal static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
396cfcc706cSMiquel Raynal {
397cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
398cfcc706cSMiquel Raynal struct mtd_oob_ops ops;
399cfcc706cSMiquel Raynal uint8_t buf[2] = { 0, 0 };
400cfcc706cSMiquel Raynal int ret = 0, res, i = 0;
401cfcc706cSMiquel Raynal
402cfcc706cSMiquel Raynal memset(&ops, 0, sizeof(ops));
403cfcc706cSMiquel Raynal ops.oobbuf = buf;
404cfcc706cSMiquel Raynal ops.ooboffs = chip->badblockpos;
405cfcc706cSMiquel Raynal if (chip->options & NAND_BUSWIDTH_16) {
406cfcc706cSMiquel Raynal ops.ooboffs &= ~0x01;
407cfcc706cSMiquel Raynal ops.len = ops.ooblen = 2;
408cfcc706cSMiquel Raynal } else {
409cfcc706cSMiquel Raynal ops.len = ops.ooblen = 1;
410cfcc706cSMiquel Raynal }
411cfcc706cSMiquel Raynal ops.mode = MTD_OPS_PLACE_OOB;
412cfcc706cSMiquel Raynal
413cfcc706cSMiquel Raynal /* Write to first/last page(s) if necessary */
414cfcc706cSMiquel Raynal if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
415cfcc706cSMiquel Raynal ofs += mtd->erasesize - mtd->writesize;
416cfcc706cSMiquel Raynal do {
417cfcc706cSMiquel Raynal res = nand_do_write_oob(mtd, ofs, &ops);
418cfcc706cSMiquel Raynal if (!ret)
419cfcc706cSMiquel Raynal ret = res;
420cfcc706cSMiquel Raynal
421cfcc706cSMiquel Raynal i++;
422cfcc706cSMiquel Raynal ofs += mtd->writesize;
423cfcc706cSMiquel Raynal } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);
424cfcc706cSMiquel Raynal
425cfcc706cSMiquel Raynal return ret;
426cfcc706cSMiquel Raynal }
427cfcc706cSMiquel Raynal
428cfcc706cSMiquel Raynal /**
429cfcc706cSMiquel Raynal * nand_block_markbad_lowlevel - mark a block bad
430cfcc706cSMiquel Raynal * @mtd: MTD device structure
431cfcc706cSMiquel Raynal * @ofs: offset from device start
432cfcc706cSMiquel Raynal *
433cfcc706cSMiquel Raynal * This function performs the generic NAND bad block marking steps (i.e., bad
434cfcc706cSMiquel Raynal * block table(s) and/or marker(s)). We only allow the hardware driver to
435cfcc706cSMiquel Raynal * specify how to write bad block markers to OOB (chip->block_markbad).
436cfcc706cSMiquel Raynal *
437cfcc706cSMiquel Raynal * We try operations in the following order:
438cfcc706cSMiquel Raynal * (1) erase the affected block, to allow OOB marker to be written cleanly
439cfcc706cSMiquel Raynal * (2) write bad block marker to OOB area of affected block (unless flag
440cfcc706cSMiquel Raynal * NAND_BBT_NO_OOB_BBM is present)
441cfcc706cSMiquel Raynal * (3) update the BBT
442cfcc706cSMiquel Raynal * Note that we retain the first error encountered in (2) or (3), finish the
443cfcc706cSMiquel Raynal * procedures, and dump the error in the end.
444cfcc706cSMiquel Raynal */
nand_block_markbad_lowlevel(struct mtd_info * mtd,loff_t ofs)445cfcc706cSMiquel Raynal static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
446cfcc706cSMiquel Raynal {
447cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
448cfcc706cSMiquel Raynal int res, ret = 0;
449cfcc706cSMiquel Raynal
450cfcc706cSMiquel Raynal if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) {
451cfcc706cSMiquel Raynal struct erase_info einfo;
452cfcc706cSMiquel Raynal
453cfcc706cSMiquel Raynal /* Attempt erase before marking OOB */
454cfcc706cSMiquel Raynal memset(&einfo, 0, sizeof(einfo));
455cfcc706cSMiquel Raynal einfo.mtd = mtd;
456cfcc706cSMiquel Raynal einfo.addr = ofs;
457cfcc706cSMiquel Raynal einfo.len = 1ULL << chip->phys_erase_shift;
458cfcc706cSMiquel Raynal nand_erase_nand(mtd, &einfo, 0);
459cfcc706cSMiquel Raynal
460cfcc706cSMiquel Raynal /* Write bad block marker to OOB */
461cfcc706cSMiquel Raynal nand_get_device(mtd, FL_WRITING);
462cfcc706cSMiquel Raynal ret = chip->block_markbad(mtd, ofs);
463cfcc706cSMiquel Raynal nand_release_device(mtd);
464cfcc706cSMiquel Raynal }
465cfcc706cSMiquel Raynal
466cfcc706cSMiquel Raynal /* Mark block bad in BBT */
467cfcc706cSMiquel Raynal if (chip->bbt) {
468cfcc706cSMiquel Raynal res = nand_markbad_bbt(mtd, ofs);
469cfcc706cSMiquel Raynal if (!ret)
470cfcc706cSMiquel Raynal ret = res;
471cfcc706cSMiquel Raynal }
472cfcc706cSMiquel Raynal
473cfcc706cSMiquel Raynal if (!ret)
474cfcc706cSMiquel Raynal mtd->ecc_stats.badblocks++;
475cfcc706cSMiquel Raynal
476cfcc706cSMiquel Raynal return ret;
477cfcc706cSMiquel Raynal }
478cfcc706cSMiquel Raynal
479cfcc706cSMiquel Raynal /**
480cfcc706cSMiquel Raynal * nand_check_wp - [GENERIC] check if the chip is write protected
481cfcc706cSMiquel Raynal * @mtd: MTD device structure
482cfcc706cSMiquel Raynal *
483cfcc706cSMiquel Raynal * Check, if the device is write protected. The function expects, that the
484cfcc706cSMiquel Raynal * device is already selected.
485cfcc706cSMiquel Raynal */
nand_check_wp(struct mtd_info * mtd)486cfcc706cSMiquel Raynal static int nand_check_wp(struct mtd_info *mtd)
487cfcc706cSMiquel Raynal {
488cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
48973ecea3dSBoris Brezillon u8 status;
49073ecea3dSBoris Brezillon int ret;
491cfcc706cSMiquel Raynal
492cfcc706cSMiquel Raynal /* Broken xD cards report WP despite being writable */
493cfcc706cSMiquel Raynal if (chip->options & NAND_BROKEN_XD)
494cfcc706cSMiquel Raynal return 0;
495cfcc706cSMiquel Raynal
496cfcc706cSMiquel Raynal /* Check the WP bit */
49773ecea3dSBoris Brezillon ret = nand_status_op(chip, &status);
49873ecea3dSBoris Brezillon if (ret)
49973ecea3dSBoris Brezillon return ret;
50073ecea3dSBoris Brezillon
50173ecea3dSBoris Brezillon return status & NAND_STATUS_WP ? 0 : 1;
502cfcc706cSMiquel Raynal }
503cfcc706cSMiquel Raynal
504cfcc706cSMiquel Raynal /**
505cfcc706cSMiquel Raynal * nand_block_isreserved - [GENERIC] Check if a block is marked reserved.
506cfcc706cSMiquel Raynal * @mtd: MTD device structure
507cfcc706cSMiquel Raynal * @ofs: offset from device start
508cfcc706cSMiquel Raynal *
509cfcc706cSMiquel Raynal * Check if the block is marked as reserved.
510cfcc706cSMiquel Raynal */
nand_block_isreserved(struct mtd_info * mtd,loff_t ofs)511cfcc706cSMiquel Raynal static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs)
512cfcc706cSMiquel Raynal {
513cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
514cfcc706cSMiquel Raynal
515cfcc706cSMiquel Raynal if (!chip->bbt)
516cfcc706cSMiquel Raynal return 0;
517cfcc706cSMiquel Raynal /* Return info from the table */
518cfcc706cSMiquel Raynal return nand_isreserved_bbt(mtd, ofs);
519cfcc706cSMiquel Raynal }
520cfcc706cSMiquel Raynal
521cfcc706cSMiquel Raynal /**
522cfcc706cSMiquel Raynal * nand_block_checkbad - [GENERIC] Check if a block is marked bad
523cfcc706cSMiquel Raynal * @mtd: MTD device structure
524cfcc706cSMiquel Raynal * @ofs: offset from device start
525cfcc706cSMiquel Raynal * @allowbbt: 1, if its allowed to access the bbt area
526cfcc706cSMiquel Raynal *
527cfcc706cSMiquel Raynal * Check, if the block is bad. Either by reading the bad block table or
528cfcc706cSMiquel Raynal * calling of the scan function.
529cfcc706cSMiquel Raynal */
nand_block_checkbad(struct mtd_info * mtd,loff_t ofs,int allowbbt)530cfcc706cSMiquel Raynal static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt)
531cfcc706cSMiquel Raynal {
532cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
533cfcc706cSMiquel Raynal
534cfcc706cSMiquel Raynal if (!(chip->options & NAND_SKIP_BBTSCAN) &&
535cfcc706cSMiquel Raynal !(chip->options & NAND_BBT_SCANNED)) {
536cfcc706cSMiquel Raynal chip->options |= NAND_BBT_SCANNED;
537cfcc706cSMiquel Raynal chip->scan_bbt(mtd);
538cfcc706cSMiquel Raynal }
539cfcc706cSMiquel Raynal
540cfcc706cSMiquel Raynal if (!chip->bbt)
541cfcc706cSMiquel Raynal return chip->block_bad(mtd, ofs);
542cfcc706cSMiquel Raynal
543cfcc706cSMiquel Raynal /* Return info from the table */
544cfcc706cSMiquel Raynal return nand_isbad_bbt(mtd, ofs, allowbbt);
545cfcc706cSMiquel Raynal }
546cfcc706cSMiquel Raynal
547cfcc706cSMiquel Raynal /**
548cfcc706cSMiquel Raynal * nand_wait_ready - [GENERIC] Wait for the ready pin after commands.
549cfcc706cSMiquel Raynal * @mtd: MTD device structure
550cfcc706cSMiquel Raynal *
551cfcc706cSMiquel Raynal * Wait for the ready pin after a command, and warn if a timeout occurs.
552cfcc706cSMiquel Raynal */
nand_wait_ready(struct mtd_info * mtd)553cfcc706cSMiquel Raynal void nand_wait_ready(struct mtd_info *mtd)
554cfcc706cSMiquel Raynal {
555cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
556cfcc706cSMiquel Raynal u32 timeo = (CONFIG_SYS_HZ * 400) / 1000;
557cfcc706cSMiquel Raynal u32 time_start;
558cfcc706cSMiquel Raynal
559cfcc706cSMiquel Raynal time_start = get_timer(0);
560cfcc706cSMiquel Raynal /* Wait until command is processed or timeout occurs */
561cfcc706cSMiquel Raynal while (get_timer(time_start) < timeo) {
562cfcc706cSMiquel Raynal if (chip->dev_ready)
563cfcc706cSMiquel Raynal if (chip->dev_ready(mtd))
564cfcc706cSMiquel Raynal break;
565cfcc706cSMiquel Raynal }
566cfcc706cSMiquel Raynal
567cfcc706cSMiquel Raynal if (!chip->dev_ready(mtd))
568cfcc706cSMiquel Raynal pr_warn("timeout while waiting for chip to become ready\n");
569cfcc706cSMiquel Raynal }
570cfcc706cSMiquel Raynal EXPORT_SYMBOL_GPL(nand_wait_ready);
571cfcc706cSMiquel Raynal
572cfcc706cSMiquel Raynal /**
573cfcc706cSMiquel Raynal * nand_wait_status_ready - [GENERIC] Wait for the ready status after commands.
574cfcc706cSMiquel Raynal * @mtd: MTD device structure
575cfcc706cSMiquel Raynal * @timeo: Timeout in ms
576cfcc706cSMiquel Raynal *
577cfcc706cSMiquel Raynal * Wait for status ready (i.e. command done) or timeout.
578cfcc706cSMiquel Raynal */
nand_wait_status_ready(struct mtd_info * mtd,unsigned long timeo)579cfcc706cSMiquel Raynal static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo)
580cfcc706cSMiquel Raynal {
581cfcc706cSMiquel Raynal register struct nand_chip *chip = mtd_to_nand(mtd);
582cfcc706cSMiquel Raynal u32 time_start;
58373ecea3dSBoris Brezillon int ret;
584cfcc706cSMiquel Raynal
585cfcc706cSMiquel Raynal timeo = (CONFIG_SYS_HZ * timeo) / 1000;
586cfcc706cSMiquel Raynal time_start = get_timer(0);
587cfcc706cSMiquel Raynal while (get_timer(time_start) < timeo) {
58873ecea3dSBoris Brezillon u8 status;
58973ecea3dSBoris Brezillon
59073ecea3dSBoris Brezillon ret = nand_read_data_op(chip, &status, sizeof(status), true);
59173ecea3dSBoris Brezillon if (ret)
59273ecea3dSBoris Brezillon return;
59373ecea3dSBoris Brezillon
59473ecea3dSBoris Brezillon if (status & NAND_STATUS_READY)
595cfcc706cSMiquel Raynal break;
596cfcc706cSMiquel Raynal WATCHDOG_RESET();
597cfcc706cSMiquel Raynal }
598cfcc706cSMiquel Raynal };
599cfcc706cSMiquel Raynal
600cfcc706cSMiquel Raynal /**
601cfcc706cSMiquel Raynal * nand_command - [DEFAULT] Send command to NAND device
602cfcc706cSMiquel Raynal * @mtd: MTD device structure
603cfcc706cSMiquel Raynal * @command: the command to be sent
604cfcc706cSMiquel Raynal * @column: the column address for this command, -1 if none
605cfcc706cSMiquel Raynal * @page_addr: the page address for this command, -1 if none
606cfcc706cSMiquel Raynal *
607cfcc706cSMiquel Raynal * Send command to NAND device. This function is used for small page devices
608cfcc706cSMiquel Raynal * (512 Bytes per page).
609cfcc706cSMiquel Raynal */
nand_command(struct mtd_info * mtd,unsigned int command,int column,int page_addr)610cfcc706cSMiquel Raynal static void nand_command(struct mtd_info *mtd, unsigned int command,
611cfcc706cSMiquel Raynal int column, int page_addr)
612cfcc706cSMiquel Raynal {
613cfcc706cSMiquel Raynal register struct nand_chip *chip = mtd_to_nand(mtd);
614cfcc706cSMiquel Raynal int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
615cfcc706cSMiquel Raynal
616cfcc706cSMiquel Raynal /* Write out the command to the device */
617cfcc706cSMiquel Raynal if (command == NAND_CMD_SEQIN) {
618cfcc706cSMiquel Raynal int readcmd;
619cfcc706cSMiquel Raynal
620cfcc706cSMiquel Raynal if (column >= mtd->writesize) {
621cfcc706cSMiquel Raynal /* OOB area */
622cfcc706cSMiquel Raynal column -= mtd->writesize;
623cfcc706cSMiquel Raynal readcmd = NAND_CMD_READOOB;
624cfcc706cSMiquel Raynal } else if (column < 256) {
625cfcc706cSMiquel Raynal /* First 256 bytes --> READ0 */
626cfcc706cSMiquel Raynal readcmd = NAND_CMD_READ0;
627cfcc706cSMiquel Raynal } else {
628cfcc706cSMiquel Raynal column -= 256;
629cfcc706cSMiquel Raynal readcmd = NAND_CMD_READ1;
630cfcc706cSMiquel Raynal }
631cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, readcmd, ctrl);
632cfcc706cSMiquel Raynal ctrl &= ~NAND_CTRL_CHANGE;
633cfcc706cSMiquel Raynal }
634cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, command, ctrl);
635cfcc706cSMiquel Raynal
636cfcc706cSMiquel Raynal /* Address cycle, when necessary */
637cfcc706cSMiquel Raynal ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
638cfcc706cSMiquel Raynal /* Serially input address */
639cfcc706cSMiquel Raynal if (column != -1) {
640cfcc706cSMiquel Raynal /* Adjust columns for 16 bit buswidth */
641cfcc706cSMiquel Raynal if (chip->options & NAND_BUSWIDTH_16 &&
642cfcc706cSMiquel Raynal !nand_opcode_8bits(command))
643cfcc706cSMiquel Raynal column >>= 1;
644cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, column, ctrl);
645cfcc706cSMiquel Raynal ctrl &= ~NAND_CTRL_CHANGE;
646cfcc706cSMiquel Raynal }
647cfcc706cSMiquel Raynal if (page_addr != -1) {
648cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, page_addr, ctrl);
649cfcc706cSMiquel Raynal ctrl &= ~NAND_CTRL_CHANGE;
650cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, page_addr >> 8, ctrl);
651cfcc706cSMiquel Raynal if (chip->options & NAND_ROW_ADDR_3)
652cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, page_addr >> 16, ctrl);
653cfcc706cSMiquel Raynal }
654cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
655cfcc706cSMiquel Raynal
656cfcc706cSMiquel Raynal /*
657cfcc706cSMiquel Raynal * Program and erase have their own busy handlers status and sequential
658cfcc706cSMiquel Raynal * in needs no delay
659cfcc706cSMiquel Raynal */
660cfcc706cSMiquel Raynal switch (command) {
661cfcc706cSMiquel Raynal
662cfcc706cSMiquel Raynal case NAND_CMD_PAGEPROG:
663cfcc706cSMiquel Raynal case NAND_CMD_ERASE1:
664cfcc706cSMiquel Raynal case NAND_CMD_ERASE2:
665cfcc706cSMiquel Raynal case NAND_CMD_SEQIN:
666cfcc706cSMiquel Raynal case NAND_CMD_STATUS:
667cfcc706cSMiquel Raynal case NAND_CMD_READID:
668cfcc706cSMiquel Raynal case NAND_CMD_SET_FEATURES:
669cfcc706cSMiquel Raynal return;
670cfcc706cSMiquel Raynal
671cfcc706cSMiquel Raynal case NAND_CMD_RESET:
672cfcc706cSMiquel Raynal if (chip->dev_ready)
673cfcc706cSMiquel Raynal break;
674cfcc706cSMiquel Raynal udelay(chip->chip_delay);
675cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
676cfcc706cSMiquel Raynal NAND_CTRL_CLE | NAND_CTRL_CHANGE);
677cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd,
678cfcc706cSMiquel Raynal NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
679cfcc706cSMiquel Raynal /* EZ-NAND can take upto 250ms as per ONFi v4.0 */
680cfcc706cSMiquel Raynal nand_wait_status_ready(mtd, 250);
681cfcc706cSMiquel Raynal return;
682cfcc706cSMiquel Raynal
683cfcc706cSMiquel Raynal /* This applies to read commands */
684cfcc706cSMiquel Raynal default:
685cfcc706cSMiquel Raynal /*
686cfcc706cSMiquel Raynal * If we don't have access to the busy pin, we apply the given
687cfcc706cSMiquel Raynal * command delay
688cfcc706cSMiquel Raynal */
689cfcc706cSMiquel Raynal if (!chip->dev_ready) {
690cfcc706cSMiquel Raynal udelay(chip->chip_delay);
691cfcc706cSMiquel Raynal return;
692cfcc706cSMiquel Raynal }
693cfcc706cSMiquel Raynal }
694cfcc706cSMiquel Raynal /*
695cfcc706cSMiquel Raynal * Apply this short delay always to ensure that we do wait tWB in
696cfcc706cSMiquel Raynal * any case on any machine.
697cfcc706cSMiquel Raynal */
698cfcc706cSMiquel Raynal ndelay(100);
699cfcc706cSMiquel Raynal
700cfcc706cSMiquel Raynal nand_wait_ready(mtd);
701cfcc706cSMiquel Raynal }
702cfcc706cSMiquel Raynal
703cfcc706cSMiquel Raynal /**
704cfcc706cSMiquel Raynal * nand_command_lp - [DEFAULT] Send command to NAND large page device
705cfcc706cSMiquel Raynal * @mtd: MTD device structure
706cfcc706cSMiquel Raynal * @command: the command to be sent
707cfcc706cSMiquel Raynal * @column: the column address for this command, -1 if none
708cfcc706cSMiquel Raynal * @page_addr: the page address for this command, -1 if none
709cfcc706cSMiquel Raynal *
710cfcc706cSMiquel Raynal * Send command to NAND device. This is the version for the new large page
711cfcc706cSMiquel Raynal * devices. We don't have the separate regions as we have in the small page
712cfcc706cSMiquel Raynal * devices. We must emulate NAND_CMD_READOOB to keep the code compatible.
713cfcc706cSMiquel Raynal */
nand_command_lp(struct mtd_info * mtd,unsigned int command,int column,int page_addr)714cfcc706cSMiquel Raynal static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
715cfcc706cSMiquel Raynal int column, int page_addr)
716cfcc706cSMiquel Raynal {
717cfcc706cSMiquel Raynal register struct nand_chip *chip = mtd_to_nand(mtd);
718cfcc706cSMiquel Raynal
719cfcc706cSMiquel Raynal /* Emulate NAND_CMD_READOOB */
720cfcc706cSMiquel Raynal if (command == NAND_CMD_READOOB) {
721cfcc706cSMiquel Raynal column += mtd->writesize;
722cfcc706cSMiquel Raynal command = NAND_CMD_READ0;
723cfcc706cSMiquel Raynal }
724cfcc706cSMiquel Raynal
725cfcc706cSMiquel Raynal /* Command latch cycle */
726cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
727cfcc706cSMiquel Raynal
728cfcc706cSMiquel Raynal if (column != -1 || page_addr != -1) {
729cfcc706cSMiquel Raynal int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
730cfcc706cSMiquel Raynal
731cfcc706cSMiquel Raynal /* Serially input address */
732cfcc706cSMiquel Raynal if (column != -1) {
733cfcc706cSMiquel Raynal /* Adjust columns for 16 bit buswidth */
734cfcc706cSMiquel Raynal if (chip->options & NAND_BUSWIDTH_16 &&
735cfcc706cSMiquel Raynal !nand_opcode_8bits(command))
736cfcc706cSMiquel Raynal column >>= 1;
737cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, column, ctrl);
738cfcc706cSMiquel Raynal ctrl &= ~NAND_CTRL_CHANGE;
739cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, column >> 8, ctrl);
740cfcc706cSMiquel Raynal }
741cfcc706cSMiquel Raynal if (page_addr != -1) {
742cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, page_addr, ctrl);
743cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, page_addr >> 8,
744cfcc706cSMiquel Raynal NAND_NCE | NAND_ALE);
745cfcc706cSMiquel Raynal if (chip->options & NAND_ROW_ADDR_3)
746cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, page_addr >> 16,
747cfcc706cSMiquel Raynal NAND_NCE | NAND_ALE);
748cfcc706cSMiquel Raynal }
749cfcc706cSMiquel Raynal }
750cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
751cfcc706cSMiquel Raynal
752cfcc706cSMiquel Raynal /*
753cfcc706cSMiquel Raynal * Program and erase have their own busy handlers status, sequential
754cfcc706cSMiquel Raynal * in and status need no delay.
755cfcc706cSMiquel Raynal */
756cfcc706cSMiquel Raynal switch (command) {
757cfcc706cSMiquel Raynal
758cfcc706cSMiquel Raynal case NAND_CMD_CACHEDPROG:
759cfcc706cSMiquel Raynal case NAND_CMD_PAGEPROG:
760cfcc706cSMiquel Raynal case NAND_CMD_ERASE1:
761cfcc706cSMiquel Raynal case NAND_CMD_ERASE2:
762cfcc706cSMiquel Raynal case NAND_CMD_SEQIN:
763cfcc706cSMiquel Raynal case NAND_CMD_RNDIN:
764cfcc706cSMiquel Raynal case NAND_CMD_STATUS:
765cfcc706cSMiquel Raynal case NAND_CMD_READID:
766cfcc706cSMiquel Raynal case NAND_CMD_SET_FEATURES:
767cfcc706cSMiquel Raynal return;
768cfcc706cSMiquel Raynal
769cfcc706cSMiquel Raynal case NAND_CMD_RESET:
770cfcc706cSMiquel Raynal if (chip->dev_ready)
771cfcc706cSMiquel Raynal break;
772cfcc706cSMiquel Raynal udelay(chip->chip_delay);
773cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
774cfcc706cSMiquel Raynal NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
775cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_NONE,
776cfcc706cSMiquel Raynal NAND_NCE | NAND_CTRL_CHANGE);
777cfcc706cSMiquel Raynal /* EZ-NAND can take upto 250ms as per ONFi v4.0 */
778cfcc706cSMiquel Raynal nand_wait_status_ready(mtd, 250);
779cfcc706cSMiquel Raynal return;
780cfcc706cSMiquel Raynal
781cfcc706cSMiquel Raynal case NAND_CMD_RNDOUT:
782cfcc706cSMiquel Raynal /* No ready / busy check necessary */
783cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART,
784cfcc706cSMiquel Raynal NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
785cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_NONE,
786cfcc706cSMiquel Raynal NAND_NCE | NAND_CTRL_CHANGE);
787cfcc706cSMiquel Raynal return;
788cfcc706cSMiquel Raynal
789cfcc706cSMiquel Raynal case NAND_CMD_READ0:
790cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_READSTART,
791cfcc706cSMiquel Raynal NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
792cfcc706cSMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_NONE,
793cfcc706cSMiquel Raynal NAND_NCE | NAND_CTRL_CHANGE);
794cfcc706cSMiquel Raynal
795cfcc706cSMiquel Raynal /* This applies to read commands */
796cfcc706cSMiquel Raynal default:
797cfcc706cSMiquel Raynal /*
798cfcc706cSMiquel Raynal * If we don't have access to the busy pin, we apply the given
799cfcc706cSMiquel Raynal * command delay.
800cfcc706cSMiquel Raynal */
801cfcc706cSMiquel Raynal if (!chip->dev_ready) {
802cfcc706cSMiquel Raynal udelay(chip->chip_delay);
803cfcc706cSMiquel Raynal return;
804cfcc706cSMiquel Raynal }
805cfcc706cSMiquel Raynal }
806cfcc706cSMiquel Raynal
807cfcc706cSMiquel Raynal /*
808cfcc706cSMiquel Raynal * Apply this short delay always to ensure that we do wait tWB in
809cfcc706cSMiquel Raynal * any case on any machine.
810cfcc706cSMiquel Raynal */
811cfcc706cSMiquel Raynal ndelay(100);
812cfcc706cSMiquel Raynal
813cfcc706cSMiquel Raynal nand_wait_ready(mtd);
814cfcc706cSMiquel Raynal }
815cfcc706cSMiquel Raynal
816cfcc706cSMiquel Raynal /**
817cfcc706cSMiquel Raynal * panic_nand_get_device - [GENERIC] Get chip for selected access
818cfcc706cSMiquel Raynal * @chip: the nand chip descriptor
819cfcc706cSMiquel Raynal * @mtd: MTD device structure
820cfcc706cSMiquel Raynal * @new_state: the state which is requested
821cfcc706cSMiquel Raynal *
822cfcc706cSMiquel Raynal * Used when in panic, no locks are taken.
823cfcc706cSMiquel Raynal */
panic_nand_get_device(struct nand_chip * chip,struct mtd_info * mtd,int new_state)824cfcc706cSMiquel Raynal static void panic_nand_get_device(struct nand_chip *chip,
825cfcc706cSMiquel Raynal struct mtd_info *mtd, int new_state)
826cfcc706cSMiquel Raynal {
827cfcc706cSMiquel Raynal /* Hardware controller shared among independent devices */
828cfcc706cSMiquel Raynal chip->controller->active = chip;
829cfcc706cSMiquel Raynal chip->state = new_state;
830cfcc706cSMiquel Raynal }
831cfcc706cSMiquel Raynal
832cfcc706cSMiquel Raynal /**
833cfcc706cSMiquel Raynal * nand_get_device - [GENERIC] Get chip for selected access
834cfcc706cSMiquel Raynal * @mtd: MTD device structure
835cfcc706cSMiquel Raynal * @new_state: the state which is requested
836cfcc706cSMiquel Raynal *
837cfcc706cSMiquel Raynal * Get the device and lock it for exclusive access
838cfcc706cSMiquel Raynal */
839cfcc706cSMiquel Raynal static int
nand_get_device(struct mtd_info * mtd,int new_state)840cfcc706cSMiquel Raynal nand_get_device(struct mtd_info *mtd, int new_state)
841cfcc706cSMiquel Raynal {
842cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
843cfcc706cSMiquel Raynal chip->state = new_state;
844cfcc706cSMiquel Raynal return 0;
845cfcc706cSMiquel Raynal }
846cfcc706cSMiquel Raynal
847cfcc706cSMiquel Raynal /**
848cfcc706cSMiquel Raynal * panic_nand_wait - [GENERIC] wait until the command is done
849cfcc706cSMiquel Raynal * @mtd: MTD device structure
850cfcc706cSMiquel Raynal * @chip: NAND chip structure
851cfcc706cSMiquel Raynal * @timeo: timeout
852cfcc706cSMiquel Raynal *
853cfcc706cSMiquel Raynal * Wait for command done. This is a helper function for nand_wait used when
854cfcc706cSMiquel Raynal * we are in interrupt context. May happen when in panic and trying to write
855cfcc706cSMiquel Raynal * an oops through mtdoops.
856cfcc706cSMiquel Raynal */
panic_nand_wait(struct mtd_info * mtd,struct nand_chip * chip,unsigned long timeo)857cfcc706cSMiquel Raynal static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip,
858cfcc706cSMiquel Raynal unsigned long timeo)
859cfcc706cSMiquel Raynal {
860cfcc706cSMiquel Raynal int i;
861cfcc706cSMiquel Raynal for (i = 0; i < timeo; i++) {
862cfcc706cSMiquel Raynal if (chip->dev_ready) {
863cfcc706cSMiquel Raynal if (chip->dev_ready(mtd))
864cfcc706cSMiquel Raynal break;
865cfcc706cSMiquel Raynal } else {
86673ecea3dSBoris Brezillon int ret;
86773ecea3dSBoris Brezillon u8 status;
86873ecea3dSBoris Brezillon
86973ecea3dSBoris Brezillon ret = nand_read_data_op(chip, &status, sizeof(status),
87073ecea3dSBoris Brezillon true);
87173ecea3dSBoris Brezillon if (ret)
87273ecea3dSBoris Brezillon return;
87373ecea3dSBoris Brezillon
87473ecea3dSBoris Brezillon if (status & NAND_STATUS_READY)
875cfcc706cSMiquel Raynal break;
876cfcc706cSMiquel Raynal }
877cfcc706cSMiquel Raynal mdelay(1);
878cfcc706cSMiquel Raynal }
879cfcc706cSMiquel Raynal }
880cfcc706cSMiquel Raynal
881cfcc706cSMiquel Raynal /**
882cfcc706cSMiquel Raynal * nand_wait - [DEFAULT] wait until the command is done
883cfcc706cSMiquel Raynal * @mtd: MTD device structure
884cfcc706cSMiquel Raynal * @chip: NAND chip structure
885cfcc706cSMiquel Raynal *
886cfcc706cSMiquel Raynal * Wait for command done. This applies to erase and program only.
887cfcc706cSMiquel Raynal */
nand_wait(struct mtd_info * mtd,struct nand_chip * chip)888cfcc706cSMiquel Raynal static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
889cfcc706cSMiquel Raynal {
890cfcc706cSMiquel Raynal unsigned long timeo = 400;
89173ecea3dSBoris Brezillon u8 status;
89273ecea3dSBoris Brezillon int ret;
893cfcc706cSMiquel Raynal
894cfcc706cSMiquel Raynal led_trigger_event(nand_led_trigger, LED_FULL);
895cfcc706cSMiquel Raynal
896cfcc706cSMiquel Raynal /*
897cfcc706cSMiquel Raynal * Apply this short delay always to ensure that we do wait tWB in any
898cfcc706cSMiquel Raynal * case on any machine.
899cfcc706cSMiquel Raynal */
900cfcc706cSMiquel Raynal ndelay(100);
901cfcc706cSMiquel Raynal
90273ecea3dSBoris Brezillon ret = nand_status_op(chip, NULL);
90373ecea3dSBoris Brezillon if (ret)
90473ecea3dSBoris Brezillon return ret;
905cfcc706cSMiquel Raynal
906cfcc706cSMiquel Raynal u32 timer = (CONFIG_SYS_HZ * timeo) / 1000;
907cfcc706cSMiquel Raynal u32 time_start;
908cfcc706cSMiquel Raynal
909cfcc706cSMiquel Raynal time_start = get_timer(0);
910cfcc706cSMiquel Raynal while (get_timer(time_start) < timer) {
911cfcc706cSMiquel Raynal if (chip->dev_ready) {
912cfcc706cSMiquel Raynal if (chip->dev_ready(mtd))
913cfcc706cSMiquel Raynal break;
914cfcc706cSMiquel Raynal } else {
91573ecea3dSBoris Brezillon ret = nand_read_data_op(chip, &status,
91673ecea3dSBoris Brezillon sizeof(status), true);
91773ecea3dSBoris Brezillon if (ret)
91873ecea3dSBoris Brezillon return ret;
91973ecea3dSBoris Brezillon
92073ecea3dSBoris Brezillon if (status & NAND_STATUS_READY)
921cfcc706cSMiquel Raynal break;
922cfcc706cSMiquel Raynal }
923cfcc706cSMiquel Raynal }
924cfcc706cSMiquel Raynal led_trigger_event(nand_led_trigger, LED_OFF);
925cfcc706cSMiquel Raynal
92673ecea3dSBoris Brezillon ret = nand_read_data_op(chip, &status, sizeof(status), true);
92773ecea3dSBoris Brezillon if (ret)
92873ecea3dSBoris Brezillon return ret;
92973ecea3dSBoris Brezillon
930cfcc706cSMiquel Raynal /* This can happen if in case of timeout or buggy dev_ready */
931cfcc706cSMiquel Raynal WARN_ON(!(status & NAND_STATUS_READY));
932cfcc706cSMiquel Raynal return status;
933cfcc706cSMiquel Raynal }
934cfcc706cSMiquel Raynal
935cfcc706cSMiquel Raynal /**
936cfcc706cSMiquel Raynal * nand_reset_data_interface - Reset data interface and timings
937cfcc706cSMiquel Raynal * @chip: The NAND chip
938cfcc706cSMiquel Raynal * @chipnr: Internal die id
939cfcc706cSMiquel Raynal *
940cfcc706cSMiquel Raynal * Reset the Data interface and timings to ONFI mode 0.
941cfcc706cSMiquel Raynal *
942cfcc706cSMiquel Raynal * Returns 0 for success or negative error code otherwise.
943cfcc706cSMiquel Raynal */
nand_reset_data_interface(struct nand_chip * chip,int chipnr)944cfcc706cSMiquel Raynal static int nand_reset_data_interface(struct nand_chip *chip, int chipnr)
945cfcc706cSMiquel Raynal {
946cfcc706cSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip);
947cfcc706cSMiquel Raynal const struct nand_data_interface *conf;
948cfcc706cSMiquel Raynal int ret;
949cfcc706cSMiquel Raynal
950cfcc706cSMiquel Raynal if (!chip->setup_data_interface)
951cfcc706cSMiquel Raynal return 0;
952cfcc706cSMiquel Raynal
953cfcc706cSMiquel Raynal /*
954cfcc706cSMiquel Raynal * The ONFI specification says:
955cfcc706cSMiquel Raynal * "
956cfcc706cSMiquel Raynal * To transition from NV-DDR or NV-DDR2 to the SDR data
957cfcc706cSMiquel Raynal * interface, the host shall use the Reset (FFh) command
958cfcc706cSMiquel Raynal * using SDR timing mode 0. A device in any timing mode is
959cfcc706cSMiquel Raynal * required to recognize Reset (FFh) command issued in SDR
960cfcc706cSMiquel Raynal * timing mode 0.
961cfcc706cSMiquel Raynal * "
962cfcc706cSMiquel Raynal *
963cfcc706cSMiquel Raynal * Configure the data interface in SDR mode and set the
964cfcc706cSMiquel Raynal * timings to timing mode 0.
965cfcc706cSMiquel Raynal */
966cfcc706cSMiquel Raynal
967cfcc706cSMiquel Raynal conf = nand_get_default_data_interface();
968cfcc706cSMiquel Raynal ret = chip->setup_data_interface(mtd, chipnr, conf);
969cfcc706cSMiquel Raynal if (ret)
970cfcc706cSMiquel Raynal pr_err("Failed to configure data interface to SDR timing mode 0\n");
971cfcc706cSMiquel Raynal
972cfcc706cSMiquel Raynal return ret;
973cfcc706cSMiquel Raynal }
974cfcc706cSMiquel Raynal
975cfcc706cSMiquel Raynal /**
976cfcc706cSMiquel Raynal * nand_setup_data_interface - Setup the best data interface and timings
977cfcc706cSMiquel Raynal * @chip: The NAND chip
978cfcc706cSMiquel Raynal * @chipnr: Internal die id
979cfcc706cSMiquel Raynal *
980cfcc706cSMiquel Raynal * Find and configure the best data interface and NAND timings supported by
981cfcc706cSMiquel Raynal * the chip and the driver.
982cfcc706cSMiquel Raynal * First tries to retrieve supported timing modes from ONFI information,
983cfcc706cSMiquel Raynal * and if the NAND chip does not support ONFI, relies on the
984cfcc706cSMiquel Raynal * ->onfi_timing_mode_default specified in the nand_ids table.
985cfcc706cSMiquel Raynal *
986cfcc706cSMiquel Raynal * Returns 0 for success or negative error code otherwise.
987cfcc706cSMiquel Raynal */
nand_setup_data_interface(struct nand_chip * chip,int chipnr)988cfcc706cSMiquel Raynal static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
989cfcc706cSMiquel Raynal {
990cfcc706cSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip);
991cfcc706cSMiquel Raynal int ret;
992cfcc706cSMiquel Raynal
993cfcc706cSMiquel Raynal if (!chip->setup_data_interface || !chip->data_interface)
994cfcc706cSMiquel Raynal return 0;
995cfcc706cSMiquel Raynal
996cfcc706cSMiquel Raynal /*
997cfcc706cSMiquel Raynal * Ensure the timing mode has been changed on the chip side
998cfcc706cSMiquel Raynal * before changing timings on the controller side.
999cfcc706cSMiquel Raynal */
1000cfcc706cSMiquel Raynal if (chip->onfi_version) {
1001cfcc706cSMiquel Raynal u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {
1002cfcc706cSMiquel Raynal chip->onfi_timing_mode_default,
1003cfcc706cSMiquel Raynal };
1004cfcc706cSMiquel Raynal
1005cfcc706cSMiquel Raynal ret = chip->onfi_set_features(mtd, chip,
1006cfcc706cSMiquel Raynal ONFI_FEATURE_ADDR_TIMING_MODE,
1007cfcc706cSMiquel Raynal tmode_param);
1008cfcc706cSMiquel Raynal if (ret)
1009cfcc706cSMiquel Raynal goto err;
1010cfcc706cSMiquel Raynal }
1011cfcc706cSMiquel Raynal
1012cfcc706cSMiquel Raynal ret = chip->setup_data_interface(mtd, chipnr, chip->data_interface);
1013cfcc706cSMiquel Raynal err:
1014cfcc706cSMiquel Raynal return ret;
1015cfcc706cSMiquel Raynal }
1016cfcc706cSMiquel Raynal
1017cfcc706cSMiquel Raynal /**
1018cfcc706cSMiquel Raynal * nand_init_data_interface - find the best data interface and timings
1019cfcc706cSMiquel Raynal * @chip: The NAND chip
1020cfcc706cSMiquel Raynal *
1021cfcc706cSMiquel Raynal * Find the best data interface and NAND timings supported by the chip
1022cfcc706cSMiquel Raynal * and the driver.
1023cfcc706cSMiquel Raynal * First tries to retrieve supported timing modes from ONFI information,
1024cfcc706cSMiquel Raynal * and if the NAND chip does not support ONFI, relies on the
1025cfcc706cSMiquel Raynal * ->onfi_timing_mode_default specified in the nand_ids table. After this
1026cfcc706cSMiquel Raynal * function nand_chip->data_interface is initialized with the best timing mode
1027cfcc706cSMiquel Raynal * available.
1028cfcc706cSMiquel Raynal *
1029cfcc706cSMiquel Raynal * Returns 0 for success or negative error code otherwise.
1030cfcc706cSMiquel Raynal */
nand_init_data_interface(struct nand_chip * chip)1031cfcc706cSMiquel Raynal static int nand_init_data_interface(struct nand_chip *chip)
1032cfcc706cSMiquel Raynal {
1033cfcc706cSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip);
1034cfcc706cSMiquel Raynal int modes, mode, ret;
1035cfcc706cSMiquel Raynal
1036cfcc706cSMiquel Raynal if (!chip->setup_data_interface)
1037cfcc706cSMiquel Raynal return 0;
1038cfcc706cSMiquel Raynal
1039cfcc706cSMiquel Raynal /*
1040cfcc706cSMiquel Raynal * First try to identify the best timings from ONFI parameters and
1041cfcc706cSMiquel Raynal * if the NAND does not support ONFI, fallback to the default ONFI
1042cfcc706cSMiquel Raynal * timing mode.
1043cfcc706cSMiquel Raynal */
1044cfcc706cSMiquel Raynal modes = onfi_get_async_timing_mode(chip);
1045cfcc706cSMiquel Raynal if (modes == ONFI_TIMING_MODE_UNKNOWN) {
1046cfcc706cSMiquel Raynal if (!chip->onfi_timing_mode_default)
1047cfcc706cSMiquel Raynal return 0;
1048cfcc706cSMiquel Raynal
1049cfcc706cSMiquel Raynal modes = GENMASK(chip->onfi_timing_mode_default, 0);
1050cfcc706cSMiquel Raynal }
1051cfcc706cSMiquel Raynal
1052cfcc706cSMiquel Raynal chip->data_interface = kzalloc(sizeof(*chip->data_interface),
1053cfcc706cSMiquel Raynal GFP_KERNEL);
1054cfcc706cSMiquel Raynal if (!chip->data_interface)
1055cfcc706cSMiquel Raynal return -ENOMEM;
1056cfcc706cSMiquel Raynal
1057cfcc706cSMiquel Raynal for (mode = fls(modes) - 1; mode >= 0; mode--) {
1058cfcc706cSMiquel Raynal ret = onfi_init_data_interface(chip, chip->data_interface,
1059cfcc706cSMiquel Raynal NAND_SDR_IFACE, mode);
1060cfcc706cSMiquel Raynal if (ret)
1061cfcc706cSMiquel Raynal continue;
1062cfcc706cSMiquel Raynal
1063cfcc706cSMiquel Raynal /* Pass -1 to only */
1064cfcc706cSMiquel Raynal ret = chip->setup_data_interface(mtd,
1065cfcc706cSMiquel Raynal NAND_DATA_IFACE_CHECK_ONLY,
1066cfcc706cSMiquel Raynal chip->data_interface);
1067cfcc706cSMiquel Raynal if (!ret) {
1068cfcc706cSMiquel Raynal chip->onfi_timing_mode_default = mode;
1069cfcc706cSMiquel Raynal break;
1070cfcc706cSMiquel Raynal }
1071cfcc706cSMiquel Raynal }
1072cfcc706cSMiquel Raynal
1073cfcc706cSMiquel Raynal return 0;
1074cfcc706cSMiquel Raynal }
1075cfcc706cSMiquel Raynal
nand_release_data_interface(struct nand_chip * chip)1076cfcc706cSMiquel Raynal static void __maybe_unused nand_release_data_interface(struct nand_chip *chip)
1077cfcc706cSMiquel Raynal {
1078cfcc706cSMiquel Raynal kfree(chip->data_interface);
1079cfcc706cSMiquel Raynal }
1080cfcc706cSMiquel Raynal
1081cfcc706cSMiquel Raynal /**
108273ecea3dSBoris Brezillon * nand_read_page_op - Do a READ PAGE operation
108373ecea3dSBoris Brezillon * @chip: The NAND chip
108473ecea3dSBoris Brezillon * @page: page to read
108573ecea3dSBoris Brezillon * @offset_in_page: offset within the page
108673ecea3dSBoris Brezillon * @buf: buffer used to store the data
108773ecea3dSBoris Brezillon * @len: length of the buffer
108873ecea3dSBoris Brezillon *
108973ecea3dSBoris Brezillon * This function issues a READ PAGE operation.
109073ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
109173ecea3dSBoris Brezillon *
109273ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
109373ecea3dSBoris Brezillon */
nand_read_page_op(struct nand_chip * chip,unsigned int page,unsigned int offset_in_page,void * buf,unsigned int len)109473ecea3dSBoris Brezillon int nand_read_page_op(struct nand_chip *chip, unsigned int page,
109573ecea3dSBoris Brezillon unsigned int offset_in_page, void *buf, unsigned int len)
109673ecea3dSBoris Brezillon {
109773ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
109873ecea3dSBoris Brezillon
109973ecea3dSBoris Brezillon if (len && !buf)
110073ecea3dSBoris Brezillon return -EINVAL;
110173ecea3dSBoris Brezillon
110273ecea3dSBoris Brezillon if (offset_in_page + len > mtd->writesize + mtd->oobsize)
110373ecea3dSBoris Brezillon return -EINVAL;
110473ecea3dSBoris Brezillon
110573ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_READ0, offset_in_page, page);
110673ecea3dSBoris Brezillon if (len)
110773ecea3dSBoris Brezillon chip->read_buf(mtd, buf, len);
110873ecea3dSBoris Brezillon
110973ecea3dSBoris Brezillon return 0;
111073ecea3dSBoris Brezillon }
111173ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_read_page_op);
111273ecea3dSBoris Brezillon
111373ecea3dSBoris Brezillon /**
111473ecea3dSBoris Brezillon * nand_read_param_page_op - Do a READ PARAMETER PAGE operation
111573ecea3dSBoris Brezillon * @chip: The NAND chip
111673ecea3dSBoris Brezillon * @page: parameter page to read
111773ecea3dSBoris Brezillon * @buf: buffer used to store the data
111873ecea3dSBoris Brezillon * @len: length of the buffer
111973ecea3dSBoris Brezillon *
112073ecea3dSBoris Brezillon * This function issues a READ PARAMETER PAGE operation.
112173ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
112273ecea3dSBoris Brezillon *
112373ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
112473ecea3dSBoris Brezillon */
nand_read_param_page_op(struct nand_chip * chip,u8 page,void * buf,unsigned int len)112573ecea3dSBoris Brezillon static int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf,
112673ecea3dSBoris Brezillon unsigned int len)
112773ecea3dSBoris Brezillon {
112873ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
112973ecea3dSBoris Brezillon unsigned int i;
113073ecea3dSBoris Brezillon u8 *p = buf;
113173ecea3dSBoris Brezillon
113273ecea3dSBoris Brezillon if (len && !buf)
113373ecea3dSBoris Brezillon return -EINVAL;
113473ecea3dSBoris Brezillon
113573ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_PARAM, page, -1);
113673ecea3dSBoris Brezillon for (i = 0; i < len; i++)
113773ecea3dSBoris Brezillon p[i] = chip->read_byte(mtd);
113873ecea3dSBoris Brezillon
113973ecea3dSBoris Brezillon return 0;
114073ecea3dSBoris Brezillon }
114173ecea3dSBoris Brezillon
114273ecea3dSBoris Brezillon /**
114373ecea3dSBoris Brezillon * nand_change_read_column_op - Do a CHANGE READ COLUMN operation
114473ecea3dSBoris Brezillon * @chip: The NAND chip
114573ecea3dSBoris Brezillon * @offset_in_page: offset within the page
114673ecea3dSBoris Brezillon * @buf: buffer used to store the data
114773ecea3dSBoris Brezillon * @len: length of the buffer
114873ecea3dSBoris Brezillon * @force_8bit: force 8-bit bus access
114973ecea3dSBoris Brezillon *
115073ecea3dSBoris Brezillon * This function issues a CHANGE READ COLUMN operation.
115173ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
115273ecea3dSBoris Brezillon *
115373ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
115473ecea3dSBoris Brezillon */
nand_change_read_column_op(struct nand_chip * chip,unsigned int offset_in_page,void * buf,unsigned int len,bool force_8bit)115573ecea3dSBoris Brezillon int nand_change_read_column_op(struct nand_chip *chip,
115673ecea3dSBoris Brezillon unsigned int offset_in_page, void *buf,
115773ecea3dSBoris Brezillon unsigned int len, bool force_8bit)
115873ecea3dSBoris Brezillon {
115973ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
116073ecea3dSBoris Brezillon
116173ecea3dSBoris Brezillon if (len && !buf)
116273ecea3dSBoris Brezillon return -EINVAL;
116373ecea3dSBoris Brezillon
116473ecea3dSBoris Brezillon if (offset_in_page + len > mtd->writesize + mtd->oobsize)
116573ecea3dSBoris Brezillon return -EINVAL;
116673ecea3dSBoris Brezillon
116773ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset_in_page, -1);
116873ecea3dSBoris Brezillon if (len)
116973ecea3dSBoris Brezillon chip->read_buf(mtd, buf, len);
117073ecea3dSBoris Brezillon
117173ecea3dSBoris Brezillon return 0;
117273ecea3dSBoris Brezillon }
117373ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_change_read_column_op);
117473ecea3dSBoris Brezillon
117573ecea3dSBoris Brezillon /**
117673ecea3dSBoris Brezillon * nand_read_oob_op - Do a READ OOB operation
117773ecea3dSBoris Brezillon * @chip: The NAND chip
117873ecea3dSBoris Brezillon * @page: page to read
117973ecea3dSBoris Brezillon * @offset_in_oob: offset within the OOB area
118073ecea3dSBoris Brezillon * @buf: buffer used to store the data
118173ecea3dSBoris Brezillon * @len: length of the buffer
118273ecea3dSBoris Brezillon *
118373ecea3dSBoris Brezillon * This function issues a READ OOB operation.
118473ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
118573ecea3dSBoris Brezillon *
118673ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
118773ecea3dSBoris Brezillon */
nand_read_oob_op(struct nand_chip * chip,unsigned int page,unsigned int offset_in_oob,void * buf,unsigned int len)118873ecea3dSBoris Brezillon int nand_read_oob_op(struct nand_chip *chip, unsigned int page,
118973ecea3dSBoris Brezillon unsigned int offset_in_oob, void *buf, unsigned int len)
119073ecea3dSBoris Brezillon {
119173ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
119273ecea3dSBoris Brezillon
119373ecea3dSBoris Brezillon if (len && !buf)
119473ecea3dSBoris Brezillon return -EINVAL;
119573ecea3dSBoris Brezillon
119673ecea3dSBoris Brezillon if (offset_in_oob + len > mtd->oobsize)
119773ecea3dSBoris Brezillon return -EINVAL;
119873ecea3dSBoris Brezillon
119973ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_READOOB, offset_in_oob, page);
120073ecea3dSBoris Brezillon if (len)
120173ecea3dSBoris Brezillon chip->read_buf(mtd, buf, len);
120273ecea3dSBoris Brezillon
120373ecea3dSBoris Brezillon return 0;
120473ecea3dSBoris Brezillon }
120573ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_read_oob_op);
120673ecea3dSBoris Brezillon
120773ecea3dSBoris Brezillon /**
120873ecea3dSBoris Brezillon * nand_prog_page_begin_op - starts a PROG PAGE operation
120973ecea3dSBoris Brezillon * @chip: The NAND chip
121073ecea3dSBoris Brezillon * @page: page to write
121173ecea3dSBoris Brezillon * @offset_in_page: offset within the page
121273ecea3dSBoris Brezillon * @buf: buffer containing the data to write to the page
121373ecea3dSBoris Brezillon * @len: length of the buffer
121473ecea3dSBoris Brezillon *
121573ecea3dSBoris Brezillon * This function issues the first half of a PROG PAGE operation.
121673ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
121773ecea3dSBoris Brezillon *
121873ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
121973ecea3dSBoris Brezillon */
nand_prog_page_begin_op(struct nand_chip * chip,unsigned int page,unsigned int offset_in_page,const void * buf,unsigned int len)122073ecea3dSBoris Brezillon int nand_prog_page_begin_op(struct nand_chip *chip, unsigned int page,
122173ecea3dSBoris Brezillon unsigned int offset_in_page, const void *buf,
122273ecea3dSBoris Brezillon unsigned int len)
122373ecea3dSBoris Brezillon {
122473ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
122573ecea3dSBoris Brezillon
122673ecea3dSBoris Brezillon if (len && !buf)
122773ecea3dSBoris Brezillon return -EINVAL;
122873ecea3dSBoris Brezillon
122973ecea3dSBoris Brezillon if (offset_in_page + len > mtd->writesize + mtd->oobsize)
123073ecea3dSBoris Brezillon return -EINVAL;
123173ecea3dSBoris Brezillon
123273ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_SEQIN, offset_in_page, page);
123373ecea3dSBoris Brezillon
123473ecea3dSBoris Brezillon if (buf)
123573ecea3dSBoris Brezillon chip->write_buf(mtd, buf, len);
123673ecea3dSBoris Brezillon
123773ecea3dSBoris Brezillon return 0;
123873ecea3dSBoris Brezillon }
123973ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_prog_page_begin_op);
124073ecea3dSBoris Brezillon
124173ecea3dSBoris Brezillon /**
124273ecea3dSBoris Brezillon * nand_prog_page_end_op - ends a PROG PAGE operation
124373ecea3dSBoris Brezillon * @chip: The NAND chip
124473ecea3dSBoris Brezillon *
124573ecea3dSBoris Brezillon * This function issues the second half of a PROG PAGE operation.
124673ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
124773ecea3dSBoris Brezillon *
124873ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
124973ecea3dSBoris Brezillon */
nand_prog_page_end_op(struct nand_chip * chip)125073ecea3dSBoris Brezillon int nand_prog_page_end_op(struct nand_chip *chip)
125173ecea3dSBoris Brezillon {
125273ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
125373ecea3dSBoris Brezillon int status;
125473ecea3dSBoris Brezillon
125573ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
125673ecea3dSBoris Brezillon
125773ecea3dSBoris Brezillon status = chip->waitfunc(mtd, chip);
125873ecea3dSBoris Brezillon if (status & NAND_STATUS_FAIL)
125973ecea3dSBoris Brezillon return -EIO;
126073ecea3dSBoris Brezillon
126173ecea3dSBoris Brezillon return 0;
126273ecea3dSBoris Brezillon }
126373ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_prog_page_end_op);
126473ecea3dSBoris Brezillon
126573ecea3dSBoris Brezillon /**
126673ecea3dSBoris Brezillon * nand_prog_page_op - Do a full PROG PAGE operation
126773ecea3dSBoris Brezillon * @chip: The NAND chip
126873ecea3dSBoris Brezillon * @page: page to write
126973ecea3dSBoris Brezillon * @offset_in_page: offset within the page
127073ecea3dSBoris Brezillon * @buf: buffer containing the data to write to the page
127173ecea3dSBoris Brezillon * @len: length of the buffer
127273ecea3dSBoris Brezillon *
127373ecea3dSBoris Brezillon * This function issues a full PROG PAGE operation.
127473ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
127573ecea3dSBoris Brezillon *
127673ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
127773ecea3dSBoris Brezillon */
nand_prog_page_op(struct nand_chip * chip,unsigned int page,unsigned int offset_in_page,const void * buf,unsigned int len)127873ecea3dSBoris Brezillon int nand_prog_page_op(struct nand_chip *chip, unsigned int page,
127973ecea3dSBoris Brezillon unsigned int offset_in_page, const void *buf,
128073ecea3dSBoris Brezillon unsigned int len)
128173ecea3dSBoris Brezillon {
128273ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
128373ecea3dSBoris Brezillon int status;
128473ecea3dSBoris Brezillon
128573ecea3dSBoris Brezillon if (!len || !buf)
128673ecea3dSBoris Brezillon return -EINVAL;
128773ecea3dSBoris Brezillon
128873ecea3dSBoris Brezillon if (offset_in_page + len > mtd->writesize + mtd->oobsize)
128973ecea3dSBoris Brezillon return -EINVAL;
129073ecea3dSBoris Brezillon
129173ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_SEQIN, offset_in_page, page);
129273ecea3dSBoris Brezillon chip->write_buf(mtd, buf, len);
129373ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
129473ecea3dSBoris Brezillon
129573ecea3dSBoris Brezillon status = chip->waitfunc(mtd, chip);
129673ecea3dSBoris Brezillon if (status & NAND_STATUS_FAIL)
129773ecea3dSBoris Brezillon return -EIO;
129873ecea3dSBoris Brezillon
129973ecea3dSBoris Brezillon return 0;
130073ecea3dSBoris Brezillon }
130173ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_prog_page_op);
130273ecea3dSBoris Brezillon
130373ecea3dSBoris Brezillon /**
130473ecea3dSBoris Brezillon * nand_change_write_column_op - Do a CHANGE WRITE COLUMN operation
130573ecea3dSBoris Brezillon * @chip: The NAND chip
130673ecea3dSBoris Brezillon * @offset_in_page: offset within the page
130773ecea3dSBoris Brezillon * @buf: buffer containing the data to send to the NAND
130873ecea3dSBoris Brezillon * @len: length of the buffer
130973ecea3dSBoris Brezillon * @force_8bit: force 8-bit bus access
131073ecea3dSBoris Brezillon *
131173ecea3dSBoris Brezillon * This function issues a CHANGE WRITE COLUMN operation.
131273ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
131373ecea3dSBoris Brezillon *
131473ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
131573ecea3dSBoris Brezillon */
nand_change_write_column_op(struct nand_chip * chip,unsigned int offset_in_page,const void * buf,unsigned int len,bool force_8bit)131673ecea3dSBoris Brezillon int nand_change_write_column_op(struct nand_chip *chip,
131773ecea3dSBoris Brezillon unsigned int offset_in_page,
131873ecea3dSBoris Brezillon const void *buf, unsigned int len,
131973ecea3dSBoris Brezillon bool force_8bit)
132073ecea3dSBoris Brezillon {
132173ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
132273ecea3dSBoris Brezillon
132373ecea3dSBoris Brezillon if (len && !buf)
132473ecea3dSBoris Brezillon return -EINVAL;
132573ecea3dSBoris Brezillon
132673ecea3dSBoris Brezillon if (offset_in_page + len > mtd->writesize + mtd->oobsize)
132773ecea3dSBoris Brezillon return -EINVAL;
132873ecea3dSBoris Brezillon
132973ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset_in_page, -1);
133073ecea3dSBoris Brezillon if (len)
133173ecea3dSBoris Brezillon chip->write_buf(mtd, buf, len);
133273ecea3dSBoris Brezillon
133373ecea3dSBoris Brezillon return 0;
133473ecea3dSBoris Brezillon }
133573ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_change_write_column_op);
133673ecea3dSBoris Brezillon
133773ecea3dSBoris Brezillon /**
133873ecea3dSBoris Brezillon * nand_readid_op - Do a READID operation
133973ecea3dSBoris Brezillon * @chip: The NAND chip
134073ecea3dSBoris Brezillon * @addr: address cycle to pass after the READID command
134173ecea3dSBoris Brezillon * @buf: buffer used to store the ID
134273ecea3dSBoris Brezillon * @len: length of the buffer
134373ecea3dSBoris Brezillon *
134473ecea3dSBoris Brezillon * This function sends a READID command and reads back the ID returned by the
134573ecea3dSBoris Brezillon * NAND.
134673ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
134773ecea3dSBoris Brezillon *
134873ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
134973ecea3dSBoris Brezillon */
nand_readid_op(struct nand_chip * chip,u8 addr,void * buf,unsigned int len)135073ecea3dSBoris Brezillon int nand_readid_op(struct nand_chip *chip, u8 addr, void *buf,
135173ecea3dSBoris Brezillon unsigned int len)
135273ecea3dSBoris Brezillon {
135373ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
135473ecea3dSBoris Brezillon unsigned int i;
135573ecea3dSBoris Brezillon u8 *id = buf;
135673ecea3dSBoris Brezillon
135773ecea3dSBoris Brezillon if (len && !buf)
135873ecea3dSBoris Brezillon return -EINVAL;
135973ecea3dSBoris Brezillon
136073ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_READID, addr, -1);
136173ecea3dSBoris Brezillon
136273ecea3dSBoris Brezillon for (i = 0; i < len; i++)
136373ecea3dSBoris Brezillon id[i] = chip->read_byte(mtd);
136473ecea3dSBoris Brezillon
136573ecea3dSBoris Brezillon return 0;
136673ecea3dSBoris Brezillon }
136773ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_readid_op);
136873ecea3dSBoris Brezillon
136973ecea3dSBoris Brezillon /**
137073ecea3dSBoris Brezillon * nand_status_op - Do a STATUS operation
137173ecea3dSBoris Brezillon * @chip: The NAND chip
137273ecea3dSBoris Brezillon * @status: out variable to store the NAND status
137373ecea3dSBoris Brezillon *
137473ecea3dSBoris Brezillon * This function sends a STATUS command and reads back the status returned by
137573ecea3dSBoris Brezillon * the NAND.
137673ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
137773ecea3dSBoris Brezillon *
137873ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
137973ecea3dSBoris Brezillon */
nand_status_op(struct nand_chip * chip,u8 * status)138073ecea3dSBoris Brezillon int nand_status_op(struct nand_chip *chip, u8 *status)
138173ecea3dSBoris Brezillon {
138273ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
138373ecea3dSBoris Brezillon
138473ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
138573ecea3dSBoris Brezillon if (status)
138673ecea3dSBoris Brezillon *status = chip->read_byte(mtd);
138773ecea3dSBoris Brezillon
138873ecea3dSBoris Brezillon return 0;
138973ecea3dSBoris Brezillon }
139073ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_status_op);
139173ecea3dSBoris Brezillon
139273ecea3dSBoris Brezillon /**
139373ecea3dSBoris Brezillon * nand_exit_status_op - Exit a STATUS operation
139473ecea3dSBoris Brezillon * @chip: The NAND chip
139573ecea3dSBoris Brezillon *
139673ecea3dSBoris Brezillon * This function sends a READ0 command to cancel the effect of the STATUS
139773ecea3dSBoris Brezillon * command to avoid reading only the status until a new read command is sent.
139873ecea3dSBoris Brezillon *
139973ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
140073ecea3dSBoris Brezillon *
140173ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
140273ecea3dSBoris Brezillon */
nand_exit_status_op(struct nand_chip * chip)140373ecea3dSBoris Brezillon int nand_exit_status_op(struct nand_chip *chip)
140473ecea3dSBoris Brezillon {
140573ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
140673ecea3dSBoris Brezillon
140773ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_READ0, -1, -1);
140873ecea3dSBoris Brezillon
140973ecea3dSBoris Brezillon return 0;
141073ecea3dSBoris Brezillon }
141173ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_exit_status_op);
141273ecea3dSBoris Brezillon
141373ecea3dSBoris Brezillon /**
141473ecea3dSBoris Brezillon * nand_erase_op - Do an erase operation
141573ecea3dSBoris Brezillon * @chip: The NAND chip
141673ecea3dSBoris Brezillon * @eraseblock: block to erase
141773ecea3dSBoris Brezillon *
141873ecea3dSBoris Brezillon * This function sends an ERASE command and waits for the NAND to be ready
141973ecea3dSBoris Brezillon * before returning.
142073ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
142173ecea3dSBoris Brezillon *
142273ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
142373ecea3dSBoris Brezillon */
nand_erase_op(struct nand_chip * chip,unsigned int eraseblock)142473ecea3dSBoris Brezillon int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock)
142573ecea3dSBoris Brezillon {
142673ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
142773ecea3dSBoris Brezillon unsigned int page = eraseblock <<
142873ecea3dSBoris Brezillon (chip->phys_erase_shift - chip->page_shift);
142973ecea3dSBoris Brezillon int status;
143073ecea3dSBoris Brezillon
143173ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
143273ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
143373ecea3dSBoris Brezillon
143473ecea3dSBoris Brezillon status = chip->waitfunc(mtd, chip);
143573ecea3dSBoris Brezillon if (status < 0)
143673ecea3dSBoris Brezillon return status;
143773ecea3dSBoris Brezillon
143873ecea3dSBoris Brezillon if (status & NAND_STATUS_FAIL)
143973ecea3dSBoris Brezillon return -EIO;
144073ecea3dSBoris Brezillon
144173ecea3dSBoris Brezillon return 0;
144273ecea3dSBoris Brezillon }
144373ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_erase_op);
144473ecea3dSBoris Brezillon
144573ecea3dSBoris Brezillon /**
144673ecea3dSBoris Brezillon * nand_set_features_op - Do a SET FEATURES operation
144773ecea3dSBoris Brezillon * @chip: The NAND chip
144873ecea3dSBoris Brezillon * @feature: feature id
144973ecea3dSBoris Brezillon * @data: 4 bytes of data
145073ecea3dSBoris Brezillon *
145173ecea3dSBoris Brezillon * This function sends a SET FEATURES command and waits for the NAND to be
145273ecea3dSBoris Brezillon * ready before returning.
145373ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
145473ecea3dSBoris Brezillon *
145573ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
145673ecea3dSBoris Brezillon */
nand_set_features_op(struct nand_chip * chip,u8 feature,const void * data)145773ecea3dSBoris Brezillon static int nand_set_features_op(struct nand_chip *chip, u8 feature,
145873ecea3dSBoris Brezillon const void *data)
145973ecea3dSBoris Brezillon {
146073ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
146173ecea3dSBoris Brezillon const u8 *params = data;
146273ecea3dSBoris Brezillon int i, status;
146373ecea3dSBoris Brezillon
146473ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, feature, -1);
146573ecea3dSBoris Brezillon for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
146673ecea3dSBoris Brezillon chip->write_byte(mtd, params[i]);
146773ecea3dSBoris Brezillon
146873ecea3dSBoris Brezillon status = chip->waitfunc(mtd, chip);
146973ecea3dSBoris Brezillon if (status & NAND_STATUS_FAIL)
147073ecea3dSBoris Brezillon return -EIO;
147173ecea3dSBoris Brezillon
147273ecea3dSBoris Brezillon return 0;
147373ecea3dSBoris Brezillon }
147473ecea3dSBoris Brezillon
147573ecea3dSBoris Brezillon /**
147673ecea3dSBoris Brezillon * nand_get_features_op - Do a GET FEATURES operation
147773ecea3dSBoris Brezillon * @chip: The NAND chip
147873ecea3dSBoris Brezillon * @feature: feature id
147973ecea3dSBoris Brezillon * @data: 4 bytes of data
148073ecea3dSBoris Brezillon *
148173ecea3dSBoris Brezillon * This function sends a GET FEATURES command and waits for the NAND to be
148273ecea3dSBoris Brezillon * ready before returning.
148373ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
148473ecea3dSBoris Brezillon *
148573ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
148673ecea3dSBoris Brezillon */
nand_get_features_op(struct nand_chip * chip,u8 feature,void * data)148773ecea3dSBoris Brezillon static int nand_get_features_op(struct nand_chip *chip, u8 feature,
148873ecea3dSBoris Brezillon void *data)
148973ecea3dSBoris Brezillon {
149073ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
149173ecea3dSBoris Brezillon u8 *params = data;
149273ecea3dSBoris Brezillon int i;
149373ecea3dSBoris Brezillon
149473ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, feature, -1);
149573ecea3dSBoris Brezillon for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
149673ecea3dSBoris Brezillon params[i] = chip->read_byte(mtd);
149773ecea3dSBoris Brezillon
149873ecea3dSBoris Brezillon return 0;
149973ecea3dSBoris Brezillon }
150073ecea3dSBoris Brezillon
150173ecea3dSBoris Brezillon /**
150273ecea3dSBoris Brezillon * nand_reset_op - Do a reset operation
150373ecea3dSBoris Brezillon * @chip: The NAND chip
150473ecea3dSBoris Brezillon *
150573ecea3dSBoris Brezillon * This function sends a RESET command and waits for the NAND to be ready
150673ecea3dSBoris Brezillon * before returning.
150773ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
150873ecea3dSBoris Brezillon *
150973ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
151073ecea3dSBoris Brezillon */
nand_reset_op(struct nand_chip * chip)151173ecea3dSBoris Brezillon int nand_reset_op(struct nand_chip *chip)
151273ecea3dSBoris Brezillon {
151373ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
151473ecea3dSBoris Brezillon
151573ecea3dSBoris Brezillon chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
151673ecea3dSBoris Brezillon
151773ecea3dSBoris Brezillon return 0;
151873ecea3dSBoris Brezillon }
151973ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_reset_op);
152073ecea3dSBoris Brezillon
152173ecea3dSBoris Brezillon /**
152273ecea3dSBoris Brezillon * nand_read_data_op - Read data from the NAND
152373ecea3dSBoris Brezillon * @chip: The NAND chip
152473ecea3dSBoris Brezillon * @buf: buffer used to store the data
152573ecea3dSBoris Brezillon * @len: length of the buffer
152673ecea3dSBoris Brezillon * @force_8bit: force 8-bit bus access
152773ecea3dSBoris Brezillon *
152873ecea3dSBoris Brezillon * This function does a raw data read on the bus. Usually used after launching
152973ecea3dSBoris Brezillon * another NAND operation like nand_read_page_op().
153073ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
153173ecea3dSBoris Brezillon *
153273ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
153373ecea3dSBoris Brezillon */
nand_read_data_op(struct nand_chip * chip,void * buf,unsigned int len,bool force_8bit)153473ecea3dSBoris Brezillon int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
153573ecea3dSBoris Brezillon bool force_8bit)
153673ecea3dSBoris Brezillon {
153773ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
153873ecea3dSBoris Brezillon
153973ecea3dSBoris Brezillon if (!len || !buf)
154073ecea3dSBoris Brezillon return -EINVAL;
154173ecea3dSBoris Brezillon
154273ecea3dSBoris Brezillon if (force_8bit) {
154373ecea3dSBoris Brezillon u8 *p = buf;
154473ecea3dSBoris Brezillon unsigned int i;
154573ecea3dSBoris Brezillon
154673ecea3dSBoris Brezillon for (i = 0; i < len; i++)
154773ecea3dSBoris Brezillon p[i] = chip->read_byte(mtd);
154873ecea3dSBoris Brezillon } else {
154973ecea3dSBoris Brezillon chip->read_buf(mtd, buf, len);
155073ecea3dSBoris Brezillon }
155173ecea3dSBoris Brezillon
155273ecea3dSBoris Brezillon return 0;
155373ecea3dSBoris Brezillon }
155473ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_read_data_op);
155573ecea3dSBoris Brezillon
155673ecea3dSBoris Brezillon /**
155773ecea3dSBoris Brezillon * nand_write_data_op - Write data from the NAND
155873ecea3dSBoris Brezillon * @chip: The NAND chip
155973ecea3dSBoris Brezillon * @buf: buffer containing the data to send on the bus
156073ecea3dSBoris Brezillon * @len: length of the buffer
156173ecea3dSBoris Brezillon * @force_8bit: force 8-bit bus access
156273ecea3dSBoris Brezillon *
156373ecea3dSBoris Brezillon * This function does a raw data write on the bus. Usually used after launching
156473ecea3dSBoris Brezillon * another NAND operation like nand_write_page_begin_op().
156573ecea3dSBoris Brezillon * This function does not select/unselect the CS line.
156673ecea3dSBoris Brezillon *
156773ecea3dSBoris Brezillon * Returns 0 on success, a negative error code otherwise.
156873ecea3dSBoris Brezillon */
nand_write_data_op(struct nand_chip * chip,const void * buf,unsigned int len,bool force_8bit)156973ecea3dSBoris Brezillon int nand_write_data_op(struct nand_chip *chip, const void *buf,
157073ecea3dSBoris Brezillon unsigned int len, bool force_8bit)
157173ecea3dSBoris Brezillon {
157273ecea3dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip);
157373ecea3dSBoris Brezillon
157473ecea3dSBoris Brezillon if (!len || !buf)
157573ecea3dSBoris Brezillon return -EINVAL;
157673ecea3dSBoris Brezillon
157773ecea3dSBoris Brezillon if (force_8bit) {
157873ecea3dSBoris Brezillon const u8 *p = buf;
157973ecea3dSBoris Brezillon unsigned int i;
158073ecea3dSBoris Brezillon
158173ecea3dSBoris Brezillon for (i = 0; i < len; i++)
158273ecea3dSBoris Brezillon chip->write_byte(mtd, p[i]);
158373ecea3dSBoris Brezillon } else {
158473ecea3dSBoris Brezillon chip->write_buf(mtd, buf, len);
158573ecea3dSBoris Brezillon }
158673ecea3dSBoris Brezillon
158773ecea3dSBoris Brezillon return 0;
158873ecea3dSBoris Brezillon }
158973ecea3dSBoris Brezillon EXPORT_SYMBOL_GPL(nand_write_data_op);
159073ecea3dSBoris Brezillon
159173ecea3dSBoris Brezillon /**
1592cfcc706cSMiquel Raynal * nand_reset - Reset and initialize a NAND device
1593cfcc706cSMiquel Raynal * @chip: The NAND chip
1594cfcc706cSMiquel Raynal * @chipnr: Internal die id
1595cfcc706cSMiquel Raynal *
1596cfcc706cSMiquel Raynal * Returns 0 for success or negative error code otherwise
1597cfcc706cSMiquel Raynal */
nand_reset(struct nand_chip * chip,int chipnr)1598cfcc706cSMiquel Raynal int nand_reset(struct nand_chip *chip, int chipnr)
1599cfcc706cSMiquel Raynal {
1600cfcc706cSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip);
1601cfcc706cSMiquel Raynal int ret;
1602cfcc706cSMiquel Raynal
1603cfcc706cSMiquel Raynal ret = nand_reset_data_interface(chip, chipnr);
1604cfcc706cSMiquel Raynal if (ret)
1605cfcc706cSMiquel Raynal return ret;
1606cfcc706cSMiquel Raynal
1607cfcc706cSMiquel Raynal /*
1608cfcc706cSMiquel Raynal * The CS line has to be released before we can apply the new NAND
1609cfcc706cSMiquel Raynal * interface settings, hence this weird ->select_chip() dance.
1610cfcc706cSMiquel Raynal */
1611cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
161273ecea3dSBoris Brezillon ret = nand_reset_op(chip);
1613cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
161473ecea3dSBoris Brezillon if (ret)
161573ecea3dSBoris Brezillon return ret;
1616cfcc706cSMiquel Raynal
1617cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
1618cfcc706cSMiquel Raynal ret = nand_setup_data_interface(chip, chipnr);
1619cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
1620cfcc706cSMiquel Raynal if (ret)
1621cfcc706cSMiquel Raynal return ret;
1622cfcc706cSMiquel Raynal
1623cfcc706cSMiquel Raynal return 0;
1624cfcc706cSMiquel Raynal }
1625cfcc706cSMiquel Raynal
1626cfcc706cSMiquel Raynal /**
1627cfcc706cSMiquel Raynal * nand_check_erased_buf - check if a buffer contains (almost) only 0xff data
1628cfcc706cSMiquel Raynal * @buf: buffer to test
1629cfcc706cSMiquel Raynal * @len: buffer length
1630cfcc706cSMiquel Raynal * @bitflips_threshold: maximum number of bitflips
1631cfcc706cSMiquel Raynal *
1632cfcc706cSMiquel Raynal * Check if a buffer contains only 0xff, which means the underlying region
1633cfcc706cSMiquel Raynal * has been erased and is ready to be programmed.
1634cfcc706cSMiquel Raynal * The bitflips_threshold specify the maximum number of bitflips before
1635cfcc706cSMiquel Raynal * considering the region is not erased.
1636cfcc706cSMiquel Raynal * Note: The logic of this function has been extracted from the memweight
1637cfcc706cSMiquel Raynal * implementation, except that nand_check_erased_buf function exit before
1638cfcc706cSMiquel Raynal * testing the whole buffer if the number of bitflips exceed the
1639cfcc706cSMiquel Raynal * bitflips_threshold value.
1640cfcc706cSMiquel Raynal *
1641cfcc706cSMiquel Raynal * Returns a positive number of bitflips less than or equal to
1642cfcc706cSMiquel Raynal * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the
1643cfcc706cSMiquel Raynal * threshold.
1644cfcc706cSMiquel Raynal */
nand_check_erased_buf(void * buf,int len,int bitflips_threshold)1645cfcc706cSMiquel Raynal static int nand_check_erased_buf(void *buf, int len, int bitflips_threshold)
1646cfcc706cSMiquel Raynal {
1647cfcc706cSMiquel Raynal const unsigned char *bitmap = buf;
1648cfcc706cSMiquel Raynal int bitflips = 0;
1649cfcc706cSMiquel Raynal int weight;
1650cfcc706cSMiquel Raynal
1651cfcc706cSMiquel Raynal for (; len && ((uintptr_t)bitmap) % sizeof(long);
1652cfcc706cSMiquel Raynal len--, bitmap++) {
1653cfcc706cSMiquel Raynal weight = hweight8(*bitmap);
1654cfcc706cSMiquel Raynal bitflips += BITS_PER_BYTE - weight;
1655cfcc706cSMiquel Raynal if (unlikely(bitflips > bitflips_threshold))
1656cfcc706cSMiquel Raynal return -EBADMSG;
1657cfcc706cSMiquel Raynal }
1658cfcc706cSMiquel Raynal
1659cfcc706cSMiquel Raynal for (; len >= 4; len -= 4, bitmap += 4) {
1660cfcc706cSMiquel Raynal weight = hweight32(*((u32 *)bitmap));
1661cfcc706cSMiquel Raynal bitflips += 32 - weight;
1662cfcc706cSMiquel Raynal if (unlikely(bitflips > bitflips_threshold))
1663cfcc706cSMiquel Raynal return -EBADMSG;
1664cfcc706cSMiquel Raynal }
1665cfcc706cSMiquel Raynal
1666cfcc706cSMiquel Raynal for (; len > 0; len--, bitmap++) {
1667cfcc706cSMiquel Raynal weight = hweight8(*bitmap);
1668cfcc706cSMiquel Raynal bitflips += BITS_PER_BYTE - weight;
1669cfcc706cSMiquel Raynal if (unlikely(bitflips > bitflips_threshold))
1670cfcc706cSMiquel Raynal return -EBADMSG;
1671cfcc706cSMiquel Raynal }
1672cfcc706cSMiquel Raynal
1673cfcc706cSMiquel Raynal return bitflips;
1674cfcc706cSMiquel Raynal }
1675cfcc706cSMiquel Raynal
1676cfcc706cSMiquel Raynal /**
1677cfcc706cSMiquel Raynal * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only
1678cfcc706cSMiquel Raynal * 0xff data
1679cfcc706cSMiquel Raynal * @data: data buffer to test
1680cfcc706cSMiquel Raynal * @datalen: data length
1681cfcc706cSMiquel Raynal * @ecc: ECC buffer
1682cfcc706cSMiquel Raynal * @ecclen: ECC length
1683cfcc706cSMiquel Raynal * @extraoob: extra OOB buffer
1684cfcc706cSMiquel Raynal * @extraooblen: extra OOB length
1685cfcc706cSMiquel Raynal * @bitflips_threshold: maximum number of bitflips
1686cfcc706cSMiquel Raynal *
1687cfcc706cSMiquel Raynal * Check if a data buffer and its associated ECC and OOB data contains only
1688cfcc706cSMiquel Raynal * 0xff pattern, which means the underlying region has been erased and is
1689cfcc706cSMiquel Raynal * ready to be programmed.
1690cfcc706cSMiquel Raynal * The bitflips_threshold specify the maximum number of bitflips before
1691cfcc706cSMiquel Raynal * considering the region as not erased.
1692cfcc706cSMiquel Raynal *
1693cfcc706cSMiquel Raynal * Note:
1694cfcc706cSMiquel Raynal * 1/ ECC algorithms are working on pre-defined block sizes which are usually
1695cfcc706cSMiquel Raynal * different from the NAND page size. When fixing bitflips, ECC engines will
1696cfcc706cSMiquel Raynal * report the number of errors per chunk, and the NAND core infrastructure
1697cfcc706cSMiquel Raynal * expect you to return the maximum number of bitflips for the whole page.
1698cfcc706cSMiquel Raynal * This is why you should always use this function on a single chunk and
1699cfcc706cSMiquel Raynal * not on the whole page. After checking each chunk you should update your
1700cfcc706cSMiquel Raynal * max_bitflips value accordingly.
1701cfcc706cSMiquel Raynal * 2/ When checking for bitflips in erased pages you should not only check
1702cfcc706cSMiquel Raynal * the payload data but also their associated ECC data, because a user might
1703cfcc706cSMiquel Raynal * have programmed almost all bits to 1 but a few. In this case, we
1704cfcc706cSMiquel Raynal * shouldn't consider the chunk as erased, and checking ECC bytes prevent
1705cfcc706cSMiquel Raynal * this case.
1706cfcc706cSMiquel Raynal * 3/ The extraoob argument is optional, and should be used if some of your OOB
1707cfcc706cSMiquel Raynal * data are protected by the ECC engine.
1708cfcc706cSMiquel Raynal * It could also be used if you support subpages and want to attach some
1709cfcc706cSMiquel Raynal * extra OOB data to an ECC chunk.
1710cfcc706cSMiquel Raynal *
1711cfcc706cSMiquel Raynal * Returns a positive number of bitflips less than or equal to
1712cfcc706cSMiquel Raynal * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the
1713cfcc706cSMiquel Raynal * threshold. In case of success, the passed buffers are filled with 0xff.
1714cfcc706cSMiquel Raynal */
nand_check_erased_ecc_chunk(void * data,int datalen,void * ecc,int ecclen,void * extraoob,int extraooblen,int bitflips_threshold)1715cfcc706cSMiquel Raynal int nand_check_erased_ecc_chunk(void *data, int datalen,
1716cfcc706cSMiquel Raynal void *ecc, int ecclen,
1717cfcc706cSMiquel Raynal void *extraoob, int extraooblen,
1718cfcc706cSMiquel Raynal int bitflips_threshold)
1719cfcc706cSMiquel Raynal {
1720cfcc706cSMiquel Raynal int data_bitflips = 0, ecc_bitflips = 0, extraoob_bitflips = 0;
1721cfcc706cSMiquel Raynal
1722cfcc706cSMiquel Raynal data_bitflips = nand_check_erased_buf(data, datalen,
1723cfcc706cSMiquel Raynal bitflips_threshold);
1724cfcc706cSMiquel Raynal if (data_bitflips < 0)
1725cfcc706cSMiquel Raynal return data_bitflips;
1726cfcc706cSMiquel Raynal
1727cfcc706cSMiquel Raynal bitflips_threshold -= data_bitflips;
1728cfcc706cSMiquel Raynal
1729cfcc706cSMiquel Raynal ecc_bitflips = nand_check_erased_buf(ecc, ecclen, bitflips_threshold);
1730cfcc706cSMiquel Raynal if (ecc_bitflips < 0)
1731cfcc706cSMiquel Raynal return ecc_bitflips;
1732cfcc706cSMiquel Raynal
1733cfcc706cSMiquel Raynal bitflips_threshold -= ecc_bitflips;
1734cfcc706cSMiquel Raynal
1735cfcc706cSMiquel Raynal extraoob_bitflips = nand_check_erased_buf(extraoob, extraooblen,
1736cfcc706cSMiquel Raynal bitflips_threshold);
1737cfcc706cSMiquel Raynal if (extraoob_bitflips < 0)
1738cfcc706cSMiquel Raynal return extraoob_bitflips;
1739cfcc706cSMiquel Raynal
1740cfcc706cSMiquel Raynal if (data_bitflips)
1741cfcc706cSMiquel Raynal memset(data, 0xff, datalen);
1742cfcc706cSMiquel Raynal
1743cfcc706cSMiquel Raynal if (ecc_bitflips)
1744cfcc706cSMiquel Raynal memset(ecc, 0xff, ecclen);
1745cfcc706cSMiquel Raynal
1746cfcc706cSMiquel Raynal if (extraoob_bitflips)
1747cfcc706cSMiquel Raynal memset(extraoob, 0xff, extraooblen);
1748cfcc706cSMiquel Raynal
1749cfcc706cSMiquel Raynal return data_bitflips + ecc_bitflips + extraoob_bitflips;
1750cfcc706cSMiquel Raynal }
1751cfcc706cSMiquel Raynal EXPORT_SYMBOL(nand_check_erased_ecc_chunk);
1752cfcc706cSMiquel Raynal
1753cfcc706cSMiquel Raynal /**
1754cfcc706cSMiquel Raynal * nand_read_page_raw - [INTERN] read raw page data without ecc
1755cfcc706cSMiquel Raynal * @mtd: mtd info structure
1756cfcc706cSMiquel Raynal * @chip: nand chip info structure
1757cfcc706cSMiquel Raynal * @buf: buffer to store read data
1758cfcc706cSMiquel Raynal * @oob_required: caller requires OOB data read to chip->oob_poi
1759cfcc706cSMiquel Raynal * @page: page number to read
1760cfcc706cSMiquel Raynal *
1761cfcc706cSMiquel Raynal * Not for syndrome calculating ECC controllers, which use a special oob layout.
1762cfcc706cSMiquel Raynal */
nand_read_page_raw(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)1763cfcc706cSMiquel Raynal static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1764cfcc706cSMiquel Raynal uint8_t *buf, int oob_required, int page)
1765cfcc706cSMiquel Raynal {
176673ecea3dSBoris Brezillon int ret;
176773ecea3dSBoris Brezillon
176873ecea3dSBoris Brezillon ret = nand_read_data_op(chip, buf, mtd->writesize, false);
176973ecea3dSBoris Brezillon if (ret)
177073ecea3dSBoris Brezillon return ret;
177173ecea3dSBoris Brezillon
177273ecea3dSBoris Brezillon if (oob_required) {
177373ecea3dSBoris Brezillon ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
177473ecea3dSBoris Brezillon false);
177573ecea3dSBoris Brezillon if (ret)
177673ecea3dSBoris Brezillon return ret;
177773ecea3dSBoris Brezillon }
177873ecea3dSBoris Brezillon
1779cfcc706cSMiquel Raynal return 0;
1780cfcc706cSMiquel Raynal }
1781cfcc706cSMiquel Raynal
1782cfcc706cSMiquel Raynal /**
1783cfcc706cSMiquel Raynal * nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc
1784cfcc706cSMiquel Raynal * @mtd: mtd info structure
1785cfcc706cSMiquel Raynal * @chip: nand chip info structure
1786cfcc706cSMiquel Raynal * @buf: buffer to store read data
1787cfcc706cSMiquel Raynal * @oob_required: caller requires OOB data read to chip->oob_poi
1788cfcc706cSMiquel Raynal * @page: page number to read
1789cfcc706cSMiquel Raynal *
1790cfcc706cSMiquel Raynal * We need a special oob layout and handling even when OOB isn't used.
1791cfcc706cSMiquel Raynal */
nand_read_page_raw_syndrome(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)1792cfcc706cSMiquel Raynal static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
1793cfcc706cSMiquel Raynal struct nand_chip *chip, uint8_t *buf,
1794cfcc706cSMiquel Raynal int oob_required, int page)
1795cfcc706cSMiquel Raynal {
1796cfcc706cSMiquel Raynal int eccsize = chip->ecc.size;
1797cfcc706cSMiquel Raynal int eccbytes = chip->ecc.bytes;
1798cfcc706cSMiquel Raynal uint8_t *oob = chip->oob_poi;
179973ecea3dSBoris Brezillon int steps, size, ret;
1800cfcc706cSMiquel Raynal
1801cfcc706cSMiquel Raynal for (steps = chip->ecc.steps; steps > 0; steps--) {
180273ecea3dSBoris Brezillon ret = nand_read_data_op(chip, buf, eccsize, false);
180373ecea3dSBoris Brezillon if (ret)
180473ecea3dSBoris Brezillon return ret;
180573ecea3dSBoris Brezillon
1806cfcc706cSMiquel Raynal buf += eccsize;
1807cfcc706cSMiquel Raynal
1808cfcc706cSMiquel Raynal if (chip->ecc.prepad) {
180973ecea3dSBoris Brezillon ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
181073ecea3dSBoris Brezillon false);
181173ecea3dSBoris Brezillon if (ret)
181273ecea3dSBoris Brezillon return ret;
181373ecea3dSBoris Brezillon
1814cfcc706cSMiquel Raynal oob += chip->ecc.prepad;
1815cfcc706cSMiquel Raynal }
1816cfcc706cSMiquel Raynal
181773ecea3dSBoris Brezillon ret = nand_read_data_op(chip, oob, eccbytes, false);
181873ecea3dSBoris Brezillon if (ret)
181973ecea3dSBoris Brezillon return ret;
182073ecea3dSBoris Brezillon
1821cfcc706cSMiquel Raynal oob += eccbytes;
1822cfcc706cSMiquel Raynal
1823cfcc706cSMiquel Raynal if (chip->ecc.postpad) {
182473ecea3dSBoris Brezillon ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
182573ecea3dSBoris Brezillon false);
182673ecea3dSBoris Brezillon if (ret)
182773ecea3dSBoris Brezillon return ret;
182873ecea3dSBoris Brezillon
1829cfcc706cSMiquel Raynal oob += chip->ecc.postpad;
1830cfcc706cSMiquel Raynal }
1831cfcc706cSMiquel Raynal }
1832cfcc706cSMiquel Raynal
1833cfcc706cSMiquel Raynal size = mtd->oobsize - (oob - chip->oob_poi);
183473ecea3dSBoris Brezillon if (size) {
183573ecea3dSBoris Brezillon ret = nand_read_data_op(chip, oob, size, false);
183673ecea3dSBoris Brezillon if (ret)
183773ecea3dSBoris Brezillon return ret;
183873ecea3dSBoris Brezillon }
1839cfcc706cSMiquel Raynal
1840cfcc706cSMiquel Raynal return 0;
1841cfcc706cSMiquel Raynal }
1842cfcc706cSMiquel Raynal
1843cfcc706cSMiquel Raynal /**
1844cfcc706cSMiquel Raynal * nand_read_page_swecc - [REPLACEABLE] software ECC based page read function
1845cfcc706cSMiquel Raynal * @mtd: mtd info structure
1846cfcc706cSMiquel Raynal * @chip: nand chip info structure
1847cfcc706cSMiquel Raynal * @buf: buffer to store read data
1848cfcc706cSMiquel Raynal * @oob_required: caller requires OOB data read to chip->oob_poi
1849cfcc706cSMiquel Raynal * @page: page number to read
1850cfcc706cSMiquel Raynal */
nand_read_page_swecc(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)1851cfcc706cSMiquel Raynal static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
1852cfcc706cSMiquel Raynal uint8_t *buf, int oob_required, int page)
1853cfcc706cSMiquel Raynal {
1854cfcc706cSMiquel Raynal int i, eccsize = chip->ecc.size;
1855cfcc706cSMiquel Raynal int eccbytes = chip->ecc.bytes;
1856cfcc706cSMiquel Raynal int eccsteps = chip->ecc.steps;
1857cfcc706cSMiquel Raynal uint8_t *p = buf;
1858cfcc706cSMiquel Raynal uint8_t *ecc_calc = chip->buffers->ecccalc;
1859cfcc706cSMiquel Raynal uint8_t *ecc_code = chip->buffers->ecccode;
1860cfcc706cSMiquel Raynal uint32_t *eccpos = chip->ecc.layout->eccpos;
1861cfcc706cSMiquel Raynal unsigned int max_bitflips = 0;
1862cfcc706cSMiquel Raynal
1863cfcc706cSMiquel Raynal chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
1864cfcc706cSMiquel Raynal
1865cfcc706cSMiquel Raynal for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
1866cfcc706cSMiquel Raynal chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1867cfcc706cSMiquel Raynal
1868cfcc706cSMiquel Raynal for (i = 0; i < chip->ecc.total; i++)
1869cfcc706cSMiquel Raynal ecc_code[i] = chip->oob_poi[eccpos[i]];
1870cfcc706cSMiquel Raynal
1871cfcc706cSMiquel Raynal eccsteps = chip->ecc.steps;
1872cfcc706cSMiquel Raynal p = buf;
1873cfcc706cSMiquel Raynal
1874cfcc706cSMiquel Raynal for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1875cfcc706cSMiquel Raynal int stat;
1876cfcc706cSMiquel Raynal
1877cfcc706cSMiquel Raynal stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
1878cfcc706cSMiquel Raynal if (stat < 0) {
1879cfcc706cSMiquel Raynal mtd->ecc_stats.failed++;
1880cfcc706cSMiquel Raynal } else {
1881cfcc706cSMiquel Raynal mtd->ecc_stats.corrected += stat;
1882cfcc706cSMiquel Raynal max_bitflips = max_t(unsigned int, max_bitflips, stat);
1883cfcc706cSMiquel Raynal }
1884cfcc706cSMiquel Raynal }
1885cfcc706cSMiquel Raynal return max_bitflips;
1886cfcc706cSMiquel Raynal }
1887cfcc706cSMiquel Raynal
1888cfcc706cSMiquel Raynal /**
1889cfcc706cSMiquel Raynal * nand_read_subpage - [REPLACEABLE] ECC based sub-page read function
1890cfcc706cSMiquel Raynal * @mtd: mtd info structure
1891cfcc706cSMiquel Raynal * @chip: nand chip info structure
1892cfcc706cSMiquel Raynal * @data_offs: offset of requested data within the page
1893cfcc706cSMiquel Raynal * @readlen: data length
1894cfcc706cSMiquel Raynal * @bufpoi: buffer to store read data
1895cfcc706cSMiquel Raynal * @page: page number to read
1896cfcc706cSMiquel Raynal */
nand_read_subpage(struct mtd_info * mtd,struct nand_chip * chip,uint32_t data_offs,uint32_t readlen,uint8_t * bufpoi,int page)1897cfcc706cSMiquel Raynal static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
1898cfcc706cSMiquel Raynal uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi,
1899cfcc706cSMiquel Raynal int page)
1900cfcc706cSMiquel Raynal {
1901cfcc706cSMiquel Raynal int start_step, end_step, num_steps;
1902cfcc706cSMiquel Raynal uint32_t *eccpos = chip->ecc.layout->eccpos;
1903cfcc706cSMiquel Raynal uint8_t *p;
1904cfcc706cSMiquel Raynal int data_col_addr, i, gaps = 0;
1905cfcc706cSMiquel Raynal int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
1906cfcc706cSMiquel Raynal int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
1907cfcc706cSMiquel Raynal int index;
1908cfcc706cSMiquel Raynal unsigned int max_bitflips = 0;
190973ecea3dSBoris Brezillon int ret;
1910cfcc706cSMiquel Raynal
1911cfcc706cSMiquel Raynal /* Column address within the page aligned to ECC size (256bytes) */
1912cfcc706cSMiquel Raynal start_step = data_offs / chip->ecc.size;
1913cfcc706cSMiquel Raynal end_step = (data_offs + readlen - 1) / chip->ecc.size;
1914cfcc706cSMiquel Raynal num_steps = end_step - start_step + 1;
1915cfcc706cSMiquel Raynal index = start_step * chip->ecc.bytes;
1916cfcc706cSMiquel Raynal
1917cfcc706cSMiquel Raynal /* Data size aligned to ECC ecc.size */
1918cfcc706cSMiquel Raynal datafrag_len = num_steps * chip->ecc.size;
1919cfcc706cSMiquel Raynal eccfrag_len = num_steps * chip->ecc.bytes;
1920cfcc706cSMiquel Raynal
1921cfcc706cSMiquel Raynal data_col_addr = start_step * chip->ecc.size;
1922cfcc706cSMiquel Raynal /* If we read not a page aligned data */
1923cfcc706cSMiquel Raynal if (data_col_addr != 0)
1924cfcc706cSMiquel Raynal chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1);
1925cfcc706cSMiquel Raynal
1926cfcc706cSMiquel Raynal p = bufpoi + data_col_addr;
192773ecea3dSBoris Brezillon ret = nand_read_data_op(chip, p, datafrag_len, false);
192873ecea3dSBoris Brezillon if (ret)
192973ecea3dSBoris Brezillon return ret;
1930cfcc706cSMiquel Raynal
1931cfcc706cSMiquel Raynal /* Calculate ECC */
1932cfcc706cSMiquel Raynal for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
1933cfcc706cSMiquel Raynal chip->ecc.calculate(mtd, p, &chip->buffers->ecccalc[i]);
1934cfcc706cSMiquel Raynal
1935cfcc706cSMiquel Raynal /*
1936cfcc706cSMiquel Raynal * The performance is faster if we position offsets according to
1937cfcc706cSMiquel Raynal * ecc.pos. Let's make sure that there are no gaps in ECC positions.
1938cfcc706cSMiquel Raynal */
1939cfcc706cSMiquel Raynal for (i = 0; i < eccfrag_len - 1; i++) {
1940cfcc706cSMiquel Raynal if (eccpos[i + index] + 1 != eccpos[i + index + 1]) {
1941cfcc706cSMiquel Raynal gaps = 1;
1942cfcc706cSMiquel Raynal break;
1943cfcc706cSMiquel Raynal }
1944cfcc706cSMiquel Raynal }
1945cfcc706cSMiquel Raynal if (gaps) {
194673ecea3dSBoris Brezillon ret = nand_change_read_column_op(chip, mtd->writesize,
194773ecea3dSBoris Brezillon chip->oob_poi, mtd->oobsize,
194873ecea3dSBoris Brezillon false);
194973ecea3dSBoris Brezillon if (ret)
195073ecea3dSBoris Brezillon return ret;
1951cfcc706cSMiquel Raynal } else {
1952cfcc706cSMiquel Raynal /*
1953cfcc706cSMiquel Raynal * Send the command to read the particular ECC bytes take care
1954cfcc706cSMiquel Raynal * about buswidth alignment in read_buf.
1955cfcc706cSMiquel Raynal */
1956cfcc706cSMiquel Raynal aligned_pos = eccpos[index] & ~(busw - 1);
1957cfcc706cSMiquel Raynal aligned_len = eccfrag_len;
1958cfcc706cSMiquel Raynal if (eccpos[index] & (busw - 1))
1959cfcc706cSMiquel Raynal aligned_len++;
1960cfcc706cSMiquel Raynal if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
1961cfcc706cSMiquel Raynal aligned_len++;
1962cfcc706cSMiquel Raynal
196373ecea3dSBoris Brezillon ret = nand_change_read_column_op(chip,
196473ecea3dSBoris Brezillon mtd->writesize + aligned_pos,
196573ecea3dSBoris Brezillon &chip->oob_poi[aligned_pos],
196673ecea3dSBoris Brezillon aligned_len, false);
196773ecea3dSBoris Brezillon if (ret)
196873ecea3dSBoris Brezillon return ret;
1969cfcc706cSMiquel Raynal }
1970cfcc706cSMiquel Raynal
1971cfcc706cSMiquel Raynal for (i = 0; i < eccfrag_len; i++)
1972cfcc706cSMiquel Raynal chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
1973cfcc706cSMiquel Raynal
1974cfcc706cSMiquel Raynal p = bufpoi + data_col_addr;
1975cfcc706cSMiquel Raynal for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
1976cfcc706cSMiquel Raynal int stat;
1977cfcc706cSMiquel Raynal
1978cfcc706cSMiquel Raynal stat = chip->ecc.correct(mtd, p,
1979cfcc706cSMiquel Raynal &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
1980cfcc706cSMiquel Raynal if (stat == -EBADMSG &&
1981cfcc706cSMiquel Raynal (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
1982cfcc706cSMiquel Raynal /* check for empty pages with bitflips */
1983cfcc706cSMiquel Raynal stat = nand_check_erased_ecc_chunk(p, chip->ecc.size,
1984cfcc706cSMiquel Raynal &chip->buffers->ecccode[i],
1985cfcc706cSMiquel Raynal chip->ecc.bytes,
1986cfcc706cSMiquel Raynal NULL, 0,
1987cfcc706cSMiquel Raynal chip->ecc.strength);
1988cfcc706cSMiquel Raynal }
1989cfcc706cSMiquel Raynal
1990cfcc706cSMiquel Raynal if (stat < 0) {
1991cfcc706cSMiquel Raynal mtd->ecc_stats.failed++;
1992cfcc706cSMiquel Raynal } else {
1993cfcc706cSMiquel Raynal mtd->ecc_stats.corrected += stat;
1994cfcc706cSMiquel Raynal max_bitflips = max_t(unsigned int, max_bitflips, stat);
1995cfcc706cSMiquel Raynal }
1996cfcc706cSMiquel Raynal }
1997cfcc706cSMiquel Raynal return max_bitflips;
1998cfcc706cSMiquel Raynal }
1999cfcc706cSMiquel Raynal
2000cfcc706cSMiquel Raynal /**
2001cfcc706cSMiquel Raynal * nand_read_page_hwecc - [REPLACEABLE] hardware ECC based page read function
2002cfcc706cSMiquel Raynal * @mtd: mtd info structure
2003cfcc706cSMiquel Raynal * @chip: nand chip info structure
2004cfcc706cSMiquel Raynal * @buf: buffer to store read data
2005cfcc706cSMiquel Raynal * @oob_required: caller requires OOB data read to chip->oob_poi
2006cfcc706cSMiquel Raynal * @page: page number to read
2007cfcc706cSMiquel Raynal *
2008cfcc706cSMiquel Raynal * Not for syndrome calculating ECC controllers which need a special oob layout.
2009cfcc706cSMiquel Raynal */
nand_read_page_hwecc(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)2010cfcc706cSMiquel Raynal static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
2011cfcc706cSMiquel Raynal uint8_t *buf, int oob_required, int page)
2012cfcc706cSMiquel Raynal {
2013cfcc706cSMiquel Raynal int i, eccsize = chip->ecc.size;
2014cfcc706cSMiquel Raynal int eccbytes = chip->ecc.bytes;
2015cfcc706cSMiquel Raynal int eccsteps = chip->ecc.steps;
2016cfcc706cSMiquel Raynal uint8_t *p = buf;
2017cfcc706cSMiquel Raynal uint8_t *ecc_calc = chip->buffers->ecccalc;
2018cfcc706cSMiquel Raynal uint8_t *ecc_code = chip->buffers->ecccode;
2019cfcc706cSMiquel Raynal uint32_t *eccpos = chip->ecc.layout->eccpos;
2020cfcc706cSMiquel Raynal unsigned int max_bitflips = 0;
202173ecea3dSBoris Brezillon int ret;
2022cfcc706cSMiquel Raynal
2023cfcc706cSMiquel Raynal for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
2024cfcc706cSMiquel Raynal chip->ecc.hwctl(mtd, NAND_ECC_READ);
202573ecea3dSBoris Brezillon
202673ecea3dSBoris Brezillon ret = nand_read_data_op(chip, p, eccsize, false);
202773ecea3dSBoris Brezillon if (ret)
202873ecea3dSBoris Brezillon return ret;
202973ecea3dSBoris Brezillon
2030cfcc706cSMiquel Raynal chip->ecc.calculate(mtd, p, &ecc_calc[i]);
2031cfcc706cSMiquel Raynal }
203273ecea3dSBoris Brezillon
203373ecea3dSBoris Brezillon ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false);
203473ecea3dSBoris Brezillon if (ret)
203573ecea3dSBoris Brezillon return ret;
2036cfcc706cSMiquel Raynal
2037cfcc706cSMiquel Raynal for (i = 0; i < chip->ecc.total; i++)
2038cfcc706cSMiquel Raynal ecc_code[i] = chip->oob_poi[eccpos[i]];
2039cfcc706cSMiquel Raynal
2040cfcc706cSMiquel Raynal eccsteps = chip->ecc.steps;
2041cfcc706cSMiquel Raynal p = buf;
2042cfcc706cSMiquel Raynal
2043cfcc706cSMiquel Raynal for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
2044cfcc706cSMiquel Raynal int stat;
2045cfcc706cSMiquel Raynal
2046cfcc706cSMiquel Raynal stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
2047cfcc706cSMiquel Raynal if (stat == -EBADMSG &&
2048cfcc706cSMiquel Raynal (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
2049cfcc706cSMiquel Raynal /* check for empty pages with bitflips */
2050cfcc706cSMiquel Raynal stat = nand_check_erased_ecc_chunk(p, eccsize,
2051cfcc706cSMiquel Raynal &ecc_code[i], eccbytes,
2052cfcc706cSMiquel Raynal NULL, 0,
2053cfcc706cSMiquel Raynal chip->ecc.strength);
2054cfcc706cSMiquel Raynal }
2055cfcc706cSMiquel Raynal
2056cfcc706cSMiquel Raynal if (stat < 0) {
2057cfcc706cSMiquel Raynal mtd->ecc_stats.failed++;
2058cfcc706cSMiquel Raynal } else {
2059cfcc706cSMiquel Raynal mtd->ecc_stats.corrected += stat;
2060cfcc706cSMiquel Raynal max_bitflips = max_t(unsigned int, max_bitflips, stat);
2061cfcc706cSMiquel Raynal }
2062cfcc706cSMiquel Raynal }
2063cfcc706cSMiquel Raynal return max_bitflips;
2064cfcc706cSMiquel Raynal }
2065cfcc706cSMiquel Raynal
2066cfcc706cSMiquel Raynal /**
2067cfcc706cSMiquel Raynal * nand_read_page_hwecc_oob_first - [REPLACEABLE] hw ecc, read oob first
2068cfcc706cSMiquel Raynal * @mtd: mtd info structure
2069cfcc706cSMiquel Raynal * @chip: nand chip info structure
2070cfcc706cSMiquel Raynal * @buf: buffer to store read data
2071cfcc706cSMiquel Raynal * @oob_required: caller requires OOB data read to chip->oob_poi
2072cfcc706cSMiquel Raynal * @page: page number to read
2073cfcc706cSMiquel Raynal *
2074cfcc706cSMiquel Raynal * Hardware ECC for large page chips, require OOB to be read first. For this
2075cfcc706cSMiquel Raynal * ECC mode, the write_page method is re-used from ECC_HW. These methods
2076cfcc706cSMiquel Raynal * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with
2077cfcc706cSMiquel Raynal * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from
2078cfcc706cSMiquel Raynal * the data area, by overwriting the NAND manufacturer bad block markings.
2079cfcc706cSMiquel Raynal */
nand_read_page_hwecc_oob_first(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)2080cfcc706cSMiquel Raynal static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
2081cfcc706cSMiquel Raynal struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
2082cfcc706cSMiquel Raynal {
2083cfcc706cSMiquel Raynal int i, eccsize = chip->ecc.size;
2084cfcc706cSMiquel Raynal int eccbytes = chip->ecc.bytes;
2085cfcc706cSMiquel Raynal int eccsteps = chip->ecc.steps;
2086cfcc706cSMiquel Raynal uint8_t *p = buf;
2087cfcc706cSMiquel Raynal uint8_t *ecc_code = chip->buffers->ecccode;
2088cfcc706cSMiquel Raynal uint32_t *eccpos = chip->ecc.layout->eccpos;
2089cfcc706cSMiquel Raynal uint8_t *ecc_calc = chip->buffers->ecccalc;
2090cfcc706cSMiquel Raynal unsigned int max_bitflips = 0;
209173ecea3dSBoris Brezillon int ret;
2092cfcc706cSMiquel Raynal
2093cfcc706cSMiquel Raynal /* Read the OOB area first */
209473ecea3dSBoris Brezillon ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
209573ecea3dSBoris Brezillon if (ret)
209673ecea3dSBoris Brezillon return ret;
209773ecea3dSBoris Brezillon
209873ecea3dSBoris Brezillon ret = nand_read_page_op(chip, page, 0, NULL, 0);
209973ecea3dSBoris Brezillon if (ret)
210073ecea3dSBoris Brezillon return ret;
2101cfcc706cSMiquel Raynal
2102cfcc706cSMiquel Raynal for (i = 0; i < chip->ecc.total; i++)
2103cfcc706cSMiquel Raynal ecc_code[i] = chip->oob_poi[eccpos[i]];
2104cfcc706cSMiquel Raynal
2105cfcc706cSMiquel Raynal for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
2106cfcc706cSMiquel Raynal int stat;
2107cfcc706cSMiquel Raynal
2108cfcc706cSMiquel Raynal chip->ecc.hwctl(mtd, NAND_ECC_READ);
210973ecea3dSBoris Brezillon
211073ecea3dSBoris Brezillon ret = nand_read_data_op(chip, p, eccsize, false);
211173ecea3dSBoris Brezillon if (ret)
211273ecea3dSBoris Brezillon return ret;
211373ecea3dSBoris Brezillon
2114cfcc706cSMiquel Raynal chip->ecc.calculate(mtd, p, &ecc_calc[i]);
2115cfcc706cSMiquel Raynal
2116cfcc706cSMiquel Raynal stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
2117cfcc706cSMiquel Raynal if (stat == -EBADMSG &&
2118cfcc706cSMiquel Raynal (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
2119cfcc706cSMiquel Raynal /* check for empty pages with bitflips */
2120cfcc706cSMiquel Raynal stat = nand_check_erased_ecc_chunk(p, eccsize,
2121cfcc706cSMiquel Raynal &ecc_code[i], eccbytes,
2122cfcc706cSMiquel Raynal NULL, 0,
2123cfcc706cSMiquel Raynal chip->ecc.strength);
2124cfcc706cSMiquel Raynal }
2125cfcc706cSMiquel Raynal
2126cfcc706cSMiquel Raynal if (stat < 0) {
2127cfcc706cSMiquel Raynal mtd->ecc_stats.failed++;
2128cfcc706cSMiquel Raynal } else {
2129cfcc706cSMiquel Raynal mtd->ecc_stats.corrected += stat;
2130cfcc706cSMiquel Raynal max_bitflips = max_t(unsigned int, max_bitflips, stat);
2131cfcc706cSMiquel Raynal }
2132cfcc706cSMiquel Raynal }
2133cfcc706cSMiquel Raynal return max_bitflips;
2134cfcc706cSMiquel Raynal }
2135cfcc706cSMiquel Raynal
2136cfcc706cSMiquel Raynal /**
2137cfcc706cSMiquel Raynal * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
2138cfcc706cSMiquel Raynal * @mtd: mtd info structure
2139cfcc706cSMiquel Raynal * @chip: nand chip info structure
2140cfcc706cSMiquel Raynal * @buf: buffer to store read data
2141cfcc706cSMiquel Raynal * @oob_required: caller requires OOB data read to chip->oob_poi
2142cfcc706cSMiquel Raynal * @page: page number to read
2143cfcc706cSMiquel Raynal *
2144cfcc706cSMiquel Raynal * The hw generator calculates the error syndrome automatically. Therefore we
2145cfcc706cSMiquel Raynal * need a special oob layout and handling.
2146cfcc706cSMiquel Raynal */
nand_read_page_syndrome(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)2147cfcc706cSMiquel Raynal static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
2148cfcc706cSMiquel Raynal uint8_t *buf, int oob_required, int page)
2149cfcc706cSMiquel Raynal {
215073ecea3dSBoris Brezillon int ret, i, eccsize = chip->ecc.size;
2151cfcc706cSMiquel Raynal int eccbytes = chip->ecc.bytes;
2152cfcc706cSMiquel Raynal int eccsteps = chip->ecc.steps;
2153cfcc706cSMiquel Raynal int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
2154cfcc706cSMiquel Raynal uint8_t *p = buf;
2155cfcc706cSMiquel Raynal uint8_t *oob = chip->oob_poi;
2156cfcc706cSMiquel Raynal unsigned int max_bitflips = 0;
2157cfcc706cSMiquel Raynal
2158cfcc706cSMiquel Raynal for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
2159cfcc706cSMiquel Raynal int stat;
2160cfcc706cSMiquel Raynal
2161cfcc706cSMiquel Raynal chip->ecc.hwctl(mtd, NAND_ECC_READ);
216273ecea3dSBoris Brezillon
216373ecea3dSBoris Brezillon ret = nand_read_data_op(chip, p, eccsize, false);
216473ecea3dSBoris Brezillon if (ret)
216573ecea3dSBoris Brezillon return ret;
2166cfcc706cSMiquel Raynal
2167cfcc706cSMiquel Raynal if (chip->ecc.prepad) {
216873ecea3dSBoris Brezillon ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
216973ecea3dSBoris Brezillon false);
217073ecea3dSBoris Brezillon if (ret)
217173ecea3dSBoris Brezillon return ret;
217273ecea3dSBoris Brezillon
2173cfcc706cSMiquel Raynal oob += chip->ecc.prepad;
2174cfcc706cSMiquel Raynal }
2175cfcc706cSMiquel Raynal
2176cfcc706cSMiquel Raynal chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
217773ecea3dSBoris Brezillon
217873ecea3dSBoris Brezillon ret = nand_read_data_op(chip, oob, eccbytes, false);
217973ecea3dSBoris Brezillon if (ret)
218073ecea3dSBoris Brezillon return ret;
218173ecea3dSBoris Brezillon
2182cfcc706cSMiquel Raynal stat = chip->ecc.correct(mtd, p, oob, NULL);
2183cfcc706cSMiquel Raynal
2184cfcc706cSMiquel Raynal oob += eccbytes;
2185cfcc706cSMiquel Raynal
2186cfcc706cSMiquel Raynal if (chip->ecc.postpad) {
218773ecea3dSBoris Brezillon ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
218873ecea3dSBoris Brezillon false);
218973ecea3dSBoris Brezillon if (ret)
219073ecea3dSBoris Brezillon return ret;
219173ecea3dSBoris Brezillon
2192cfcc706cSMiquel Raynal oob += chip->ecc.postpad;
2193cfcc706cSMiquel Raynal }
2194cfcc706cSMiquel Raynal
2195cfcc706cSMiquel Raynal if (stat == -EBADMSG &&
2196cfcc706cSMiquel Raynal (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
2197cfcc706cSMiquel Raynal /* check for empty pages with bitflips */
2198cfcc706cSMiquel Raynal stat = nand_check_erased_ecc_chunk(p, chip->ecc.size,
2199cfcc706cSMiquel Raynal oob - eccpadbytes,
2200cfcc706cSMiquel Raynal eccpadbytes,
2201cfcc706cSMiquel Raynal NULL, 0,
2202cfcc706cSMiquel Raynal chip->ecc.strength);
2203cfcc706cSMiquel Raynal }
2204cfcc706cSMiquel Raynal
2205cfcc706cSMiquel Raynal if (stat < 0) {
2206cfcc706cSMiquel Raynal mtd->ecc_stats.failed++;
2207cfcc706cSMiquel Raynal } else {
2208cfcc706cSMiquel Raynal mtd->ecc_stats.corrected += stat;
2209cfcc706cSMiquel Raynal max_bitflips = max_t(unsigned int, max_bitflips, stat);
2210cfcc706cSMiquel Raynal }
2211cfcc706cSMiquel Raynal }
2212cfcc706cSMiquel Raynal
2213cfcc706cSMiquel Raynal /* Calculate remaining oob bytes */
2214cfcc706cSMiquel Raynal i = mtd->oobsize - (oob - chip->oob_poi);
221573ecea3dSBoris Brezillon if (i) {
221673ecea3dSBoris Brezillon ret = nand_read_data_op(chip, oob, i, false);
221773ecea3dSBoris Brezillon if (ret)
221873ecea3dSBoris Brezillon return ret;
221973ecea3dSBoris Brezillon }
2220cfcc706cSMiquel Raynal
2221cfcc706cSMiquel Raynal return max_bitflips;
2222cfcc706cSMiquel Raynal }
2223cfcc706cSMiquel Raynal
2224cfcc706cSMiquel Raynal /**
2225cfcc706cSMiquel Raynal * nand_transfer_oob - [INTERN] Transfer oob to client buffer
2226cfcc706cSMiquel Raynal * @chip: nand chip structure
2227cfcc706cSMiquel Raynal * @oob: oob destination address
2228cfcc706cSMiquel Raynal * @ops: oob ops structure
2229cfcc706cSMiquel Raynal * @len: size of oob to transfer
2230cfcc706cSMiquel Raynal */
nand_transfer_oob(struct nand_chip * chip,uint8_t * oob,struct mtd_oob_ops * ops,size_t len)2231cfcc706cSMiquel Raynal static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
2232cfcc706cSMiquel Raynal struct mtd_oob_ops *ops, size_t len)
2233cfcc706cSMiquel Raynal {
2234cfcc706cSMiquel Raynal switch (ops->mode) {
2235cfcc706cSMiquel Raynal
2236cfcc706cSMiquel Raynal case MTD_OPS_PLACE_OOB:
2237cfcc706cSMiquel Raynal case MTD_OPS_RAW:
2238cfcc706cSMiquel Raynal memcpy(oob, chip->oob_poi + ops->ooboffs, len);
2239cfcc706cSMiquel Raynal return oob + len;
2240cfcc706cSMiquel Raynal
2241cfcc706cSMiquel Raynal case MTD_OPS_AUTO_OOB: {
2242cfcc706cSMiquel Raynal struct nand_oobfree *free = chip->ecc.layout->oobfree;
2243cfcc706cSMiquel Raynal uint32_t boffs = 0, roffs = ops->ooboffs;
2244cfcc706cSMiquel Raynal size_t bytes = 0;
2245cfcc706cSMiquel Raynal
2246cfcc706cSMiquel Raynal for (; free->length && len; free++, len -= bytes) {
2247cfcc706cSMiquel Raynal /* Read request not from offset 0? */
2248cfcc706cSMiquel Raynal if (unlikely(roffs)) {
2249cfcc706cSMiquel Raynal if (roffs >= free->length) {
2250cfcc706cSMiquel Raynal roffs -= free->length;
2251cfcc706cSMiquel Raynal continue;
2252cfcc706cSMiquel Raynal }
2253cfcc706cSMiquel Raynal boffs = free->offset + roffs;
2254cfcc706cSMiquel Raynal bytes = min_t(size_t, len,
2255cfcc706cSMiquel Raynal (free->length - roffs));
2256cfcc706cSMiquel Raynal roffs = 0;
2257cfcc706cSMiquel Raynal } else {
2258cfcc706cSMiquel Raynal bytes = min_t(size_t, len, free->length);
2259cfcc706cSMiquel Raynal boffs = free->offset;
2260cfcc706cSMiquel Raynal }
2261cfcc706cSMiquel Raynal memcpy(oob, chip->oob_poi + boffs, bytes);
2262cfcc706cSMiquel Raynal oob += bytes;
2263cfcc706cSMiquel Raynal }
2264cfcc706cSMiquel Raynal return oob;
2265cfcc706cSMiquel Raynal }
2266cfcc706cSMiquel Raynal default:
2267cfcc706cSMiquel Raynal BUG();
2268cfcc706cSMiquel Raynal }
2269cfcc706cSMiquel Raynal return NULL;
2270cfcc706cSMiquel Raynal }
2271cfcc706cSMiquel Raynal
2272cfcc706cSMiquel Raynal /**
2273cfcc706cSMiquel Raynal * nand_setup_read_retry - [INTERN] Set the READ RETRY mode
2274cfcc706cSMiquel Raynal * @mtd: MTD device structure
2275cfcc706cSMiquel Raynal * @retry_mode: the retry mode to use
2276cfcc706cSMiquel Raynal *
2277cfcc706cSMiquel Raynal * Some vendors supply a special command to shift the Vt threshold, to be used
2278cfcc706cSMiquel Raynal * when there are too many bitflips in a page (i.e., ECC error). After setting
2279cfcc706cSMiquel Raynal * a new threshold, the host should retry reading the page.
2280cfcc706cSMiquel Raynal */
nand_setup_read_retry(struct mtd_info * mtd,int retry_mode)2281cfcc706cSMiquel Raynal static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
2282cfcc706cSMiquel Raynal {
2283cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
2284cfcc706cSMiquel Raynal
2285cfcc706cSMiquel Raynal pr_debug("setting READ RETRY mode %d\n", retry_mode);
2286cfcc706cSMiquel Raynal
2287cfcc706cSMiquel Raynal if (retry_mode >= chip->read_retries)
2288cfcc706cSMiquel Raynal return -EINVAL;
2289cfcc706cSMiquel Raynal
2290cfcc706cSMiquel Raynal if (!chip->setup_read_retry)
2291cfcc706cSMiquel Raynal return -EOPNOTSUPP;
2292cfcc706cSMiquel Raynal
2293cfcc706cSMiquel Raynal return chip->setup_read_retry(mtd, retry_mode);
2294cfcc706cSMiquel Raynal }
2295cfcc706cSMiquel Raynal
2296cfcc706cSMiquel Raynal /**
2297cfcc706cSMiquel Raynal * nand_do_read_ops - [INTERN] Read data with ECC
2298cfcc706cSMiquel Raynal * @mtd: MTD device structure
2299cfcc706cSMiquel Raynal * @from: offset to read from
2300cfcc706cSMiquel Raynal * @ops: oob ops structure
2301cfcc706cSMiquel Raynal *
2302cfcc706cSMiquel Raynal * Internal function. Called with chip held.
2303cfcc706cSMiquel Raynal */
nand_do_read_ops(struct mtd_info * mtd,loff_t from,struct mtd_oob_ops * ops)2304cfcc706cSMiquel Raynal static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
2305cfcc706cSMiquel Raynal struct mtd_oob_ops *ops)
2306cfcc706cSMiquel Raynal {
2307cfcc706cSMiquel Raynal int chipnr, page, realpage, col, bytes, aligned, oob_required;
2308cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
2309cfcc706cSMiquel Raynal int ret = 0;
2310cfcc706cSMiquel Raynal uint32_t readlen = ops->len;
2311cfcc706cSMiquel Raynal uint32_t oobreadlen = ops->ooblen;
2312cfcc706cSMiquel Raynal uint32_t max_oobsize = mtd_oobavail(mtd, ops);
2313cfcc706cSMiquel Raynal
2314cfcc706cSMiquel Raynal uint8_t *bufpoi, *oob, *buf;
2315cfcc706cSMiquel Raynal int use_bufpoi;
2316cfcc706cSMiquel Raynal unsigned int max_bitflips = 0;
2317cfcc706cSMiquel Raynal int retry_mode = 0;
2318cfcc706cSMiquel Raynal bool ecc_fail = false;
2319cfcc706cSMiquel Raynal
2320cfcc706cSMiquel Raynal chipnr = (int)(from >> chip->chip_shift);
2321cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
2322cfcc706cSMiquel Raynal
2323cfcc706cSMiquel Raynal realpage = (int)(from >> chip->page_shift);
2324cfcc706cSMiquel Raynal page = realpage & chip->pagemask;
2325cfcc706cSMiquel Raynal
2326cfcc706cSMiquel Raynal col = (int)(from & (mtd->writesize - 1));
2327cfcc706cSMiquel Raynal
2328cfcc706cSMiquel Raynal buf = ops->datbuf;
2329cfcc706cSMiquel Raynal oob = ops->oobbuf;
2330cfcc706cSMiquel Raynal oob_required = oob ? 1 : 0;
2331cfcc706cSMiquel Raynal
2332cfcc706cSMiquel Raynal while (1) {
2333cfcc706cSMiquel Raynal unsigned int ecc_failures = mtd->ecc_stats.failed;
2334cfcc706cSMiquel Raynal
2335cfcc706cSMiquel Raynal WATCHDOG_RESET();
2336cfcc706cSMiquel Raynal bytes = min(mtd->writesize - col, readlen);
2337cfcc706cSMiquel Raynal aligned = (bytes == mtd->writesize);
2338cfcc706cSMiquel Raynal
2339cfcc706cSMiquel Raynal if (!aligned)
2340cfcc706cSMiquel Raynal use_bufpoi = 1;
2341cfcc706cSMiquel Raynal else if (chip->options & NAND_USE_BOUNCE_BUFFER)
2342cfcc706cSMiquel Raynal use_bufpoi = !IS_ALIGNED((unsigned long)buf,
2343cfcc706cSMiquel Raynal chip->buf_align);
2344cfcc706cSMiquel Raynal else
2345cfcc706cSMiquel Raynal use_bufpoi = 0;
2346cfcc706cSMiquel Raynal
2347cfcc706cSMiquel Raynal /* Is the current page in the buffer? */
2348cfcc706cSMiquel Raynal if (realpage != chip->pagebuf || oob) {
2349cfcc706cSMiquel Raynal bufpoi = use_bufpoi ? chip->buffers->databuf : buf;
2350cfcc706cSMiquel Raynal
2351cfcc706cSMiquel Raynal if (use_bufpoi && aligned)
2352cfcc706cSMiquel Raynal pr_debug("%s: using read bounce buffer for buf@%p\n",
2353cfcc706cSMiquel Raynal __func__, buf);
2354cfcc706cSMiquel Raynal
2355cfcc706cSMiquel Raynal read_retry:
235673ecea3dSBoris Brezillon if (nand_standard_page_accessors(&chip->ecc)) {
235773ecea3dSBoris Brezillon ret = nand_read_page_op(chip, page, 0, NULL, 0);
235873ecea3dSBoris Brezillon if (ret)
235973ecea3dSBoris Brezillon break;
236073ecea3dSBoris Brezillon }
2361cfcc706cSMiquel Raynal
2362cfcc706cSMiquel Raynal /*
2363cfcc706cSMiquel Raynal * Now read the page into the buffer. Absent an error,
2364cfcc706cSMiquel Raynal * the read methods return max bitflips per ecc step.
2365cfcc706cSMiquel Raynal */
2366cfcc706cSMiquel Raynal if (unlikely(ops->mode == MTD_OPS_RAW))
2367cfcc706cSMiquel Raynal ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
2368cfcc706cSMiquel Raynal oob_required,
2369cfcc706cSMiquel Raynal page);
2370cfcc706cSMiquel Raynal else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
2371cfcc706cSMiquel Raynal !oob)
2372cfcc706cSMiquel Raynal ret = chip->ecc.read_subpage(mtd, chip,
2373cfcc706cSMiquel Raynal col, bytes, bufpoi,
2374cfcc706cSMiquel Raynal page);
2375cfcc706cSMiquel Raynal else
2376cfcc706cSMiquel Raynal ret = chip->ecc.read_page(mtd, chip, bufpoi,
2377cfcc706cSMiquel Raynal oob_required, page);
2378cfcc706cSMiquel Raynal if (ret < 0) {
2379cfcc706cSMiquel Raynal if (use_bufpoi)
2380cfcc706cSMiquel Raynal /* Invalidate page cache */
2381cfcc706cSMiquel Raynal chip->pagebuf = -1;
2382cfcc706cSMiquel Raynal break;
2383cfcc706cSMiquel Raynal }
2384cfcc706cSMiquel Raynal
2385cfcc706cSMiquel Raynal max_bitflips = max_t(unsigned int, max_bitflips, ret);
2386cfcc706cSMiquel Raynal
2387cfcc706cSMiquel Raynal /* Transfer not aligned data */
2388cfcc706cSMiquel Raynal if (use_bufpoi) {
2389cfcc706cSMiquel Raynal if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
2390cfcc706cSMiquel Raynal !(mtd->ecc_stats.failed - ecc_failures) &&
2391cfcc706cSMiquel Raynal (ops->mode != MTD_OPS_RAW)) {
2392cfcc706cSMiquel Raynal chip->pagebuf = realpage;
2393cfcc706cSMiquel Raynal chip->pagebuf_bitflips = ret;
2394cfcc706cSMiquel Raynal } else {
2395cfcc706cSMiquel Raynal /* Invalidate page cache */
2396cfcc706cSMiquel Raynal chip->pagebuf = -1;
2397cfcc706cSMiquel Raynal }
2398cfcc706cSMiquel Raynal memcpy(buf, chip->buffers->databuf + col, bytes);
2399cfcc706cSMiquel Raynal }
2400cfcc706cSMiquel Raynal
2401cfcc706cSMiquel Raynal if (unlikely(oob)) {
2402cfcc706cSMiquel Raynal int toread = min(oobreadlen, max_oobsize);
2403cfcc706cSMiquel Raynal
2404cfcc706cSMiquel Raynal if (toread) {
2405cfcc706cSMiquel Raynal oob = nand_transfer_oob(chip,
2406cfcc706cSMiquel Raynal oob, ops, toread);
2407cfcc706cSMiquel Raynal oobreadlen -= toread;
2408cfcc706cSMiquel Raynal }
2409cfcc706cSMiquel Raynal }
2410cfcc706cSMiquel Raynal
2411cfcc706cSMiquel Raynal if (chip->options & NAND_NEED_READRDY) {
2412cfcc706cSMiquel Raynal /* Apply delay or wait for ready/busy pin */
2413cfcc706cSMiquel Raynal if (!chip->dev_ready)
2414cfcc706cSMiquel Raynal udelay(chip->chip_delay);
2415cfcc706cSMiquel Raynal else
2416cfcc706cSMiquel Raynal nand_wait_ready(mtd);
2417cfcc706cSMiquel Raynal }
2418cfcc706cSMiquel Raynal
2419cfcc706cSMiquel Raynal if (mtd->ecc_stats.failed - ecc_failures) {
2420cfcc706cSMiquel Raynal if (retry_mode + 1 < chip->read_retries) {
2421cfcc706cSMiquel Raynal retry_mode++;
2422cfcc706cSMiquel Raynal ret = nand_setup_read_retry(mtd,
2423cfcc706cSMiquel Raynal retry_mode);
2424cfcc706cSMiquel Raynal if (ret < 0)
2425cfcc706cSMiquel Raynal break;
2426cfcc706cSMiquel Raynal
2427cfcc706cSMiquel Raynal /* Reset failures; retry */
2428cfcc706cSMiquel Raynal mtd->ecc_stats.failed = ecc_failures;
2429cfcc706cSMiquel Raynal goto read_retry;
2430cfcc706cSMiquel Raynal } else {
2431cfcc706cSMiquel Raynal /* No more retry modes; real failure */
2432cfcc706cSMiquel Raynal ecc_fail = true;
2433cfcc706cSMiquel Raynal }
2434cfcc706cSMiquel Raynal }
2435cfcc706cSMiquel Raynal
2436cfcc706cSMiquel Raynal buf += bytes;
2437cfcc706cSMiquel Raynal } else {
2438cfcc706cSMiquel Raynal memcpy(buf, chip->buffers->databuf + col, bytes);
2439cfcc706cSMiquel Raynal buf += bytes;
2440cfcc706cSMiquel Raynal max_bitflips = max_t(unsigned int, max_bitflips,
2441cfcc706cSMiquel Raynal chip->pagebuf_bitflips);
2442cfcc706cSMiquel Raynal }
2443cfcc706cSMiquel Raynal
2444cfcc706cSMiquel Raynal readlen -= bytes;
2445cfcc706cSMiquel Raynal
2446cfcc706cSMiquel Raynal /* Reset to retry mode 0 */
2447cfcc706cSMiquel Raynal if (retry_mode) {
2448cfcc706cSMiquel Raynal ret = nand_setup_read_retry(mtd, 0);
2449cfcc706cSMiquel Raynal if (ret < 0)
2450cfcc706cSMiquel Raynal break;
2451cfcc706cSMiquel Raynal retry_mode = 0;
2452cfcc706cSMiquel Raynal }
2453cfcc706cSMiquel Raynal
2454cfcc706cSMiquel Raynal if (!readlen)
2455cfcc706cSMiquel Raynal break;
2456cfcc706cSMiquel Raynal
2457cfcc706cSMiquel Raynal /* For subsequent reads align to page boundary */
2458cfcc706cSMiquel Raynal col = 0;
2459cfcc706cSMiquel Raynal /* Increment page address */
2460cfcc706cSMiquel Raynal realpage++;
2461cfcc706cSMiquel Raynal
2462cfcc706cSMiquel Raynal page = realpage & chip->pagemask;
2463cfcc706cSMiquel Raynal /* Check, if we cross a chip boundary */
2464cfcc706cSMiquel Raynal if (!page) {
2465cfcc706cSMiquel Raynal chipnr++;
2466cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
2467cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
2468cfcc706cSMiquel Raynal }
2469cfcc706cSMiquel Raynal }
2470cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
2471cfcc706cSMiquel Raynal
2472cfcc706cSMiquel Raynal ops->retlen = ops->len - (size_t) readlen;
2473cfcc706cSMiquel Raynal if (oob)
2474cfcc706cSMiquel Raynal ops->oobretlen = ops->ooblen - oobreadlen;
2475cfcc706cSMiquel Raynal
2476cfcc706cSMiquel Raynal if (ret < 0)
2477cfcc706cSMiquel Raynal return ret;
2478cfcc706cSMiquel Raynal
2479cfcc706cSMiquel Raynal if (ecc_fail)
2480cfcc706cSMiquel Raynal return -EBADMSG;
2481cfcc706cSMiquel Raynal
2482cfcc706cSMiquel Raynal return max_bitflips;
2483cfcc706cSMiquel Raynal }
2484cfcc706cSMiquel Raynal
2485cfcc706cSMiquel Raynal /**
2486cfcc706cSMiquel Raynal * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function
2487cfcc706cSMiquel Raynal * @mtd: mtd info structure
2488cfcc706cSMiquel Raynal * @chip: nand chip info structure
2489cfcc706cSMiquel Raynal * @page: page number to read
2490cfcc706cSMiquel Raynal */
nand_read_oob_std(struct mtd_info * mtd,struct nand_chip * chip,int page)2491cfcc706cSMiquel Raynal static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
2492cfcc706cSMiquel Raynal int page)
2493cfcc706cSMiquel Raynal {
249473ecea3dSBoris Brezillon return nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
2495cfcc706cSMiquel Raynal }
2496cfcc706cSMiquel Raynal
2497cfcc706cSMiquel Raynal /**
2498cfcc706cSMiquel Raynal * nand_read_oob_syndrome - [REPLACEABLE] OOB data read function for HW ECC
2499cfcc706cSMiquel Raynal * with syndromes
2500cfcc706cSMiquel Raynal * @mtd: mtd info structure
2501cfcc706cSMiquel Raynal * @chip: nand chip info structure
2502cfcc706cSMiquel Raynal * @page: page number to read
2503cfcc706cSMiquel Raynal */
nand_read_oob_syndrome(struct mtd_info * mtd,struct nand_chip * chip,int page)2504cfcc706cSMiquel Raynal static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
2505cfcc706cSMiquel Raynal int page)
2506cfcc706cSMiquel Raynal {
2507cfcc706cSMiquel Raynal int length = mtd->oobsize;
2508cfcc706cSMiquel Raynal int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
2509cfcc706cSMiquel Raynal int eccsize = chip->ecc.size;
2510cfcc706cSMiquel Raynal uint8_t *bufpoi = chip->oob_poi;
251173ecea3dSBoris Brezillon int i, toread, sndrnd = 0, pos, ret;
2512cfcc706cSMiquel Raynal
251373ecea3dSBoris Brezillon ret = nand_read_page_op(chip, page, chip->ecc.size, NULL, 0);
251473ecea3dSBoris Brezillon if (ret)
251573ecea3dSBoris Brezillon return ret;
251673ecea3dSBoris Brezillon
2517cfcc706cSMiquel Raynal for (i = 0; i < chip->ecc.steps; i++) {
2518cfcc706cSMiquel Raynal if (sndrnd) {
251973ecea3dSBoris Brezillon int ret;
252073ecea3dSBoris Brezillon
2521cfcc706cSMiquel Raynal pos = eccsize + i * (eccsize + chunk);
2522cfcc706cSMiquel Raynal if (mtd->writesize > 512)
252373ecea3dSBoris Brezillon ret = nand_change_read_column_op(chip, pos,
252473ecea3dSBoris Brezillon NULL, 0,
252573ecea3dSBoris Brezillon false);
2526cfcc706cSMiquel Raynal else
252773ecea3dSBoris Brezillon ret = nand_read_page_op(chip, page, pos, NULL,
252873ecea3dSBoris Brezillon 0);
252973ecea3dSBoris Brezillon
253073ecea3dSBoris Brezillon if (ret)
253173ecea3dSBoris Brezillon return ret;
2532cfcc706cSMiquel Raynal } else
2533cfcc706cSMiquel Raynal sndrnd = 1;
2534cfcc706cSMiquel Raynal toread = min_t(int, length, chunk);
253573ecea3dSBoris Brezillon
253673ecea3dSBoris Brezillon ret = nand_read_data_op(chip, bufpoi, toread, false);
253773ecea3dSBoris Brezillon if (ret)
253873ecea3dSBoris Brezillon return ret;
253973ecea3dSBoris Brezillon
2540cfcc706cSMiquel Raynal bufpoi += toread;
2541cfcc706cSMiquel Raynal length -= toread;
2542cfcc706cSMiquel Raynal }
254373ecea3dSBoris Brezillon if (length > 0) {
254473ecea3dSBoris Brezillon ret = nand_read_data_op(chip, bufpoi, length, false);
254573ecea3dSBoris Brezillon if (ret)
254673ecea3dSBoris Brezillon return ret;
254773ecea3dSBoris Brezillon }
2548cfcc706cSMiquel Raynal
2549cfcc706cSMiquel Raynal return 0;
2550cfcc706cSMiquel Raynal }
2551cfcc706cSMiquel Raynal
2552cfcc706cSMiquel Raynal /**
2553cfcc706cSMiquel Raynal * nand_write_oob_std - [REPLACEABLE] the most common OOB data write function
2554cfcc706cSMiquel Raynal * @mtd: mtd info structure
2555cfcc706cSMiquel Raynal * @chip: nand chip info structure
2556cfcc706cSMiquel Raynal * @page: page number to write
2557cfcc706cSMiquel Raynal */
nand_write_oob_std(struct mtd_info * mtd,struct nand_chip * chip,int page)2558cfcc706cSMiquel Raynal static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
2559cfcc706cSMiquel Raynal int page)
2560cfcc706cSMiquel Raynal {
256173ecea3dSBoris Brezillon return nand_prog_page_op(chip, page, mtd->writesize, chip->oob_poi,
256273ecea3dSBoris Brezillon mtd->oobsize);
2563cfcc706cSMiquel Raynal }
2564cfcc706cSMiquel Raynal
2565cfcc706cSMiquel Raynal /**
2566cfcc706cSMiquel Raynal * nand_write_oob_syndrome - [REPLACEABLE] OOB data write function for HW ECC
2567cfcc706cSMiquel Raynal * with syndrome - only for large page flash
2568cfcc706cSMiquel Raynal * @mtd: mtd info structure
2569cfcc706cSMiquel Raynal * @chip: nand chip info structure
2570cfcc706cSMiquel Raynal * @page: page number to write
2571cfcc706cSMiquel Raynal */
nand_write_oob_syndrome(struct mtd_info * mtd,struct nand_chip * chip,int page)2572cfcc706cSMiquel Raynal static int nand_write_oob_syndrome(struct mtd_info *mtd,
2573cfcc706cSMiquel Raynal struct nand_chip *chip, int page)
2574cfcc706cSMiquel Raynal {
2575cfcc706cSMiquel Raynal int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
2576cfcc706cSMiquel Raynal int eccsize = chip->ecc.size, length = mtd->oobsize;
257773ecea3dSBoris Brezillon int ret, i, len, pos, sndcmd = 0, steps = chip->ecc.steps;
2578cfcc706cSMiquel Raynal const uint8_t *bufpoi = chip->oob_poi;
2579cfcc706cSMiquel Raynal
2580cfcc706cSMiquel Raynal /*
2581cfcc706cSMiquel Raynal * data-ecc-data-ecc ... ecc-oob
2582cfcc706cSMiquel Raynal * or
2583cfcc706cSMiquel Raynal * data-pad-ecc-pad-data-pad .... ecc-pad-oob
2584cfcc706cSMiquel Raynal */
2585cfcc706cSMiquel Raynal if (!chip->ecc.prepad && !chip->ecc.postpad) {
2586cfcc706cSMiquel Raynal pos = steps * (eccsize + chunk);
2587cfcc706cSMiquel Raynal steps = 0;
2588cfcc706cSMiquel Raynal } else
2589cfcc706cSMiquel Raynal pos = eccsize;
2590cfcc706cSMiquel Raynal
259173ecea3dSBoris Brezillon ret = nand_prog_page_begin_op(chip, page, pos, NULL, 0);
259273ecea3dSBoris Brezillon if (ret)
259373ecea3dSBoris Brezillon return ret;
259473ecea3dSBoris Brezillon
2595cfcc706cSMiquel Raynal for (i = 0; i < steps; i++) {
2596cfcc706cSMiquel Raynal if (sndcmd) {
2597cfcc706cSMiquel Raynal if (mtd->writesize <= 512) {
2598cfcc706cSMiquel Raynal uint32_t fill = 0xFFFFFFFF;
2599cfcc706cSMiquel Raynal
2600cfcc706cSMiquel Raynal len = eccsize;
2601cfcc706cSMiquel Raynal while (len > 0) {
2602cfcc706cSMiquel Raynal int num = min_t(int, len, 4);
260373ecea3dSBoris Brezillon
260473ecea3dSBoris Brezillon ret = nand_write_data_op(chip, &fill,
260573ecea3dSBoris Brezillon num, false);
260673ecea3dSBoris Brezillon if (ret)
260773ecea3dSBoris Brezillon return ret;
260873ecea3dSBoris Brezillon
2609cfcc706cSMiquel Raynal len -= num;
2610cfcc706cSMiquel Raynal }
2611cfcc706cSMiquel Raynal } else {
2612cfcc706cSMiquel Raynal pos = eccsize + i * (eccsize + chunk);
261373ecea3dSBoris Brezillon ret = nand_change_write_column_op(chip, pos,
261473ecea3dSBoris Brezillon NULL, 0,
261573ecea3dSBoris Brezillon false);
261673ecea3dSBoris Brezillon if (ret)
261773ecea3dSBoris Brezillon return ret;
2618cfcc706cSMiquel Raynal }
2619cfcc706cSMiquel Raynal } else
2620cfcc706cSMiquel Raynal sndcmd = 1;
2621cfcc706cSMiquel Raynal len = min_t(int, length, chunk);
262273ecea3dSBoris Brezillon
262373ecea3dSBoris Brezillon ret = nand_write_data_op(chip, bufpoi, len, false);
262473ecea3dSBoris Brezillon if (ret)
262573ecea3dSBoris Brezillon return ret;
262673ecea3dSBoris Brezillon
2627cfcc706cSMiquel Raynal bufpoi += len;
2628cfcc706cSMiquel Raynal length -= len;
2629cfcc706cSMiquel Raynal }
263073ecea3dSBoris Brezillon if (length > 0) {
263173ecea3dSBoris Brezillon ret = nand_write_data_op(chip, bufpoi, length, false);
263273ecea3dSBoris Brezillon if (ret)
263373ecea3dSBoris Brezillon return ret;
263473ecea3dSBoris Brezillon }
2635cfcc706cSMiquel Raynal
263673ecea3dSBoris Brezillon return nand_prog_page_end_op(chip);
2637cfcc706cSMiquel Raynal }
2638cfcc706cSMiquel Raynal
2639cfcc706cSMiquel Raynal /**
2640cfcc706cSMiquel Raynal * nand_do_read_oob - [INTERN] NAND read out-of-band
2641cfcc706cSMiquel Raynal * @mtd: MTD device structure
2642cfcc706cSMiquel Raynal * @from: offset to read from
2643cfcc706cSMiquel Raynal * @ops: oob operations description structure
2644cfcc706cSMiquel Raynal *
2645cfcc706cSMiquel Raynal * NAND read out-of-band data from the spare area.
2646cfcc706cSMiquel Raynal */
nand_do_read_oob(struct mtd_info * mtd,loff_t from,struct mtd_oob_ops * ops)2647cfcc706cSMiquel Raynal static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
2648cfcc706cSMiquel Raynal struct mtd_oob_ops *ops)
2649cfcc706cSMiquel Raynal {
2650cfcc706cSMiquel Raynal int page, realpage, chipnr;
2651cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
2652cfcc706cSMiquel Raynal struct mtd_ecc_stats stats;
2653cfcc706cSMiquel Raynal int readlen = ops->ooblen;
2654cfcc706cSMiquel Raynal int len;
2655cfcc706cSMiquel Raynal uint8_t *buf = ops->oobbuf;
2656cfcc706cSMiquel Raynal int ret = 0;
2657cfcc706cSMiquel Raynal
2658cfcc706cSMiquel Raynal pr_debug("%s: from = 0x%08Lx, len = %i\n",
2659cfcc706cSMiquel Raynal __func__, (unsigned long long)from, readlen);
2660cfcc706cSMiquel Raynal
2661cfcc706cSMiquel Raynal stats = mtd->ecc_stats;
2662cfcc706cSMiquel Raynal
2663cfcc706cSMiquel Raynal len = mtd_oobavail(mtd, ops);
2664cfcc706cSMiquel Raynal
2665cfcc706cSMiquel Raynal if (unlikely(ops->ooboffs >= len)) {
2666cfcc706cSMiquel Raynal pr_debug("%s: attempt to start read outside oob\n",
2667cfcc706cSMiquel Raynal __func__);
2668cfcc706cSMiquel Raynal return -EINVAL;
2669cfcc706cSMiquel Raynal }
2670cfcc706cSMiquel Raynal
2671cfcc706cSMiquel Raynal /* Do not allow reads past end of device */
2672cfcc706cSMiquel Raynal if (unlikely(from >= mtd->size ||
2673cfcc706cSMiquel Raynal ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
2674cfcc706cSMiquel Raynal (from >> chip->page_shift)) * len)) {
2675cfcc706cSMiquel Raynal pr_debug("%s: attempt to read beyond end of device\n",
2676cfcc706cSMiquel Raynal __func__);
2677cfcc706cSMiquel Raynal return -EINVAL;
2678cfcc706cSMiquel Raynal }
2679cfcc706cSMiquel Raynal
2680cfcc706cSMiquel Raynal chipnr = (int)(from >> chip->chip_shift);
2681cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
2682cfcc706cSMiquel Raynal
2683cfcc706cSMiquel Raynal /* Shift to get page */
2684cfcc706cSMiquel Raynal realpage = (int)(from >> chip->page_shift);
2685cfcc706cSMiquel Raynal page = realpage & chip->pagemask;
2686cfcc706cSMiquel Raynal
2687cfcc706cSMiquel Raynal while (1) {
2688cfcc706cSMiquel Raynal WATCHDOG_RESET();
2689cfcc706cSMiquel Raynal
2690cfcc706cSMiquel Raynal if (ops->mode == MTD_OPS_RAW)
2691cfcc706cSMiquel Raynal ret = chip->ecc.read_oob_raw(mtd, chip, page);
2692cfcc706cSMiquel Raynal else
2693cfcc706cSMiquel Raynal ret = chip->ecc.read_oob(mtd, chip, page);
2694cfcc706cSMiquel Raynal
2695cfcc706cSMiquel Raynal if (ret < 0)
2696cfcc706cSMiquel Raynal break;
2697cfcc706cSMiquel Raynal
2698cfcc706cSMiquel Raynal len = min(len, readlen);
2699cfcc706cSMiquel Raynal buf = nand_transfer_oob(chip, buf, ops, len);
2700cfcc706cSMiquel Raynal
2701cfcc706cSMiquel Raynal if (chip->options & NAND_NEED_READRDY) {
2702cfcc706cSMiquel Raynal /* Apply delay or wait for ready/busy pin */
2703cfcc706cSMiquel Raynal if (!chip->dev_ready)
2704cfcc706cSMiquel Raynal udelay(chip->chip_delay);
2705cfcc706cSMiquel Raynal else
2706cfcc706cSMiquel Raynal nand_wait_ready(mtd);
2707cfcc706cSMiquel Raynal }
2708cfcc706cSMiquel Raynal
2709cfcc706cSMiquel Raynal readlen -= len;
2710cfcc706cSMiquel Raynal if (!readlen)
2711cfcc706cSMiquel Raynal break;
2712cfcc706cSMiquel Raynal
2713cfcc706cSMiquel Raynal /* Increment page address */
2714cfcc706cSMiquel Raynal realpage++;
2715cfcc706cSMiquel Raynal
2716cfcc706cSMiquel Raynal page = realpage & chip->pagemask;
2717cfcc706cSMiquel Raynal /* Check, if we cross a chip boundary */
2718cfcc706cSMiquel Raynal if (!page) {
2719cfcc706cSMiquel Raynal chipnr++;
2720cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
2721cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
2722cfcc706cSMiquel Raynal }
2723cfcc706cSMiquel Raynal }
2724cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
2725cfcc706cSMiquel Raynal
2726cfcc706cSMiquel Raynal ops->oobretlen = ops->ooblen - readlen;
2727cfcc706cSMiquel Raynal
2728cfcc706cSMiquel Raynal if (ret < 0)
2729cfcc706cSMiquel Raynal return ret;
2730cfcc706cSMiquel Raynal
2731cfcc706cSMiquel Raynal if (mtd->ecc_stats.failed - stats.failed)
2732cfcc706cSMiquel Raynal return -EBADMSG;
2733cfcc706cSMiquel Raynal
2734cfcc706cSMiquel Raynal return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
2735cfcc706cSMiquel Raynal }
2736cfcc706cSMiquel Raynal
2737cfcc706cSMiquel Raynal /**
2738cfcc706cSMiquel Raynal * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band
2739cfcc706cSMiquel Raynal * @mtd: MTD device structure
2740cfcc706cSMiquel Raynal * @from: offset to read from
2741cfcc706cSMiquel Raynal * @ops: oob operation description structure
2742cfcc706cSMiquel Raynal *
2743cfcc706cSMiquel Raynal * NAND read data and/or out-of-band data.
2744cfcc706cSMiquel Raynal */
nand_read_oob(struct mtd_info * mtd,loff_t from,struct mtd_oob_ops * ops)2745cfcc706cSMiquel Raynal static int nand_read_oob(struct mtd_info *mtd, loff_t from,
2746cfcc706cSMiquel Raynal struct mtd_oob_ops *ops)
2747cfcc706cSMiquel Raynal {
2748cfcc706cSMiquel Raynal int ret = -ENOTSUPP;
2749cfcc706cSMiquel Raynal
2750cfcc706cSMiquel Raynal ops->retlen = 0;
2751cfcc706cSMiquel Raynal
2752cfcc706cSMiquel Raynal /* Do not allow reads past end of device */
2753cfcc706cSMiquel Raynal if (ops->datbuf && (from + ops->len) > mtd->size) {
2754cfcc706cSMiquel Raynal pr_debug("%s: attempt to read beyond end of device\n",
2755cfcc706cSMiquel Raynal __func__);
2756cfcc706cSMiquel Raynal return -EINVAL;
2757cfcc706cSMiquel Raynal }
2758cfcc706cSMiquel Raynal
2759cfcc706cSMiquel Raynal nand_get_device(mtd, FL_READING);
2760cfcc706cSMiquel Raynal
2761cfcc706cSMiquel Raynal switch (ops->mode) {
2762cfcc706cSMiquel Raynal case MTD_OPS_PLACE_OOB:
2763cfcc706cSMiquel Raynal case MTD_OPS_AUTO_OOB:
2764cfcc706cSMiquel Raynal case MTD_OPS_RAW:
2765cfcc706cSMiquel Raynal break;
2766cfcc706cSMiquel Raynal
2767cfcc706cSMiquel Raynal default:
2768cfcc706cSMiquel Raynal goto out;
2769cfcc706cSMiquel Raynal }
2770cfcc706cSMiquel Raynal
2771cfcc706cSMiquel Raynal if (!ops->datbuf)
2772cfcc706cSMiquel Raynal ret = nand_do_read_oob(mtd, from, ops);
2773cfcc706cSMiquel Raynal else
2774cfcc706cSMiquel Raynal ret = nand_do_read_ops(mtd, from, ops);
2775cfcc706cSMiquel Raynal
2776cfcc706cSMiquel Raynal out:
2777cfcc706cSMiquel Raynal nand_release_device(mtd);
2778cfcc706cSMiquel Raynal return ret;
2779cfcc706cSMiquel Raynal }
2780cfcc706cSMiquel Raynal
2781cfcc706cSMiquel Raynal
2782cfcc706cSMiquel Raynal /**
2783cfcc706cSMiquel Raynal * nand_write_page_raw - [INTERN] raw page write function
2784cfcc706cSMiquel Raynal * @mtd: mtd info structure
2785cfcc706cSMiquel Raynal * @chip: nand chip info structure
2786cfcc706cSMiquel Raynal * @buf: data buffer
2787cfcc706cSMiquel Raynal * @oob_required: must write chip->oob_poi to OOB
2788cfcc706cSMiquel Raynal * @page: page number to write
2789cfcc706cSMiquel Raynal *
2790cfcc706cSMiquel Raynal * Not for syndrome calculating ECC controllers, which use a special oob layout.
2791cfcc706cSMiquel Raynal */
nand_write_page_raw(struct mtd_info * mtd,struct nand_chip * chip,const uint8_t * buf,int oob_required,int page)2792cfcc706cSMiquel Raynal static int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
2793cfcc706cSMiquel Raynal const uint8_t *buf, int oob_required, int page)
2794cfcc706cSMiquel Raynal {
279573ecea3dSBoris Brezillon int ret;
279673ecea3dSBoris Brezillon
279773ecea3dSBoris Brezillon ret = nand_write_data_op(chip, buf, mtd->writesize, false);
279873ecea3dSBoris Brezillon if (ret)
279973ecea3dSBoris Brezillon return ret;
280073ecea3dSBoris Brezillon
280173ecea3dSBoris Brezillon if (oob_required) {
280273ecea3dSBoris Brezillon ret = nand_write_data_op(chip, chip->oob_poi, mtd->oobsize,
280373ecea3dSBoris Brezillon false);
280473ecea3dSBoris Brezillon if (ret)
280573ecea3dSBoris Brezillon return ret;
280673ecea3dSBoris Brezillon }
2807cfcc706cSMiquel Raynal
2808cfcc706cSMiquel Raynal return 0;
2809cfcc706cSMiquel Raynal }
2810cfcc706cSMiquel Raynal
2811cfcc706cSMiquel Raynal /**
2812cfcc706cSMiquel Raynal * nand_write_page_raw_syndrome - [INTERN] raw page write function
2813cfcc706cSMiquel Raynal * @mtd: mtd info structure
2814cfcc706cSMiquel Raynal * @chip: nand chip info structure
2815cfcc706cSMiquel Raynal * @buf: data buffer
2816cfcc706cSMiquel Raynal * @oob_required: must write chip->oob_poi to OOB
2817cfcc706cSMiquel Raynal * @page: page number to write
2818cfcc706cSMiquel Raynal *
2819cfcc706cSMiquel Raynal * We need a special oob layout and handling even when ECC isn't checked.
2820cfcc706cSMiquel Raynal */
nand_write_page_raw_syndrome(struct mtd_info * mtd,struct nand_chip * chip,const uint8_t * buf,int oob_required,int page)2821cfcc706cSMiquel Raynal static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
2822cfcc706cSMiquel Raynal struct nand_chip *chip,
2823cfcc706cSMiquel Raynal const uint8_t *buf, int oob_required,
2824cfcc706cSMiquel Raynal int page)
2825cfcc706cSMiquel Raynal {
2826cfcc706cSMiquel Raynal int eccsize = chip->ecc.size;
2827cfcc706cSMiquel Raynal int eccbytes = chip->ecc.bytes;
2828cfcc706cSMiquel Raynal uint8_t *oob = chip->oob_poi;
282973ecea3dSBoris Brezillon int steps, size, ret;
2830cfcc706cSMiquel Raynal
2831cfcc706cSMiquel Raynal for (steps = chip->ecc.steps; steps > 0; steps--) {
283273ecea3dSBoris Brezillon ret = nand_write_data_op(chip, buf, eccsize, false);
283373ecea3dSBoris Brezillon if (ret)
283473ecea3dSBoris Brezillon return ret;
283573ecea3dSBoris Brezillon
2836cfcc706cSMiquel Raynal buf += eccsize;
2837cfcc706cSMiquel Raynal
2838cfcc706cSMiquel Raynal if (chip->ecc.prepad) {
283973ecea3dSBoris Brezillon ret = nand_write_data_op(chip, oob, chip->ecc.prepad,
284073ecea3dSBoris Brezillon false);
284173ecea3dSBoris Brezillon if (ret)
284273ecea3dSBoris Brezillon return ret;
284373ecea3dSBoris Brezillon
2844cfcc706cSMiquel Raynal oob += chip->ecc.prepad;
2845cfcc706cSMiquel Raynal }
2846cfcc706cSMiquel Raynal
284773ecea3dSBoris Brezillon ret = nand_write_data_op(chip, oob, eccbytes, false);
284873ecea3dSBoris Brezillon if (ret)
284973ecea3dSBoris Brezillon return ret;
285073ecea3dSBoris Brezillon
2851cfcc706cSMiquel Raynal oob += eccbytes;
2852cfcc706cSMiquel Raynal
2853cfcc706cSMiquel Raynal if (chip->ecc.postpad) {
285473ecea3dSBoris Brezillon ret = nand_write_data_op(chip, oob, chip->ecc.postpad,
285573ecea3dSBoris Brezillon false);
285673ecea3dSBoris Brezillon if (ret)
285773ecea3dSBoris Brezillon return ret;
285873ecea3dSBoris Brezillon
2859cfcc706cSMiquel Raynal oob += chip->ecc.postpad;
2860cfcc706cSMiquel Raynal }
2861cfcc706cSMiquel Raynal }
2862cfcc706cSMiquel Raynal
2863cfcc706cSMiquel Raynal size = mtd->oobsize - (oob - chip->oob_poi);
286473ecea3dSBoris Brezillon if (size) {
286573ecea3dSBoris Brezillon ret = nand_write_data_op(chip, oob, size, false);
286673ecea3dSBoris Brezillon if (ret)
286773ecea3dSBoris Brezillon return ret;
286873ecea3dSBoris Brezillon }
2869cfcc706cSMiquel Raynal
2870cfcc706cSMiquel Raynal return 0;
2871cfcc706cSMiquel Raynal }
2872cfcc706cSMiquel Raynal /**
2873cfcc706cSMiquel Raynal * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
2874cfcc706cSMiquel Raynal * @mtd: mtd info structure
2875cfcc706cSMiquel Raynal * @chip: nand chip info structure
2876cfcc706cSMiquel Raynal * @buf: data buffer
2877cfcc706cSMiquel Raynal * @oob_required: must write chip->oob_poi to OOB
2878cfcc706cSMiquel Raynal * @page: page number to write
2879cfcc706cSMiquel Raynal */
nand_write_page_swecc(struct mtd_info * mtd,struct nand_chip * chip,const uint8_t * buf,int oob_required,int page)2880cfcc706cSMiquel Raynal static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
2881cfcc706cSMiquel Raynal const uint8_t *buf, int oob_required,
2882cfcc706cSMiquel Raynal int page)
2883cfcc706cSMiquel Raynal {
2884cfcc706cSMiquel Raynal int i, eccsize = chip->ecc.size;
2885cfcc706cSMiquel Raynal int eccbytes = chip->ecc.bytes;
2886cfcc706cSMiquel Raynal int eccsteps = chip->ecc.steps;
2887cfcc706cSMiquel Raynal uint8_t *ecc_calc = chip->buffers->ecccalc;
2888cfcc706cSMiquel Raynal const uint8_t *p = buf;
2889cfcc706cSMiquel Raynal uint32_t *eccpos = chip->ecc.layout->eccpos;
2890cfcc706cSMiquel Raynal
2891cfcc706cSMiquel Raynal /* Software ECC calculation */
2892cfcc706cSMiquel Raynal for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
2893cfcc706cSMiquel Raynal chip->ecc.calculate(mtd, p, &ecc_calc[i]);
2894cfcc706cSMiquel Raynal
2895cfcc706cSMiquel Raynal for (i = 0; i < chip->ecc.total; i++)
2896cfcc706cSMiquel Raynal chip->oob_poi[eccpos[i]] = ecc_calc[i];
2897cfcc706cSMiquel Raynal
2898cfcc706cSMiquel Raynal return chip->ecc.write_page_raw(mtd, chip, buf, 1, page);
2899cfcc706cSMiquel Raynal }
2900cfcc706cSMiquel Raynal
2901cfcc706cSMiquel Raynal /**
2902cfcc706cSMiquel Raynal * nand_write_page_hwecc - [REPLACEABLE] hardware ECC based page write function
2903cfcc706cSMiquel Raynal * @mtd: mtd info structure
2904cfcc706cSMiquel Raynal * @chip: nand chip info structure
2905cfcc706cSMiquel Raynal * @buf: data buffer
2906cfcc706cSMiquel Raynal * @oob_required: must write chip->oob_poi to OOB
2907cfcc706cSMiquel Raynal * @page: page number to write
2908cfcc706cSMiquel Raynal */
nand_write_page_hwecc(struct mtd_info * mtd,struct nand_chip * chip,const uint8_t * buf,int oob_required,int page)2909cfcc706cSMiquel Raynal static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
2910cfcc706cSMiquel Raynal const uint8_t *buf, int oob_required,
2911cfcc706cSMiquel Raynal int page)
2912cfcc706cSMiquel Raynal {
2913cfcc706cSMiquel Raynal int i, eccsize = chip->ecc.size;
2914cfcc706cSMiquel Raynal int eccbytes = chip->ecc.bytes;
2915cfcc706cSMiquel Raynal int eccsteps = chip->ecc.steps;
2916cfcc706cSMiquel Raynal uint8_t *ecc_calc = chip->buffers->ecccalc;
2917cfcc706cSMiquel Raynal const uint8_t *p = buf;
2918cfcc706cSMiquel Raynal uint32_t *eccpos = chip->ecc.layout->eccpos;
291973ecea3dSBoris Brezillon int ret;
2920cfcc706cSMiquel Raynal
2921cfcc706cSMiquel Raynal for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
2922cfcc706cSMiquel Raynal chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
292373ecea3dSBoris Brezillon
292473ecea3dSBoris Brezillon ret = nand_write_data_op(chip, p, eccsize, false);
292573ecea3dSBoris Brezillon if (ret)
292673ecea3dSBoris Brezillon return ret;
292773ecea3dSBoris Brezillon
2928cfcc706cSMiquel Raynal chip->ecc.calculate(mtd, p, &ecc_calc[i]);
2929cfcc706cSMiquel Raynal }
2930cfcc706cSMiquel Raynal
2931cfcc706cSMiquel Raynal for (i = 0; i < chip->ecc.total; i++)
2932cfcc706cSMiquel Raynal chip->oob_poi[eccpos[i]] = ecc_calc[i];
2933cfcc706cSMiquel Raynal
293473ecea3dSBoris Brezillon ret = nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false);
293573ecea3dSBoris Brezillon if (ret)
293673ecea3dSBoris Brezillon return ret;
2937cfcc706cSMiquel Raynal
2938cfcc706cSMiquel Raynal return 0;
2939cfcc706cSMiquel Raynal }
2940cfcc706cSMiquel Raynal
2941cfcc706cSMiquel Raynal
2942cfcc706cSMiquel Raynal /**
2943cfcc706cSMiquel Raynal * nand_write_subpage_hwecc - [REPLACEABLE] hardware ECC based subpage write
2944cfcc706cSMiquel Raynal * @mtd: mtd info structure
2945cfcc706cSMiquel Raynal * @chip: nand chip info structure
2946cfcc706cSMiquel Raynal * @offset: column address of subpage within the page
2947cfcc706cSMiquel Raynal * @data_len: data length
2948cfcc706cSMiquel Raynal * @buf: data buffer
2949cfcc706cSMiquel Raynal * @oob_required: must write chip->oob_poi to OOB
2950cfcc706cSMiquel Raynal * @page: page number to write
2951cfcc706cSMiquel Raynal */
nand_write_subpage_hwecc(struct mtd_info * mtd,struct nand_chip * chip,uint32_t offset,uint32_t data_len,const uint8_t * buf,int oob_required,int page)2952cfcc706cSMiquel Raynal static int nand_write_subpage_hwecc(struct mtd_info *mtd,
2953cfcc706cSMiquel Raynal struct nand_chip *chip, uint32_t offset,
2954cfcc706cSMiquel Raynal uint32_t data_len, const uint8_t *buf,
2955cfcc706cSMiquel Raynal int oob_required, int page)
2956cfcc706cSMiquel Raynal {
2957cfcc706cSMiquel Raynal uint8_t *oob_buf = chip->oob_poi;
2958cfcc706cSMiquel Raynal uint8_t *ecc_calc = chip->buffers->ecccalc;
2959cfcc706cSMiquel Raynal int ecc_size = chip->ecc.size;
2960cfcc706cSMiquel Raynal int ecc_bytes = chip->ecc.bytes;
2961cfcc706cSMiquel Raynal int ecc_steps = chip->ecc.steps;
2962cfcc706cSMiquel Raynal uint32_t *eccpos = chip->ecc.layout->eccpos;
2963cfcc706cSMiquel Raynal uint32_t start_step = offset / ecc_size;
2964cfcc706cSMiquel Raynal uint32_t end_step = (offset + data_len - 1) / ecc_size;
2965cfcc706cSMiquel Raynal int oob_bytes = mtd->oobsize / ecc_steps;
2966cfcc706cSMiquel Raynal int step, i;
296773ecea3dSBoris Brezillon int ret;
2968cfcc706cSMiquel Raynal
2969cfcc706cSMiquel Raynal for (step = 0; step < ecc_steps; step++) {
2970cfcc706cSMiquel Raynal /* configure controller for WRITE access */
2971cfcc706cSMiquel Raynal chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
2972cfcc706cSMiquel Raynal
2973cfcc706cSMiquel Raynal /* write data (untouched subpages already masked by 0xFF) */
297473ecea3dSBoris Brezillon ret = nand_write_data_op(chip, buf, ecc_size, false);
297573ecea3dSBoris Brezillon if (ret)
297673ecea3dSBoris Brezillon return ret;
2977cfcc706cSMiquel Raynal
2978cfcc706cSMiquel Raynal /* mask ECC of un-touched subpages by padding 0xFF */
2979cfcc706cSMiquel Raynal if ((step < start_step) || (step > end_step))
2980cfcc706cSMiquel Raynal memset(ecc_calc, 0xff, ecc_bytes);
2981cfcc706cSMiquel Raynal else
2982cfcc706cSMiquel Raynal chip->ecc.calculate(mtd, buf, ecc_calc);
2983cfcc706cSMiquel Raynal
2984cfcc706cSMiquel Raynal /* mask OOB of un-touched subpages by padding 0xFF */
2985cfcc706cSMiquel Raynal /* if oob_required, preserve OOB metadata of written subpage */
2986cfcc706cSMiquel Raynal if (!oob_required || (step < start_step) || (step > end_step))
2987cfcc706cSMiquel Raynal memset(oob_buf, 0xff, oob_bytes);
2988cfcc706cSMiquel Raynal
2989cfcc706cSMiquel Raynal buf += ecc_size;
2990cfcc706cSMiquel Raynal ecc_calc += ecc_bytes;
2991cfcc706cSMiquel Raynal oob_buf += oob_bytes;
2992cfcc706cSMiquel Raynal }
2993cfcc706cSMiquel Raynal
2994cfcc706cSMiquel Raynal /* copy calculated ECC for whole page to chip->buffer->oob */
2995cfcc706cSMiquel Raynal /* this include masked-value(0xFF) for unwritten subpages */
2996cfcc706cSMiquel Raynal ecc_calc = chip->buffers->ecccalc;
2997cfcc706cSMiquel Raynal for (i = 0; i < chip->ecc.total; i++)
2998cfcc706cSMiquel Raynal chip->oob_poi[eccpos[i]] = ecc_calc[i];
2999cfcc706cSMiquel Raynal
3000cfcc706cSMiquel Raynal /* write OOB buffer to NAND device */
300173ecea3dSBoris Brezillon ret = nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false);
300273ecea3dSBoris Brezillon if (ret)
300373ecea3dSBoris Brezillon return ret;
3004cfcc706cSMiquel Raynal
3005cfcc706cSMiquel Raynal return 0;
3006cfcc706cSMiquel Raynal }
3007cfcc706cSMiquel Raynal
3008cfcc706cSMiquel Raynal
3009cfcc706cSMiquel Raynal /**
3010cfcc706cSMiquel Raynal * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
3011cfcc706cSMiquel Raynal * @mtd: mtd info structure
3012cfcc706cSMiquel Raynal * @chip: nand chip info structure
3013cfcc706cSMiquel Raynal * @buf: data buffer
3014cfcc706cSMiquel Raynal * @oob_required: must write chip->oob_poi to OOB
3015cfcc706cSMiquel Raynal * @page: page number to write
3016cfcc706cSMiquel Raynal *
3017cfcc706cSMiquel Raynal * The hw generator calculates the error syndrome automatically. Therefore we
3018cfcc706cSMiquel Raynal * need a special oob layout and handling.
3019cfcc706cSMiquel Raynal */
nand_write_page_syndrome(struct mtd_info * mtd,struct nand_chip * chip,const uint8_t * buf,int oob_required,int page)3020cfcc706cSMiquel Raynal static int nand_write_page_syndrome(struct mtd_info *mtd,
3021cfcc706cSMiquel Raynal struct nand_chip *chip,
3022cfcc706cSMiquel Raynal const uint8_t *buf, int oob_required,
3023cfcc706cSMiquel Raynal int page)
3024cfcc706cSMiquel Raynal {
3025cfcc706cSMiquel Raynal int i, eccsize = chip->ecc.size;
3026cfcc706cSMiquel Raynal int eccbytes = chip->ecc.bytes;
3027cfcc706cSMiquel Raynal int eccsteps = chip->ecc.steps;
3028cfcc706cSMiquel Raynal const uint8_t *p = buf;
3029cfcc706cSMiquel Raynal uint8_t *oob = chip->oob_poi;
303073ecea3dSBoris Brezillon int ret;
3031cfcc706cSMiquel Raynal
3032cfcc706cSMiquel Raynal for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
3033cfcc706cSMiquel Raynal chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
303473ecea3dSBoris Brezillon
303573ecea3dSBoris Brezillon ret = nand_write_data_op(chip, p, eccsize, false);
303673ecea3dSBoris Brezillon if (ret)
303773ecea3dSBoris Brezillon return ret;
3038cfcc706cSMiquel Raynal
3039cfcc706cSMiquel Raynal if (chip->ecc.prepad) {
304073ecea3dSBoris Brezillon ret = nand_write_data_op(chip, oob, chip->ecc.prepad,
304173ecea3dSBoris Brezillon false);
304273ecea3dSBoris Brezillon if (ret)
304373ecea3dSBoris Brezillon return ret;
304473ecea3dSBoris Brezillon
3045cfcc706cSMiquel Raynal oob += chip->ecc.prepad;
3046cfcc706cSMiquel Raynal }
3047cfcc706cSMiquel Raynal
3048cfcc706cSMiquel Raynal chip->ecc.calculate(mtd, p, oob);
304973ecea3dSBoris Brezillon
305073ecea3dSBoris Brezillon ret = nand_write_data_op(chip, oob, eccbytes, false);
305173ecea3dSBoris Brezillon if (ret)
305273ecea3dSBoris Brezillon return ret;
305373ecea3dSBoris Brezillon
3054cfcc706cSMiquel Raynal oob += eccbytes;
3055cfcc706cSMiquel Raynal
3056cfcc706cSMiquel Raynal if (chip->ecc.postpad) {
305773ecea3dSBoris Brezillon ret = nand_write_data_op(chip, oob, chip->ecc.postpad,
305873ecea3dSBoris Brezillon false);
305973ecea3dSBoris Brezillon if (ret)
306073ecea3dSBoris Brezillon return ret;
306173ecea3dSBoris Brezillon
3062cfcc706cSMiquel Raynal oob += chip->ecc.postpad;
3063cfcc706cSMiquel Raynal }
3064cfcc706cSMiquel Raynal }
3065cfcc706cSMiquel Raynal
3066cfcc706cSMiquel Raynal /* Calculate remaining oob bytes */
3067cfcc706cSMiquel Raynal i = mtd->oobsize - (oob - chip->oob_poi);
306873ecea3dSBoris Brezillon if (i) {
306973ecea3dSBoris Brezillon ret = nand_write_data_op(chip, oob, i, false);
307073ecea3dSBoris Brezillon if (ret)
307173ecea3dSBoris Brezillon return ret;
307273ecea3dSBoris Brezillon }
3073cfcc706cSMiquel Raynal
3074cfcc706cSMiquel Raynal return 0;
3075cfcc706cSMiquel Raynal }
3076cfcc706cSMiquel Raynal
3077cfcc706cSMiquel Raynal /**
3078cfcc706cSMiquel Raynal * nand_write_page - [REPLACEABLE] write one page
3079cfcc706cSMiquel Raynal * @mtd: MTD device structure
3080cfcc706cSMiquel Raynal * @chip: NAND chip descriptor
3081cfcc706cSMiquel Raynal * @offset: address offset within the page
3082cfcc706cSMiquel Raynal * @data_len: length of actual data to be written
3083cfcc706cSMiquel Raynal * @buf: the data to write
3084cfcc706cSMiquel Raynal * @oob_required: must write chip->oob_poi to OOB
3085cfcc706cSMiquel Raynal * @page: page number to write
3086cfcc706cSMiquel Raynal * @raw: use _raw version of write_page
3087cfcc706cSMiquel Raynal */
nand_write_page(struct mtd_info * mtd,struct nand_chip * chip,uint32_t offset,int data_len,const uint8_t * buf,int oob_required,int page,int raw)3088cfcc706cSMiquel Raynal static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
3089cfcc706cSMiquel Raynal uint32_t offset, int data_len, const uint8_t *buf,
3090cfcc706cSMiquel Raynal int oob_required, int page, int raw)
3091cfcc706cSMiquel Raynal {
3092cfcc706cSMiquel Raynal int status, subpage;
3093cfcc706cSMiquel Raynal
3094cfcc706cSMiquel Raynal if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
3095cfcc706cSMiquel Raynal chip->ecc.write_subpage)
3096cfcc706cSMiquel Raynal subpage = offset || (data_len < mtd->writesize);
3097cfcc706cSMiquel Raynal else
3098cfcc706cSMiquel Raynal subpage = 0;
3099cfcc706cSMiquel Raynal
310073ecea3dSBoris Brezillon if (nand_standard_page_accessors(&chip->ecc)) {
310173ecea3dSBoris Brezillon status = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
310273ecea3dSBoris Brezillon if (status)
310373ecea3dSBoris Brezillon return status;
310473ecea3dSBoris Brezillon }
3105cfcc706cSMiquel Raynal
3106cfcc706cSMiquel Raynal if (unlikely(raw))
3107cfcc706cSMiquel Raynal status = chip->ecc.write_page_raw(mtd, chip, buf,
3108cfcc706cSMiquel Raynal oob_required, page);
3109cfcc706cSMiquel Raynal else if (subpage)
3110cfcc706cSMiquel Raynal status = chip->ecc.write_subpage(mtd, chip, offset, data_len,
3111cfcc706cSMiquel Raynal buf, oob_required, page);
3112cfcc706cSMiquel Raynal else
3113cfcc706cSMiquel Raynal status = chip->ecc.write_page(mtd, chip, buf, oob_required,
3114cfcc706cSMiquel Raynal page);
3115cfcc706cSMiquel Raynal
3116cfcc706cSMiquel Raynal if (status < 0)
3117cfcc706cSMiquel Raynal return status;
3118cfcc706cSMiquel Raynal
311973ecea3dSBoris Brezillon if (nand_standard_page_accessors(&chip->ecc))
312073ecea3dSBoris Brezillon return nand_prog_page_end_op(chip);
3121cfcc706cSMiquel Raynal
3122cfcc706cSMiquel Raynal return 0;
3123cfcc706cSMiquel Raynal }
3124cfcc706cSMiquel Raynal
3125cfcc706cSMiquel Raynal /**
3126cfcc706cSMiquel Raynal * nand_fill_oob - [INTERN] Transfer client buffer to oob
3127cfcc706cSMiquel Raynal * @mtd: MTD device structure
3128cfcc706cSMiquel Raynal * @oob: oob data buffer
3129cfcc706cSMiquel Raynal * @len: oob data write length
3130cfcc706cSMiquel Raynal * @ops: oob ops structure
3131cfcc706cSMiquel Raynal */
nand_fill_oob(struct mtd_info * mtd,uint8_t * oob,size_t len,struct mtd_oob_ops * ops)3132cfcc706cSMiquel Raynal static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
3133cfcc706cSMiquel Raynal struct mtd_oob_ops *ops)
3134cfcc706cSMiquel Raynal {
3135cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
3136cfcc706cSMiquel Raynal
3137cfcc706cSMiquel Raynal /*
3138cfcc706cSMiquel Raynal * Initialise to all 0xFF, to avoid the possibility of left over OOB
3139cfcc706cSMiquel Raynal * data from a previous OOB read.
3140cfcc706cSMiquel Raynal */
3141cfcc706cSMiquel Raynal memset(chip->oob_poi, 0xff, mtd->oobsize);
3142cfcc706cSMiquel Raynal
3143cfcc706cSMiquel Raynal switch (ops->mode) {
3144cfcc706cSMiquel Raynal
3145cfcc706cSMiquel Raynal case MTD_OPS_PLACE_OOB:
3146cfcc706cSMiquel Raynal case MTD_OPS_RAW:
3147cfcc706cSMiquel Raynal memcpy(chip->oob_poi + ops->ooboffs, oob, len);
3148cfcc706cSMiquel Raynal return oob + len;
3149cfcc706cSMiquel Raynal
3150cfcc706cSMiquel Raynal case MTD_OPS_AUTO_OOB: {
3151cfcc706cSMiquel Raynal struct nand_oobfree *free = chip->ecc.layout->oobfree;
3152cfcc706cSMiquel Raynal uint32_t boffs = 0, woffs = ops->ooboffs;
3153cfcc706cSMiquel Raynal size_t bytes = 0;
3154cfcc706cSMiquel Raynal
3155cfcc706cSMiquel Raynal for (; free->length && len; free++, len -= bytes) {
3156cfcc706cSMiquel Raynal /* Write request not from offset 0? */
3157cfcc706cSMiquel Raynal if (unlikely(woffs)) {
3158cfcc706cSMiquel Raynal if (woffs >= free->length) {
3159cfcc706cSMiquel Raynal woffs -= free->length;
3160cfcc706cSMiquel Raynal continue;
3161cfcc706cSMiquel Raynal }
3162cfcc706cSMiquel Raynal boffs = free->offset + woffs;
3163cfcc706cSMiquel Raynal bytes = min_t(size_t, len,
3164cfcc706cSMiquel Raynal (free->length - woffs));
3165cfcc706cSMiquel Raynal woffs = 0;
3166cfcc706cSMiquel Raynal } else {
3167cfcc706cSMiquel Raynal bytes = min_t(size_t, len, free->length);
3168cfcc706cSMiquel Raynal boffs = free->offset;
3169cfcc706cSMiquel Raynal }
3170cfcc706cSMiquel Raynal memcpy(chip->oob_poi + boffs, oob, bytes);
3171cfcc706cSMiquel Raynal oob += bytes;
3172cfcc706cSMiquel Raynal }
3173cfcc706cSMiquel Raynal return oob;
3174cfcc706cSMiquel Raynal }
3175cfcc706cSMiquel Raynal default:
3176cfcc706cSMiquel Raynal BUG();
3177cfcc706cSMiquel Raynal }
3178cfcc706cSMiquel Raynal return NULL;
3179cfcc706cSMiquel Raynal }
3180cfcc706cSMiquel Raynal
3181cfcc706cSMiquel Raynal #define NOTALIGNED(x) ((x & (chip->subpagesize - 1)) != 0)
3182cfcc706cSMiquel Raynal
3183cfcc706cSMiquel Raynal /**
3184cfcc706cSMiquel Raynal * nand_do_write_ops - [INTERN] NAND write with ECC
3185cfcc706cSMiquel Raynal * @mtd: MTD device structure
3186cfcc706cSMiquel Raynal * @to: offset to write to
3187cfcc706cSMiquel Raynal * @ops: oob operations description structure
3188cfcc706cSMiquel Raynal *
3189cfcc706cSMiquel Raynal * NAND write with ECC.
3190cfcc706cSMiquel Raynal */
nand_do_write_ops(struct mtd_info * mtd,loff_t to,struct mtd_oob_ops * ops)3191cfcc706cSMiquel Raynal static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
3192cfcc706cSMiquel Raynal struct mtd_oob_ops *ops)
3193cfcc706cSMiquel Raynal {
3194cfcc706cSMiquel Raynal int chipnr, realpage, page, column;
3195cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
3196cfcc706cSMiquel Raynal uint32_t writelen = ops->len;
3197cfcc706cSMiquel Raynal
3198cfcc706cSMiquel Raynal uint32_t oobwritelen = ops->ooblen;
3199cfcc706cSMiquel Raynal uint32_t oobmaxlen = mtd_oobavail(mtd, ops);
3200cfcc706cSMiquel Raynal
3201cfcc706cSMiquel Raynal uint8_t *oob = ops->oobbuf;
3202cfcc706cSMiquel Raynal uint8_t *buf = ops->datbuf;
3203cfcc706cSMiquel Raynal int ret;
3204cfcc706cSMiquel Raynal int oob_required = oob ? 1 : 0;
3205cfcc706cSMiquel Raynal
3206cfcc706cSMiquel Raynal ops->retlen = 0;
3207cfcc706cSMiquel Raynal if (!writelen)
3208cfcc706cSMiquel Raynal return 0;
3209cfcc706cSMiquel Raynal
3210cfcc706cSMiquel Raynal /* Reject writes, which are not page aligned */
3211cfcc706cSMiquel Raynal if (NOTALIGNED(to)) {
3212cfcc706cSMiquel Raynal pr_notice("%s: attempt to write non page aligned data\n",
3213cfcc706cSMiquel Raynal __func__);
3214cfcc706cSMiquel Raynal return -EINVAL;
3215cfcc706cSMiquel Raynal }
3216cfcc706cSMiquel Raynal
3217cfcc706cSMiquel Raynal column = to & (mtd->writesize - 1);
3218cfcc706cSMiquel Raynal
3219cfcc706cSMiquel Raynal chipnr = (int)(to >> chip->chip_shift);
3220cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
3221cfcc706cSMiquel Raynal
3222cfcc706cSMiquel Raynal /* Check, if it is write protected */
3223cfcc706cSMiquel Raynal if (nand_check_wp(mtd)) {
3224cfcc706cSMiquel Raynal ret = -EIO;
3225cfcc706cSMiquel Raynal goto err_out;
3226cfcc706cSMiquel Raynal }
3227cfcc706cSMiquel Raynal
3228cfcc706cSMiquel Raynal realpage = (int)(to >> chip->page_shift);
3229cfcc706cSMiquel Raynal page = realpage & chip->pagemask;
3230cfcc706cSMiquel Raynal
3231cfcc706cSMiquel Raynal /* Invalidate the page cache, when we write to the cached page */
3232cfcc706cSMiquel Raynal if (to <= ((loff_t)chip->pagebuf << chip->page_shift) &&
3233cfcc706cSMiquel Raynal ((loff_t)chip->pagebuf << chip->page_shift) < (to + ops->len))
3234cfcc706cSMiquel Raynal chip->pagebuf = -1;
3235cfcc706cSMiquel Raynal
3236cfcc706cSMiquel Raynal /* Don't allow multipage oob writes with offset */
3237cfcc706cSMiquel Raynal if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) {
3238cfcc706cSMiquel Raynal ret = -EINVAL;
3239cfcc706cSMiquel Raynal goto err_out;
3240cfcc706cSMiquel Raynal }
3241cfcc706cSMiquel Raynal
3242cfcc706cSMiquel Raynal while (1) {
3243cfcc706cSMiquel Raynal int bytes = mtd->writesize;
3244cfcc706cSMiquel Raynal uint8_t *wbuf = buf;
3245cfcc706cSMiquel Raynal int use_bufpoi;
3246cfcc706cSMiquel Raynal int part_pagewr = (column || writelen < mtd->writesize);
3247cfcc706cSMiquel Raynal
3248cfcc706cSMiquel Raynal if (part_pagewr)
3249cfcc706cSMiquel Raynal use_bufpoi = 1;
3250cfcc706cSMiquel Raynal else if (chip->options & NAND_USE_BOUNCE_BUFFER)
3251cfcc706cSMiquel Raynal use_bufpoi = !IS_ALIGNED((unsigned long)buf,
3252cfcc706cSMiquel Raynal chip->buf_align);
3253cfcc706cSMiquel Raynal else
3254cfcc706cSMiquel Raynal use_bufpoi = 0;
3255cfcc706cSMiquel Raynal
3256cfcc706cSMiquel Raynal WATCHDOG_RESET();
3257cfcc706cSMiquel Raynal /* Partial page write?, or need to use bounce buffer */
3258cfcc706cSMiquel Raynal if (use_bufpoi) {
3259cfcc706cSMiquel Raynal pr_debug("%s: using write bounce buffer for buf@%p\n",
3260cfcc706cSMiquel Raynal __func__, buf);
3261cfcc706cSMiquel Raynal if (part_pagewr)
3262cfcc706cSMiquel Raynal bytes = min_t(int, bytes - column, writelen);
3263cfcc706cSMiquel Raynal chip->pagebuf = -1;
3264cfcc706cSMiquel Raynal memset(chip->buffers->databuf, 0xff, mtd->writesize);
3265cfcc706cSMiquel Raynal memcpy(&chip->buffers->databuf[column], buf, bytes);
3266cfcc706cSMiquel Raynal wbuf = chip->buffers->databuf;
3267cfcc706cSMiquel Raynal }
3268cfcc706cSMiquel Raynal
3269cfcc706cSMiquel Raynal if (unlikely(oob)) {
3270cfcc706cSMiquel Raynal size_t len = min(oobwritelen, oobmaxlen);
3271cfcc706cSMiquel Raynal oob = nand_fill_oob(mtd, oob, len, ops);
3272cfcc706cSMiquel Raynal oobwritelen -= len;
3273cfcc706cSMiquel Raynal } else {
3274cfcc706cSMiquel Raynal /* We still need to erase leftover OOB data */
3275cfcc706cSMiquel Raynal memset(chip->oob_poi, 0xff, mtd->oobsize);
3276cfcc706cSMiquel Raynal }
3277cfcc706cSMiquel Raynal ret = chip->write_page(mtd, chip, column, bytes, wbuf,
3278cfcc706cSMiquel Raynal oob_required, page,
3279cfcc706cSMiquel Raynal (ops->mode == MTD_OPS_RAW));
3280cfcc706cSMiquel Raynal if (ret)
3281cfcc706cSMiquel Raynal break;
3282cfcc706cSMiquel Raynal
3283cfcc706cSMiquel Raynal writelen -= bytes;
3284cfcc706cSMiquel Raynal if (!writelen)
3285cfcc706cSMiquel Raynal break;
3286cfcc706cSMiquel Raynal
3287cfcc706cSMiquel Raynal column = 0;
3288cfcc706cSMiquel Raynal buf += bytes;
3289cfcc706cSMiquel Raynal realpage++;
3290cfcc706cSMiquel Raynal
3291cfcc706cSMiquel Raynal page = realpage & chip->pagemask;
3292cfcc706cSMiquel Raynal /* Check, if we cross a chip boundary */
3293cfcc706cSMiquel Raynal if (!page) {
3294cfcc706cSMiquel Raynal chipnr++;
3295cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
3296cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
3297cfcc706cSMiquel Raynal }
3298cfcc706cSMiquel Raynal }
3299cfcc706cSMiquel Raynal
3300cfcc706cSMiquel Raynal ops->retlen = ops->len - writelen;
3301cfcc706cSMiquel Raynal if (unlikely(oob))
3302cfcc706cSMiquel Raynal ops->oobretlen = ops->ooblen;
3303cfcc706cSMiquel Raynal
3304cfcc706cSMiquel Raynal err_out:
3305cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
3306cfcc706cSMiquel Raynal return ret;
3307cfcc706cSMiquel Raynal }
3308cfcc706cSMiquel Raynal
3309cfcc706cSMiquel Raynal /**
3310cfcc706cSMiquel Raynal * panic_nand_write - [MTD Interface] NAND write with ECC
3311cfcc706cSMiquel Raynal * @mtd: MTD device structure
3312cfcc706cSMiquel Raynal * @to: offset to write to
3313cfcc706cSMiquel Raynal * @len: number of bytes to write
3314cfcc706cSMiquel Raynal * @retlen: pointer to variable to store the number of written bytes
3315cfcc706cSMiquel Raynal * @buf: the data to write
3316cfcc706cSMiquel Raynal *
3317cfcc706cSMiquel Raynal * NAND write with ECC. Used when performing writes in interrupt context, this
3318cfcc706cSMiquel Raynal * may for example be called by mtdoops when writing an oops while in panic.
3319cfcc706cSMiquel Raynal */
panic_nand_write(struct mtd_info * mtd,loff_t to,size_t len,size_t * retlen,const uint8_t * buf)3320cfcc706cSMiquel Raynal static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
3321cfcc706cSMiquel Raynal size_t *retlen, const uint8_t *buf)
3322cfcc706cSMiquel Raynal {
3323cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
3324cfcc706cSMiquel Raynal struct mtd_oob_ops ops;
3325cfcc706cSMiquel Raynal int ret;
3326cfcc706cSMiquel Raynal
3327cfcc706cSMiquel Raynal /* Wait for the device to get ready */
3328cfcc706cSMiquel Raynal panic_nand_wait(mtd, chip, 400);
3329cfcc706cSMiquel Raynal
3330cfcc706cSMiquel Raynal /* Grab the device */
3331cfcc706cSMiquel Raynal panic_nand_get_device(chip, mtd, FL_WRITING);
3332cfcc706cSMiquel Raynal
3333cfcc706cSMiquel Raynal memset(&ops, 0, sizeof(ops));
3334cfcc706cSMiquel Raynal ops.len = len;
3335cfcc706cSMiquel Raynal ops.datbuf = (uint8_t *)buf;
3336cfcc706cSMiquel Raynal ops.mode = MTD_OPS_PLACE_OOB;
3337cfcc706cSMiquel Raynal
3338cfcc706cSMiquel Raynal ret = nand_do_write_ops(mtd, to, &ops);
3339cfcc706cSMiquel Raynal
3340cfcc706cSMiquel Raynal *retlen = ops.retlen;
3341cfcc706cSMiquel Raynal return ret;
3342cfcc706cSMiquel Raynal }
3343cfcc706cSMiquel Raynal
3344cfcc706cSMiquel Raynal /**
3345cfcc706cSMiquel Raynal * nand_do_write_oob - [MTD Interface] NAND write out-of-band
3346cfcc706cSMiquel Raynal * @mtd: MTD device structure
3347cfcc706cSMiquel Raynal * @to: offset to write to
3348cfcc706cSMiquel Raynal * @ops: oob operation description structure
3349cfcc706cSMiquel Raynal *
3350cfcc706cSMiquel Raynal * NAND write out-of-band.
3351cfcc706cSMiquel Raynal */
nand_do_write_oob(struct mtd_info * mtd,loff_t to,struct mtd_oob_ops * ops)3352cfcc706cSMiquel Raynal static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
3353cfcc706cSMiquel Raynal struct mtd_oob_ops *ops)
3354cfcc706cSMiquel Raynal {
3355cfcc706cSMiquel Raynal int chipnr, page, status, len;
3356cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
3357cfcc706cSMiquel Raynal
3358cfcc706cSMiquel Raynal pr_debug("%s: to = 0x%08x, len = %i\n",
3359cfcc706cSMiquel Raynal __func__, (unsigned int)to, (int)ops->ooblen);
3360cfcc706cSMiquel Raynal
3361cfcc706cSMiquel Raynal len = mtd_oobavail(mtd, ops);
3362cfcc706cSMiquel Raynal
3363cfcc706cSMiquel Raynal /* Do not allow write past end of page */
3364cfcc706cSMiquel Raynal if ((ops->ooboffs + ops->ooblen) > len) {
3365cfcc706cSMiquel Raynal pr_debug("%s: attempt to write past end of page\n",
3366cfcc706cSMiquel Raynal __func__);
3367cfcc706cSMiquel Raynal return -EINVAL;
3368cfcc706cSMiquel Raynal }
3369cfcc706cSMiquel Raynal
3370cfcc706cSMiquel Raynal if (unlikely(ops->ooboffs >= len)) {
3371cfcc706cSMiquel Raynal pr_debug("%s: attempt to start write outside oob\n",
3372cfcc706cSMiquel Raynal __func__);
3373cfcc706cSMiquel Raynal return -EINVAL;
3374cfcc706cSMiquel Raynal }
3375cfcc706cSMiquel Raynal
3376cfcc706cSMiquel Raynal /* Do not allow write past end of device */
3377cfcc706cSMiquel Raynal if (unlikely(to >= mtd->size ||
3378cfcc706cSMiquel Raynal ops->ooboffs + ops->ooblen >
3379cfcc706cSMiquel Raynal ((mtd->size >> chip->page_shift) -
3380cfcc706cSMiquel Raynal (to >> chip->page_shift)) * len)) {
3381cfcc706cSMiquel Raynal pr_debug("%s: attempt to write beyond end of device\n",
3382cfcc706cSMiquel Raynal __func__);
3383cfcc706cSMiquel Raynal return -EINVAL;
3384cfcc706cSMiquel Raynal }
3385cfcc706cSMiquel Raynal
3386cfcc706cSMiquel Raynal chipnr = (int)(to >> chip->chip_shift);
3387cfcc706cSMiquel Raynal
3388cfcc706cSMiquel Raynal /*
3389cfcc706cSMiquel Raynal * Reset the chip. Some chips (like the Toshiba TC5832DC found in one
3390cfcc706cSMiquel Raynal * of my DiskOnChip 2000 test units) will clear the whole data page too
3391cfcc706cSMiquel Raynal * if we don't do this. I have no clue why, but I seem to have 'fixed'
3392cfcc706cSMiquel Raynal * it in the doc2000 driver in August 1999. dwmw2.
3393cfcc706cSMiquel Raynal */
3394cfcc706cSMiquel Raynal nand_reset(chip, chipnr);
3395cfcc706cSMiquel Raynal
3396cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
3397cfcc706cSMiquel Raynal
3398cfcc706cSMiquel Raynal /* Shift to get page */
3399cfcc706cSMiquel Raynal page = (int)(to >> chip->page_shift);
3400cfcc706cSMiquel Raynal
3401cfcc706cSMiquel Raynal /* Check, if it is write protected */
3402cfcc706cSMiquel Raynal if (nand_check_wp(mtd)) {
3403cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
3404cfcc706cSMiquel Raynal return -EROFS;
3405cfcc706cSMiquel Raynal }
3406cfcc706cSMiquel Raynal
3407cfcc706cSMiquel Raynal /* Invalidate the page cache, if we write to the cached page */
3408cfcc706cSMiquel Raynal if (page == chip->pagebuf)
3409cfcc706cSMiquel Raynal chip->pagebuf = -1;
3410cfcc706cSMiquel Raynal
3411cfcc706cSMiquel Raynal nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops);
3412cfcc706cSMiquel Raynal
3413cfcc706cSMiquel Raynal if (ops->mode == MTD_OPS_RAW)
3414cfcc706cSMiquel Raynal status = chip->ecc.write_oob_raw(mtd, chip, page & chip->pagemask);
3415cfcc706cSMiquel Raynal else
3416cfcc706cSMiquel Raynal status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
3417cfcc706cSMiquel Raynal
3418cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
3419cfcc706cSMiquel Raynal
3420cfcc706cSMiquel Raynal if (status)
3421cfcc706cSMiquel Raynal return status;
3422cfcc706cSMiquel Raynal
3423cfcc706cSMiquel Raynal ops->oobretlen = ops->ooblen;
3424cfcc706cSMiquel Raynal
3425cfcc706cSMiquel Raynal return 0;
3426cfcc706cSMiquel Raynal }
3427cfcc706cSMiquel Raynal
3428cfcc706cSMiquel Raynal /**
3429cfcc706cSMiquel Raynal * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
3430cfcc706cSMiquel Raynal * @mtd: MTD device structure
3431cfcc706cSMiquel Raynal * @to: offset to write to
3432cfcc706cSMiquel Raynal * @ops: oob operation description structure
3433cfcc706cSMiquel Raynal */
nand_write_oob(struct mtd_info * mtd,loff_t to,struct mtd_oob_ops * ops)3434cfcc706cSMiquel Raynal static int nand_write_oob(struct mtd_info *mtd, loff_t to,
3435cfcc706cSMiquel Raynal struct mtd_oob_ops *ops)
3436cfcc706cSMiquel Raynal {
3437cfcc706cSMiquel Raynal int ret = -ENOTSUPP;
3438cfcc706cSMiquel Raynal
3439cfcc706cSMiquel Raynal ops->retlen = 0;
3440cfcc706cSMiquel Raynal
3441cfcc706cSMiquel Raynal /* Do not allow writes past end of device */
3442cfcc706cSMiquel Raynal if (ops->datbuf && (to + ops->len) > mtd->size) {
3443cfcc706cSMiquel Raynal pr_debug("%s: attempt to write beyond end of device\n",
3444cfcc706cSMiquel Raynal __func__);
3445cfcc706cSMiquel Raynal return -EINVAL;
3446cfcc706cSMiquel Raynal }
3447cfcc706cSMiquel Raynal
3448cfcc706cSMiquel Raynal nand_get_device(mtd, FL_WRITING);
3449cfcc706cSMiquel Raynal
3450cfcc706cSMiquel Raynal switch (ops->mode) {
3451cfcc706cSMiquel Raynal case MTD_OPS_PLACE_OOB:
3452cfcc706cSMiquel Raynal case MTD_OPS_AUTO_OOB:
3453cfcc706cSMiquel Raynal case MTD_OPS_RAW:
3454cfcc706cSMiquel Raynal break;
3455cfcc706cSMiquel Raynal
3456cfcc706cSMiquel Raynal default:
3457cfcc706cSMiquel Raynal goto out;
3458cfcc706cSMiquel Raynal }
3459cfcc706cSMiquel Raynal
3460cfcc706cSMiquel Raynal if (!ops->datbuf)
3461cfcc706cSMiquel Raynal ret = nand_do_write_oob(mtd, to, ops);
3462cfcc706cSMiquel Raynal else
3463cfcc706cSMiquel Raynal ret = nand_do_write_ops(mtd, to, ops);
3464cfcc706cSMiquel Raynal
3465cfcc706cSMiquel Raynal out:
3466cfcc706cSMiquel Raynal nand_release_device(mtd);
3467cfcc706cSMiquel Raynal return ret;
3468cfcc706cSMiquel Raynal }
3469cfcc706cSMiquel Raynal
3470cfcc706cSMiquel Raynal /**
3471cfcc706cSMiquel Raynal * single_erase - [GENERIC] NAND standard block erase command function
3472cfcc706cSMiquel Raynal * @mtd: MTD device structure
3473cfcc706cSMiquel Raynal * @page: the page address of the block which will be erased
3474cfcc706cSMiquel Raynal *
3475cfcc706cSMiquel Raynal * Standard erase command for NAND chips. Returns NAND status.
3476cfcc706cSMiquel Raynal */
single_erase(struct mtd_info * mtd,int page)3477cfcc706cSMiquel Raynal static int single_erase(struct mtd_info *mtd, int page)
3478cfcc706cSMiquel Raynal {
3479cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
348073ecea3dSBoris Brezillon unsigned int eraseblock;
3481cfcc706cSMiquel Raynal
348273ecea3dSBoris Brezillon /* Send commands to erase a block */
348373ecea3dSBoris Brezillon eraseblock = page >> (chip->phys_erase_shift - chip->page_shift);
348473ecea3dSBoris Brezillon
348573ecea3dSBoris Brezillon return nand_erase_op(chip, eraseblock);
3486cfcc706cSMiquel Raynal }
3487cfcc706cSMiquel Raynal
3488cfcc706cSMiquel Raynal /**
3489cfcc706cSMiquel Raynal * nand_erase - [MTD Interface] erase block(s)
3490cfcc706cSMiquel Raynal * @mtd: MTD device structure
3491cfcc706cSMiquel Raynal * @instr: erase instruction
3492cfcc706cSMiquel Raynal *
3493cfcc706cSMiquel Raynal * Erase one ore more blocks.
3494cfcc706cSMiquel Raynal */
nand_erase(struct mtd_info * mtd,struct erase_info * instr)3495cfcc706cSMiquel Raynal static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
3496cfcc706cSMiquel Raynal {
3497cfcc706cSMiquel Raynal return nand_erase_nand(mtd, instr, 0);
3498cfcc706cSMiquel Raynal }
3499cfcc706cSMiquel Raynal
3500cfcc706cSMiquel Raynal /**
3501cfcc706cSMiquel Raynal * nand_erase_nand - [INTERN] erase block(s)
3502cfcc706cSMiquel Raynal * @mtd: MTD device structure
3503cfcc706cSMiquel Raynal * @instr: erase instruction
3504cfcc706cSMiquel Raynal * @allowbbt: allow erasing the bbt area
3505cfcc706cSMiquel Raynal *
3506cfcc706cSMiquel Raynal * Erase one ore more blocks.
3507cfcc706cSMiquel Raynal */
nand_erase_nand(struct mtd_info * mtd,struct erase_info * instr,int allowbbt)3508cfcc706cSMiquel Raynal int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
3509cfcc706cSMiquel Raynal int allowbbt)
3510cfcc706cSMiquel Raynal {
3511cfcc706cSMiquel Raynal int page, status, pages_per_block, ret, chipnr;
3512cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
3513cfcc706cSMiquel Raynal loff_t len;
3514cfcc706cSMiquel Raynal
3515cfcc706cSMiquel Raynal pr_debug("%s: start = 0x%012llx, len = %llu\n",
3516cfcc706cSMiquel Raynal __func__, (unsigned long long)instr->addr,
3517cfcc706cSMiquel Raynal (unsigned long long)instr->len);
3518cfcc706cSMiquel Raynal
3519cfcc706cSMiquel Raynal if (check_offs_len(mtd, instr->addr, instr->len))
3520cfcc706cSMiquel Raynal return -EINVAL;
3521cfcc706cSMiquel Raynal
3522cfcc706cSMiquel Raynal /* Grab the lock and see if the device is available */
3523cfcc706cSMiquel Raynal nand_get_device(mtd, FL_ERASING);
3524cfcc706cSMiquel Raynal
3525cfcc706cSMiquel Raynal /* Shift to get first page */
3526cfcc706cSMiquel Raynal page = (int)(instr->addr >> chip->page_shift);
3527cfcc706cSMiquel Raynal chipnr = (int)(instr->addr >> chip->chip_shift);
3528cfcc706cSMiquel Raynal
3529cfcc706cSMiquel Raynal /* Calculate pages in each block */
3530cfcc706cSMiquel Raynal pages_per_block = 1 << (chip->phys_erase_shift - chip->page_shift);
3531cfcc706cSMiquel Raynal
3532cfcc706cSMiquel Raynal /* Select the NAND device */
3533cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
3534cfcc706cSMiquel Raynal
3535cfcc706cSMiquel Raynal /* Check, if it is write protected */
3536cfcc706cSMiquel Raynal if (nand_check_wp(mtd)) {
3537cfcc706cSMiquel Raynal pr_debug("%s: device is write protected!\n",
3538cfcc706cSMiquel Raynal __func__);
3539cfcc706cSMiquel Raynal instr->state = MTD_ERASE_FAILED;
3540cfcc706cSMiquel Raynal goto erase_exit;
3541cfcc706cSMiquel Raynal }
3542cfcc706cSMiquel Raynal
3543cfcc706cSMiquel Raynal /* Loop through the pages */
3544cfcc706cSMiquel Raynal len = instr->len;
3545cfcc706cSMiquel Raynal
3546cfcc706cSMiquel Raynal instr->state = MTD_ERASING;
3547cfcc706cSMiquel Raynal
3548cfcc706cSMiquel Raynal while (len) {
3549cfcc706cSMiquel Raynal WATCHDOG_RESET();
3550cfcc706cSMiquel Raynal
3551cfcc706cSMiquel Raynal /* Check if we have a bad block, we do not erase bad blocks! */
3552cfcc706cSMiquel Raynal if (!instr->scrub && nand_block_checkbad(mtd, ((loff_t) page) <<
3553cfcc706cSMiquel Raynal chip->page_shift, allowbbt)) {
3554cfcc706cSMiquel Raynal pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
3555cfcc706cSMiquel Raynal __func__, page);
3556cfcc706cSMiquel Raynal instr->state = MTD_ERASE_FAILED;
3557cfcc706cSMiquel Raynal goto erase_exit;
3558cfcc706cSMiquel Raynal }
3559cfcc706cSMiquel Raynal
3560cfcc706cSMiquel Raynal /*
3561cfcc706cSMiquel Raynal * Invalidate the page cache, if we erase the block which
3562cfcc706cSMiquel Raynal * contains the current cached page.
3563cfcc706cSMiquel Raynal */
3564cfcc706cSMiquel Raynal if (page <= chip->pagebuf && chip->pagebuf <
3565cfcc706cSMiquel Raynal (page + pages_per_block))
3566cfcc706cSMiquel Raynal chip->pagebuf = -1;
3567cfcc706cSMiquel Raynal
3568cfcc706cSMiquel Raynal status = chip->erase(mtd, page & chip->pagemask);
3569cfcc706cSMiquel Raynal
3570cfcc706cSMiquel Raynal /* See if block erase succeeded */
3571cfcc706cSMiquel Raynal if (status & NAND_STATUS_FAIL) {
3572cfcc706cSMiquel Raynal pr_debug("%s: failed erase, page 0x%08x\n",
3573cfcc706cSMiquel Raynal __func__, page);
3574cfcc706cSMiquel Raynal instr->state = MTD_ERASE_FAILED;
3575cfcc706cSMiquel Raynal instr->fail_addr =
3576cfcc706cSMiquel Raynal ((loff_t)page << chip->page_shift);
3577cfcc706cSMiquel Raynal goto erase_exit;
3578cfcc706cSMiquel Raynal }
3579cfcc706cSMiquel Raynal
3580cfcc706cSMiquel Raynal /* Increment page address and decrement length */
3581cfcc706cSMiquel Raynal len -= (1ULL << chip->phys_erase_shift);
3582cfcc706cSMiquel Raynal page += pages_per_block;
3583cfcc706cSMiquel Raynal
3584cfcc706cSMiquel Raynal /* Check, if we cross a chip boundary */
3585cfcc706cSMiquel Raynal if (len && !(page & chip->pagemask)) {
3586cfcc706cSMiquel Raynal chipnr++;
3587cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
3588cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
3589cfcc706cSMiquel Raynal }
3590cfcc706cSMiquel Raynal }
3591cfcc706cSMiquel Raynal instr->state = MTD_ERASE_DONE;
3592cfcc706cSMiquel Raynal
3593cfcc706cSMiquel Raynal erase_exit:
3594cfcc706cSMiquel Raynal
3595cfcc706cSMiquel Raynal ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
3596cfcc706cSMiquel Raynal
3597cfcc706cSMiquel Raynal /* Deselect and wake up anyone waiting on the device */
3598cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
3599cfcc706cSMiquel Raynal nand_release_device(mtd);
3600cfcc706cSMiquel Raynal
3601cfcc706cSMiquel Raynal /* Do call back function */
3602cfcc706cSMiquel Raynal if (!ret)
3603cfcc706cSMiquel Raynal mtd_erase_callback(instr);
3604cfcc706cSMiquel Raynal
3605cfcc706cSMiquel Raynal /* Return more or less happy */
3606cfcc706cSMiquel Raynal return ret;
3607cfcc706cSMiquel Raynal }
3608cfcc706cSMiquel Raynal
3609cfcc706cSMiquel Raynal /**
3610cfcc706cSMiquel Raynal * nand_sync - [MTD Interface] sync
3611cfcc706cSMiquel Raynal * @mtd: MTD device structure
3612cfcc706cSMiquel Raynal *
3613cfcc706cSMiquel Raynal * Sync is actually a wait for chip ready function.
3614cfcc706cSMiquel Raynal */
nand_sync(struct mtd_info * mtd)3615cfcc706cSMiquel Raynal static void nand_sync(struct mtd_info *mtd)
3616cfcc706cSMiquel Raynal {
3617cfcc706cSMiquel Raynal pr_debug("%s: called\n", __func__);
3618cfcc706cSMiquel Raynal
3619cfcc706cSMiquel Raynal /* Grab the lock and see if the device is available */
3620cfcc706cSMiquel Raynal nand_get_device(mtd, FL_SYNCING);
3621cfcc706cSMiquel Raynal /* Release it and go back */
3622cfcc706cSMiquel Raynal nand_release_device(mtd);
3623cfcc706cSMiquel Raynal }
3624cfcc706cSMiquel Raynal
3625cfcc706cSMiquel Raynal /**
3626cfcc706cSMiquel Raynal * nand_block_isbad - [MTD Interface] Check if block at offset is bad
3627cfcc706cSMiquel Raynal * @mtd: MTD device structure
3628cfcc706cSMiquel Raynal * @offs: offset relative to mtd start
3629cfcc706cSMiquel Raynal */
nand_block_isbad(struct mtd_info * mtd,loff_t offs)3630cfcc706cSMiquel Raynal static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
3631cfcc706cSMiquel Raynal {
3632cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
3633cfcc706cSMiquel Raynal int chipnr = (int)(offs >> chip->chip_shift);
3634cfcc706cSMiquel Raynal int ret;
3635cfcc706cSMiquel Raynal
3636cfcc706cSMiquel Raynal /* Select the NAND device */
3637cfcc706cSMiquel Raynal nand_get_device(mtd, FL_READING);
3638cfcc706cSMiquel Raynal chip->select_chip(mtd, chipnr);
3639cfcc706cSMiquel Raynal
3640cfcc706cSMiquel Raynal ret = nand_block_checkbad(mtd, offs, 0);
3641cfcc706cSMiquel Raynal
3642cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
3643cfcc706cSMiquel Raynal nand_release_device(mtd);
3644cfcc706cSMiquel Raynal
3645cfcc706cSMiquel Raynal return ret;
3646cfcc706cSMiquel Raynal }
3647cfcc706cSMiquel Raynal
3648cfcc706cSMiquel Raynal /**
3649cfcc706cSMiquel Raynal * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad
3650cfcc706cSMiquel Raynal * @mtd: MTD device structure
3651cfcc706cSMiquel Raynal * @ofs: offset relative to mtd start
3652cfcc706cSMiquel Raynal */
nand_block_markbad(struct mtd_info * mtd,loff_t ofs)3653cfcc706cSMiquel Raynal static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
3654cfcc706cSMiquel Raynal {
3655cfcc706cSMiquel Raynal int ret;
3656cfcc706cSMiquel Raynal
3657cfcc706cSMiquel Raynal ret = nand_block_isbad(mtd, ofs);
3658cfcc706cSMiquel Raynal if (ret) {
3659cfcc706cSMiquel Raynal /* If it was bad already, return success and do nothing */
3660cfcc706cSMiquel Raynal if (ret > 0)
3661cfcc706cSMiquel Raynal return 0;
3662cfcc706cSMiquel Raynal return ret;
3663cfcc706cSMiquel Raynal }
3664cfcc706cSMiquel Raynal
3665cfcc706cSMiquel Raynal return nand_block_markbad_lowlevel(mtd, ofs);
3666cfcc706cSMiquel Raynal }
3667cfcc706cSMiquel Raynal
3668cfcc706cSMiquel Raynal /**
3669cfcc706cSMiquel Raynal * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
3670cfcc706cSMiquel Raynal * @mtd: MTD device structure
3671cfcc706cSMiquel Raynal * @chip: nand chip info structure
3672cfcc706cSMiquel Raynal * @addr: feature address.
3673cfcc706cSMiquel Raynal * @subfeature_param: the subfeature parameters, a four bytes array.
3674cfcc706cSMiquel Raynal */
nand_onfi_set_features(struct mtd_info * mtd,struct nand_chip * chip,int addr,uint8_t * subfeature_param)3675cfcc706cSMiquel Raynal static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
3676cfcc706cSMiquel Raynal int addr, uint8_t *subfeature_param)
3677cfcc706cSMiquel Raynal {
3678cfcc706cSMiquel Raynal #ifdef CONFIG_SYS_NAND_ONFI_DETECTION
3679cfcc706cSMiquel Raynal if (!chip->onfi_version ||
3680cfcc706cSMiquel Raynal !(le16_to_cpu(chip->onfi_params.opt_cmd)
3681cfcc706cSMiquel Raynal & ONFI_OPT_CMD_SET_GET_FEATURES))
3682cfcc706cSMiquel Raynal return -ENOTSUPP;
3683cfcc706cSMiquel Raynal #endif
3684cfcc706cSMiquel Raynal
368573ecea3dSBoris Brezillon return nand_set_features_op(chip, addr, subfeature_param);
3686cfcc706cSMiquel Raynal }
3687cfcc706cSMiquel Raynal
3688cfcc706cSMiquel Raynal /**
3689cfcc706cSMiquel Raynal * nand_onfi_get_features- [REPLACEABLE] get features for ONFI nand
3690cfcc706cSMiquel Raynal * @mtd: MTD device structure
3691cfcc706cSMiquel Raynal * @chip: nand chip info structure
3692cfcc706cSMiquel Raynal * @addr: feature address.
3693cfcc706cSMiquel Raynal * @subfeature_param: the subfeature parameters, a four bytes array.
3694cfcc706cSMiquel Raynal */
nand_onfi_get_features(struct mtd_info * mtd,struct nand_chip * chip,int addr,uint8_t * subfeature_param)3695cfcc706cSMiquel Raynal static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
3696cfcc706cSMiquel Raynal int addr, uint8_t *subfeature_param)
3697cfcc706cSMiquel Raynal {
3698cfcc706cSMiquel Raynal #ifdef CONFIG_SYS_NAND_ONFI_DETECTION
3699cfcc706cSMiquel Raynal if (!chip->onfi_version ||
3700cfcc706cSMiquel Raynal !(le16_to_cpu(chip->onfi_params.opt_cmd)
3701cfcc706cSMiquel Raynal & ONFI_OPT_CMD_SET_GET_FEATURES))
3702cfcc706cSMiquel Raynal return -ENOTSUPP;
3703cfcc706cSMiquel Raynal #endif
3704cfcc706cSMiquel Raynal
370573ecea3dSBoris Brezillon return nand_get_features_op(chip, addr, subfeature_param);
3706cfcc706cSMiquel Raynal }
3707cfcc706cSMiquel Raynal
3708cfcc706cSMiquel Raynal /* Set default functions */
nand_set_defaults(struct nand_chip * chip,int busw)3709cfcc706cSMiquel Raynal static void nand_set_defaults(struct nand_chip *chip, int busw)
3710cfcc706cSMiquel Raynal {
3711cfcc706cSMiquel Raynal /* check for proper chip_delay setup, set 20us if not */
3712cfcc706cSMiquel Raynal if (!chip->chip_delay)
3713cfcc706cSMiquel Raynal chip->chip_delay = 20;
3714cfcc706cSMiquel Raynal
3715cfcc706cSMiquel Raynal /* check, if a user supplied command function given */
3716cfcc706cSMiquel Raynal if (chip->cmdfunc == NULL)
3717cfcc706cSMiquel Raynal chip->cmdfunc = nand_command;
3718cfcc706cSMiquel Raynal
3719cfcc706cSMiquel Raynal /* check, if a user supplied wait function given */
3720cfcc706cSMiquel Raynal if (chip->waitfunc == NULL)
3721cfcc706cSMiquel Raynal chip->waitfunc = nand_wait;
3722cfcc706cSMiquel Raynal
3723cfcc706cSMiquel Raynal if (!chip->select_chip)
3724cfcc706cSMiquel Raynal chip->select_chip = nand_select_chip;
3725cfcc706cSMiquel Raynal
3726cfcc706cSMiquel Raynal /* set for ONFI nand */
3727cfcc706cSMiquel Raynal if (!chip->onfi_set_features)
3728cfcc706cSMiquel Raynal chip->onfi_set_features = nand_onfi_set_features;
3729cfcc706cSMiquel Raynal if (!chip->onfi_get_features)
3730cfcc706cSMiquel Raynal chip->onfi_get_features = nand_onfi_get_features;
3731cfcc706cSMiquel Raynal
3732cfcc706cSMiquel Raynal /* If called twice, pointers that depend on busw may need to be reset */
3733cfcc706cSMiquel Raynal if (!chip->read_byte || chip->read_byte == nand_read_byte)
3734cfcc706cSMiquel Raynal chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
3735cfcc706cSMiquel Raynal if (!chip->read_word)
3736cfcc706cSMiquel Raynal chip->read_word = nand_read_word;
3737cfcc706cSMiquel Raynal if (!chip->block_bad)
3738cfcc706cSMiquel Raynal chip->block_bad = nand_block_bad;
3739cfcc706cSMiquel Raynal if (!chip->block_markbad)
3740cfcc706cSMiquel Raynal chip->block_markbad = nand_default_block_markbad;
3741cfcc706cSMiquel Raynal if (!chip->write_buf || chip->write_buf == nand_write_buf)
3742cfcc706cSMiquel Raynal chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
3743cfcc706cSMiquel Raynal if (!chip->write_byte || chip->write_byte == nand_write_byte)
3744cfcc706cSMiquel Raynal chip->write_byte = busw ? nand_write_byte16 : nand_write_byte;
3745cfcc706cSMiquel Raynal if (!chip->read_buf || chip->read_buf == nand_read_buf)
3746cfcc706cSMiquel Raynal chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
3747cfcc706cSMiquel Raynal if (!chip->scan_bbt)
3748cfcc706cSMiquel Raynal chip->scan_bbt = nand_default_bbt;
3749cfcc706cSMiquel Raynal
3750cfcc706cSMiquel Raynal if (!chip->controller) {
3751cfcc706cSMiquel Raynal chip->controller = &chip->hwcontrol;
3752cfcc706cSMiquel Raynal spin_lock_init(&chip->controller->lock);
3753cfcc706cSMiquel Raynal init_waitqueue_head(&chip->controller->wq);
3754cfcc706cSMiquel Raynal }
3755cfcc706cSMiquel Raynal
3756cfcc706cSMiquel Raynal if (!chip->buf_align)
3757cfcc706cSMiquel Raynal chip->buf_align = 1;
3758cfcc706cSMiquel Raynal }
3759cfcc706cSMiquel Raynal
3760cfcc706cSMiquel Raynal /* Sanitize ONFI strings so we can safely print them */
sanitize_string(char * s,size_t len)3761cfcc706cSMiquel Raynal static void sanitize_string(char *s, size_t len)
3762cfcc706cSMiquel Raynal {
3763cfcc706cSMiquel Raynal ssize_t i;
3764cfcc706cSMiquel Raynal
3765cfcc706cSMiquel Raynal /* Null terminate */
3766cfcc706cSMiquel Raynal s[len - 1] = 0;
3767cfcc706cSMiquel Raynal
3768cfcc706cSMiquel Raynal /* Remove non printable chars */
3769cfcc706cSMiquel Raynal for (i = 0; i < len - 1; i++) {
3770cfcc706cSMiquel Raynal if (s[i] < ' ' || s[i] > 127)
3771cfcc706cSMiquel Raynal s[i] = '?';
3772cfcc706cSMiquel Raynal }
3773cfcc706cSMiquel Raynal
3774cfcc706cSMiquel Raynal /* Remove trailing spaces */
3775cfcc706cSMiquel Raynal strim(s);
3776cfcc706cSMiquel Raynal }
3777cfcc706cSMiquel Raynal
onfi_crc16(u16 crc,u8 const * p,size_t len)3778cfcc706cSMiquel Raynal static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
3779cfcc706cSMiquel Raynal {
3780cfcc706cSMiquel Raynal int i;
3781cfcc706cSMiquel Raynal while (len--) {
3782cfcc706cSMiquel Raynal crc ^= *p++ << 8;
3783cfcc706cSMiquel Raynal for (i = 0; i < 8; i++)
3784cfcc706cSMiquel Raynal crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
3785cfcc706cSMiquel Raynal }
3786cfcc706cSMiquel Raynal
3787cfcc706cSMiquel Raynal return crc;
3788cfcc706cSMiquel Raynal }
3789cfcc706cSMiquel Raynal
3790cfcc706cSMiquel Raynal #ifdef CONFIG_SYS_NAND_ONFI_DETECTION
3791cfcc706cSMiquel Raynal /* Parse the Extended Parameter Page. */
nand_flash_detect_ext_param_page(struct mtd_info * mtd,struct nand_chip * chip,struct nand_onfi_params * p)3792cfcc706cSMiquel Raynal static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
3793cfcc706cSMiquel Raynal struct nand_chip *chip, struct nand_onfi_params *p)
3794cfcc706cSMiquel Raynal {
3795cfcc706cSMiquel Raynal struct onfi_ext_param_page *ep;
3796cfcc706cSMiquel Raynal struct onfi_ext_section *s;
3797cfcc706cSMiquel Raynal struct onfi_ext_ecc_info *ecc;
3798cfcc706cSMiquel Raynal uint8_t *cursor;
379973ecea3dSBoris Brezillon int ret;
3800cfcc706cSMiquel Raynal int len;
3801cfcc706cSMiquel Raynal int i;
3802cfcc706cSMiquel Raynal
3803cfcc706cSMiquel Raynal len = le16_to_cpu(p->ext_param_page_length) * 16;
3804cfcc706cSMiquel Raynal ep = kmalloc(len, GFP_KERNEL);
3805cfcc706cSMiquel Raynal if (!ep)
3806cfcc706cSMiquel Raynal return -ENOMEM;
3807cfcc706cSMiquel Raynal
3808cfcc706cSMiquel Raynal /* Send our own NAND_CMD_PARAM. */
380973ecea3dSBoris Brezillon ret = nand_read_param_page_op(chip, 0, NULL, 0);
381073ecea3dSBoris Brezillon if (ret)
381173ecea3dSBoris Brezillon goto ext_out;
3812cfcc706cSMiquel Raynal
3813cfcc706cSMiquel Raynal /* Use the Change Read Column command to skip the ONFI param pages. */
381473ecea3dSBoris Brezillon ret = nand_change_read_column_op(chip,
381573ecea3dSBoris Brezillon sizeof(*p) * p->num_of_param_pages,
381673ecea3dSBoris Brezillon ep, len, true);
381773ecea3dSBoris Brezillon if (ret)
381873ecea3dSBoris Brezillon goto ext_out;
3819cfcc706cSMiquel Raynal
382073ecea3dSBoris Brezillon ret = -EINVAL;
3821cfcc706cSMiquel Raynal if ((onfi_crc16(ONFI_CRC_BASE, ((uint8_t *)ep) + 2, len - 2)
3822cfcc706cSMiquel Raynal != le16_to_cpu(ep->crc))) {
3823cfcc706cSMiquel Raynal pr_debug("fail in the CRC.\n");
3824cfcc706cSMiquel Raynal goto ext_out;
3825cfcc706cSMiquel Raynal }
3826cfcc706cSMiquel Raynal
3827cfcc706cSMiquel Raynal /*
3828cfcc706cSMiquel Raynal * Check the signature.
3829cfcc706cSMiquel Raynal * Do not strictly follow the ONFI spec, maybe changed in future.
3830cfcc706cSMiquel Raynal */
3831cfcc706cSMiquel Raynal if (strncmp((char *)ep->sig, "EPPS", 4)) {
3832cfcc706cSMiquel Raynal pr_debug("The signature is invalid.\n");
3833cfcc706cSMiquel Raynal goto ext_out;
3834cfcc706cSMiquel Raynal }
3835cfcc706cSMiquel Raynal
3836cfcc706cSMiquel Raynal /* find the ECC section. */
3837cfcc706cSMiquel Raynal cursor = (uint8_t *)(ep + 1);
3838cfcc706cSMiquel Raynal for (i = 0; i < ONFI_EXT_SECTION_MAX; i++) {
3839cfcc706cSMiquel Raynal s = ep->sections + i;
3840cfcc706cSMiquel Raynal if (s->type == ONFI_SECTION_TYPE_2)
3841cfcc706cSMiquel Raynal break;
3842cfcc706cSMiquel Raynal cursor += s->length * 16;
3843cfcc706cSMiquel Raynal }
3844cfcc706cSMiquel Raynal if (i == ONFI_EXT_SECTION_MAX) {
3845cfcc706cSMiquel Raynal pr_debug("We can not find the ECC section.\n");
3846cfcc706cSMiquel Raynal goto ext_out;
3847cfcc706cSMiquel Raynal }
3848cfcc706cSMiquel Raynal
3849cfcc706cSMiquel Raynal /* get the info we want. */
3850cfcc706cSMiquel Raynal ecc = (struct onfi_ext_ecc_info *)cursor;
3851cfcc706cSMiquel Raynal
3852cfcc706cSMiquel Raynal if (!ecc->codeword_size) {
3853cfcc706cSMiquel Raynal pr_debug("Invalid codeword size\n");
3854cfcc706cSMiquel Raynal goto ext_out;
3855cfcc706cSMiquel Raynal }
3856cfcc706cSMiquel Raynal
3857cfcc706cSMiquel Raynal chip->ecc_strength_ds = ecc->ecc_bits;
3858cfcc706cSMiquel Raynal chip->ecc_step_ds = 1 << ecc->codeword_size;
3859cfcc706cSMiquel Raynal ret = 0;
3860cfcc706cSMiquel Raynal
3861cfcc706cSMiquel Raynal ext_out:
3862cfcc706cSMiquel Raynal kfree(ep);
3863cfcc706cSMiquel Raynal return ret;
3864cfcc706cSMiquel Raynal }
3865cfcc706cSMiquel Raynal
nand_setup_read_retry_micron(struct mtd_info * mtd,int retry_mode)3866cfcc706cSMiquel Raynal static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode)
3867cfcc706cSMiquel Raynal {
3868cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
3869cfcc706cSMiquel Raynal uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode};
3870cfcc706cSMiquel Raynal
3871cfcc706cSMiquel Raynal return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY,
3872cfcc706cSMiquel Raynal feature);
3873cfcc706cSMiquel Raynal }
3874cfcc706cSMiquel Raynal
3875cfcc706cSMiquel Raynal /*
3876cfcc706cSMiquel Raynal * Configure chip properties from Micron vendor-specific ONFI table
3877cfcc706cSMiquel Raynal */
nand_onfi_detect_micron(struct nand_chip * chip,struct nand_onfi_params * p)3878cfcc706cSMiquel Raynal static void nand_onfi_detect_micron(struct nand_chip *chip,
3879cfcc706cSMiquel Raynal struct nand_onfi_params *p)
3880cfcc706cSMiquel Raynal {
3881cfcc706cSMiquel Raynal struct nand_onfi_vendor_micron *micron = (void *)p->vendor;
3882cfcc706cSMiquel Raynal
3883cfcc706cSMiquel Raynal if (le16_to_cpu(p->vendor_revision) < 1)
3884cfcc706cSMiquel Raynal return;
3885cfcc706cSMiquel Raynal
3886cfcc706cSMiquel Raynal chip->read_retries = micron->read_retry_options;
3887cfcc706cSMiquel Raynal chip->setup_read_retry = nand_setup_read_retry_micron;
3888cfcc706cSMiquel Raynal }
3889cfcc706cSMiquel Raynal
3890cfcc706cSMiquel Raynal /*
3891cfcc706cSMiquel Raynal * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise.
3892cfcc706cSMiquel Raynal */
nand_flash_detect_onfi(struct mtd_info * mtd,struct nand_chip * chip,int * busw)3893cfcc706cSMiquel Raynal static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
3894cfcc706cSMiquel Raynal int *busw)
3895cfcc706cSMiquel Raynal {
3896cfcc706cSMiquel Raynal struct nand_onfi_params *p = &chip->onfi_params;
389773ecea3dSBoris Brezillon char id[4];
389873ecea3dSBoris Brezillon int i, ret, val;
3899cfcc706cSMiquel Raynal
3900cfcc706cSMiquel Raynal /* Try ONFI for unknown chip or LP */
390173ecea3dSBoris Brezillon ret = nand_readid_op(chip, 0x20, id, sizeof(id));
390273ecea3dSBoris Brezillon if (ret || strncmp(id, "ONFI", 4))
3903cfcc706cSMiquel Raynal return 0;
3904cfcc706cSMiquel Raynal
390573ecea3dSBoris Brezillon ret = nand_read_param_page_op(chip, 0, NULL, 0);
390673ecea3dSBoris Brezillon if (ret)
390773ecea3dSBoris Brezillon return 0;
390873ecea3dSBoris Brezillon
3909cfcc706cSMiquel Raynal for (i = 0; i < 3; i++) {
391073ecea3dSBoris Brezillon ret = nand_read_data_op(chip, p, sizeof(*p), true);
391173ecea3dSBoris Brezillon if (ret)
391273ecea3dSBoris Brezillon return 0;
391373ecea3dSBoris Brezillon
3914cfcc706cSMiquel Raynal if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
3915cfcc706cSMiquel Raynal le16_to_cpu(p->crc)) {
3916cfcc706cSMiquel Raynal break;
3917cfcc706cSMiquel Raynal }
3918cfcc706cSMiquel Raynal }
3919cfcc706cSMiquel Raynal
3920cfcc706cSMiquel Raynal if (i == 3) {
3921cfcc706cSMiquel Raynal pr_err("Could not find valid ONFI parameter page; aborting\n");
3922cfcc706cSMiquel Raynal return 0;
3923cfcc706cSMiquel Raynal }
3924cfcc706cSMiquel Raynal
3925cfcc706cSMiquel Raynal /* Check version */
3926cfcc706cSMiquel Raynal val = le16_to_cpu(p->revision);
3927cfcc706cSMiquel Raynal if (val & (1 << 5))
3928cfcc706cSMiquel Raynal chip->onfi_version = 23;
3929cfcc706cSMiquel Raynal else if (val & (1 << 4))
3930cfcc706cSMiquel Raynal chip->onfi_version = 22;
3931cfcc706cSMiquel Raynal else if (val & (1 << 3))
3932cfcc706cSMiquel Raynal chip->onfi_version = 21;
3933cfcc706cSMiquel Raynal else if (val & (1 << 2))
3934cfcc706cSMiquel Raynal chip->onfi_version = 20;
3935cfcc706cSMiquel Raynal else if (val & (1 << 1))
3936cfcc706cSMiquel Raynal chip->onfi_version = 10;
3937cfcc706cSMiquel Raynal
3938cfcc706cSMiquel Raynal if (!chip->onfi_version) {
3939cfcc706cSMiquel Raynal pr_info("unsupported ONFI version: %d\n", val);
3940cfcc706cSMiquel Raynal return 0;
3941cfcc706cSMiquel Raynal }
3942cfcc706cSMiquel Raynal
3943cfcc706cSMiquel Raynal sanitize_string(p->manufacturer, sizeof(p->manufacturer));
3944cfcc706cSMiquel Raynal sanitize_string(p->model, sizeof(p->model));
3945cfcc706cSMiquel Raynal if (!mtd->name)
3946cfcc706cSMiquel Raynal mtd->name = p->model;
3947cfcc706cSMiquel Raynal
3948cfcc706cSMiquel Raynal mtd->writesize = le32_to_cpu(p->byte_per_page);
3949cfcc706cSMiquel Raynal
3950cfcc706cSMiquel Raynal /*
3951cfcc706cSMiquel Raynal * pages_per_block and blocks_per_lun may not be a power-of-2 size
3952cfcc706cSMiquel Raynal * (don't ask me who thought of this...). MTD assumes that these
3953cfcc706cSMiquel Raynal * dimensions will be power-of-2, so just truncate the remaining area.
3954cfcc706cSMiquel Raynal */
3955cfcc706cSMiquel Raynal mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
3956cfcc706cSMiquel Raynal mtd->erasesize *= mtd->writesize;
3957cfcc706cSMiquel Raynal
3958cfcc706cSMiquel Raynal mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
3959cfcc706cSMiquel Raynal
3960cfcc706cSMiquel Raynal /* See erasesize comment */
3961cfcc706cSMiquel Raynal chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
3962cfcc706cSMiquel Raynal chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
3963cfcc706cSMiquel Raynal chip->bits_per_cell = p->bits_per_cell;
3964cfcc706cSMiquel Raynal
3965cfcc706cSMiquel Raynal if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
3966cfcc706cSMiquel Raynal *busw = NAND_BUSWIDTH_16;
3967cfcc706cSMiquel Raynal else
3968cfcc706cSMiquel Raynal *busw = 0;
3969cfcc706cSMiquel Raynal
3970cfcc706cSMiquel Raynal if (p->ecc_bits != 0xff) {
3971cfcc706cSMiquel Raynal chip->ecc_strength_ds = p->ecc_bits;
3972cfcc706cSMiquel Raynal chip->ecc_step_ds = 512;
3973cfcc706cSMiquel Raynal } else if (chip->onfi_version >= 21 &&
3974cfcc706cSMiquel Raynal (onfi_feature(chip) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
3975cfcc706cSMiquel Raynal
3976cfcc706cSMiquel Raynal /*
3977cfcc706cSMiquel Raynal * The nand_flash_detect_ext_param_page() uses the
3978cfcc706cSMiquel Raynal * Change Read Column command which maybe not supported
3979cfcc706cSMiquel Raynal * by the chip->cmdfunc. So try to update the chip->cmdfunc
3980cfcc706cSMiquel Raynal * now. We do not replace user supplied command function.
3981cfcc706cSMiquel Raynal */
3982cfcc706cSMiquel Raynal if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
3983cfcc706cSMiquel Raynal chip->cmdfunc = nand_command_lp;
3984cfcc706cSMiquel Raynal
3985cfcc706cSMiquel Raynal /* The Extended Parameter Page is supported since ONFI 2.1. */
3986cfcc706cSMiquel Raynal if (nand_flash_detect_ext_param_page(mtd, chip, p))
3987cfcc706cSMiquel Raynal pr_warn("Failed to detect ONFI extended param page\n");
3988cfcc706cSMiquel Raynal } else {
3989cfcc706cSMiquel Raynal pr_warn("Could not retrieve ONFI ECC requirements\n");
3990cfcc706cSMiquel Raynal }
3991cfcc706cSMiquel Raynal
3992cfcc706cSMiquel Raynal if (p->jedec_id == NAND_MFR_MICRON)
3993cfcc706cSMiquel Raynal nand_onfi_detect_micron(chip, p);
3994cfcc706cSMiquel Raynal
3995cfcc706cSMiquel Raynal return 1;
3996cfcc706cSMiquel Raynal }
3997cfcc706cSMiquel Raynal #else
nand_flash_detect_onfi(struct mtd_info * mtd,struct nand_chip * chip,int * busw)3998cfcc706cSMiquel Raynal static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
3999cfcc706cSMiquel Raynal int *busw)
4000cfcc706cSMiquel Raynal {
4001cfcc706cSMiquel Raynal return 0;
4002cfcc706cSMiquel Raynal }
4003cfcc706cSMiquel Raynal #endif
4004cfcc706cSMiquel Raynal
4005cfcc706cSMiquel Raynal /*
4006cfcc706cSMiquel Raynal * Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise.
4007cfcc706cSMiquel Raynal */
nand_flash_detect_jedec(struct mtd_info * mtd,struct nand_chip * chip,int * busw)4008cfcc706cSMiquel Raynal static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip,
4009cfcc706cSMiquel Raynal int *busw)
4010cfcc706cSMiquel Raynal {
4011cfcc706cSMiquel Raynal struct nand_jedec_params *p = &chip->jedec_params;
4012cfcc706cSMiquel Raynal struct jedec_ecc_info *ecc;
401373ecea3dSBoris Brezillon char id[5];
401473ecea3dSBoris Brezillon int i, val, ret;
4015cfcc706cSMiquel Raynal
4016cfcc706cSMiquel Raynal /* Try JEDEC for unknown chip or LP */
401773ecea3dSBoris Brezillon ret = nand_readid_op(chip, 0x40, id, sizeof(id));
401873ecea3dSBoris Brezillon if (ret || strncmp(id, "JEDEC", sizeof(id)))
4019cfcc706cSMiquel Raynal return 0;
4020cfcc706cSMiquel Raynal
402173ecea3dSBoris Brezillon ret = nand_read_param_page_op(chip, 0x40, NULL, 0);
402273ecea3dSBoris Brezillon if (ret)
402373ecea3dSBoris Brezillon return 0;
402473ecea3dSBoris Brezillon
4025cfcc706cSMiquel Raynal for (i = 0; i < 3; i++) {
402673ecea3dSBoris Brezillon ret = nand_read_data_op(chip, p, sizeof(*p), true);
402773ecea3dSBoris Brezillon if (ret)
402873ecea3dSBoris Brezillon return 0;
4029cfcc706cSMiquel Raynal
4030cfcc706cSMiquel Raynal if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) ==
4031cfcc706cSMiquel Raynal le16_to_cpu(p->crc))
4032cfcc706cSMiquel Raynal break;
4033cfcc706cSMiquel Raynal }
4034cfcc706cSMiquel Raynal
4035cfcc706cSMiquel Raynal if (i == 3) {
4036cfcc706cSMiquel Raynal pr_err("Could not find valid JEDEC parameter page; aborting\n");
4037cfcc706cSMiquel Raynal return 0;
4038cfcc706cSMiquel Raynal }
4039cfcc706cSMiquel Raynal
4040cfcc706cSMiquel Raynal /* Check version */
4041cfcc706cSMiquel Raynal val = le16_to_cpu(p->revision);
4042cfcc706cSMiquel Raynal if (val & (1 << 2))
4043cfcc706cSMiquel Raynal chip->jedec_version = 10;
4044cfcc706cSMiquel Raynal else if (val & (1 << 1))
4045cfcc706cSMiquel Raynal chip->jedec_version = 1; /* vendor specific version */
4046cfcc706cSMiquel Raynal
4047cfcc706cSMiquel Raynal if (!chip->jedec_version) {
4048cfcc706cSMiquel Raynal pr_info("unsupported JEDEC version: %d\n", val);
4049cfcc706cSMiquel Raynal return 0;
4050cfcc706cSMiquel Raynal }
4051cfcc706cSMiquel Raynal
4052cfcc706cSMiquel Raynal sanitize_string(p->manufacturer, sizeof(p->manufacturer));
4053cfcc706cSMiquel Raynal sanitize_string(p->model, sizeof(p->model));
4054cfcc706cSMiquel Raynal if (!mtd->name)
4055cfcc706cSMiquel Raynal mtd->name = p->model;
4056cfcc706cSMiquel Raynal
4057cfcc706cSMiquel Raynal mtd->writesize = le32_to_cpu(p->byte_per_page);
4058cfcc706cSMiquel Raynal
4059cfcc706cSMiquel Raynal /* Please reference to the comment for nand_flash_detect_onfi. */
4060cfcc706cSMiquel Raynal mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
4061cfcc706cSMiquel Raynal mtd->erasesize *= mtd->writesize;
4062cfcc706cSMiquel Raynal
4063cfcc706cSMiquel Raynal mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
4064cfcc706cSMiquel Raynal
4065cfcc706cSMiquel Raynal /* Please reference to the comment for nand_flash_detect_onfi. */
4066cfcc706cSMiquel Raynal chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
4067cfcc706cSMiquel Raynal chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
4068cfcc706cSMiquel Raynal chip->bits_per_cell = p->bits_per_cell;
4069cfcc706cSMiquel Raynal
4070cfcc706cSMiquel Raynal if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS)
4071cfcc706cSMiquel Raynal *busw = NAND_BUSWIDTH_16;
4072cfcc706cSMiquel Raynal else
4073cfcc706cSMiquel Raynal *busw = 0;
4074cfcc706cSMiquel Raynal
4075cfcc706cSMiquel Raynal /* ECC info */
4076cfcc706cSMiquel Raynal ecc = &p->ecc_info[0];
4077cfcc706cSMiquel Raynal
4078cfcc706cSMiquel Raynal if (ecc->codeword_size >= 9) {
4079cfcc706cSMiquel Raynal chip->ecc_strength_ds = ecc->ecc_bits;
4080cfcc706cSMiquel Raynal chip->ecc_step_ds = 1 << ecc->codeword_size;
4081cfcc706cSMiquel Raynal } else {
4082cfcc706cSMiquel Raynal pr_warn("Invalid codeword size\n");
4083cfcc706cSMiquel Raynal }
4084cfcc706cSMiquel Raynal
4085cfcc706cSMiquel Raynal return 1;
4086cfcc706cSMiquel Raynal }
4087cfcc706cSMiquel Raynal
4088cfcc706cSMiquel Raynal /*
4089cfcc706cSMiquel Raynal * nand_id_has_period - Check if an ID string has a given wraparound period
4090cfcc706cSMiquel Raynal * @id_data: the ID string
4091cfcc706cSMiquel Raynal * @arrlen: the length of the @id_data array
4092cfcc706cSMiquel Raynal * @period: the period of repitition
4093cfcc706cSMiquel Raynal *
4094cfcc706cSMiquel Raynal * Check if an ID string is repeated within a given sequence of bytes at
4095cfcc706cSMiquel Raynal * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a
4096cfcc706cSMiquel Raynal * period of 3). This is a helper function for nand_id_len(). Returns non-zero
4097cfcc706cSMiquel Raynal * if the repetition has a period of @period; otherwise, returns zero.
4098cfcc706cSMiquel Raynal */
nand_id_has_period(u8 * id_data,int arrlen,int period)4099cfcc706cSMiquel Raynal static int nand_id_has_period(u8 *id_data, int arrlen, int period)
4100cfcc706cSMiquel Raynal {
4101cfcc706cSMiquel Raynal int i, j;
4102cfcc706cSMiquel Raynal for (i = 0; i < period; i++)
4103cfcc706cSMiquel Raynal for (j = i + period; j < arrlen; j += period)
4104cfcc706cSMiquel Raynal if (id_data[i] != id_data[j])
4105cfcc706cSMiquel Raynal return 0;
4106cfcc706cSMiquel Raynal return 1;
4107cfcc706cSMiquel Raynal }
4108cfcc706cSMiquel Raynal
4109cfcc706cSMiquel Raynal /*
4110cfcc706cSMiquel Raynal * nand_id_len - Get the length of an ID string returned by CMD_READID
4111cfcc706cSMiquel Raynal * @id_data: the ID string
4112cfcc706cSMiquel Raynal * @arrlen: the length of the @id_data array
4113cfcc706cSMiquel Raynal
4114cfcc706cSMiquel Raynal * Returns the length of the ID string, according to known wraparound/trailing
4115cfcc706cSMiquel Raynal * zero patterns. If no pattern exists, returns the length of the array.
4116cfcc706cSMiquel Raynal */
nand_id_len(u8 * id_data,int arrlen)4117cfcc706cSMiquel Raynal static int nand_id_len(u8 *id_data, int arrlen)
4118cfcc706cSMiquel Raynal {
4119cfcc706cSMiquel Raynal int last_nonzero, period;
4120cfcc706cSMiquel Raynal
4121cfcc706cSMiquel Raynal /* Find last non-zero byte */
4122cfcc706cSMiquel Raynal for (last_nonzero = arrlen - 1; last_nonzero >= 0; last_nonzero--)
4123cfcc706cSMiquel Raynal if (id_data[last_nonzero])
4124cfcc706cSMiquel Raynal break;
4125cfcc706cSMiquel Raynal
4126cfcc706cSMiquel Raynal /* All zeros */
4127cfcc706cSMiquel Raynal if (last_nonzero < 0)
4128cfcc706cSMiquel Raynal return 0;
4129cfcc706cSMiquel Raynal
4130cfcc706cSMiquel Raynal /* Calculate wraparound period */
4131cfcc706cSMiquel Raynal for (period = 1; period < arrlen; period++)
4132cfcc706cSMiquel Raynal if (nand_id_has_period(id_data, arrlen, period))
4133cfcc706cSMiquel Raynal break;
4134cfcc706cSMiquel Raynal
4135cfcc706cSMiquel Raynal /* There's a repeated pattern */
4136cfcc706cSMiquel Raynal if (period < arrlen)
4137cfcc706cSMiquel Raynal return period;
4138cfcc706cSMiquel Raynal
4139cfcc706cSMiquel Raynal /* There are trailing zeros */
4140cfcc706cSMiquel Raynal if (last_nonzero < arrlen - 1)
4141cfcc706cSMiquel Raynal return last_nonzero + 1;
4142cfcc706cSMiquel Raynal
4143cfcc706cSMiquel Raynal /* No pattern detected */
4144cfcc706cSMiquel Raynal return arrlen;
4145cfcc706cSMiquel Raynal }
4146cfcc706cSMiquel Raynal
4147cfcc706cSMiquel Raynal /* Extract the bits of per cell from the 3rd byte of the extended ID */
nand_get_bits_per_cell(u8 cellinfo)4148cfcc706cSMiquel Raynal static int nand_get_bits_per_cell(u8 cellinfo)
4149cfcc706cSMiquel Raynal {
4150cfcc706cSMiquel Raynal int bits;
4151cfcc706cSMiquel Raynal
4152cfcc706cSMiquel Raynal bits = cellinfo & NAND_CI_CELLTYPE_MSK;
4153cfcc706cSMiquel Raynal bits >>= NAND_CI_CELLTYPE_SHIFT;
4154cfcc706cSMiquel Raynal return bits + 1;
4155cfcc706cSMiquel Raynal }
4156cfcc706cSMiquel Raynal
4157cfcc706cSMiquel Raynal /*
4158cfcc706cSMiquel Raynal * Many new NAND share similar device ID codes, which represent the size of the
4159cfcc706cSMiquel Raynal * chip. The rest of the parameters must be decoded according to generic or
4160cfcc706cSMiquel Raynal * manufacturer-specific "extended ID" decoding patterns.
4161cfcc706cSMiquel Raynal */
nand_decode_ext_id(struct mtd_info * mtd,struct nand_chip * chip,u8 id_data[8],int * busw)4162cfcc706cSMiquel Raynal static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
4163cfcc706cSMiquel Raynal u8 id_data[8], int *busw)
4164cfcc706cSMiquel Raynal {
4165cfcc706cSMiquel Raynal int extid, id_len;
4166cfcc706cSMiquel Raynal /* The 3rd id byte holds MLC / multichip data */
4167cfcc706cSMiquel Raynal chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
4168cfcc706cSMiquel Raynal /* The 4th id byte is the important one */
4169cfcc706cSMiquel Raynal extid = id_data[3];
4170cfcc706cSMiquel Raynal
4171cfcc706cSMiquel Raynal id_len = nand_id_len(id_data, 8);
4172cfcc706cSMiquel Raynal
4173cfcc706cSMiquel Raynal /*
4174cfcc706cSMiquel Raynal * Field definitions are in the following datasheets:
4175cfcc706cSMiquel Raynal * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
4176cfcc706cSMiquel Raynal * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
4177cfcc706cSMiquel Raynal * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22)
4178cfcc706cSMiquel Raynal *
4179cfcc706cSMiquel Raynal * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
4180cfcc706cSMiquel Raynal * ID to decide what to do.
4181cfcc706cSMiquel Raynal */
4182cfcc706cSMiquel Raynal if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
4183cfcc706cSMiquel Raynal !nand_is_slc(chip) && id_data[5] != 0x00) {
4184cfcc706cSMiquel Raynal /* Calc pagesize */
4185cfcc706cSMiquel Raynal mtd->writesize = 2048 << (extid & 0x03);
4186cfcc706cSMiquel Raynal extid >>= 2;
4187cfcc706cSMiquel Raynal /* Calc oobsize */
4188cfcc706cSMiquel Raynal switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
4189cfcc706cSMiquel Raynal case 1:
4190cfcc706cSMiquel Raynal mtd->oobsize = 128;
4191cfcc706cSMiquel Raynal break;
4192cfcc706cSMiquel Raynal case 2:
4193cfcc706cSMiquel Raynal mtd->oobsize = 218;
4194cfcc706cSMiquel Raynal break;
4195cfcc706cSMiquel Raynal case 3:
4196cfcc706cSMiquel Raynal mtd->oobsize = 400;
4197cfcc706cSMiquel Raynal break;
4198cfcc706cSMiquel Raynal case 4:
4199cfcc706cSMiquel Raynal mtd->oobsize = 436;
4200cfcc706cSMiquel Raynal break;
4201cfcc706cSMiquel Raynal case 5:
4202cfcc706cSMiquel Raynal mtd->oobsize = 512;
4203cfcc706cSMiquel Raynal break;
4204cfcc706cSMiquel Raynal case 6:
4205cfcc706cSMiquel Raynal mtd->oobsize = 640;
4206cfcc706cSMiquel Raynal break;
4207cfcc706cSMiquel Raynal case 7:
4208cfcc706cSMiquel Raynal default: /* Other cases are "reserved" (unknown) */
4209cfcc706cSMiquel Raynal mtd->oobsize = 1024;
4210cfcc706cSMiquel Raynal break;
4211cfcc706cSMiquel Raynal }
4212cfcc706cSMiquel Raynal extid >>= 2;
4213cfcc706cSMiquel Raynal /* Calc blocksize */
4214cfcc706cSMiquel Raynal mtd->erasesize = (128 * 1024) <<
4215cfcc706cSMiquel Raynal (((extid >> 1) & 0x04) | (extid & 0x03));
4216cfcc706cSMiquel Raynal *busw = 0;
4217cfcc706cSMiquel Raynal } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
4218cfcc706cSMiquel Raynal !nand_is_slc(chip)) {
4219cfcc706cSMiquel Raynal unsigned int tmp;
4220cfcc706cSMiquel Raynal
4221cfcc706cSMiquel Raynal /* Calc pagesize */
4222cfcc706cSMiquel Raynal mtd->writesize = 2048 << (extid & 0x03);
4223cfcc706cSMiquel Raynal extid >>= 2;
4224cfcc706cSMiquel Raynal /* Calc oobsize */
4225cfcc706cSMiquel Raynal switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
4226cfcc706cSMiquel Raynal case 0:
4227cfcc706cSMiquel Raynal mtd->oobsize = 128;
4228cfcc706cSMiquel Raynal break;
4229cfcc706cSMiquel Raynal case 1:
4230cfcc706cSMiquel Raynal mtd->oobsize = 224;
4231cfcc706cSMiquel Raynal break;
4232cfcc706cSMiquel Raynal case 2:
4233cfcc706cSMiquel Raynal mtd->oobsize = 448;
4234cfcc706cSMiquel Raynal break;
4235cfcc706cSMiquel Raynal case 3:
4236cfcc706cSMiquel Raynal mtd->oobsize = 64;
4237cfcc706cSMiquel Raynal break;
4238cfcc706cSMiquel Raynal case 4:
4239cfcc706cSMiquel Raynal mtd->oobsize = 32;
4240cfcc706cSMiquel Raynal break;
4241cfcc706cSMiquel Raynal case 5:
4242cfcc706cSMiquel Raynal mtd->oobsize = 16;
4243cfcc706cSMiquel Raynal break;
4244cfcc706cSMiquel Raynal default:
4245cfcc706cSMiquel Raynal mtd->oobsize = 640;
4246cfcc706cSMiquel Raynal break;
4247cfcc706cSMiquel Raynal }
4248cfcc706cSMiquel Raynal extid >>= 2;
4249cfcc706cSMiquel Raynal /* Calc blocksize */
4250cfcc706cSMiquel Raynal tmp = ((extid >> 1) & 0x04) | (extid & 0x03);
4251cfcc706cSMiquel Raynal if (tmp < 0x03)
4252cfcc706cSMiquel Raynal mtd->erasesize = (128 * 1024) << tmp;
4253cfcc706cSMiquel Raynal else if (tmp == 0x03)
4254cfcc706cSMiquel Raynal mtd->erasesize = 768 * 1024;
4255cfcc706cSMiquel Raynal else
4256cfcc706cSMiquel Raynal mtd->erasesize = (64 * 1024) << tmp;
4257cfcc706cSMiquel Raynal *busw = 0;
4258cfcc706cSMiquel Raynal } else {
4259cfcc706cSMiquel Raynal /* Calc pagesize */
4260cfcc706cSMiquel Raynal mtd->writesize = 1024 << (extid & 0x03);
4261cfcc706cSMiquel Raynal extid >>= 2;
4262cfcc706cSMiquel Raynal /* Calc oobsize */
4263cfcc706cSMiquel Raynal mtd->oobsize = (8 << (extid & 0x01)) *
4264cfcc706cSMiquel Raynal (mtd->writesize >> 9);
4265cfcc706cSMiquel Raynal extid >>= 2;
4266cfcc706cSMiquel Raynal /* Calc blocksize. Blocksize is multiples of 64KiB */
4267cfcc706cSMiquel Raynal mtd->erasesize = (64 * 1024) << (extid & 0x03);
4268cfcc706cSMiquel Raynal extid >>= 2;
4269cfcc706cSMiquel Raynal /* Get buswidth information */
4270cfcc706cSMiquel Raynal *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
4271cfcc706cSMiquel Raynal
4272cfcc706cSMiquel Raynal /*
4273cfcc706cSMiquel Raynal * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
4274cfcc706cSMiquel Raynal * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
4275cfcc706cSMiquel Raynal * follows:
4276cfcc706cSMiquel Raynal * - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm,
4277cfcc706cSMiquel Raynal * 110b -> 24nm
4278cfcc706cSMiquel Raynal * - ID byte 5, bit[7]: 1 -> BENAND, 0 -> raw SLC
4279cfcc706cSMiquel Raynal */
4280cfcc706cSMiquel Raynal if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA &&
4281cfcc706cSMiquel Raynal nand_is_slc(chip) &&
4282cfcc706cSMiquel Raynal (id_data[5] & 0x7) == 0x6 /* 24nm */ &&
4283cfcc706cSMiquel Raynal !(id_data[4] & 0x80) /* !BENAND */) {
4284cfcc706cSMiquel Raynal mtd->oobsize = 32 * mtd->writesize >> 9;
4285cfcc706cSMiquel Raynal }
4286cfcc706cSMiquel Raynal
4287cfcc706cSMiquel Raynal }
4288cfcc706cSMiquel Raynal }
4289cfcc706cSMiquel Raynal
4290cfcc706cSMiquel Raynal /*
4291cfcc706cSMiquel Raynal * Old devices have chip data hardcoded in the device ID table. nand_decode_id
4292cfcc706cSMiquel Raynal * decodes a matching ID table entry and assigns the MTD size parameters for
4293cfcc706cSMiquel Raynal * the chip.
4294cfcc706cSMiquel Raynal */
nand_decode_id(struct mtd_info * mtd,struct nand_chip * chip,struct nand_flash_dev * type,u8 id_data[8],int * busw)4295cfcc706cSMiquel Raynal static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
4296cfcc706cSMiquel Raynal struct nand_flash_dev *type, u8 id_data[8],
4297cfcc706cSMiquel Raynal int *busw)
4298cfcc706cSMiquel Raynal {
4299cfcc706cSMiquel Raynal int maf_id = id_data[0];
4300cfcc706cSMiquel Raynal
4301cfcc706cSMiquel Raynal mtd->erasesize = type->erasesize;
4302cfcc706cSMiquel Raynal mtd->writesize = type->pagesize;
4303cfcc706cSMiquel Raynal mtd->oobsize = mtd->writesize / 32;
4304cfcc706cSMiquel Raynal *busw = type->options & NAND_BUSWIDTH_16;
4305cfcc706cSMiquel Raynal
4306cfcc706cSMiquel Raynal /* All legacy ID NAND are small-page, SLC */
4307cfcc706cSMiquel Raynal chip->bits_per_cell = 1;
4308cfcc706cSMiquel Raynal
4309cfcc706cSMiquel Raynal /*
4310cfcc706cSMiquel Raynal * Check for Spansion/AMD ID + repeating 5th, 6th byte since
4311cfcc706cSMiquel Raynal * some Spansion chips have erasesize that conflicts with size
4312cfcc706cSMiquel Raynal * listed in nand_ids table.
4313cfcc706cSMiquel Raynal * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
4314cfcc706cSMiquel Raynal */
4315cfcc706cSMiquel Raynal if (maf_id == NAND_MFR_AMD && id_data[4] != 0x00 && id_data[5] == 0x00
4316cfcc706cSMiquel Raynal && id_data[6] == 0x00 && id_data[7] == 0x00
4317cfcc706cSMiquel Raynal && mtd->writesize == 512) {
4318cfcc706cSMiquel Raynal mtd->erasesize = 128 * 1024;
4319cfcc706cSMiquel Raynal mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
4320cfcc706cSMiquel Raynal }
4321cfcc706cSMiquel Raynal }
4322cfcc706cSMiquel Raynal
4323cfcc706cSMiquel Raynal /*
4324cfcc706cSMiquel Raynal * Set the bad block marker/indicator (BBM/BBI) patterns according to some
4325cfcc706cSMiquel Raynal * heuristic patterns using various detected parameters (e.g., manufacturer,
4326cfcc706cSMiquel Raynal * page size, cell-type information).
4327cfcc706cSMiquel Raynal */
nand_decode_bbm_options(struct mtd_info * mtd,struct nand_chip * chip,u8 id_data[8])4328cfcc706cSMiquel Raynal static void nand_decode_bbm_options(struct mtd_info *mtd,
4329cfcc706cSMiquel Raynal struct nand_chip *chip, u8 id_data[8])
4330cfcc706cSMiquel Raynal {
4331cfcc706cSMiquel Raynal int maf_id = id_data[0];
4332cfcc706cSMiquel Raynal
4333cfcc706cSMiquel Raynal /* Set the bad block position */
4334cfcc706cSMiquel Raynal if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16))
4335cfcc706cSMiquel Raynal chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
4336cfcc706cSMiquel Raynal else
4337cfcc706cSMiquel Raynal chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
4338cfcc706cSMiquel Raynal
4339cfcc706cSMiquel Raynal /*
4340cfcc706cSMiquel Raynal * Bad block marker is stored in the last page of each block on Samsung
4341cfcc706cSMiquel Raynal * and Hynix MLC devices; stored in first two pages of each block on
4342cfcc706cSMiquel Raynal * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,
4343cfcc706cSMiquel Raynal * AMD/Spansion, and Macronix. All others scan only the first page.
4344cfcc706cSMiquel Raynal */
4345cfcc706cSMiquel Raynal if (!nand_is_slc(chip) &&
4346cfcc706cSMiquel Raynal (maf_id == NAND_MFR_SAMSUNG ||
4347cfcc706cSMiquel Raynal maf_id == NAND_MFR_HYNIX))
4348cfcc706cSMiquel Raynal chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
4349cfcc706cSMiquel Raynal else if ((nand_is_slc(chip) &&
4350cfcc706cSMiquel Raynal (maf_id == NAND_MFR_SAMSUNG ||
4351cfcc706cSMiquel Raynal maf_id == NAND_MFR_HYNIX ||
4352cfcc706cSMiquel Raynal maf_id == NAND_MFR_TOSHIBA ||
4353cfcc706cSMiquel Raynal maf_id == NAND_MFR_AMD ||
4354cfcc706cSMiquel Raynal maf_id == NAND_MFR_MACRONIX)) ||
4355cfcc706cSMiquel Raynal (mtd->writesize == 2048 &&
4356cfcc706cSMiquel Raynal maf_id == NAND_MFR_MICRON))
4357cfcc706cSMiquel Raynal chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
4358cfcc706cSMiquel Raynal }
4359cfcc706cSMiquel Raynal
is_full_id_nand(struct nand_flash_dev * type)4360cfcc706cSMiquel Raynal static inline bool is_full_id_nand(struct nand_flash_dev *type)
4361cfcc706cSMiquel Raynal {
4362cfcc706cSMiquel Raynal return type->id_len;
4363cfcc706cSMiquel Raynal }
4364cfcc706cSMiquel Raynal
find_full_id_nand(struct mtd_info * mtd,struct nand_chip * chip,struct nand_flash_dev * type,u8 * id_data,int * busw)4365cfcc706cSMiquel Raynal static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
4366cfcc706cSMiquel Raynal struct nand_flash_dev *type, u8 *id_data, int *busw)
4367cfcc706cSMiquel Raynal {
4368cfcc706cSMiquel Raynal if (!strncmp((char *)type->id, (char *)id_data, type->id_len)) {
4369cfcc706cSMiquel Raynal mtd->writesize = type->pagesize;
4370cfcc706cSMiquel Raynal mtd->erasesize = type->erasesize;
4371cfcc706cSMiquel Raynal mtd->oobsize = type->oobsize;
4372cfcc706cSMiquel Raynal
4373cfcc706cSMiquel Raynal chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
4374cfcc706cSMiquel Raynal chip->chipsize = (uint64_t)type->chipsize << 20;
4375cfcc706cSMiquel Raynal chip->options |= type->options;
4376cfcc706cSMiquel Raynal chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
4377cfcc706cSMiquel Raynal chip->ecc_step_ds = NAND_ECC_STEP(type);
4378cfcc706cSMiquel Raynal chip->onfi_timing_mode_default =
4379cfcc706cSMiquel Raynal type->onfi_timing_mode_default;
4380cfcc706cSMiquel Raynal
4381cfcc706cSMiquel Raynal *busw = type->options & NAND_BUSWIDTH_16;
4382cfcc706cSMiquel Raynal
4383cfcc706cSMiquel Raynal if (!mtd->name)
4384cfcc706cSMiquel Raynal mtd->name = type->name;
4385cfcc706cSMiquel Raynal
4386cfcc706cSMiquel Raynal return true;
4387cfcc706cSMiquel Raynal }
4388cfcc706cSMiquel Raynal return false;
4389cfcc706cSMiquel Raynal }
4390cfcc706cSMiquel Raynal
4391cfcc706cSMiquel Raynal /*
4392cfcc706cSMiquel Raynal * Get the flash and manufacturer id and lookup if the type is supported.
4393cfcc706cSMiquel Raynal */
nand_get_flash_type(struct mtd_info * mtd,struct nand_chip * chip,int * maf_id,int * dev_id,struct nand_flash_dev * type)4394cfcc706cSMiquel Raynal struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
4395cfcc706cSMiquel Raynal struct nand_chip *chip,
4396cfcc706cSMiquel Raynal int *maf_id, int *dev_id,
4397cfcc706cSMiquel Raynal struct nand_flash_dev *type)
4398cfcc706cSMiquel Raynal {
439973ecea3dSBoris Brezillon int busw, ret;
440073ecea3dSBoris Brezillon int maf_idx;
4401cfcc706cSMiquel Raynal u8 id_data[8];
4402cfcc706cSMiquel Raynal
4403cfcc706cSMiquel Raynal /*
4404cfcc706cSMiquel Raynal * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
4405cfcc706cSMiquel Raynal * after power-up.
4406cfcc706cSMiquel Raynal */
440773ecea3dSBoris Brezillon ret = nand_reset(chip, 0);
440873ecea3dSBoris Brezillon if (ret)
440973ecea3dSBoris Brezillon return ERR_PTR(ret);
4410cfcc706cSMiquel Raynal
4411cfcc706cSMiquel Raynal /* Select the device */
4412cfcc706cSMiquel Raynal chip->select_chip(mtd, 0);
4413cfcc706cSMiquel Raynal
4414cfcc706cSMiquel Raynal /* Send the command for reading device ID */
441573ecea3dSBoris Brezillon ret = nand_readid_op(chip, 0, id_data, 2);
441673ecea3dSBoris Brezillon if (ret)
441773ecea3dSBoris Brezillon return ERR_PTR(ret);
4418cfcc706cSMiquel Raynal
4419cfcc706cSMiquel Raynal /* Read manufacturer and device IDs */
442073ecea3dSBoris Brezillon *maf_id = id_data[0];
442173ecea3dSBoris Brezillon *dev_id = id_data[1];
4422cfcc706cSMiquel Raynal
4423cfcc706cSMiquel Raynal /*
4424cfcc706cSMiquel Raynal * Try again to make sure, as some systems the bus-hold or other
4425cfcc706cSMiquel Raynal * interface concerns can cause random data which looks like a
4426cfcc706cSMiquel Raynal * possibly credible NAND flash to appear. If the two results do
4427cfcc706cSMiquel Raynal * not match, ignore the device completely.
4428cfcc706cSMiquel Raynal */
4429cfcc706cSMiquel Raynal
4430cfcc706cSMiquel Raynal /* Read entire ID string */
443173ecea3dSBoris Brezillon ret = nand_readid_op(chip, 0, id_data, 8);
443273ecea3dSBoris Brezillon if (ret)
443373ecea3dSBoris Brezillon return ERR_PTR(ret);
4434cfcc706cSMiquel Raynal
4435cfcc706cSMiquel Raynal if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
4436cfcc706cSMiquel Raynal pr_info("second ID read did not match %02x,%02x against %02x,%02x\n",
4437cfcc706cSMiquel Raynal *maf_id, *dev_id, id_data[0], id_data[1]);
4438cfcc706cSMiquel Raynal return ERR_PTR(-ENODEV);
4439cfcc706cSMiquel Raynal }
4440cfcc706cSMiquel Raynal
4441cfcc706cSMiquel Raynal if (!type)
4442cfcc706cSMiquel Raynal type = nand_flash_ids;
4443cfcc706cSMiquel Raynal
4444cfcc706cSMiquel Raynal for (; type->name != NULL; type++) {
4445cfcc706cSMiquel Raynal if (is_full_id_nand(type)) {
4446cfcc706cSMiquel Raynal if (find_full_id_nand(mtd, chip, type, id_data, &busw))
4447cfcc706cSMiquel Raynal goto ident_done;
4448cfcc706cSMiquel Raynal } else if (*dev_id == type->dev_id) {
4449cfcc706cSMiquel Raynal break;
4450cfcc706cSMiquel Raynal }
4451cfcc706cSMiquel Raynal }
4452cfcc706cSMiquel Raynal
4453cfcc706cSMiquel Raynal chip->onfi_version = 0;
4454cfcc706cSMiquel Raynal if (!type->name || !type->pagesize) {
4455cfcc706cSMiquel Raynal /* Check if the chip is ONFI compliant */
4456cfcc706cSMiquel Raynal if (nand_flash_detect_onfi(mtd, chip, &busw))
4457cfcc706cSMiquel Raynal goto ident_done;
4458cfcc706cSMiquel Raynal
4459cfcc706cSMiquel Raynal /* Check if the chip is JEDEC compliant */
4460cfcc706cSMiquel Raynal if (nand_flash_detect_jedec(mtd, chip, &busw))
4461cfcc706cSMiquel Raynal goto ident_done;
4462cfcc706cSMiquel Raynal }
4463cfcc706cSMiquel Raynal
4464cfcc706cSMiquel Raynal if (!type->name)
4465cfcc706cSMiquel Raynal return ERR_PTR(-ENODEV);
4466cfcc706cSMiquel Raynal
4467cfcc706cSMiquel Raynal if (!mtd->name)
4468cfcc706cSMiquel Raynal mtd->name = type->name;
4469cfcc706cSMiquel Raynal
4470cfcc706cSMiquel Raynal chip->chipsize = (uint64_t)type->chipsize << 20;
4471cfcc706cSMiquel Raynal
4472cfcc706cSMiquel Raynal if (!type->pagesize) {
4473cfcc706cSMiquel Raynal /* Decode parameters from extended ID */
4474cfcc706cSMiquel Raynal nand_decode_ext_id(mtd, chip, id_data, &busw);
4475cfcc706cSMiquel Raynal } else {
4476cfcc706cSMiquel Raynal nand_decode_id(mtd, chip, type, id_data, &busw);
4477cfcc706cSMiquel Raynal }
4478cfcc706cSMiquel Raynal /* Get chip options */
4479cfcc706cSMiquel Raynal chip->options |= type->options;
4480cfcc706cSMiquel Raynal
4481cfcc706cSMiquel Raynal /*
4482cfcc706cSMiquel Raynal * Check if chip is not a Samsung device. Do not clear the
4483cfcc706cSMiquel Raynal * options for chips which do not have an extended id.
4484cfcc706cSMiquel Raynal */
4485cfcc706cSMiquel Raynal if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
4486cfcc706cSMiquel Raynal chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
4487cfcc706cSMiquel Raynal ident_done:
4488cfcc706cSMiquel Raynal
4489cfcc706cSMiquel Raynal /* Try to identify manufacturer */
4490cfcc706cSMiquel Raynal for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
4491cfcc706cSMiquel Raynal if (nand_manuf_ids[maf_idx].id == *maf_id)
4492cfcc706cSMiquel Raynal break;
4493cfcc706cSMiquel Raynal }
4494cfcc706cSMiquel Raynal
4495cfcc706cSMiquel Raynal if (chip->options & NAND_BUSWIDTH_AUTO) {
4496cfcc706cSMiquel Raynal WARN_ON(chip->options & NAND_BUSWIDTH_16);
4497cfcc706cSMiquel Raynal chip->options |= busw;
4498cfcc706cSMiquel Raynal nand_set_defaults(chip, busw);
4499cfcc706cSMiquel Raynal } else if (busw != (chip->options & NAND_BUSWIDTH_16)) {
4500cfcc706cSMiquel Raynal /*
4501cfcc706cSMiquel Raynal * Check, if buswidth is correct. Hardware drivers should set
4502cfcc706cSMiquel Raynal * chip correct!
4503cfcc706cSMiquel Raynal */
4504cfcc706cSMiquel Raynal pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
4505cfcc706cSMiquel Raynal *maf_id, *dev_id);
4506cfcc706cSMiquel Raynal pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, mtd->name);
4507cfcc706cSMiquel Raynal pr_warn("bus width %d instead %d bit\n",
4508cfcc706cSMiquel Raynal (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
4509cfcc706cSMiquel Raynal busw ? 16 : 8);
4510cfcc706cSMiquel Raynal return ERR_PTR(-EINVAL);
4511cfcc706cSMiquel Raynal }
4512cfcc706cSMiquel Raynal
4513cfcc706cSMiquel Raynal nand_decode_bbm_options(mtd, chip, id_data);
4514cfcc706cSMiquel Raynal
4515cfcc706cSMiquel Raynal /* Calculate the address shift from the page size */
4516cfcc706cSMiquel Raynal chip->page_shift = ffs(mtd->writesize) - 1;
4517cfcc706cSMiquel Raynal /* Convert chipsize to number of pages per chip -1 */
4518cfcc706cSMiquel Raynal chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
4519cfcc706cSMiquel Raynal
4520cfcc706cSMiquel Raynal chip->bbt_erase_shift = chip->phys_erase_shift =
4521cfcc706cSMiquel Raynal ffs(mtd->erasesize) - 1;
4522cfcc706cSMiquel Raynal if (chip->chipsize & 0xffffffff)
4523cfcc706cSMiquel Raynal chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
4524cfcc706cSMiquel Raynal else {
4525cfcc706cSMiquel Raynal chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32));
4526cfcc706cSMiquel Raynal chip->chip_shift += 32 - 1;
4527cfcc706cSMiquel Raynal }
4528cfcc706cSMiquel Raynal
4529cfcc706cSMiquel Raynal if (chip->chip_shift - chip->page_shift > 16)
4530cfcc706cSMiquel Raynal chip->options |= NAND_ROW_ADDR_3;
4531cfcc706cSMiquel Raynal
4532cfcc706cSMiquel Raynal chip->badblockbits = 8;
4533cfcc706cSMiquel Raynal chip->erase = single_erase;
4534cfcc706cSMiquel Raynal
4535cfcc706cSMiquel Raynal /* Do not replace user supplied command function! */
4536cfcc706cSMiquel Raynal if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
4537cfcc706cSMiquel Raynal chip->cmdfunc = nand_command_lp;
4538cfcc706cSMiquel Raynal
4539cfcc706cSMiquel Raynal pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
4540cfcc706cSMiquel Raynal *maf_id, *dev_id);
4541cfcc706cSMiquel Raynal
4542cfcc706cSMiquel Raynal #ifdef CONFIG_SYS_NAND_ONFI_DETECTION
4543cfcc706cSMiquel Raynal if (chip->onfi_version)
4544cfcc706cSMiquel Raynal pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
4545cfcc706cSMiquel Raynal chip->onfi_params.model);
4546cfcc706cSMiquel Raynal else if (chip->jedec_version)
4547cfcc706cSMiquel Raynal pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
4548cfcc706cSMiquel Raynal chip->jedec_params.model);
4549cfcc706cSMiquel Raynal else
4550cfcc706cSMiquel Raynal pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
4551cfcc706cSMiquel Raynal type->name);
4552cfcc706cSMiquel Raynal #else
4553cfcc706cSMiquel Raynal if (chip->jedec_version)
4554cfcc706cSMiquel Raynal pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
4555cfcc706cSMiquel Raynal chip->jedec_params.model);
4556cfcc706cSMiquel Raynal else
4557cfcc706cSMiquel Raynal pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
4558cfcc706cSMiquel Raynal type->name);
4559cfcc706cSMiquel Raynal
4560cfcc706cSMiquel Raynal pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
4561cfcc706cSMiquel Raynal type->name);
4562cfcc706cSMiquel Raynal #endif
4563cfcc706cSMiquel Raynal
4564cfcc706cSMiquel Raynal pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n",
4565cfcc706cSMiquel Raynal (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
4566cfcc706cSMiquel Raynal mtd->erasesize >> 10, mtd->writesize, mtd->oobsize);
4567cfcc706cSMiquel Raynal return type;
4568cfcc706cSMiquel Raynal }
4569cfcc706cSMiquel Raynal EXPORT_SYMBOL(nand_get_flash_type);
4570cfcc706cSMiquel Raynal
4571cfcc706cSMiquel Raynal #if CONFIG_IS_ENABLED(OF_CONTROL)
4572cfcc706cSMiquel Raynal DECLARE_GLOBAL_DATA_PTR;
4573cfcc706cSMiquel Raynal
nand_dt_init(struct mtd_info * mtd,struct nand_chip * chip,int node)4574cfcc706cSMiquel Raynal static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, int node)
4575cfcc706cSMiquel Raynal {
4576cfcc706cSMiquel Raynal int ret, ecc_mode = -1, ecc_strength, ecc_step;
4577cfcc706cSMiquel Raynal const void *blob = gd->fdt_blob;
4578cfcc706cSMiquel Raynal const char *str;
4579cfcc706cSMiquel Raynal
4580cfcc706cSMiquel Raynal ret = fdtdec_get_int(blob, node, "nand-bus-width", -1);
4581cfcc706cSMiquel Raynal if (ret == 16)
4582cfcc706cSMiquel Raynal chip->options |= NAND_BUSWIDTH_16;
4583cfcc706cSMiquel Raynal
4584cfcc706cSMiquel Raynal if (fdtdec_get_bool(blob, node, "nand-on-flash-bbt"))
4585cfcc706cSMiquel Raynal chip->bbt_options |= NAND_BBT_USE_FLASH;
4586cfcc706cSMiquel Raynal
4587cfcc706cSMiquel Raynal str = fdt_getprop(blob, node, "nand-ecc-mode", NULL);
4588cfcc706cSMiquel Raynal if (str) {
4589cfcc706cSMiquel Raynal if (!strcmp(str, "none"))
4590cfcc706cSMiquel Raynal ecc_mode = NAND_ECC_NONE;
4591cfcc706cSMiquel Raynal else if (!strcmp(str, "soft"))
4592cfcc706cSMiquel Raynal ecc_mode = NAND_ECC_SOFT;
4593cfcc706cSMiquel Raynal else if (!strcmp(str, "hw"))
4594cfcc706cSMiquel Raynal ecc_mode = NAND_ECC_HW;
4595cfcc706cSMiquel Raynal else if (!strcmp(str, "hw_syndrome"))
4596cfcc706cSMiquel Raynal ecc_mode = NAND_ECC_HW_SYNDROME;
4597cfcc706cSMiquel Raynal else if (!strcmp(str, "hw_oob_first"))
4598cfcc706cSMiquel Raynal ecc_mode = NAND_ECC_HW_OOB_FIRST;
4599cfcc706cSMiquel Raynal else if (!strcmp(str, "soft_bch"))
4600cfcc706cSMiquel Raynal ecc_mode = NAND_ECC_SOFT_BCH;
4601cfcc706cSMiquel Raynal }
4602cfcc706cSMiquel Raynal
4603cfcc706cSMiquel Raynal
4604cfcc706cSMiquel Raynal ecc_strength = fdtdec_get_int(blob, node, "nand-ecc-strength", -1);
4605cfcc706cSMiquel Raynal ecc_step = fdtdec_get_int(blob, node, "nand-ecc-step-size", -1);
4606cfcc706cSMiquel Raynal
4607cfcc706cSMiquel Raynal if ((ecc_step >= 0 && !(ecc_strength >= 0)) ||
4608cfcc706cSMiquel Raynal (!(ecc_step >= 0) && ecc_strength >= 0)) {
4609cfcc706cSMiquel Raynal pr_err("must set both strength and step size in DT\n");
4610cfcc706cSMiquel Raynal return -EINVAL;
4611cfcc706cSMiquel Raynal }
4612cfcc706cSMiquel Raynal
4613cfcc706cSMiquel Raynal if (ecc_mode >= 0)
4614cfcc706cSMiquel Raynal chip->ecc.mode = ecc_mode;
4615cfcc706cSMiquel Raynal
4616cfcc706cSMiquel Raynal if (ecc_strength >= 0)
4617cfcc706cSMiquel Raynal chip->ecc.strength = ecc_strength;
4618cfcc706cSMiquel Raynal
4619cfcc706cSMiquel Raynal if (ecc_step > 0)
4620cfcc706cSMiquel Raynal chip->ecc.size = ecc_step;
4621cfcc706cSMiquel Raynal
4622cfcc706cSMiquel Raynal if (fdt_getprop(blob, node, "nand-ecc-maximize", NULL))
4623cfcc706cSMiquel Raynal chip->ecc.options |= NAND_ECC_MAXIMIZE;
4624cfcc706cSMiquel Raynal
4625cfcc706cSMiquel Raynal return 0;
4626cfcc706cSMiquel Raynal }
4627cfcc706cSMiquel Raynal #else
nand_dt_init(struct mtd_info * mtd,struct nand_chip * chip,int node)4628cfcc706cSMiquel Raynal static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, int node)
4629cfcc706cSMiquel Raynal {
4630cfcc706cSMiquel Raynal return 0;
4631cfcc706cSMiquel Raynal }
4632cfcc706cSMiquel Raynal #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
4633cfcc706cSMiquel Raynal
4634cfcc706cSMiquel Raynal /**
4635cfcc706cSMiquel Raynal * nand_scan_ident - [NAND Interface] Scan for the NAND device
4636cfcc706cSMiquel Raynal * @mtd: MTD device structure
4637cfcc706cSMiquel Raynal * @maxchips: number of chips to scan for
4638cfcc706cSMiquel Raynal * @table: alternative NAND ID table
4639cfcc706cSMiquel Raynal *
4640cfcc706cSMiquel Raynal * This is the first phase of the normal nand_scan() function. It reads the
4641cfcc706cSMiquel Raynal * flash ID and sets up MTD fields accordingly.
4642cfcc706cSMiquel Raynal *
4643cfcc706cSMiquel Raynal */
nand_scan_ident(struct mtd_info * mtd,int maxchips,struct nand_flash_dev * table)4644cfcc706cSMiquel Raynal int nand_scan_ident(struct mtd_info *mtd, int maxchips,
4645cfcc706cSMiquel Raynal struct nand_flash_dev *table)
4646cfcc706cSMiquel Raynal {
4647cfcc706cSMiquel Raynal int i, nand_maf_id, nand_dev_id;
4648cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
4649cfcc706cSMiquel Raynal struct nand_flash_dev *type;
4650cfcc706cSMiquel Raynal int ret;
4651cfcc706cSMiquel Raynal
4652cfcc706cSMiquel Raynal if (chip->flash_node) {
4653cfcc706cSMiquel Raynal ret = nand_dt_init(mtd, chip, chip->flash_node);
4654cfcc706cSMiquel Raynal if (ret)
4655cfcc706cSMiquel Raynal return ret;
4656cfcc706cSMiquel Raynal }
4657cfcc706cSMiquel Raynal
4658cfcc706cSMiquel Raynal /* Set the default functions */
4659cfcc706cSMiquel Raynal nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
4660cfcc706cSMiquel Raynal
4661cfcc706cSMiquel Raynal /* Read the flash type */
4662cfcc706cSMiquel Raynal type = nand_get_flash_type(mtd, chip, &nand_maf_id,
4663cfcc706cSMiquel Raynal &nand_dev_id, table);
4664cfcc706cSMiquel Raynal
4665cfcc706cSMiquel Raynal if (IS_ERR(type)) {
4666cfcc706cSMiquel Raynal if (!(chip->options & NAND_SCAN_SILENT_NODEV))
4667cfcc706cSMiquel Raynal pr_warn("No NAND device found\n");
4668cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
4669cfcc706cSMiquel Raynal return PTR_ERR(type);
4670cfcc706cSMiquel Raynal }
4671cfcc706cSMiquel Raynal
4672cfcc706cSMiquel Raynal /* Initialize the ->data_interface field. */
4673cfcc706cSMiquel Raynal ret = nand_init_data_interface(chip);
4674cfcc706cSMiquel Raynal if (ret)
4675cfcc706cSMiquel Raynal return ret;
4676cfcc706cSMiquel Raynal
4677cfcc706cSMiquel Raynal /*
4678cfcc706cSMiquel Raynal * Setup the data interface correctly on the chip and controller side.
4679cfcc706cSMiquel Raynal * This explicit call to nand_setup_data_interface() is only required
4680cfcc706cSMiquel Raynal * for the first die, because nand_reset() has been called before
4681cfcc706cSMiquel Raynal * ->data_interface and ->default_onfi_timing_mode were set.
4682cfcc706cSMiquel Raynal * For the other dies, nand_reset() will automatically switch to the
4683cfcc706cSMiquel Raynal * best mode for us.
4684cfcc706cSMiquel Raynal */
4685cfcc706cSMiquel Raynal ret = nand_setup_data_interface(chip, 0);
4686cfcc706cSMiquel Raynal if (ret)
4687cfcc706cSMiquel Raynal return ret;
4688cfcc706cSMiquel Raynal
4689cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
4690cfcc706cSMiquel Raynal
4691cfcc706cSMiquel Raynal /* Check for a chip array */
4692cfcc706cSMiquel Raynal for (i = 1; i < maxchips; i++) {
469373ecea3dSBoris Brezillon u8 id[2];
469473ecea3dSBoris Brezillon
4695cfcc706cSMiquel Raynal /* See comment in nand_get_flash_type for reset */
4696cfcc706cSMiquel Raynal nand_reset(chip, i);
4697cfcc706cSMiquel Raynal
4698cfcc706cSMiquel Raynal chip->select_chip(mtd, i);
4699cfcc706cSMiquel Raynal /* Send the command for reading device ID */
470073ecea3dSBoris Brezillon nand_readid_op(chip, 0, id, sizeof(id));
470173ecea3dSBoris Brezillon
4702cfcc706cSMiquel Raynal /* Read manufacturer and device IDs */
470373ecea3dSBoris Brezillon if (nand_maf_id != id[0] || nand_dev_id != id[1]) {
4704cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
4705cfcc706cSMiquel Raynal break;
4706cfcc706cSMiquel Raynal }
4707cfcc706cSMiquel Raynal chip->select_chip(mtd, -1);
4708cfcc706cSMiquel Raynal }
4709cfcc706cSMiquel Raynal
4710cfcc706cSMiquel Raynal #ifdef DEBUG
4711cfcc706cSMiquel Raynal if (i > 1)
4712cfcc706cSMiquel Raynal pr_info("%d chips detected\n", i);
4713cfcc706cSMiquel Raynal #endif
4714cfcc706cSMiquel Raynal
4715cfcc706cSMiquel Raynal /* Store the number of chips and calc total size for mtd */
4716cfcc706cSMiquel Raynal chip->numchips = i;
4717cfcc706cSMiquel Raynal mtd->size = i * chip->chipsize;
4718cfcc706cSMiquel Raynal
4719cfcc706cSMiquel Raynal return 0;
4720cfcc706cSMiquel Raynal }
4721cfcc706cSMiquel Raynal EXPORT_SYMBOL(nand_scan_ident);
4722cfcc706cSMiquel Raynal
4723cfcc706cSMiquel Raynal /**
4724cfcc706cSMiquel Raynal * nand_check_ecc_caps - check the sanity of preset ECC settings
4725cfcc706cSMiquel Raynal * @chip: nand chip info structure
4726cfcc706cSMiquel Raynal * @caps: ECC caps info structure
4727cfcc706cSMiquel Raynal * @oobavail: OOB size that the ECC engine can use
4728cfcc706cSMiquel Raynal *
4729cfcc706cSMiquel Raynal * When ECC step size and strength are already set, check if they are supported
4730cfcc706cSMiquel Raynal * by the controller and the calculated ECC bytes fit within the chip's OOB.
4731cfcc706cSMiquel Raynal * On success, the calculated ECC bytes is set.
4732cfcc706cSMiquel Raynal */
nand_check_ecc_caps(struct nand_chip * chip,const struct nand_ecc_caps * caps,int oobavail)4733cfcc706cSMiquel Raynal int nand_check_ecc_caps(struct nand_chip *chip,
4734cfcc706cSMiquel Raynal const struct nand_ecc_caps *caps, int oobavail)
4735cfcc706cSMiquel Raynal {
4736cfcc706cSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip);
4737cfcc706cSMiquel Raynal const struct nand_ecc_step_info *stepinfo;
4738cfcc706cSMiquel Raynal int preset_step = chip->ecc.size;
4739cfcc706cSMiquel Raynal int preset_strength = chip->ecc.strength;
4740cfcc706cSMiquel Raynal int nsteps, ecc_bytes;
4741cfcc706cSMiquel Raynal int i, j;
4742cfcc706cSMiquel Raynal
4743cfcc706cSMiquel Raynal if (WARN_ON(oobavail < 0))
4744cfcc706cSMiquel Raynal return -EINVAL;
4745cfcc706cSMiquel Raynal
4746cfcc706cSMiquel Raynal if (!preset_step || !preset_strength)
4747cfcc706cSMiquel Raynal return -ENODATA;
4748cfcc706cSMiquel Raynal
4749cfcc706cSMiquel Raynal nsteps = mtd->writesize / preset_step;
4750cfcc706cSMiquel Raynal
4751cfcc706cSMiquel Raynal for (i = 0; i < caps->nstepinfos; i++) {
4752cfcc706cSMiquel Raynal stepinfo = &caps->stepinfos[i];
4753cfcc706cSMiquel Raynal
4754cfcc706cSMiquel Raynal if (stepinfo->stepsize != preset_step)
4755cfcc706cSMiquel Raynal continue;
4756cfcc706cSMiquel Raynal
4757cfcc706cSMiquel Raynal for (j = 0; j < stepinfo->nstrengths; j++) {
4758cfcc706cSMiquel Raynal if (stepinfo->strengths[j] != preset_strength)
4759cfcc706cSMiquel Raynal continue;
4760cfcc706cSMiquel Raynal
4761cfcc706cSMiquel Raynal ecc_bytes = caps->calc_ecc_bytes(preset_step,
4762cfcc706cSMiquel Raynal preset_strength);
4763cfcc706cSMiquel Raynal if (WARN_ON_ONCE(ecc_bytes < 0))
4764cfcc706cSMiquel Raynal return ecc_bytes;
4765cfcc706cSMiquel Raynal
4766cfcc706cSMiquel Raynal if (ecc_bytes * nsteps > oobavail) {
4767cfcc706cSMiquel Raynal pr_err("ECC (step, strength) = (%d, %d) does not fit in OOB",
4768cfcc706cSMiquel Raynal preset_step, preset_strength);
4769cfcc706cSMiquel Raynal return -ENOSPC;
4770cfcc706cSMiquel Raynal }
4771cfcc706cSMiquel Raynal
4772cfcc706cSMiquel Raynal chip->ecc.bytes = ecc_bytes;
4773cfcc706cSMiquel Raynal
4774cfcc706cSMiquel Raynal return 0;
4775cfcc706cSMiquel Raynal }
4776cfcc706cSMiquel Raynal }
4777cfcc706cSMiquel Raynal
4778cfcc706cSMiquel Raynal pr_err("ECC (step, strength) = (%d, %d) not supported on this controller",
4779cfcc706cSMiquel Raynal preset_step, preset_strength);
4780cfcc706cSMiquel Raynal
4781cfcc706cSMiquel Raynal return -ENOTSUPP;
4782cfcc706cSMiquel Raynal }
4783cfcc706cSMiquel Raynal EXPORT_SYMBOL_GPL(nand_check_ecc_caps);
4784cfcc706cSMiquel Raynal
4785cfcc706cSMiquel Raynal /**
4786cfcc706cSMiquel Raynal * nand_match_ecc_req - meet the chip's requirement with least ECC bytes
4787cfcc706cSMiquel Raynal * @chip: nand chip info structure
4788cfcc706cSMiquel Raynal * @caps: ECC engine caps info structure
4789cfcc706cSMiquel Raynal * @oobavail: OOB size that the ECC engine can use
4790cfcc706cSMiquel Raynal *
4791cfcc706cSMiquel Raynal * If a chip's ECC requirement is provided, try to meet it with the least
4792cfcc706cSMiquel Raynal * number of ECC bytes (i.e. with the largest number of OOB-free bytes).
4793cfcc706cSMiquel Raynal * On success, the chosen ECC settings are set.
4794cfcc706cSMiquel Raynal */
nand_match_ecc_req(struct nand_chip * chip,const struct nand_ecc_caps * caps,int oobavail)4795cfcc706cSMiquel Raynal int nand_match_ecc_req(struct nand_chip *chip,
4796cfcc706cSMiquel Raynal const struct nand_ecc_caps *caps, int oobavail)
4797cfcc706cSMiquel Raynal {
4798cfcc706cSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip);
4799cfcc706cSMiquel Raynal const struct nand_ecc_step_info *stepinfo;
4800cfcc706cSMiquel Raynal int req_step = chip->ecc_step_ds;
4801cfcc706cSMiquel Raynal int req_strength = chip->ecc_strength_ds;
4802cfcc706cSMiquel Raynal int req_corr, step_size, strength, nsteps, ecc_bytes, ecc_bytes_total;
4803cfcc706cSMiquel Raynal int best_step, best_strength, best_ecc_bytes;
4804cfcc706cSMiquel Raynal int best_ecc_bytes_total = INT_MAX;
4805cfcc706cSMiquel Raynal int i, j;
4806cfcc706cSMiquel Raynal
4807cfcc706cSMiquel Raynal if (WARN_ON(oobavail < 0))
4808cfcc706cSMiquel Raynal return -EINVAL;
4809cfcc706cSMiquel Raynal
4810cfcc706cSMiquel Raynal /* No information provided by the NAND chip */
4811cfcc706cSMiquel Raynal if (!req_step || !req_strength)
4812cfcc706cSMiquel Raynal return -ENOTSUPP;
4813cfcc706cSMiquel Raynal
4814cfcc706cSMiquel Raynal /* number of correctable bits the chip requires in a page */
4815cfcc706cSMiquel Raynal req_corr = mtd->writesize / req_step * req_strength;
4816cfcc706cSMiquel Raynal
4817cfcc706cSMiquel Raynal for (i = 0; i < caps->nstepinfos; i++) {
4818cfcc706cSMiquel Raynal stepinfo = &caps->stepinfos[i];
4819cfcc706cSMiquel Raynal step_size = stepinfo->stepsize;
4820cfcc706cSMiquel Raynal
4821cfcc706cSMiquel Raynal for (j = 0; j < stepinfo->nstrengths; j++) {
4822cfcc706cSMiquel Raynal strength = stepinfo->strengths[j];
4823cfcc706cSMiquel Raynal
4824cfcc706cSMiquel Raynal /*
4825cfcc706cSMiquel Raynal * If both step size and strength are smaller than the
4826cfcc706cSMiquel Raynal * chip's requirement, it is not easy to compare the
4827cfcc706cSMiquel Raynal * resulted reliability.
4828cfcc706cSMiquel Raynal */
4829cfcc706cSMiquel Raynal if (step_size < req_step && strength < req_strength)
4830cfcc706cSMiquel Raynal continue;
4831cfcc706cSMiquel Raynal
4832cfcc706cSMiquel Raynal if (mtd->writesize % step_size)
4833cfcc706cSMiquel Raynal continue;
4834cfcc706cSMiquel Raynal
4835cfcc706cSMiquel Raynal nsteps = mtd->writesize / step_size;
4836cfcc706cSMiquel Raynal
4837cfcc706cSMiquel Raynal ecc_bytes = caps->calc_ecc_bytes(step_size, strength);
4838cfcc706cSMiquel Raynal if (WARN_ON_ONCE(ecc_bytes < 0))
4839cfcc706cSMiquel Raynal continue;
4840cfcc706cSMiquel Raynal ecc_bytes_total = ecc_bytes * nsteps;
4841cfcc706cSMiquel Raynal
4842cfcc706cSMiquel Raynal if (ecc_bytes_total > oobavail ||
4843cfcc706cSMiquel Raynal strength * nsteps < req_corr)
4844cfcc706cSMiquel Raynal continue;
4845cfcc706cSMiquel Raynal
4846cfcc706cSMiquel Raynal /*
4847cfcc706cSMiquel Raynal * We assume the best is to meet the chip's requrement
4848cfcc706cSMiquel Raynal * with the least number of ECC bytes.
4849cfcc706cSMiquel Raynal */
4850cfcc706cSMiquel Raynal if (ecc_bytes_total < best_ecc_bytes_total) {
4851cfcc706cSMiquel Raynal best_ecc_bytes_total = ecc_bytes_total;
4852cfcc706cSMiquel Raynal best_step = step_size;
4853cfcc706cSMiquel Raynal best_strength = strength;
4854cfcc706cSMiquel Raynal best_ecc_bytes = ecc_bytes;
4855cfcc706cSMiquel Raynal }
4856cfcc706cSMiquel Raynal }
4857cfcc706cSMiquel Raynal }
4858cfcc706cSMiquel Raynal
4859cfcc706cSMiquel Raynal if (best_ecc_bytes_total == INT_MAX)
4860cfcc706cSMiquel Raynal return -ENOTSUPP;
4861cfcc706cSMiquel Raynal
4862cfcc706cSMiquel Raynal chip->ecc.size = best_step;
4863cfcc706cSMiquel Raynal chip->ecc.strength = best_strength;
4864cfcc706cSMiquel Raynal chip->ecc.bytes = best_ecc_bytes;
4865cfcc706cSMiquel Raynal
4866cfcc706cSMiquel Raynal return 0;
4867cfcc706cSMiquel Raynal }
4868cfcc706cSMiquel Raynal EXPORT_SYMBOL_GPL(nand_match_ecc_req);
4869cfcc706cSMiquel Raynal
4870cfcc706cSMiquel Raynal /**
4871cfcc706cSMiquel Raynal * nand_maximize_ecc - choose the max ECC strength available
4872cfcc706cSMiquel Raynal * @chip: nand chip info structure
4873cfcc706cSMiquel Raynal * @caps: ECC engine caps info structure
4874cfcc706cSMiquel Raynal * @oobavail: OOB size that the ECC engine can use
4875cfcc706cSMiquel Raynal *
4876cfcc706cSMiquel Raynal * Choose the max ECC strength that is supported on the controller, and can fit
4877cfcc706cSMiquel Raynal * within the chip's OOB. On success, the chosen ECC settings are set.
4878cfcc706cSMiquel Raynal */
nand_maximize_ecc(struct nand_chip * chip,const struct nand_ecc_caps * caps,int oobavail)4879cfcc706cSMiquel Raynal int nand_maximize_ecc(struct nand_chip *chip,
4880cfcc706cSMiquel Raynal const struct nand_ecc_caps *caps, int oobavail)
4881cfcc706cSMiquel Raynal {
4882cfcc706cSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip);
4883cfcc706cSMiquel Raynal const struct nand_ecc_step_info *stepinfo;
4884cfcc706cSMiquel Raynal int step_size, strength, nsteps, ecc_bytes, corr;
4885cfcc706cSMiquel Raynal int best_corr = 0;
4886cfcc706cSMiquel Raynal int best_step = 0;
4887cfcc706cSMiquel Raynal int best_strength, best_ecc_bytes;
4888cfcc706cSMiquel Raynal int i, j;
4889cfcc706cSMiquel Raynal
4890cfcc706cSMiquel Raynal if (WARN_ON(oobavail < 0))
4891cfcc706cSMiquel Raynal return -EINVAL;
4892cfcc706cSMiquel Raynal
4893cfcc706cSMiquel Raynal for (i = 0; i < caps->nstepinfos; i++) {
4894cfcc706cSMiquel Raynal stepinfo = &caps->stepinfos[i];
4895cfcc706cSMiquel Raynal step_size = stepinfo->stepsize;
4896cfcc706cSMiquel Raynal
4897cfcc706cSMiquel Raynal /* If chip->ecc.size is already set, respect it */
4898cfcc706cSMiquel Raynal if (chip->ecc.size && step_size != chip->ecc.size)
4899cfcc706cSMiquel Raynal continue;
4900cfcc706cSMiquel Raynal
4901cfcc706cSMiquel Raynal for (j = 0; j < stepinfo->nstrengths; j++) {
4902cfcc706cSMiquel Raynal strength = stepinfo->strengths[j];
4903cfcc706cSMiquel Raynal
4904cfcc706cSMiquel Raynal if (mtd->writesize % step_size)
4905cfcc706cSMiquel Raynal continue;
4906cfcc706cSMiquel Raynal
4907cfcc706cSMiquel Raynal nsteps = mtd->writesize / step_size;
4908cfcc706cSMiquel Raynal
4909cfcc706cSMiquel Raynal ecc_bytes = caps->calc_ecc_bytes(step_size, strength);
4910cfcc706cSMiquel Raynal if (WARN_ON_ONCE(ecc_bytes < 0))
4911cfcc706cSMiquel Raynal continue;
4912cfcc706cSMiquel Raynal
4913cfcc706cSMiquel Raynal if (ecc_bytes * nsteps > oobavail)
4914cfcc706cSMiquel Raynal continue;
4915cfcc706cSMiquel Raynal
4916cfcc706cSMiquel Raynal corr = strength * nsteps;
4917cfcc706cSMiquel Raynal
4918cfcc706cSMiquel Raynal /*
4919cfcc706cSMiquel Raynal * If the number of correctable bits is the same,
4920cfcc706cSMiquel Raynal * bigger step_size has more reliability.
4921cfcc706cSMiquel Raynal */
4922cfcc706cSMiquel Raynal if (corr > best_corr ||
4923cfcc706cSMiquel Raynal (corr == best_corr && step_size > best_step)) {
4924cfcc706cSMiquel Raynal best_corr = corr;
4925cfcc706cSMiquel Raynal best_step = step_size;
4926cfcc706cSMiquel Raynal best_strength = strength;
4927cfcc706cSMiquel Raynal best_ecc_bytes = ecc_bytes;
4928cfcc706cSMiquel Raynal }
4929cfcc706cSMiquel Raynal }
4930cfcc706cSMiquel Raynal }
4931cfcc706cSMiquel Raynal
4932cfcc706cSMiquel Raynal if (!best_corr)
4933cfcc706cSMiquel Raynal return -ENOTSUPP;
4934cfcc706cSMiquel Raynal
4935cfcc706cSMiquel Raynal chip->ecc.size = best_step;
4936cfcc706cSMiquel Raynal chip->ecc.strength = best_strength;
4937cfcc706cSMiquel Raynal chip->ecc.bytes = best_ecc_bytes;
4938cfcc706cSMiquel Raynal
4939cfcc706cSMiquel Raynal return 0;
4940cfcc706cSMiquel Raynal }
4941cfcc706cSMiquel Raynal EXPORT_SYMBOL_GPL(nand_maximize_ecc);
4942cfcc706cSMiquel Raynal
4943cfcc706cSMiquel Raynal /*
4944cfcc706cSMiquel Raynal * Check if the chip configuration meet the datasheet requirements.
4945cfcc706cSMiquel Raynal
4946cfcc706cSMiquel Raynal * If our configuration corrects A bits per B bytes and the minimum
4947cfcc706cSMiquel Raynal * required correction level is X bits per Y bytes, then we must ensure
4948cfcc706cSMiquel Raynal * both of the following are true:
4949cfcc706cSMiquel Raynal *
4950cfcc706cSMiquel Raynal * (1) A / B >= X / Y
4951cfcc706cSMiquel Raynal * (2) A >= X
4952cfcc706cSMiquel Raynal *
4953cfcc706cSMiquel Raynal * Requirement (1) ensures we can correct for the required bitflip density.
4954cfcc706cSMiquel Raynal * Requirement (2) ensures we can correct even when all bitflips are clumped
4955cfcc706cSMiquel Raynal * in the same sector.
4956cfcc706cSMiquel Raynal */
nand_ecc_strength_good(struct mtd_info * mtd)4957cfcc706cSMiquel Raynal static bool nand_ecc_strength_good(struct mtd_info *mtd)
4958cfcc706cSMiquel Raynal {
4959cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
4960cfcc706cSMiquel Raynal struct nand_ecc_ctrl *ecc = &chip->ecc;
4961cfcc706cSMiquel Raynal int corr, ds_corr;
4962cfcc706cSMiquel Raynal
4963cfcc706cSMiquel Raynal if (ecc->size == 0 || chip->ecc_step_ds == 0)
4964cfcc706cSMiquel Raynal /* Not enough information */
4965cfcc706cSMiquel Raynal return true;
4966cfcc706cSMiquel Raynal
4967cfcc706cSMiquel Raynal /*
4968cfcc706cSMiquel Raynal * We get the number of corrected bits per page to compare
4969cfcc706cSMiquel Raynal * the correction density.
4970cfcc706cSMiquel Raynal */
4971cfcc706cSMiquel Raynal corr = (mtd->writesize * ecc->strength) / ecc->size;
4972cfcc706cSMiquel Raynal ds_corr = (mtd->writesize * chip->ecc_strength_ds) / chip->ecc_step_ds;
4973cfcc706cSMiquel Raynal
4974cfcc706cSMiquel Raynal return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
4975cfcc706cSMiquel Raynal }
4976cfcc706cSMiquel Raynal
invalid_ecc_page_accessors(struct nand_chip * chip)4977cfcc706cSMiquel Raynal static bool invalid_ecc_page_accessors(struct nand_chip *chip)
4978cfcc706cSMiquel Raynal {
4979cfcc706cSMiquel Raynal struct nand_ecc_ctrl *ecc = &chip->ecc;
4980cfcc706cSMiquel Raynal
4981cfcc706cSMiquel Raynal if (nand_standard_page_accessors(ecc))
4982cfcc706cSMiquel Raynal return false;
4983cfcc706cSMiquel Raynal
4984cfcc706cSMiquel Raynal /*
4985cfcc706cSMiquel Raynal * NAND_ECC_CUSTOM_PAGE_ACCESS flag is set, make sure the NAND
4986cfcc706cSMiquel Raynal * controller driver implements all the page accessors because
4987cfcc706cSMiquel Raynal * default helpers are not suitable when the core does not
4988cfcc706cSMiquel Raynal * send the READ0/PAGEPROG commands.
4989cfcc706cSMiquel Raynal */
4990cfcc706cSMiquel Raynal return (!ecc->read_page || !ecc->write_page ||
4991cfcc706cSMiquel Raynal !ecc->read_page_raw || !ecc->write_page_raw ||
4992cfcc706cSMiquel Raynal (NAND_HAS_SUBPAGE_READ(chip) && !ecc->read_subpage) ||
4993cfcc706cSMiquel Raynal (NAND_HAS_SUBPAGE_WRITE(chip) && !ecc->write_subpage &&
4994cfcc706cSMiquel Raynal ecc->hwctl && ecc->calculate));
4995cfcc706cSMiquel Raynal }
4996cfcc706cSMiquel Raynal
4997cfcc706cSMiquel Raynal /**
4998cfcc706cSMiquel Raynal * nand_scan_tail - [NAND Interface] Scan for the NAND device
4999cfcc706cSMiquel Raynal * @mtd: MTD device structure
5000cfcc706cSMiquel Raynal *
5001cfcc706cSMiquel Raynal * This is the second phase of the normal nand_scan() function. It fills out
5002cfcc706cSMiquel Raynal * all the uninitialized function pointers with the defaults and scans for a
5003cfcc706cSMiquel Raynal * bad block table if appropriate.
5004cfcc706cSMiquel Raynal */
nand_scan_tail(struct mtd_info * mtd)5005cfcc706cSMiquel Raynal int nand_scan_tail(struct mtd_info *mtd)
5006cfcc706cSMiquel Raynal {
5007cfcc706cSMiquel Raynal int i;
5008cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
5009cfcc706cSMiquel Raynal struct nand_ecc_ctrl *ecc = &chip->ecc;
5010cfcc706cSMiquel Raynal struct nand_buffers *nbuf;
5011cfcc706cSMiquel Raynal
5012cfcc706cSMiquel Raynal /* New bad blocks should be marked in OOB, flash-based BBT, or both */
5013cfcc706cSMiquel Raynal BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
5014cfcc706cSMiquel Raynal !(chip->bbt_options & NAND_BBT_USE_FLASH));
5015cfcc706cSMiquel Raynal
5016cfcc706cSMiquel Raynal if (invalid_ecc_page_accessors(chip)) {
5017cfcc706cSMiquel Raynal pr_err("Invalid ECC page accessors setup\n");
5018cfcc706cSMiquel Raynal return -EINVAL;
5019cfcc706cSMiquel Raynal }
5020cfcc706cSMiquel Raynal
5021cfcc706cSMiquel Raynal if (!(chip->options & NAND_OWN_BUFFERS)) {
5022cfcc706cSMiquel Raynal nbuf = kzalloc(sizeof(struct nand_buffers), GFP_KERNEL);
5023cfcc706cSMiquel Raynal chip->buffers = nbuf;
5024cfcc706cSMiquel Raynal } else {
5025cfcc706cSMiquel Raynal if (!chip->buffers)
5026cfcc706cSMiquel Raynal return -ENOMEM;
5027cfcc706cSMiquel Raynal }
5028cfcc706cSMiquel Raynal
5029cfcc706cSMiquel Raynal /* Set the internal oob buffer location, just after the page data */
5030cfcc706cSMiquel Raynal chip->oob_poi = chip->buffers->databuf + mtd->writesize;
5031cfcc706cSMiquel Raynal
5032cfcc706cSMiquel Raynal /*
5033cfcc706cSMiquel Raynal * If no default placement scheme is given, select an appropriate one.
5034cfcc706cSMiquel Raynal */
5035cfcc706cSMiquel Raynal if (!ecc->layout && (ecc->mode != NAND_ECC_SOFT_BCH)) {
5036cfcc706cSMiquel Raynal switch (mtd->oobsize) {
5037*0cc120e3SGregory CLEMENT #ifndef CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT
5038cfcc706cSMiquel Raynal case 8:
5039cfcc706cSMiquel Raynal ecc->layout = &nand_oob_8;
5040cfcc706cSMiquel Raynal break;
5041cfcc706cSMiquel Raynal case 16:
5042cfcc706cSMiquel Raynal ecc->layout = &nand_oob_16;
5043cfcc706cSMiquel Raynal break;
5044cfcc706cSMiquel Raynal case 64:
5045cfcc706cSMiquel Raynal ecc->layout = &nand_oob_64;
5046cfcc706cSMiquel Raynal break;
5047cfcc706cSMiquel Raynal case 128:
5048cfcc706cSMiquel Raynal ecc->layout = &nand_oob_128;
5049cfcc706cSMiquel Raynal break;
505050c9e2f7SStefan Agner #endif
5051cfcc706cSMiquel Raynal default:
5052cfcc706cSMiquel Raynal pr_warn("No oob scheme defined for oobsize %d\n",
5053cfcc706cSMiquel Raynal mtd->oobsize);
5054cfcc706cSMiquel Raynal BUG();
5055cfcc706cSMiquel Raynal }
5056cfcc706cSMiquel Raynal }
5057cfcc706cSMiquel Raynal
5058cfcc706cSMiquel Raynal if (!chip->write_page)
5059cfcc706cSMiquel Raynal chip->write_page = nand_write_page;
5060cfcc706cSMiquel Raynal
5061cfcc706cSMiquel Raynal /*
5062cfcc706cSMiquel Raynal * Check ECC mode, default to software if 3byte/512byte hardware ECC is
5063cfcc706cSMiquel Raynal * selected and we have 256 byte pagesize fallback to software ECC
5064cfcc706cSMiquel Raynal */
5065cfcc706cSMiquel Raynal
5066cfcc706cSMiquel Raynal switch (ecc->mode) {
5067cfcc706cSMiquel Raynal case NAND_ECC_HW_OOB_FIRST:
5068cfcc706cSMiquel Raynal /* Similar to NAND_ECC_HW, but a separate read_page handle */
5069cfcc706cSMiquel Raynal if (!ecc->calculate || !ecc->correct || !ecc->hwctl) {
5070cfcc706cSMiquel Raynal pr_warn("No ECC functions supplied; hardware ECC not possible\n");
5071cfcc706cSMiquel Raynal BUG();
5072cfcc706cSMiquel Raynal }
5073cfcc706cSMiquel Raynal if (!ecc->read_page)
5074cfcc706cSMiquel Raynal ecc->read_page = nand_read_page_hwecc_oob_first;
5075cfcc706cSMiquel Raynal
5076cfcc706cSMiquel Raynal case NAND_ECC_HW:
5077cfcc706cSMiquel Raynal /* Use standard hwecc read page function? */
5078cfcc706cSMiquel Raynal if (!ecc->read_page)
5079cfcc706cSMiquel Raynal ecc->read_page = nand_read_page_hwecc;
5080cfcc706cSMiquel Raynal if (!ecc->write_page)
5081cfcc706cSMiquel Raynal ecc->write_page = nand_write_page_hwecc;
5082cfcc706cSMiquel Raynal if (!ecc->read_page_raw)
5083cfcc706cSMiquel Raynal ecc->read_page_raw = nand_read_page_raw;
5084cfcc706cSMiquel Raynal if (!ecc->write_page_raw)
5085cfcc706cSMiquel Raynal ecc->write_page_raw = nand_write_page_raw;
5086cfcc706cSMiquel Raynal if (!ecc->read_oob)
5087cfcc706cSMiquel Raynal ecc->read_oob = nand_read_oob_std;
5088cfcc706cSMiquel Raynal if (!ecc->write_oob)
5089cfcc706cSMiquel Raynal ecc->write_oob = nand_write_oob_std;
5090cfcc706cSMiquel Raynal if (!ecc->read_subpage)
5091cfcc706cSMiquel Raynal ecc->read_subpage = nand_read_subpage;
5092cfcc706cSMiquel Raynal if (!ecc->write_subpage && ecc->hwctl && ecc->calculate)
5093cfcc706cSMiquel Raynal ecc->write_subpage = nand_write_subpage_hwecc;
5094cfcc706cSMiquel Raynal
5095cfcc706cSMiquel Raynal case NAND_ECC_HW_SYNDROME:
5096cfcc706cSMiquel Raynal if ((!ecc->calculate || !ecc->correct || !ecc->hwctl) &&
5097cfcc706cSMiquel Raynal (!ecc->read_page ||
5098cfcc706cSMiquel Raynal ecc->read_page == nand_read_page_hwecc ||
5099cfcc706cSMiquel Raynal !ecc->write_page ||
5100cfcc706cSMiquel Raynal ecc->write_page == nand_write_page_hwecc)) {
5101cfcc706cSMiquel Raynal pr_warn("No ECC functions supplied; hardware ECC not possible\n");
5102cfcc706cSMiquel Raynal BUG();
5103cfcc706cSMiquel Raynal }
5104cfcc706cSMiquel Raynal /* Use standard syndrome read/write page function? */
5105cfcc706cSMiquel Raynal if (!ecc->read_page)
5106cfcc706cSMiquel Raynal ecc->read_page = nand_read_page_syndrome;
5107cfcc706cSMiquel Raynal if (!ecc->write_page)
5108cfcc706cSMiquel Raynal ecc->write_page = nand_write_page_syndrome;
5109cfcc706cSMiquel Raynal if (!ecc->read_page_raw)
5110cfcc706cSMiquel Raynal ecc->read_page_raw = nand_read_page_raw_syndrome;
5111cfcc706cSMiquel Raynal if (!ecc->write_page_raw)
5112cfcc706cSMiquel Raynal ecc->write_page_raw = nand_write_page_raw_syndrome;
5113cfcc706cSMiquel Raynal if (!ecc->read_oob)
5114cfcc706cSMiquel Raynal ecc->read_oob = nand_read_oob_syndrome;
5115cfcc706cSMiquel Raynal if (!ecc->write_oob)
5116cfcc706cSMiquel Raynal ecc->write_oob = nand_write_oob_syndrome;
5117cfcc706cSMiquel Raynal
5118cfcc706cSMiquel Raynal if (mtd->writesize >= ecc->size) {
5119cfcc706cSMiquel Raynal if (!ecc->strength) {
5120cfcc706cSMiquel Raynal pr_warn("Driver must set ecc.strength when using hardware ECC\n");
5121cfcc706cSMiquel Raynal BUG();
5122cfcc706cSMiquel Raynal }
5123cfcc706cSMiquel Raynal break;
5124cfcc706cSMiquel Raynal }
5125cfcc706cSMiquel Raynal pr_warn("%d byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
5126cfcc706cSMiquel Raynal ecc->size, mtd->writesize);
5127cfcc706cSMiquel Raynal ecc->mode = NAND_ECC_SOFT;
5128cfcc706cSMiquel Raynal
5129cfcc706cSMiquel Raynal case NAND_ECC_SOFT:
5130cfcc706cSMiquel Raynal ecc->calculate = nand_calculate_ecc;
5131cfcc706cSMiquel Raynal ecc->correct = nand_correct_data;
5132cfcc706cSMiquel Raynal ecc->read_page = nand_read_page_swecc;
5133cfcc706cSMiquel Raynal ecc->read_subpage = nand_read_subpage;
5134cfcc706cSMiquel Raynal ecc->write_page = nand_write_page_swecc;
5135cfcc706cSMiquel Raynal ecc->read_page_raw = nand_read_page_raw;
5136cfcc706cSMiquel Raynal ecc->write_page_raw = nand_write_page_raw;
5137cfcc706cSMiquel Raynal ecc->read_oob = nand_read_oob_std;
5138cfcc706cSMiquel Raynal ecc->write_oob = nand_write_oob_std;
5139cfcc706cSMiquel Raynal if (!ecc->size)
5140cfcc706cSMiquel Raynal ecc->size = 256;
5141cfcc706cSMiquel Raynal ecc->bytes = 3;
5142cfcc706cSMiquel Raynal ecc->strength = 1;
5143cfcc706cSMiquel Raynal break;
5144cfcc706cSMiquel Raynal
5145cfcc706cSMiquel Raynal case NAND_ECC_SOFT_BCH:
5146cfcc706cSMiquel Raynal if (!mtd_nand_has_bch()) {
5147cfcc706cSMiquel Raynal pr_warn("CONFIG_MTD_NAND_ECC_BCH not enabled\n");
5148cfcc706cSMiquel Raynal BUG();
5149cfcc706cSMiquel Raynal }
5150cfcc706cSMiquel Raynal ecc->calculate = nand_bch_calculate_ecc;
5151cfcc706cSMiquel Raynal ecc->correct = nand_bch_correct_data;
5152cfcc706cSMiquel Raynal ecc->read_page = nand_read_page_swecc;
5153cfcc706cSMiquel Raynal ecc->read_subpage = nand_read_subpage;
5154cfcc706cSMiquel Raynal ecc->write_page = nand_write_page_swecc;
5155cfcc706cSMiquel Raynal ecc->read_page_raw = nand_read_page_raw;
5156cfcc706cSMiquel Raynal ecc->write_page_raw = nand_write_page_raw;
5157cfcc706cSMiquel Raynal ecc->read_oob = nand_read_oob_std;
5158cfcc706cSMiquel Raynal ecc->write_oob = nand_write_oob_std;
5159cfcc706cSMiquel Raynal /*
5160cfcc706cSMiquel Raynal * Board driver should supply ecc.size and ecc.strength values
5161cfcc706cSMiquel Raynal * to select how many bits are correctable. Otherwise, default
5162cfcc706cSMiquel Raynal * to 4 bits for large page devices.
5163cfcc706cSMiquel Raynal */
5164cfcc706cSMiquel Raynal if (!ecc->size && (mtd->oobsize >= 64)) {
5165cfcc706cSMiquel Raynal ecc->size = 512;
5166cfcc706cSMiquel Raynal ecc->strength = 4;
5167cfcc706cSMiquel Raynal }
5168cfcc706cSMiquel Raynal
5169cfcc706cSMiquel Raynal /* See nand_bch_init() for details. */
5170cfcc706cSMiquel Raynal ecc->bytes = 0;
5171cfcc706cSMiquel Raynal ecc->priv = nand_bch_init(mtd);
5172cfcc706cSMiquel Raynal if (!ecc->priv) {
5173cfcc706cSMiquel Raynal pr_warn("BCH ECC initialization failed!\n");
5174cfcc706cSMiquel Raynal BUG();
5175cfcc706cSMiquel Raynal }
5176cfcc706cSMiquel Raynal break;
5177cfcc706cSMiquel Raynal
5178cfcc706cSMiquel Raynal case NAND_ECC_NONE:
5179cfcc706cSMiquel Raynal pr_warn("NAND_ECC_NONE selected by board driver. This is not recommended!\n");
5180cfcc706cSMiquel Raynal ecc->read_page = nand_read_page_raw;
5181cfcc706cSMiquel Raynal ecc->write_page = nand_write_page_raw;
5182cfcc706cSMiquel Raynal ecc->read_oob = nand_read_oob_std;
5183cfcc706cSMiquel Raynal ecc->read_page_raw = nand_read_page_raw;
5184cfcc706cSMiquel Raynal ecc->write_page_raw = nand_write_page_raw;
5185cfcc706cSMiquel Raynal ecc->write_oob = nand_write_oob_std;
5186cfcc706cSMiquel Raynal ecc->size = mtd->writesize;
5187cfcc706cSMiquel Raynal ecc->bytes = 0;
5188cfcc706cSMiquel Raynal ecc->strength = 0;
5189cfcc706cSMiquel Raynal break;
5190cfcc706cSMiquel Raynal
5191cfcc706cSMiquel Raynal default:
5192cfcc706cSMiquel Raynal pr_warn("Invalid NAND_ECC_MODE %d\n", ecc->mode);
5193cfcc706cSMiquel Raynal BUG();
5194cfcc706cSMiquel Raynal }
5195cfcc706cSMiquel Raynal
5196cfcc706cSMiquel Raynal /* For many systems, the standard OOB write also works for raw */
5197cfcc706cSMiquel Raynal if (!ecc->read_oob_raw)
5198cfcc706cSMiquel Raynal ecc->read_oob_raw = ecc->read_oob;
5199cfcc706cSMiquel Raynal if (!ecc->write_oob_raw)
5200cfcc706cSMiquel Raynal ecc->write_oob_raw = ecc->write_oob;
5201cfcc706cSMiquel Raynal
5202cfcc706cSMiquel Raynal /*
5203cfcc706cSMiquel Raynal * The number of bytes available for a client to place data into
5204cfcc706cSMiquel Raynal * the out of band area.
5205cfcc706cSMiquel Raynal */
5206cfcc706cSMiquel Raynal mtd->oobavail = 0;
5207cfcc706cSMiquel Raynal if (ecc->layout) {
5208cfcc706cSMiquel Raynal for (i = 0; ecc->layout->oobfree[i].length; i++)
5209cfcc706cSMiquel Raynal mtd->oobavail += ecc->layout->oobfree[i].length;
5210cfcc706cSMiquel Raynal }
5211cfcc706cSMiquel Raynal
5212cfcc706cSMiquel Raynal /* ECC sanity check: warn if it's too weak */
5213cfcc706cSMiquel Raynal if (!nand_ecc_strength_good(mtd))
5214cfcc706cSMiquel Raynal pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n",
5215cfcc706cSMiquel Raynal mtd->name);
5216cfcc706cSMiquel Raynal
5217cfcc706cSMiquel Raynal /*
5218cfcc706cSMiquel Raynal * Set the number of read / write steps for one page depending on ECC
5219cfcc706cSMiquel Raynal * mode.
5220cfcc706cSMiquel Raynal */
5221cfcc706cSMiquel Raynal ecc->steps = mtd->writesize / ecc->size;
5222cfcc706cSMiquel Raynal if (ecc->steps * ecc->size != mtd->writesize) {
5223cfcc706cSMiquel Raynal pr_warn("Invalid ECC parameters\n");
5224cfcc706cSMiquel Raynal BUG();
5225cfcc706cSMiquel Raynal }
5226cfcc706cSMiquel Raynal ecc->total = ecc->steps * ecc->bytes;
5227cfcc706cSMiquel Raynal
5228cfcc706cSMiquel Raynal /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
5229cfcc706cSMiquel Raynal if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
5230cfcc706cSMiquel Raynal switch (ecc->steps) {
5231cfcc706cSMiquel Raynal case 2:
5232cfcc706cSMiquel Raynal mtd->subpage_sft = 1;
5233cfcc706cSMiquel Raynal break;
5234cfcc706cSMiquel Raynal case 4:
5235cfcc706cSMiquel Raynal case 8:
5236cfcc706cSMiquel Raynal case 16:
5237cfcc706cSMiquel Raynal mtd->subpage_sft = 2;
5238cfcc706cSMiquel Raynal break;
5239cfcc706cSMiquel Raynal }
5240cfcc706cSMiquel Raynal }
5241cfcc706cSMiquel Raynal chip->subpagesize = mtd->writesize >> mtd->subpage_sft;
5242cfcc706cSMiquel Raynal
5243cfcc706cSMiquel Raynal /* Initialize state */
5244cfcc706cSMiquel Raynal chip->state = FL_READY;
5245cfcc706cSMiquel Raynal
5246cfcc706cSMiquel Raynal /* Invalidate the pagebuffer reference */
5247cfcc706cSMiquel Raynal chip->pagebuf = -1;
5248cfcc706cSMiquel Raynal
5249cfcc706cSMiquel Raynal /* Large page NAND with SOFT_ECC should support subpage reads */
5250cfcc706cSMiquel Raynal switch (ecc->mode) {
5251cfcc706cSMiquel Raynal case NAND_ECC_SOFT:
5252cfcc706cSMiquel Raynal case NAND_ECC_SOFT_BCH:
5253cfcc706cSMiquel Raynal if (chip->page_shift > 9)
5254cfcc706cSMiquel Raynal chip->options |= NAND_SUBPAGE_READ;
5255cfcc706cSMiquel Raynal break;
5256cfcc706cSMiquel Raynal
5257cfcc706cSMiquel Raynal default:
5258cfcc706cSMiquel Raynal break;
5259cfcc706cSMiquel Raynal }
5260cfcc706cSMiquel Raynal
5261cfcc706cSMiquel Raynal /* Fill in remaining MTD driver data */
5262cfcc706cSMiquel Raynal mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH;
5263cfcc706cSMiquel Raynal mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
5264cfcc706cSMiquel Raynal MTD_CAP_NANDFLASH;
5265cfcc706cSMiquel Raynal mtd->_erase = nand_erase;
5266cfcc706cSMiquel Raynal mtd->_panic_write = panic_nand_write;
5267cfcc706cSMiquel Raynal mtd->_read_oob = nand_read_oob;
5268cfcc706cSMiquel Raynal mtd->_write_oob = nand_write_oob;
5269cfcc706cSMiquel Raynal mtd->_sync = nand_sync;
5270cfcc706cSMiquel Raynal mtd->_lock = NULL;
5271cfcc706cSMiquel Raynal mtd->_unlock = NULL;
5272cfcc706cSMiquel Raynal mtd->_block_isreserved = nand_block_isreserved;
5273cfcc706cSMiquel Raynal mtd->_block_isbad = nand_block_isbad;
5274cfcc706cSMiquel Raynal mtd->_block_markbad = nand_block_markbad;
5275cfcc706cSMiquel Raynal mtd->writebufsize = mtd->writesize;
5276cfcc706cSMiquel Raynal
5277cfcc706cSMiquel Raynal /* propagate ecc info to mtd_info */
5278cfcc706cSMiquel Raynal mtd->ecclayout = ecc->layout;
5279cfcc706cSMiquel Raynal mtd->ecc_strength = ecc->strength;
5280cfcc706cSMiquel Raynal mtd->ecc_step_size = ecc->size;
5281cfcc706cSMiquel Raynal /*
5282cfcc706cSMiquel Raynal * Initialize bitflip_threshold to its default prior scan_bbt() call.
5283cfcc706cSMiquel Raynal * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be
5284cfcc706cSMiquel Raynal * properly set.
5285cfcc706cSMiquel Raynal */
5286cfcc706cSMiquel Raynal if (!mtd->bitflip_threshold)
5287cfcc706cSMiquel Raynal mtd->bitflip_threshold = DIV_ROUND_UP(mtd->ecc_strength * 3, 4);
5288cfcc706cSMiquel Raynal
5289cfcc706cSMiquel Raynal return 0;
5290cfcc706cSMiquel Raynal }
5291cfcc706cSMiquel Raynal EXPORT_SYMBOL(nand_scan_tail);
5292cfcc706cSMiquel Raynal
5293cfcc706cSMiquel Raynal /**
5294cfcc706cSMiquel Raynal * nand_scan - [NAND Interface] Scan for the NAND device
5295cfcc706cSMiquel Raynal * @mtd: MTD device structure
5296cfcc706cSMiquel Raynal * @maxchips: number of chips to scan for
5297cfcc706cSMiquel Raynal *
5298cfcc706cSMiquel Raynal * This fills out all the uninitialized function pointers with the defaults.
5299cfcc706cSMiquel Raynal * The flash ID is read and the mtd/chip structures are filled with the
5300cfcc706cSMiquel Raynal * appropriate values.
5301cfcc706cSMiquel Raynal */
nand_scan(struct mtd_info * mtd,int maxchips)5302cfcc706cSMiquel Raynal int nand_scan(struct mtd_info *mtd, int maxchips)
5303cfcc706cSMiquel Raynal {
5304cfcc706cSMiquel Raynal int ret;
5305cfcc706cSMiquel Raynal
5306cfcc706cSMiquel Raynal ret = nand_scan_ident(mtd, maxchips, NULL);
5307cfcc706cSMiquel Raynal if (!ret)
5308cfcc706cSMiquel Raynal ret = nand_scan_tail(mtd);
5309cfcc706cSMiquel Raynal return ret;
5310cfcc706cSMiquel Raynal }
5311cfcc706cSMiquel Raynal EXPORT_SYMBOL(nand_scan);
5312cfcc706cSMiquel Raynal
5313cfcc706cSMiquel Raynal MODULE_LICENSE("GPL");
5314cfcc706cSMiquel Raynal MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
5315cfcc706cSMiquel Raynal MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
5316cfcc706cSMiquel Raynal MODULE_DESCRIPTION("Generic NAND flash driver code");
5317