aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand
diff options
context:
space:
mode:
authorKyungmin Park <kyungmin.park@samsung.com>2005-07-11 06:41:53 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 15:17:24 -0500
commitcd5f6346bc28a41375412b49b290d22ee4e4bbe8 (patch)
treee90e028e7319f2787fd8660d10d8455aba95ddc5 /drivers/mtd/onenand
parent4ce1f562189696605a84813cf71847c0cc698414 (diff)
[MTD] Add initial support for OneNAND flash chips
OneNAND is a new flash technology from Samsung with integrated SRAM buffers and logic interface. Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/mtd/onenand')
-rw-r--r--drivers/mtd/onenand/Kconfig32
-rw-r--r--drivers/mtd/onenand/Makefile9
-rw-r--r--drivers/mtd/onenand/omap-onenand.c178
-rw-r--r--drivers/mtd/onenand/onenand_base.c1462
4 files changed, 1681 insertions, 0 deletions
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
new file mode 100644
index 000000000000..7d76ede984d8
--- /dev/null
+++ b/drivers/mtd/onenand/Kconfig
@@ -0,0 +1,32 @@
1#
2# linux/drivers/mtd/onenand/Kconfig
3#
4
5menu "OneNAND Flash Device Drivers (EXPERIMENTAL)"
6 depends on MTD != n && EXPERIMENTAL
7
8config MTD_ONENAND
9 tristate "OneNAND Device Support"
10 depends on MTD
11 help
12 This enables support for accessing all type of OneNAND flash
13 devices. For further information see
14 <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
15
16config MTD_ONENAND_VERIFY_WRITE
17 bool "Verify OneNAND page writes"
18 depends on MTD_ONENAND
19 help
20 This adds an extra check when data is written to the flash. The
21 OneNAND flash device internally checks only bits transitioning
22 from 1 to 0. There is a rare possibility that even though the
23 device thinks the write was successful, a bit could have been
24 flipped accidentaly due to device wear or something else.
25
26config MTD_ONENAND_OMAP
27 tristate "OneNAND Flash device on OMAP board"
28 depends on ARCH_OMAP && MTD_ONENAND
29 help
30 Support for OneNAND flash on TI OMAP board.
31
32endmenu
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
new file mode 100644
index 000000000000..f4e75864d8b5
--- /dev/null
+++ b/drivers/mtd/onenand/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the OneNAND MTD
3#
4
5# Core functionality.
6obj-$(CONFIG_MTD_ONENAND) += onenand_base.o
7
8# Board specific.
9obj-$(CONFIG_MTD_ONENAND_OMAP) += omap-onenand.o
diff --git a/drivers/mtd/onenand/omap-onenand.c b/drivers/mtd/onenand/omap-onenand.c
new file mode 100644
index 000000000000..56e1aec6b835
--- /dev/null
+++ b/drivers/mtd/onenand/omap-onenand.c
@@ -0,0 +1,178 @@
1/*
2 * linux/drivers/mtd/onenand/omap-onenand.c
3 *
4 * Copyright (c) 2005 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * Derived from linux/drivers/mtd/nand/omap-nand-flash.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Overview:
14 * This is a device driver for the OneNAND flash device for TI OMAP boards.
15 */
16
17#include <linux/slab.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/onenand.h>
22#include <linux/mtd/partitions.h>
23
24#include <asm/io.h>
25#include <asm/arch/hardware.h>
26#include <asm/arch/tc.h>
27#include <asm/sizes.h>
28
29#define OMAP_ONENAND_FLASH_START1 OMAP_CS2A_PHYS
30#define OMAP_ONENAND_FLASH_START2 OMAP_CS0_PHYS
31/*
32 * MTD structure for OMAP board
33 */
34static struct mtd_info *omap_onenand_mtd = NULL;
35
36/*
37 * Define partitions for flash devices
38 */
39
40#ifdef CONFIG_MTD_PARTITIONS
41static struct mtd_partition static_partition[] = {
42 {
43 .name = "X-Loader + U-Boot",
44 .offset = 0,
45 .size = SZ_128K,
46 .mask_flags = MTD_WRITEABLE /* force read-only */
47 },
48 {
49 .name = "U-Boot Environment",
50 .offset = MTDPART_OFS_APPEND,
51 .size = SZ_128K,
52 .mask_flags = MTD_WRITEABLE /* force read-only */
53 },
54 {
55 .name = "kernel",
56 .offset = MTDPART_OFS_APPEND,
57 .size = 2 * SZ_1M
58 },
59 {
60 .name = "filesystem0",
61 .offset = MTDPART_OFS_APPEND,
62 .size = SZ_16M,
63 },
64 {
65 .name = "filesystem1",
66 .offset = MTDPART_OFS_APPEND,
67 .size = MTDPART_SIZ_FULL,
68 },
69};
70
71const char *part_probes[] = { "cmdlinepart", NULL, };
72
73#endif
74
75/* Scan to find existance of the device at base.
76 This also allocates oob and data internal buffers */
77static char onenand_name[] = "onenand";
78
79/*
80 * Main initialization routine
81 */
82static int __init omap_onenand_init (void)
83{
84 struct onenand_chip *this;
85 struct mtd_partition *dynamic_partition = 0;
86 int err = 0;
87
88 /* Allocate memory for MTD device structure and private data */
89 omap_onenand_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct onenand_chip),
90 GFP_KERNEL);
91 if (!omap_onenand_mtd) {
92 printk (KERN_WARNING "Unable to allocate OneNAND MTD device structure.\n");
93 err = -ENOMEM;
94 goto out;
95 }
96
97 /* Get pointer to private data */
98 this = (struct onenand_chip *) (&omap_onenand_mtd[1]);
99
100 /* Initialize structures */
101 memset((char *) omap_onenand_mtd, 0, sizeof(struct mtd_info) + sizeof(struct onenand_chip));
102
103 /* Link the private data with the MTD structure */
104 omap_onenand_mtd->priv = this;
105
106 /* try the first address */
107 this->base = ioremap(OMAP_ONENAND_FLASH_START1, SZ_128K);
108 omap_onenand_mtd->name = onenand_name;
109 if (onenand_scan(omap_onenand_mtd, 1)){
110 /* try the second address */
111 iounmap(this->base);
112 this->base = ioremap(OMAP_ONENAND_FLASH_START2, SZ_128K);
113 if (onenand_scan(omap_onenand_mtd, 1)) {
114 iounmap(this->base);
115 err = -ENXIO;
116 goto out_mtd;
117 }
118 }
119
120 /* Register the partitions */
121 switch (omap_onenand_mtd->size) {
122 case SZ_128M:
123 case SZ_64M:
124 case SZ_32M:
125#ifdef CONFIG_MTD_PARTITIONS
126 err = parse_mtd_partitions(omap_onenand_mtd, part_probes,
127 &dynamic_partition, 0);
128 if (err > 0)
129 err = add_mtd_partitions(omap_onenand_mtd,
130 dynamic_partition, err);
131 else if (1)
132 err = add_mtd_partitions(omap_onenand_mtd,
133 static_partition,
134 ARRAY_SIZE(static_partition));
135 else
136#endif
137 err = add_mtd_device(omap_onenand_mtd);
138 if (err)
139 goto out_buf;
140 break;
141
142 default:
143 printk(KERN_WARNING "Unsupported OneNAND device\n");
144 err = -ENXIO;
145 goto out_buf;
146 }
147
148 return 0;
149
150out_buf:
151 onenand_release(omap_onenand_mtd);
152 iounmap(this->base);
153out_mtd:
154 kfree(omap_onenand_mtd);
155out:
156 return err;
157}
158
159/*
160 * Clean up routine
161 */
162static void __exit omap_onenand_cleanup (void)
163{
164 struct onenand_chip *this = omap_onenand_mtd->priv;
165
166 /* onenand_release frees MTD partitions, MTD structure
167 and onenand internal buffers */
168 onenand_release(omap_onenand_mtd);
169 iounmap(this->base);
170 kfree(omap_onenand_mtd);
171}
172
173module_init(omap_onenand_init);
174module_exit(omap_onenand_cleanup);
175
176MODULE_LICENSE("GPL");
177MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
178MODULE_DESCRIPTION("Glue layer for OneNAND flash on OMAP boards");
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
new file mode 100644
index 000000000000..bcce22ae3cb1
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -0,0 +1,1462 @@
1/*
2 * linux/drivers/mtd/onenand/onenand_base.c
3 *
4 * Copyright (C) 2005 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/mtd/mtd.h>
16#include <linux/mtd/onenand.h>
17#include <linux/mtd/partitions.h>
18
19#include <asm/io.h>
20
21/**
22 * onenand_oob_64 - oob info for large (2KB) page
23 */
24static struct nand_oobinfo onenand_oob_64 = {
25 .useecc = MTD_NANDECC_AUTOPLACE,
26 .eccbytes = 20,
27 .eccpos = {
28 8, 9, 10, 11, 12,
29 24, 25, 26, 27, 28,
30 40, 41, 42, 43, 44,
31 56, 57, 58, 59, 60,
32 },
33 .oobfree = {
34 {2, 3}, {14, 2}, {18, 3}, {30, 2},
35 {24, 3}, {46, 2}, {40, 3}, {62, 2} }
36};
37
38/**
39 * onenand_oob_32 - oob info for middle (1KB) page
40 */
41static struct nand_oobinfo onenand_oob_32 = {
42 .useecc = MTD_NANDECC_AUTOPLACE,
43 .eccbytes = 10,
44 .eccpos = {
45 8, 9, 10, 11, 12,
46 24, 25, 26, 27, 28,
47 },
48 .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
49};
50
51static const unsigned char ffchars[] = {
52 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
55 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
56 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
57 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
58 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
59 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
60};
61
62/**
63 * onenand_readw - [OneNAND Interface] Read OneNAND register
64 * @param addr address to read
65 *
66 * Read OneNAND register
67 */
68static unsigned short onenand_readw(void __iomem *addr)
69{
70 return readw(addr);
71}
72
73/**
74 * onenand_writew - [OneNAND Interface] Write OneNAND register with value
75 * @param value value to write
76 * @param addr address to write
77 *
78 * Write OneNAND register with value
79 */
80static void onenand_writew(unsigned short value, void __iomem *addr)
81{
82 writew(value, addr);
83}
84
85/**
86 * onenand_block_address - [DEFAULT] Get block address
87 * @param device the device id
88 * @param block the block
89 * @return translated block address if DDP, otherwise same
90 *
91 * Setup Start Address 1 Register (F100h)
92 */
93static int onenand_block_address(int device, int block)
94{
95 if (device & ONENAND_DEVICE_IS_DDP) {
96 /* Device Flash Core select, NAND Flash Block Address */
97 int dfs = 0, density, mask;
98
99 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
100 mask = (1 << (density + 6));
101
102 if (block & mask)
103 dfs = 1;
104
105 return (dfs << ONENAND_DDP_SHIFT) | (block & (mask - 1));
106 }
107
108 return block;
109}
110
111/**
112 * onenand_bufferram_address - [DEFAULT] Get bufferram address
113 * @param device the device id
114 * @param block the block
115 * @return set DBS value if DDP, otherwise 0
116 *
117 * Setup Start Address 2 Register (F101h) for DDP
118 */
119static int onenand_bufferram_address(int device, int block)
120{
121 if (device & ONENAND_DEVICE_IS_DDP) {
122 /* Device BufferRAM Select */
123 int dbs = 0, density, mask;
124
125 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
126 mask = (1 << (density + 6));
127
128 if (block & mask)
129 dbs = 1;
130
131 return (dbs << ONENAND_DDP_SHIFT);
132 }
133
134 return 0;
135}
136
137/**
138 * onenand_page_address - [DEFAULT] Get page address
139 * @param page the page address
140 * @param sector the sector address
141 * @return combined page and sector address
142 *
143 * Setup Start Address 8 Register (F107h)
144 */
145static int onenand_page_address(int page, int sector)
146{
147 /* Flash Page Address, Flash Sector Address */
148 int fpa, fsa;
149
150 fpa = page & ONENAND_FPA_MASK;
151 fsa = sector & ONENAND_FSA_MASK;
152
153 return ((fpa << ONENAND_FPA_SHIFT) | fsa);
154}
155
156/**
157 * onenand_buffer_address - [DEFAULT] Get buffer address
158 * @param dataram1 DataRAM index
159 * @param sectors the sector address
160 * @param count the number of sectors
161 * @return the start buffer value
162 *
163 * Setup Start Buffer Register (F200h)
164 */
165static int onenand_buffer_address(int dataram1, int sectors, int count)
166{
167 int bsa, bsc;
168
169 /* BufferRAM Sector Address */
170 bsa = sectors & ONENAND_BSA_MASK;
171
172 if (dataram1)
173 bsa |= ONENAND_BSA_DATARAM1; /* DataRAM1 */
174 else
175 bsa |= ONENAND_BSA_DATARAM0; /* DataRAM0 */
176
177 /* BufferRAM Sector Count */
178 bsc = count & ONENAND_BSC_MASK;
179
180 return ((bsa << ONENAND_BSA_SHIFT) | bsc);
181}
182
183/**
184 * onenand_command - [DEFAULT] Send command to OneNAND device
185 * @param mtd MTD device structure
186 * @param cmd the command to be sent
187 * @param addr offset to read from or write to
188 * @param len number of bytes to read or write
189 *
190 * Send command to OneNAND device. This function is used for middle/large page
191 * devices (1KB/2KB Bytes per page)
192 */
193static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
194{
195 struct onenand_chip *this = mtd->priv;
196 int value, readcmd = 0;
197 int block, page;
198 /* Now we use page size operation */
199 int sectors = 4, count = 4;
200
201 /* Address translation */
202 switch (cmd) {
203 case ONENAND_CMD_UNLOCK:
204 case ONENAND_CMD_LOCK:
205 case ONENAND_CMD_LOCK_TIGHT:
206 block = -1;
207 page = -1;
208 break;
209
210 case ONENAND_CMD_ERASE:
211 case ONENAND_CMD_BUFFERRAM:
212 block = (int) (addr >> this->erase_shift);
213 page = -1;
214 break;
215
216 default:
217 block = (int) (addr >> this->erase_shift);
218 page = (int) (addr >> this->page_shift);
219 page &= this->page_mask;
220 break;
221 }
222
223 /* NOTE: The setting order of the registers is very important! */
224 if (cmd == ONENAND_CMD_BUFFERRAM) {
225 /* Select DataRAM for DDP */
226 value = onenand_bufferram_address(this->device_id, block);
227 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
228
229 /* Switch to the next data buffer */
230 ONENAND_SET_NEXT_BUFFERRAM(this);
231
232 return 0;
233 }
234
235 if (block != -1) {
236 /* Write 'DFS, FBA' of Flash */
237 value = onenand_block_address(this->device_id, block);
238 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
239 }
240
241 if (page != -1) {
242 int dataram;
243
244 switch (cmd) {
245 case ONENAND_CMD_READ:
246 case ONENAND_CMD_READOOB:
247 dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
248 readcmd = 1;
249 break;
250
251 default:
252 dataram = ONENAND_CURRENT_BUFFERRAM(this);
253 break;
254 }
255
256 /* Write 'FPA, FSA' of Flash */
257 value = onenand_page_address(page, sectors);
258 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS8);
259
260 /* Write 'BSA, BSC' of DataRAM */
261 value = onenand_buffer_address(dataram, sectors, count);
262 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
263
264 if (readcmd) {
265 /* Select DataRAM for DDP */
266 value = onenand_bufferram_address(this->device_id, block);
267 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
268 }
269 }
270
271 /* Interrupt clear */
272 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
273
274 /* Write command */
275 this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
276
277 return 0;
278}
279
280/**
281 * onenand_wait - [DEFAULT] wait until the command is done
282 * @param mtd MTD device structure
283 * @param state state to select the max. timeout value
284 *
285 * Wait for command done. This applies to all OneNAND command
286 * Read can take up to 30us, erase up to 2ms and program up to 350us
287 * according to general OneNAND specs
288 */
289static int onenand_wait(struct mtd_info *mtd, int state)
290{
291 struct onenand_chip * this = mtd->priv;
292 unsigned long timeout;
293 unsigned int flags = ONENAND_INT_MASTER;
294 unsigned int interrupt = 0;
295 unsigned int ctrl, ecc;
296
297 /* The 20 msec is enough */
298 timeout = jiffies + msecs_to_jiffies(20);
299 while (time_before(jiffies, timeout)) {
300 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
301
302 if (interrupt & flags)
303 break;
304
305 if (state != FL_READING)
306 cond_resched();
307 }
308 /* To get correct interrupt status in timeout case */
309 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
310
311 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
312
313 if (ctrl & ONENAND_CTRL_ERROR) {
314 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x", ctrl);
315 return -EIO;
316 }
317
318 if (ctrl & ONENAND_CTRL_LOCK) {
319 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x", ctrl);
320 return -EIO;
321 }
322
323 if (interrupt & ONENAND_INT_READ) {
324 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
325 if (ecc & ONENAND_ECC_2BIT_ALL) {
326 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x", ecc);
327 return -EBADMSG;
328 }
329 }
330
331 return 0;
332}
333
334/**
335 * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
336 * @param mtd MTD data structure
337 * @param area BufferRAM area
338 * @return offset given area
339 *
340 * Return BufferRAM offset given area
341 */
342static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
343{
344 struct onenand_chip *this = mtd->priv;
345
346 if (ONENAND_CURRENT_BUFFERRAM(this)) {
347 if (area == ONENAND_DATARAM)
348 return mtd->oobblock;
349 if (area == ONENAND_SPARERAM)
350 return mtd->oobsize;
351 }
352
353 return 0;
354}
355
356/**
357 * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
358 * @param mtd MTD data structure
359 * @param area BufferRAM area
360 * @param buffer the databuffer to put/get data
361 * @param offset offset to read from or write to
362 * @param count number of bytes to read/write
363 *
364 * Read the BufferRAM area
365 */
366static int onenand_read_bufferram(struct mtd_info *mtd, int area,
367 unsigned char *buffer, int offset, size_t count)
368{
369 struct onenand_chip *this = mtd->priv;
370 void __iomem *bufferram;
371
372 bufferram = this->base + area;
373
374 bufferram += onenand_bufferram_offset(mtd, area);
375
376 memcpy(buffer, bufferram + offset, count);
377
378 return 0;
379}
380
381/**
382 * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
383 * @param mtd MTD data structure
384 * @param area BufferRAM area
385 * @param buffer the databuffer to put/get data
386 * @param offset offset to read from or write to
387 * @param count number of bytes to read/write
388 *
389 * Write the BufferRAM area
390 */
391static int onenand_write_bufferram(struct mtd_info *mtd, int area,
392 const unsigned char *buffer, int offset, size_t count)
393{
394 struct onenand_chip *this = mtd->priv;
395 void __iomem *bufferram;
396
397 bufferram = this->base + area;
398
399 bufferram += onenand_bufferram_offset(mtd, area);
400
401 memcpy(bufferram + offset, buffer, count);
402
403 return 0;
404}
405
406/**
407 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
408 * @param mtd MTD data structure
409 * @param addr address to check
410 * @return 1 if there are valid data, otherwise 0
411 *
412 * Check bufferram if there is data we required
413 */
414static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
415{
416 struct onenand_chip *this = mtd->priv;
417 int block, page;
418 int i;
419
420 block = (int) (addr >> this->erase_shift);
421 page = (int) (addr >> this->page_shift);
422 page &= this->page_mask;
423
424 i = ONENAND_CURRENT_BUFFERRAM(this);
425
426 /* Is there valid data? */
427 if (this->bufferram[i].block == block &&
428 this->bufferram[i].page == page &&
429 this->bufferram[i].valid)
430 return 1;
431
432 return 0;
433}
434
435/**
436 * onenand_update_bufferram - [GENERIC] Update BufferRAM information
437 * @param mtd MTD data structure
438 * @param addr address to update
439 * @param valid valid flag
440 *
441 * Update BufferRAM information
442 */
443static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
444 int valid)
445{
446 struct onenand_chip *this = mtd->priv;
447 int block, page;
448 int i;
449
450 block = (int) (addr >> this->erase_shift);
451 page = (int) (addr >> this->page_shift);
452 page &= this->page_mask;
453
454 /* Invalidate BufferRAM */
455 for (i = 0; i < MAX_BUFFERRAM; i++) {
456 if (this->bufferram[i].block == block &&
457 this->bufferram[i].page == page)
458 this->bufferram[i].valid = 0;
459 }
460
461 /* Update BufferRAM */
462 i = ONENAND_CURRENT_BUFFERRAM(this);
463 this->bufferram[i].block = block;
464 this->bufferram[i].page = page;
465 this->bufferram[i].valid = valid;
466
467 return 0;
468}
469
470/**
471 * onenand_get_device - [GENERIC] Get chip for selected access
472 * @param mtd MTD device structure
473 * @param new_state the state which is requested
474 *
475 * Get the device and lock it for exclusive access
476 */
477static void onenand_get_device(struct mtd_info *mtd, int new_state)
478{
479 struct onenand_chip *this = mtd->priv;
480 DECLARE_WAITQUEUE(wait, current);
481
482 /*
483 * Grab the lock and see if the device is available
484 */
485 while (1) {
486 spin_lock(&this->chip_lock);
487 if (this->state == FL_READY) {
488 this->state = new_state;
489 spin_unlock(&this->chip_lock);
490 break;
491 }
492 set_current_state(TASK_UNINTERRUPTIBLE);
493 add_wait_queue(&this->wq, &wait);
494 spin_unlock(&this->chip_lock);
495 schedule();
496 remove_wait_queue(&this->wq, &wait);
497 }
498}
499
500/**
501 * onenand_release_device - [GENERIC] release chip
502 * @param mtd MTD device structure
503 *
504 * Deselect, release chip lock and wake up anyone waiting on the device
505 */
506static void onenand_release_device(struct mtd_info *mtd)
507{
508 struct onenand_chip *this = mtd->priv;
509
510 /* Release the chip */
511 spin_lock(&this->chip_lock);
512 this->state = FL_READY;
513 wake_up(&this->wq);
514 spin_unlock(&this->chip_lock);
515}
516
517/**
518 * onenand_read_ecc - [MTD Interface] Read data with ECC
519 * @param mtd MTD device structure
520 * @param from offset to read from
521 * @param len number of bytes to read
522 * @param retlen pointer to variable to store the number of read bytes
523 * @param buf the databuffer to put data
524 * @param oob_buf filesystem supplied oob data buffer
525 * @param oobsel oob selection structure
526 *
527 * OneNAND read with ECC
528 */
529static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
530 size_t *retlen, u_char *buf,
531 u_char *oob_buf, struct nand_oobinfo *oobsel)
532{
533 struct onenand_chip *this = mtd->priv;
534 int read = 0, column;
535 int thislen;
536 int ret = 0;
537
538 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
539
540 /* Do not allow reads past end of device */
541 if ((from + len) > mtd->size) {
542 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: Attempt read beyond end of device\n");
543 *retlen = 0;
544 return -EINVAL;
545 }
546
547 /* Grab the lock and see if the device is available */
548 onenand_get_device(mtd, FL_READING);
549
550 /* TODO handling oob */
551
552 while (read < len) {
553 thislen = min_t(int, mtd->oobblock, len - read);
554
555 column = from & (mtd->oobblock - 1);
556 if (column + thislen > mtd->oobblock)
557 thislen = mtd->oobblock - column;
558
559 if (!onenand_check_bufferram(mtd, from)) {
560 this->command(mtd, ONENAND_CMD_READ, from, mtd->oobblock);
561
562 ret = this->wait(mtd, FL_READING);
563 /* First copy data and check return value for ECC handling */
564 onenand_update_bufferram(mtd, from, 1);
565 }
566
567 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
568
569 read += thislen;
570
571 if (read == len)
572 break;
573
574 if (ret) {
575 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: read failed = %d\n", ret);
576 goto out;
577 }
578
579 from += thislen;
580 buf += thislen;
581 }
582
583out:
584 /* Deselect and wake up anyone waiting on the device */
585 onenand_release_device(mtd);
586
587 /*
588 * Return success, if no ECC failures, else -EBADMSG
589 * fs driver will take care of that, because
590 * retlen == desired len and result == -EBADMSG
591 */
592 *retlen = read;
593 return ret;
594}
595
596/**
597 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
598 * @param mtd MTD device structure
599 * @param from offset to read from
600 * @param len number of bytes to read
601 * @param retlen pointer to variable to store the number of read bytes
602 * @param buf the databuffer to put data
603 *
604 * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
605*/
606static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
607 size_t *retlen, u_char *buf)
608{
609 return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
610}
611
612/**
613 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
614 * @param mtd MTD device structure
615 * @param from offset to read from
616 * @param len number of bytes to read
617 * @param retlen pointer to variable to store the number of read bytes
618 * @param buf the databuffer to put data
619 *
620 * OneNAND read out-of-band data from the spare area
621 */
622static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
623 size_t *retlen, u_char *buf)
624{
625 struct onenand_chip *this = mtd->priv;
626 int read = 0, thislen, column;
627 int ret = 0;
628
629 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
630
631 /* Initialize return length value */
632 *retlen = 0;
633
634 /* Do not allow reads past end of device */
635 if (unlikely((from + len) > mtd->size)) {
636 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n");
637 return -EINVAL;
638 }
639
640 /* Grab the lock and see if the device is available */
641 onenand_get_device(mtd, FL_READING);
642
643 column = from & (mtd->oobsize - 1);
644
645 while (read < len) {
646 thislen = mtd->oobsize - column;
647 thislen = min_t(int, thislen, len);
648
649 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
650
651 onenand_update_bufferram(mtd, from, 0);
652
653 ret = this->wait(mtd, FL_READING);
654 /* First copy data and check return value for ECC handling */
655
656 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
657
658 read += thislen;
659
660 if (read == len)
661 break;
662
663 if (ret) {
664 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);
665 goto out;
666 }
667
668 buf += thislen;
669
670 /* Read more? */
671 if (read < len) {
672 /* Page size */
673 from += mtd->oobblock;
674 column = 0;
675 }
676 }
677
678out:
679 /* Deselect and wake up anyone waiting on the device */
680 onenand_release_device(mtd);
681
682 *retlen = read;
683 return ret;
684}
685
686#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
687/**
688 * onenand_verify_page - [GENERIC] verify the chip contents after a write
689 * @param mtd MTD device structure
690 * @param buf the databuffer to verify
691 * @param block block address
692 * @param page page address
693 *
694 * Check DataRAM area directly
695 */
696static int onenand_verify_page(struct mtd_info *mtd, u_char *buf,
697 loff_t addr, int block, int page)
698{
699 struct onenand_chip *this = mtd->priv;
700 void __iomem *dataram0, *dataram1;
701 int ret = 0;
702
703 this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
704
705 ret = this->wait(mtd, FL_READING);
706 if (ret)
707 return ret;
708
709 onenand_update_bufferram(mtd, addr, 1);
710
711 /* Check, if the two dataram areas are same */
712 dataram0 = this->base + ONENAND_DATARAM;
713 dataram1 = dataram0 + mtd->oobblock;
714
715 if (memcmp(dataram0, dataram1, mtd->oobblock))
716 return -EBADMSG;
717
718 return 0;
719}
720#else
721#define onenand_verify_page(...) (0)
722#endif
723
724#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0)
725
726/**
727 * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
728 * @param mtd MTD device structure
729 * @param to offset to write to
730 * @param len number of bytes to write
731 * @param retlen pointer to variable to store the number of written bytes
732 * @param buf the data to write
733 * @param eccbuf filesystem supplied oob data buffer
734 * @param oobsel oob selection structure
735 *
736 * OneNAND write with ECC
737 */
738static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
739 size_t *retlen, const u_char *buf,
740 u_char *eccbuf, struct nand_oobinfo *oobsel)
741{
742 struct onenand_chip *this = mtd->priv;
743 int written = 0;
744 int ret = 0;
745
746 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
747
748 /* Initialize retlen, in case of early exit */
749 *retlen = 0;
750
751 /* Do not allow writes past end of device */
752 if (unlikely((to + len) > mtd->size)) {
753 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt write to past end of device\n");
754 return -EINVAL;
755 }
756
757 /* Reject writes, which are not page aligned */
758 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
759 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt to write not page aligned data\n");
760 return -EINVAL;
761 }
762
763 /* Grab the lock and see if the device is available */
764 onenand_get_device(mtd, FL_WRITING);
765
766 /* Loop until all data write */
767 while (written < len) {
768 int thislen = min_t(int, mtd->oobblock, len - written);
769
770 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
771
772 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
773 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
774
775 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
776
777 onenand_update_bufferram(mtd, to, 1);
778
779 ret = this->wait(mtd, FL_WRITING);
780 if (ret) {
781 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: write filaed %d\n", ret);
782 goto out;
783 }
784
785 written += thislen;
786
787 /* Only check verify write turn on */
788 ret = onenand_verify_page(mtd, (u_char *) buf, to, block, page);
789 if (ret) {
790 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret);
791 goto out;
792 }
793
794 if (written == len)
795 break;
796
797 to += thislen;
798 buf += thislen;
799 }
800
801out:
802 /* Deselect and wake up anyone waiting on the device */
803 onenand_release_device(mtd);
804
805 *retlen = written;
806
807 return ret;
808}
809
810/**
811 * onenand_write - [MTD Interface] compability function for onenand_write_ecc
812 * @param mtd MTD device structure
813 * @param to offset to write to
814 * @param len number of bytes to write
815 * @param retlen pointer to variable to store the number of written bytes
816 * @param buf the data to write
817 *
818 * This function simply calls onenand_write_ecc
819 * with oob buffer and oobsel = NULL
820 */
821static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
822 size_t *retlen, const u_char *buf)
823{
824 return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
825}
826
827/**
828 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
829 * @param mtd MTD device structure
830 * @param to offset to write to
831 * @param len number of bytes to write
832 * @param retlen pointer to variable to store the number of written bytes
833 * @param buf the data to write
834 *
835 * OneNAND write out-of-band
836 */
837static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
838 size_t *retlen, const u_char *buf)
839{
840 struct onenand_chip *this = mtd->priv;
841 int column, status;
842 int written = 0;
843
844 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
845
846 /* Initialize retlen, in case of early exit */
847 *retlen = 0;
848
849 /* Do not allow writes past end of device */
850 if (unlikely((to + len) > mtd->size)) {
851 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n");
852 return -EINVAL;
853 }
854
855 /* Grab the lock and see if the device is available */
856 onenand_get_device(mtd, FL_WRITING);
857
858 /* Loop until all data write */
859 while (written < len) {
860 int thislen = min_t(int, mtd->oobsize, len - written);
861
862 column = to & (mtd->oobsize - 1);
863
864 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
865
866 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
867 this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
868
869 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
870
871 onenand_update_bufferram(mtd, to, 0);
872
873 status = this->wait(mtd, FL_WRITING);
874 if (status)
875 goto out;
876
877 written += thislen;
878
879 if (written == len)
880 break;
881
882 to += thislen;
883 buf += thislen;
884 }
885
886out:
887 /* Deselect and wake up anyone waiting on the device */
888 onenand_release_device(mtd);
889
890 *retlen = written;
891
892 return 0;
893}
894
895/**
896 * onenand_writev_ecc - [MTD Interface] write with iovec with ecc
897 * @param mtd MTD device structure
898 * @param vecs the iovectors to write
899 * @param count number of vectors
900 * @param to offset to write to
901 * @param retlen pointer to variable to store the number of written bytes
902 * @param eccbuf filesystem supplied oob data buffer
903 * @param oobsel oob selection structure
904 *
905 * OneNAND write with iovec with ecc
906 */
907static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
908 unsigned long count, loff_t to, size_t *retlen,
909 u_char *eccbuf, struct nand_oobinfo *oobsel)
910{
911 struct onenand_chip *this = mtd->priv;
912 unsigned char buffer[mtd->oobblock], *pbuf;
913 size_t total_len, len;
914 int i, written = 0;
915 int ret = 0;
916
917 /* Preset written len for early exit */
918 *retlen = 0;
919
920 /* Calculate total length of data */
921 total_len = 0;
922 for (i = 0; i < count; i++)
923 total_len += vecs[i].iov_len;
924
925 DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
926
927 /* Do not allow write past end of the device */
928 if (unlikely((to + total_len) > mtd->size)) {
929 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
930 return -EINVAL;
931 }
932
933 /* Reject writes, which are not page aligned */
934 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
935 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
936 return -EINVAL;
937 }
938
939 /* Grab the lock and see if the device is available */
940 onenand_get_device(mtd, FL_WRITING);
941
942 /* TODO handling oob */
943
944 /* Loop until all keve's data has been written */
945 len = 0;
946 while (count) {
947 pbuf = buffer;
948 /*
949 * If the given tuple is >= pagesize then
950 * write it out from the iov
951 */
952 if ((vecs->iov_len - len) >= mtd->oobblock) {
953 pbuf = vecs->iov_base + len;
954
955 len += mtd->oobblock;
956
957 /* Check, if we have to switch to the next tuple */
958 if (len >= (int) vecs->iov_len) {
959 vecs++;
960 len = 0;
961 count--;
962 }
963 } else {
964 int cnt = 0, thislen;
965 while (cnt < mtd->oobblock) {
966 thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
967 memcpy(buffer + cnt, vecs->iov_base + len, thislen);
968 cnt += thislen;
969 len += thislen;
970
971 /* Check, if we have to switch to the next tuple */
972 if (len >= (int) vecs->iov_len) {
973 vecs++;
974 len = 0;
975 count--;
976 }
977 }
978 }
979
980 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
981
982 this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->oobblock);
983 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
984
985 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
986
987 onenand_update_bufferram(mtd, to, 1);
988
989 ret = this->wait(mtd, FL_WRITING);
990 if (ret) {
991 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
992 goto out;
993 }
994
995
996 /* Only check verify write turn on */
997 ret = onenand_verify_page(mtd, (u_char *) pbuf, to, block, page);
998 if (ret) {
999 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
1000 goto out;
1001 }
1002
1003 written += mtd->oobblock;
1004
1005 to += mtd->oobblock;
1006 }
1007
1008out:
1009 /* Deselect and wakt up anyone waiting on the device */
1010 onenand_release_device(mtd);
1011
1012 *retlen = written;
1013
1014 return 0;
1015}
1016
1017/**
1018 * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
1019 * @param mtd MTD device structure
1020 * @param vecs the iovectors to write
1021 * @param count number of vectors
1022 * @param to offset to write to
1023 * @param retlen pointer to variable to store the number of written bytes
1024 *
1025 * OneNAND write with kvec. This just calls the ecc function
1026 */
1027static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
1028 unsigned long count, loff_t to, size_t *retlen)
1029{
1030 return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
1031}
1032
1033/**
1034 * onenand_erase - [MTD Interface] erase block(s)
1035 * @param mtd MTD device structure
1036 * @param instr erase instruction
1037 *
1038 * Erase one ore more blocks
1039 */
1040static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1041{
1042 struct onenand_chip *this = mtd->priv;
1043 unsigned int block_size;
1044 loff_t addr;
1045 int len;
1046 int ret = 0;
1047
1048 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
1049
1050 block_size = (1 << this->erase_shift);
1051
1052 /* Start address must align on block boundary */
1053 if (unlikely(instr->addr & (block_size - 1))) {
1054 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
1055 return -EINVAL;
1056 }
1057
1058 /* Length must align on block boundary */
1059 if (unlikely(instr->len & (block_size - 1))) {
1060 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n");
1061 return -EINVAL;
1062 }
1063
1064 /* Do not allow erase past end of device */
1065 if (unlikely((instr->len + instr->addr) > mtd->size)) {
1066 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n");
1067 return -EINVAL;
1068 }
1069
1070 instr->fail_addr = 0xffffffff;
1071
1072 /* Grab the lock and see if the device is available */
1073 onenand_get_device(mtd, FL_ERASING);
1074
1075 /* Loop throught the pages */
1076 len = instr->len;
1077 addr = instr->addr;
1078
1079 instr->state = MTD_ERASING;
1080
1081 while (len) {
1082
1083 /* TODO Check badblock */
1084
1085 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
1086
1087 ret = this->wait(mtd, FL_ERASING);
1088 /* Check, if it is write protected */
1089 if (ret) {
1090 if (ret == -EPERM)
1091 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");
1092 else
1093 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
1094 instr->state = MTD_ERASE_FAILED;
1095 instr->fail_addr = addr;
1096 goto erase_exit;
1097 }
1098
1099 len -= block_size;
1100 addr += block_size;
1101 }
1102
1103 instr->state = MTD_ERASE_DONE;
1104
1105erase_exit:
1106
1107 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
1108 /* Do call back function */
1109 if (!ret)
1110 mtd_erase_callback(instr);
1111
1112 /* Deselect and wake up anyone waiting on the device */
1113 onenand_release_device(mtd);
1114
1115 return ret;
1116}
1117
1118/**
1119 * onenand_sync - [MTD Interface] sync
1120 * @param mtd MTD device structure
1121 *
1122 * Sync is actually a wait for chip ready function
1123 */
1124static void onenand_sync(struct mtd_info *mtd)
1125{
1126 DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
1127
1128 /* Grab the lock and see if the device is available */
1129 onenand_get_device(mtd, FL_SYNCING);
1130
1131 /* Release it and go back */
1132 onenand_release_device(mtd);
1133}
1134
1135/**
1136 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
1137 * @param mtd MTD device structure
1138 * @param ofs offset relative to mtd start
1139 */
1140static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
1141{
1142 /*
1143 * TODO
1144 * 1. Bad block table (BBT)
1145 * -> using NAND BBT to support JFFS2
1146 * 2. Bad block management (BBM)
1147 * -> bad block replace scheme
1148 *
1149 * Currently we do nothing
1150 */
1151 return 0;
1152}
1153
1154/**
1155 * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
1156 * @param mtd MTD device structure
1157 * @param ofs offset relative to mtd start
1158 */
1159static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1160{
1161 /* see above */
1162 return 0;
1163}
1164
1165/**
1166 * onenand_unlock - [MTD Interface] Unlock block(s)
1167 * @param mtd MTD device structure
1168 * @param ofs offset relative to mtd start
1169 * @param len number of bytes to unlock
1170 *
1171 * Unlock one or more blocks
1172 */
1173static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1174{
1175 struct onenand_chip *this = mtd->priv;
1176 int start, end, block, value, status;
1177
1178 start = ofs >> this->erase_shift;
1179 end = len >> this->erase_shift;
1180
1181 /* Continuous lock scheme */
1182 if (this->options & ONENAND_CONT_LOCK) {
1183 /* Set start block address */
1184 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1185 /* Set end block address */
1186 this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1187 /* Write unlock command */
1188 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1189
1190 /* There's no return value */
1191 this->wait(mtd, FL_UNLOCKING);
1192
1193 /* Sanity check */
1194 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1195 & ONENAND_CTRL_ONGO)
1196 continue;
1197
1198 /* Check lock status */
1199 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1200 if (!(status & ONENAND_WP_US))
1201 printk(KERN_ERR "wp status = 0x%x\n", status);
1202
1203 return 0;
1204 }
1205
1206 /* Block lock scheme */
1207 for (block = start; block < end; block++) {
1208 /* Set start block address */
1209 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1210 /* Write unlock command */
1211 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1212
1213 /* There's no return value */
1214 this->wait(mtd, FL_UNLOCKING);
1215
1216 /* Sanity check */
1217 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1218 & ONENAND_CTRL_ONGO)
1219 continue;
1220
1221 /* Set block address for read block status */
1222 value = onenand_block_address(this->device_id, block);
1223 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1224
1225 /* Check lock status */
1226 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1227 if (!(status & ONENAND_WP_US))
1228 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
1229 }
1230
1231 return 0;
1232}
1233
1234/**
1235 * onenand_print_device_info - Print device ID
1236 * @param device device ID
1237 *
1238 * Print device ID
1239 */
1240static void onenand_print_device_info(int device)
1241{
1242 int vcc, demuxed, ddp, density;
1243
1244 vcc = device & ONENAND_DEVICE_VCC_MASK;
1245 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
1246 ddp = device & ONENAND_DEVICE_IS_DDP;
1247 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
1248 printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
1249 demuxed ? "" : "Muxed ",
1250 ddp ? "(DDP)" : "",
1251 (16 << density),
1252 vcc ? "2.65/3.3" : "1.8",
1253 device);
1254}
1255
1256static const struct onenand_manufacturers onenand_manuf_ids[] = {
1257 {ONENAND_MFR_SAMSUNG, "Samsung"},
1258 {ONENAND_MFR_UNKNOWN, "Unknown"}
1259};
1260
1261/**
1262 * onenand_check_maf - Check manufacturer ID
1263 * @param manuf manufacturer ID
1264 *
1265 * Check manufacturer ID
1266 */
1267static int onenand_check_maf(int manuf)
1268{
1269 int i;
1270
1271 for (i = 0; onenand_manuf_ids[i].id; i++) {
1272 if (manuf == onenand_manuf_ids[i].id)
1273 break;
1274 }
1275
1276 printk(KERN_DEBUG "OneNAND Manufacturer: %s\n",
1277 onenand_manuf_ids[i].name);
1278
1279 return (i != ONENAND_MFR_UNKNOWN);
1280}
1281
1282/**
1283 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
1284 * @param mtd MTD device structure
1285 *
1286 * OneNAND detection method:
1287 * Compare the the values from command with ones from register
1288 */
1289static int onenand_probe(struct mtd_info *mtd)
1290{
1291 struct onenand_chip *this = mtd->priv;
1292 int bram_maf_id, bram_dev_id, maf_id, dev_id;
1293 int version_id;
1294 int density;
1295
1296 /* Send the command for reading device ID from BootRAM */
1297 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
1298
1299 /* Read manufacturer and device IDs from BootRAM */
1300 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
1301 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
1302
1303 /* Check manufacturer ID */
1304 if (onenand_check_maf(bram_maf_id))
1305 return -ENXIO;
1306
1307 /* Reset OneNAND to read default register values */
1308 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
1309
1310 /* Read manufacturer and device IDs from Register */
1311 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
1312 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
1313
1314 /* Check OneNAND device */
1315 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
1316 return -ENXIO;
1317
1318 /* Flash device information */
1319 onenand_print_device_info(dev_id);
1320 this->device_id = dev_id;
1321
1322 density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1323 this->chipsize = (16 << density) << 20;
1324
1325 /* OneNAND page size & block size */
1326 /* The data buffer size is equal to page size */
1327 mtd->oobblock = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1328 mtd->oobsize = mtd->oobblock >> 5;
1329 /* Pagers per block is always 64 in OneNAND */
1330 mtd->erasesize = mtd->oobblock << 6;
1331
1332 this->erase_shift = ffs(mtd->erasesize) - 1;
1333 this->page_shift = ffs(mtd->oobblock) - 1;
1334 this->ppb_shift = (this->erase_shift - this->page_shift);
1335 this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
1336
1337 /* REVIST: Multichip handling */
1338
1339 mtd->size = this->chipsize;
1340
1341 /* Version ID */
1342 version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
1343 printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
1344
1345 /* Lock scheme */
1346 if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
1347 !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
1348 printk(KERN_INFO "Lock scheme is Continues Lock\n");
1349 this->options |= ONENAND_CONT_LOCK;
1350 }
1351
1352 return 0;
1353}
1354
1355
1356/**
1357 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
1358 * @param mtd MTD device structure
1359 * @param maxchips Number of chips to scan for
1360 *
1361 * This fills out all the not initialized function pointers
1362 * with the defaults.
1363 * The flash ID is read and the mtd/chip structures are
1364 * filled with the appropriate values.
1365 */
1366int onenand_scan(struct mtd_info *mtd, int maxchips)
1367{
1368 struct onenand_chip *this = mtd->priv;
1369
1370 if (!this->read_word)
1371 this->read_word = onenand_readw;
1372 if (!this->write_word)
1373 this->write_word = onenand_writew;
1374
1375 if (!this->command)
1376 this->command = onenand_command;
1377 if (!this->wait)
1378 this->wait = onenand_wait;
1379
1380 if (!this->read_bufferram)
1381 this->read_bufferram = onenand_read_bufferram;
1382 if (!this->write_bufferram)
1383 this->write_bufferram = onenand_write_bufferram;
1384
1385 if (onenand_probe(mtd))
1386 return -ENXIO;
1387
1388 this->state = FL_READY;
1389 init_waitqueue_head(&this->wq);
1390 spin_lock_init(&this->chip_lock);
1391
1392 switch (mtd->oobsize) {
1393 case 64:
1394 this->autooob = &onenand_oob_64;
1395 break;
1396
1397 case 32:
1398 this->autooob = &onenand_oob_32;
1399 break;
1400
1401 default:
1402 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
1403 mtd->oobsize);
1404 /* To prevent kernel oops */
1405 this->autooob = &onenand_oob_32;
1406 break;
1407 }
1408
1409 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
1410
1411 /* Fill in remaining MTD driver data */
1412 mtd->type = MTD_NANDFLASH;
1413 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
1414 mtd->ecctype = MTD_ECC_SW;
1415 mtd->erase = onenand_erase;
1416 mtd->point = NULL;
1417 mtd->unpoint = NULL;
1418 mtd->read = onenand_read;
1419 mtd->write = onenand_write;
1420 mtd->read_ecc = onenand_read_ecc;
1421 mtd->write_ecc = onenand_write_ecc;
1422 mtd->read_oob = onenand_read_oob;
1423 mtd->write_oob = onenand_write_oob;
1424 mtd->readv = NULL;
1425 mtd->readv_ecc = NULL;
1426 mtd->writev = onenand_writev;
1427 mtd->writev_ecc = onenand_writev_ecc;
1428 mtd->sync = onenand_sync;
1429 mtd->lock = NULL;
1430 mtd->unlock = onenand_unlock;
1431 mtd->suspend = NULL;
1432 mtd->resume = NULL;
1433 mtd->block_isbad = onenand_block_isbad;
1434 mtd->block_markbad = onenand_block_markbad;
1435 mtd->owner = THIS_MODULE;
1436
1437 /* Unlock whole block */
1438 mtd->unlock(mtd, 0x0, this->chipsize);
1439
1440 return 0;
1441}
1442
1443/**
1444 * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
1445 * @param mtd MTD device structure
1446 */
1447void onenand_release(struct mtd_info *mtd)
1448{
1449#ifdef CONFIG_MTD_PARTITIONS
1450 /* Deregister partitions */
1451 del_mtd_partitions (mtd);
1452#endif
1453 /* Deregister the device */
1454 del_mtd_device (mtd);
1455}
1456
1457EXPORT_SYMBOL_GPL(onenand_scan);
1458EXPORT_SYMBOL_GPL(onenand_release);
1459
1460MODULE_LICENSE("GPL");
1461MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
1462MODULE_DESCRIPTION("Generic OneNAND flash driver code");