blob: 1439c9fa1d23bd51e6dfdd814e76f910eb1fde1e [file] [log] [blame]
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001/*
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>
Andrew Morton015953d2005-11-08 21:34:28 -080015#include <linux/sched.h>
16#include <linux/jiffies.h>
Kyungmin Parkcd5f6342005-07-11 11:41:53 +010017#include <linux/mtd/mtd.h>
18#include <linux/mtd/onenand.h>
19#include <linux/mtd/partitions.h>
20
21#include <asm/io.h>
22
23/**
24 * onenand_oob_64 - oob info for large (2KB) page
25 */
26static struct nand_oobinfo onenand_oob_64 = {
27 .useecc = MTD_NANDECC_AUTOPLACE,
28 .eccbytes = 20,
29 .eccpos = {
30 8, 9, 10, 11, 12,
31 24, 25, 26, 27, 28,
32 40, 41, 42, 43, 44,
33 56, 57, 58, 59, 60,
34 },
35 .oobfree = {
36 {2, 3}, {14, 2}, {18, 3}, {30, 2},
37 {24, 3}, {46, 2}, {40, 3}, {62, 2} }
38};
39
40/**
41 * onenand_oob_32 - oob info for middle (1KB) page
42 */
43static struct nand_oobinfo onenand_oob_32 = {
44 .useecc = MTD_NANDECC_AUTOPLACE,
45 .eccbytes = 10,
46 .eccpos = {
47 8, 9, 10, 11, 12,
48 24, 25, 26, 27, 28,
49 },
50 .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
51};
52
53static const unsigned char ffchars[] = {
54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
55 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
56 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
57 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
58 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
59 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
60 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
61 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
62};
63
64/**
65 * onenand_readw - [OneNAND Interface] Read OneNAND register
66 * @param addr address to read
67 *
68 * Read OneNAND register
69 */
70static unsigned short onenand_readw(void __iomem *addr)
71{
72 return readw(addr);
73}
74
75/**
76 * onenand_writew - [OneNAND Interface] Write OneNAND register with value
77 * @param value value to write
78 * @param addr address to write
79 *
80 * Write OneNAND register with value
81 */
82static void onenand_writew(unsigned short value, void __iomem *addr)
83{
84 writew(value, addr);
85}
86
87/**
88 * onenand_block_address - [DEFAULT] Get block address
Kyungmin Park83a36832005-09-29 04:53:16 +010089 * @param this onenand chip data structure
Kyungmin Parkcd5f6342005-07-11 11:41:53 +010090 * @param block the block
91 * @return translated block address if DDP, otherwise same
92 *
93 * Setup Start Address 1 Register (F100h)
94 */
Kyungmin Park83a36832005-09-29 04:53:16 +010095static int onenand_block_address(struct onenand_chip *this, int block)
Kyungmin Parkcd5f6342005-07-11 11:41:53 +010096{
Kyungmin Park83a36832005-09-29 04:53:16 +010097 if (this->device_id & ONENAND_DEVICE_IS_DDP) {
Kyungmin Parkcd5f6342005-07-11 11:41:53 +010098 /* Device Flash Core select, NAND Flash Block Address */
Kyungmin Park83a36832005-09-29 04:53:16 +010099 int dfs = 0;
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100100
Kyungmin Park83a36832005-09-29 04:53:16 +0100101 if (block & this->density_mask)
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100102 dfs = 1;
103
Kyungmin Park83a36832005-09-29 04:53:16 +0100104 return (dfs << ONENAND_DDP_SHIFT) |
105 (block & (this->density_mask - 1));
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100106 }
107
108 return block;
109}
110
111/**
112 * onenand_bufferram_address - [DEFAULT] Get bufferram address
Kyungmin Park83a36832005-09-29 04:53:16 +0100113 * @param this onenand chip data structure
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100114 * @param block the block
115 * @return set DBS value if DDP, otherwise 0
116 *
117 * Setup Start Address 2 Register (F101h) for DDP
118 */
Kyungmin Park83a36832005-09-29 04:53:16 +0100119static int onenand_bufferram_address(struct onenand_chip *this, int block)
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100120{
Kyungmin Park83a36832005-09-29 04:53:16 +0100121 if (this->device_id & ONENAND_DEVICE_IS_DDP) {
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100122 /* Device BufferRAM Select */
Kyungmin Park83a36832005-09-29 04:53:16 +0100123 int dbs = 0;
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100124
Kyungmin Park83a36832005-09-29 04:53:16 +0100125 if (block & this->density_mask)
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100126 dbs = 1;
127
128 return (dbs << ONENAND_DDP_SHIFT);
129 }
130
131 return 0;
132}
133
134/**
135 * onenand_page_address - [DEFAULT] Get page address
136 * @param page the page address
137 * @param sector the sector address
138 * @return combined page and sector address
139 *
140 * Setup Start Address 8 Register (F107h)
141 */
142static int onenand_page_address(int page, int sector)
143{
144 /* Flash Page Address, Flash Sector Address */
145 int fpa, fsa;
146
147 fpa = page & ONENAND_FPA_MASK;
148 fsa = sector & ONENAND_FSA_MASK;
149
150 return ((fpa << ONENAND_FPA_SHIFT) | fsa);
151}
152
153/**
154 * onenand_buffer_address - [DEFAULT] Get buffer address
155 * @param dataram1 DataRAM index
156 * @param sectors the sector address
157 * @param count the number of sectors
158 * @return the start buffer value
159 *
160 * Setup Start Buffer Register (F200h)
161 */
162static int onenand_buffer_address(int dataram1, int sectors, int count)
163{
164 int bsa, bsc;
165
166 /* BufferRAM Sector Address */
167 bsa = sectors & ONENAND_BSA_MASK;
168
169 if (dataram1)
170 bsa |= ONENAND_BSA_DATARAM1; /* DataRAM1 */
171 else
172 bsa |= ONENAND_BSA_DATARAM0; /* DataRAM0 */
173
174 /* BufferRAM Sector Count */
175 bsc = count & ONENAND_BSC_MASK;
176
177 return ((bsa << ONENAND_BSA_SHIFT) | bsc);
178}
179
180/**
181 * onenand_command - [DEFAULT] Send command to OneNAND device
182 * @param mtd MTD device structure
183 * @param cmd the command to be sent
184 * @param addr offset to read from or write to
185 * @param len number of bytes to read or write
186 *
187 * Send command to OneNAND device. This function is used for middle/large page
188 * devices (1KB/2KB Bytes per page)
189 */
190static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
191{
192 struct onenand_chip *this = mtd->priv;
193 int value, readcmd = 0;
194 int block, page;
195 /* Now we use page size operation */
196 int sectors = 4, count = 4;
197
198 /* Address translation */
199 switch (cmd) {
200 case ONENAND_CMD_UNLOCK:
201 case ONENAND_CMD_LOCK:
202 case ONENAND_CMD_LOCK_TIGHT:
203 block = -1;
204 page = -1;
205 break;
206
207 case ONENAND_CMD_ERASE:
208 case ONENAND_CMD_BUFFERRAM:
209 block = (int) (addr >> this->erase_shift);
210 page = -1;
211 break;
212
213 default:
214 block = (int) (addr >> this->erase_shift);
215 page = (int) (addr >> this->page_shift);
216 page &= this->page_mask;
217 break;
218 }
219
220 /* NOTE: The setting order of the registers is very important! */
221 if (cmd == ONENAND_CMD_BUFFERRAM) {
222 /* Select DataRAM for DDP */
Kyungmin Park83a36832005-09-29 04:53:16 +0100223 value = onenand_bufferram_address(this, block);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100224 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
225
226 /* Switch to the next data buffer */
227 ONENAND_SET_NEXT_BUFFERRAM(this);
228
229 return 0;
230 }
231
232 if (block != -1) {
233 /* Write 'DFS, FBA' of Flash */
Kyungmin Park83a36832005-09-29 04:53:16 +0100234 value = onenand_block_address(this, block);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100235 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
236 }
237
238 if (page != -1) {
239 int dataram;
240
241 switch (cmd) {
242 case ONENAND_CMD_READ:
243 case ONENAND_CMD_READOOB:
244 dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
245 readcmd = 1;
246 break;
247
248 default:
249 dataram = ONENAND_CURRENT_BUFFERRAM(this);
250 break;
251 }
252
253 /* Write 'FPA, FSA' of Flash */
254 value = onenand_page_address(page, sectors);
255 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS8);
256
257 /* Write 'BSA, BSC' of DataRAM */
258 value = onenand_buffer_address(dataram, sectors, count);
259 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +0000260
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100261 if (readcmd) {
262 /* Select DataRAM for DDP */
Kyungmin Park83a36832005-09-29 04:53:16 +0100263 value = onenand_bufferram_address(this, block);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100264 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
265 }
266 }
267
268 /* Interrupt clear */
269 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
270
271 /* Write command */
272 this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
273
274 return 0;
275}
276
277/**
278 * onenand_wait - [DEFAULT] wait until the command is done
279 * @param mtd MTD device structure
280 * @param state state to select the max. timeout value
281 *
282 * Wait for command done. This applies to all OneNAND command
283 * Read can take up to 30us, erase up to 2ms and program up to 350us
284 * according to general OneNAND specs
285 */
286static int onenand_wait(struct mtd_info *mtd, int state)
287{
288 struct onenand_chip * this = mtd->priv;
289 unsigned long timeout;
290 unsigned int flags = ONENAND_INT_MASTER;
291 unsigned int interrupt = 0;
292 unsigned int ctrl, ecc;
293
294 /* The 20 msec is enough */
295 timeout = jiffies + msecs_to_jiffies(20);
296 while (time_before(jiffies, timeout)) {
297 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
298
299 if (interrupt & flags)
300 break;
301
302 if (state != FL_READING)
303 cond_resched();
Kyungmin Park628bee62006-05-12 17:02:24 +0300304 touch_softlockup_watchdog();
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100305 }
306 /* To get correct interrupt status in timeout case */
307 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
308
309 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
310
311 if (ctrl & ONENAND_CTRL_ERROR) {
Kyungmin Parkcdc00132005-09-03 07:15:48 +0100312 /* It maybe occur at initial bad block */
313 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);
314 /* Clear other interrupt bits for preventing ECC error */
315 interrupt &= ONENAND_INT_MASTER;
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100316 }
317
318 if (ctrl & ONENAND_CTRL_LOCK) {
Kyungmin Parkcdc00132005-09-03 07:15:48 +0100319 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl);
320 return -EACCES;
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100321 }
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) {
Kyungmin Parkcdc00132005-09-03 07:15:48 +0100326 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100327 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
Kyungmin Park9c01f87d2006-05-12 17:02:31 +0300376 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
377 unsigned short word;
378
379 /* Align with word(16-bit) size */
380 count--;
381
382 /* Read word and save byte */
383 word = this->read_word(bufferram + offset + count);
384 buffer[count] = (word & 0xff);
385 }
386
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100387 memcpy(buffer, bufferram + offset, count);
388
389 return 0;
390}
391
392/**
Kyungmin Park52b0eea2005-09-03 07:07:19 +0100393 * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
394 * @param mtd MTD data structure
395 * @param area BufferRAM area
396 * @param buffer the databuffer to put/get data
397 * @param offset offset to read from or write to
398 * @param count number of bytes to read/write
399 *
400 * Read the BufferRAM area with Sync. Burst Mode
401 */
402static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
403 unsigned char *buffer, int offset, size_t count)
404{
405 struct onenand_chip *this = mtd->priv;
406 void __iomem *bufferram;
407
408 bufferram = this->base + area;
409
410 bufferram += onenand_bufferram_offset(mtd, area);
411
412 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
413
Kyungmin Park9c01f87d2006-05-12 17:02:31 +0300414 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
415 unsigned short word;
416
417 /* Align with word(16-bit) size */
418 count--;
419
420 /* Read word and save byte */
421 word = this->read_word(bufferram + offset + count);
422 buffer[count] = (word & 0xff);
423 }
424
Kyungmin Park52b0eea2005-09-03 07:07:19 +0100425 memcpy(buffer, bufferram + offset, count);
426
427 this->mmcontrol(mtd, 0);
428
429 return 0;
430}
431
432/**
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100433 * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
434 * @param mtd MTD data structure
435 * @param area BufferRAM area
436 * @param buffer the databuffer to put/get data
437 * @param offset offset to read from or write to
438 * @param count number of bytes to read/write
439 *
440 * Write the BufferRAM area
441 */
442static int onenand_write_bufferram(struct mtd_info *mtd, int area,
443 const unsigned char *buffer, int offset, size_t count)
444{
445 struct onenand_chip *this = mtd->priv;
446 void __iomem *bufferram;
447
448 bufferram = this->base + area;
449
450 bufferram += onenand_bufferram_offset(mtd, area);
451
Kyungmin Park9c01f87d2006-05-12 17:02:31 +0300452 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
453 unsigned short word;
454 int byte_offset;
455
456 /* Align with word(16-bit) size */
457 count--;
458
459 /* Calculate byte access offset */
460 byte_offset = offset + count;
461
462 /* Read word and save byte */
463 word = this->read_word(bufferram + byte_offset);
464 word = (word & ~0xff) | buffer[count];
465 this->write_word(word, bufferram + byte_offset);
466 }
467
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100468 memcpy(bufferram + offset, buffer, count);
469
470 return 0;
471}
472
473/**
474 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
475 * @param mtd MTD data structure
476 * @param addr address to check
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +0000477 * @return 1 if there are valid data, otherwise 0
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100478 *
479 * Check bufferram if there is data we required
480 */
481static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
482{
483 struct onenand_chip *this = mtd->priv;
484 int block, page;
485 int i;
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +0000486
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100487 block = (int) (addr >> this->erase_shift);
488 page = (int) (addr >> this->page_shift);
489 page &= this->page_mask;
490
491 i = ONENAND_CURRENT_BUFFERRAM(this);
492
493 /* Is there valid data? */
494 if (this->bufferram[i].block == block &&
495 this->bufferram[i].page == page &&
496 this->bufferram[i].valid)
497 return 1;
498
499 return 0;
500}
501
502/**
503 * onenand_update_bufferram - [GENERIC] Update BufferRAM information
504 * @param mtd MTD data structure
505 * @param addr address to update
506 * @param valid valid flag
507 *
508 * Update BufferRAM information
509 */
510static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
511 int valid)
512{
513 struct onenand_chip *this = mtd->priv;
514 int block, page;
515 int i;
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +0000516
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100517 block = (int) (addr >> this->erase_shift);
518 page = (int) (addr >> this->page_shift);
519 page &= this->page_mask;
520
521 /* Invalidate BufferRAM */
522 for (i = 0; i < MAX_BUFFERRAM; i++) {
523 if (this->bufferram[i].block == block &&
524 this->bufferram[i].page == page)
525 this->bufferram[i].valid = 0;
526 }
527
528 /* Update BufferRAM */
529 i = ONENAND_CURRENT_BUFFERRAM(this);
530 this->bufferram[i].block = block;
531 this->bufferram[i].page = page;
532 this->bufferram[i].valid = valid;
533
534 return 0;
535}
536
537/**
538 * onenand_get_device - [GENERIC] Get chip for selected access
539 * @param mtd MTD device structure
540 * @param new_state the state which is requested
541 *
542 * Get the device and lock it for exclusive access
543 */
Kyungmin Parka41371e2005-09-29 03:55:31 +0100544static int onenand_get_device(struct mtd_info *mtd, int new_state)
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100545{
546 struct onenand_chip *this = mtd->priv;
547 DECLARE_WAITQUEUE(wait, current);
548
549 /*
550 * Grab the lock and see if the device is available
551 */
552 while (1) {
553 spin_lock(&this->chip_lock);
554 if (this->state == FL_READY) {
555 this->state = new_state;
556 spin_unlock(&this->chip_lock);
557 break;
558 }
Kyungmin Parka41371e2005-09-29 03:55:31 +0100559 if (new_state == FL_PM_SUSPENDED) {
560 spin_unlock(&this->chip_lock);
561 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
562 }
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100563 set_current_state(TASK_UNINTERRUPTIBLE);
564 add_wait_queue(&this->wq, &wait);
565 spin_unlock(&this->chip_lock);
566 schedule();
567 remove_wait_queue(&this->wq, &wait);
568 }
Kyungmin Parka41371e2005-09-29 03:55:31 +0100569
570 return 0;
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100571}
572
573/**
574 * onenand_release_device - [GENERIC] release chip
575 * @param mtd MTD device structure
576 *
577 * Deselect, release chip lock and wake up anyone waiting on the device
578 */
579static void onenand_release_device(struct mtd_info *mtd)
580{
581 struct onenand_chip *this = mtd->priv;
582
583 /* Release the chip */
584 spin_lock(&this->chip_lock);
585 this->state = FL_READY;
586 wake_up(&this->wq);
587 spin_unlock(&this->chip_lock);
588}
589
590/**
591 * onenand_read_ecc - [MTD Interface] Read data with ECC
592 * @param mtd MTD device structure
593 * @param from offset to read from
594 * @param len number of bytes to read
595 * @param retlen pointer to variable to store the number of read bytes
596 * @param buf the databuffer to put data
597 * @param oob_buf filesystem supplied oob data buffer
598 * @param oobsel oob selection structure
599 *
600 * OneNAND read with ECC
601 */
602static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
603 size_t *retlen, u_char *buf,
604 u_char *oob_buf, struct nand_oobinfo *oobsel)
605{
606 struct onenand_chip *this = mtd->priv;
607 int read = 0, column;
608 int thislen;
609 int ret = 0;
610
611 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
612
613 /* Do not allow reads past end of device */
614 if ((from + len) > mtd->size) {
615 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: Attempt read beyond end of device\n");
616 *retlen = 0;
617 return -EINVAL;
618 }
619
620 /* Grab the lock and see if the device is available */
621 onenand_get_device(mtd, FL_READING);
622
623 /* TODO handling oob */
624
625 while (read < len) {
626 thislen = min_t(int, mtd->oobblock, len - read);
627
628 column = from & (mtd->oobblock - 1);
629 if (column + thislen > mtd->oobblock)
630 thislen = mtd->oobblock - column;
631
632 if (!onenand_check_bufferram(mtd, from)) {
633 this->command(mtd, ONENAND_CMD_READ, from, mtd->oobblock);
634
635 ret = this->wait(mtd, FL_READING);
636 /* First copy data and check return value for ECC handling */
637 onenand_update_bufferram(mtd, from, 1);
638 }
639
640 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
641
642 read += thislen;
643
644 if (read == len)
645 break;
646
647 if (ret) {
648 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: read failed = %d\n", ret);
649 goto out;
650 }
651
652 from += thislen;
653 buf += thislen;
654 }
655
656out:
657 /* Deselect and wake up anyone waiting on the device */
658 onenand_release_device(mtd);
659
660 /*
661 * Return success, if no ECC failures, else -EBADMSG
662 * fs driver will take care of that, because
663 * retlen == desired len and result == -EBADMSG
664 */
665 *retlen = read;
666 return ret;
667}
668
669/**
670 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
671 * @param mtd MTD device structure
672 * @param from offset to read from
673 * @param len number of bytes to read
674 * @param retlen pointer to variable to store the number of read bytes
675 * @param buf the databuffer to put data
676 *
677 * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
678*/
679static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
680 size_t *retlen, u_char *buf)
681{
682 return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
683}
684
685/**
686 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
687 * @param mtd MTD device structure
688 * @param from offset to read from
689 * @param len number of bytes to read
690 * @param retlen pointer to variable to store the number of read bytes
691 * @param buf the databuffer to put data
692 *
693 * OneNAND read out-of-band data from the spare area
694 */
695static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
696 size_t *retlen, u_char *buf)
697{
698 struct onenand_chip *this = mtd->priv;
699 int read = 0, thislen, column;
700 int ret = 0;
701
702 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
703
704 /* Initialize return length value */
705 *retlen = 0;
706
707 /* Do not allow reads past end of device */
708 if (unlikely((from + len) > mtd->size)) {
709 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n");
710 return -EINVAL;
711 }
712
713 /* Grab the lock and see if the device is available */
714 onenand_get_device(mtd, FL_READING);
715
716 column = from & (mtd->oobsize - 1);
717
718 while (read < len) {
719 thislen = mtd->oobsize - column;
720 thislen = min_t(int, thislen, len);
721
722 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
723
724 onenand_update_bufferram(mtd, from, 0);
725
726 ret = this->wait(mtd, FL_READING);
727 /* First copy data and check return value for ECC handling */
728
729 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
730
731 read += thislen;
732
733 if (read == len)
734 break;
735
736 if (ret) {
737 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);
738 goto out;
739 }
740
741 buf += thislen;
742
743 /* Read more? */
744 if (read < len) {
745 /* Page size */
746 from += mtd->oobblock;
747 column = 0;
748 }
749 }
750
751out:
752 /* Deselect and wake up anyone waiting on the device */
753 onenand_release_device(mtd);
754
755 *retlen = read;
756 return ret;
757}
758
759#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
760/**
761 * onenand_verify_page - [GENERIC] verify the chip contents after a write
762 * @param mtd MTD device structure
763 * @param buf the databuffer to verify
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100764 *
765 * Check DataRAM area directly
766 */
Kyungmin Parkd36d63d2005-09-03 07:36:21 +0100767static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100768{
769 struct onenand_chip *this = mtd->priv;
770 void __iomem *dataram0, *dataram1;
771 int ret = 0;
772
773 this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
774
775 ret = this->wait(mtd, FL_READING);
776 if (ret)
777 return ret;
778
779 onenand_update_bufferram(mtd, addr, 1);
780
781 /* Check, if the two dataram areas are same */
782 dataram0 = this->base + ONENAND_DATARAM;
783 dataram1 = dataram0 + mtd->oobblock;
784
785 if (memcmp(dataram0, dataram1, mtd->oobblock))
786 return -EBADMSG;
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +0000787
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100788 return 0;
789}
790#else
791#define onenand_verify_page(...) (0)
792#endif
793
794#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0)
795
796/**
797 * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
798 * @param mtd MTD device structure
799 * @param to offset to write to
800 * @param len number of bytes to write
801 * @param retlen pointer to variable to store the number of written bytes
802 * @param buf the data to write
803 * @param eccbuf filesystem supplied oob data buffer
804 * @param oobsel oob selection structure
805 *
806 * OneNAND write with ECC
807 */
808static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
809 size_t *retlen, const u_char *buf,
810 u_char *eccbuf, struct nand_oobinfo *oobsel)
811{
812 struct onenand_chip *this = mtd->priv;
813 int written = 0;
814 int ret = 0;
815
816 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
817
818 /* Initialize retlen, in case of early exit */
819 *retlen = 0;
820
821 /* Do not allow writes past end of device */
822 if (unlikely((to + len) > mtd->size)) {
823 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt write to past end of device\n");
824 return -EINVAL;
825 }
826
827 /* Reject writes, which are not page aligned */
828 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
829 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt to write not page aligned data\n");
830 return -EINVAL;
831 }
832
833 /* Grab the lock and see if the device is available */
834 onenand_get_device(mtd, FL_WRITING);
835
836 /* Loop until all data write */
837 while (written < len) {
838 int thislen = min_t(int, mtd->oobblock, len - written);
839
840 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
841
842 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
843 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
844
845 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
846
847 onenand_update_bufferram(mtd, to, 1);
848
849 ret = this->wait(mtd, FL_WRITING);
850 if (ret) {
851 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: write filaed %d\n", ret);
852 goto out;
853 }
854
855 written += thislen;
856
857 /* Only check verify write turn on */
Kyungmin Parkd36d63d2005-09-03 07:36:21 +0100858 ret = onenand_verify_page(mtd, (u_char *) buf, to);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100859 if (ret) {
860 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret);
861 goto out;
862 }
863
864 if (written == len)
865 break;
866
867 to += thislen;
868 buf += thislen;
869 }
870
871out:
872 /* Deselect and wake up anyone waiting on the device */
873 onenand_release_device(mtd);
874
875 *retlen = written;
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +0000876
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100877 return ret;
878}
879
880/**
881 * onenand_write - [MTD Interface] compability function for onenand_write_ecc
882 * @param mtd MTD device structure
883 * @param to offset to write to
884 * @param len number of bytes to write
885 * @param retlen pointer to variable to store the number of written bytes
886 * @param buf the data to write
887 *
888 * This function simply calls onenand_write_ecc
889 * with oob buffer and oobsel = NULL
890 */
891static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
892 size_t *retlen, const u_char *buf)
893{
894 return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
895}
896
897/**
898 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
899 * @param mtd MTD device structure
900 * @param to offset to write to
901 * @param len number of bytes to write
902 * @param retlen pointer to variable to store the number of written bytes
903 * @param buf the data to write
904 *
905 * OneNAND write out-of-band
906 */
907static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
908 size_t *retlen, const u_char *buf)
909{
910 struct onenand_chip *this = mtd->priv;
911 int column, status;
912 int written = 0;
913
914 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
915
916 /* Initialize retlen, in case of early exit */
917 *retlen = 0;
918
919 /* Do not allow writes past end of device */
920 if (unlikely((to + len) > mtd->size)) {
921 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n");
922 return -EINVAL;
923 }
924
925 /* Grab the lock and see if the device is available */
926 onenand_get_device(mtd, FL_WRITING);
927
928 /* Loop until all data write */
929 while (written < len) {
930 int thislen = min_t(int, mtd->oobsize, len - written);
931
932 column = to & (mtd->oobsize - 1);
933
934 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
935
936 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
937 this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
938
939 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
940
941 onenand_update_bufferram(mtd, to, 0);
942
943 status = this->wait(mtd, FL_WRITING);
944 if (status)
945 goto out;
946
947 written += thislen;
948
949 if (written == len)
950 break;
951
952 to += thislen;
953 buf += thislen;
954 }
955
956out:
957 /* Deselect and wake up anyone waiting on the device */
958 onenand_release_device(mtd);
959
960 *retlen = written;
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +0000961
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100962 return 0;
963}
964
965/**
966 * onenand_writev_ecc - [MTD Interface] write with iovec with ecc
967 * @param mtd MTD device structure
968 * @param vecs the iovectors to write
969 * @param count number of vectors
970 * @param to offset to write to
971 * @param retlen pointer to variable to store the number of written bytes
972 * @param eccbuf filesystem supplied oob data buffer
973 * @param oobsel oob selection structure
974 *
975 * OneNAND write with iovec with ecc
976 */
977static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
978 unsigned long count, loff_t to, size_t *retlen,
979 u_char *eccbuf, struct nand_oobinfo *oobsel)
980{
981 struct onenand_chip *this = mtd->priv;
Kyungmin Park532a37c2005-12-16 11:17:29 +0900982 unsigned char *pbuf;
Kyungmin Parkcd5f6342005-07-11 11:41:53 +0100983 size_t total_len, len;
984 int i, written = 0;
985 int ret = 0;
986
987 /* Preset written len for early exit */
988 *retlen = 0;
989
990 /* Calculate total length of data */
991 total_len = 0;
992 for (i = 0; i < count; i++)
993 total_len += vecs[i].iov_len;
994
995 DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
996
997 /* Do not allow write past end of the device */
998 if (unlikely((to + total_len) > mtd->size)) {
999 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
1000 return -EINVAL;
1001 }
1002
1003 /* Reject writes, which are not page aligned */
1004 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
1005 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
1006 return -EINVAL;
1007 }
1008
1009 /* Grab the lock and see if the device is available */
1010 onenand_get_device(mtd, FL_WRITING);
1011
1012 /* TODO handling oob */
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +00001013
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001014 /* Loop until all keve's data has been written */
1015 len = 0;
1016 while (count) {
Kyungmin Park532a37c2005-12-16 11:17:29 +09001017 pbuf = this->page_buf;
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +00001018 /*
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001019 * If the given tuple is >= pagesize then
1020 * write it out from the iov
1021 */
1022 if ((vecs->iov_len - len) >= mtd->oobblock) {
1023 pbuf = vecs->iov_base + len;
1024
1025 len += mtd->oobblock;
1026
1027 /* Check, if we have to switch to the next tuple */
1028 if (len >= (int) vecs->iov_len) {
1029 vecs++;
1030 len = 0;
1031 count--;
1032 }
1033 } else {
1034 int cnt = 0, thislen;
1035 while (cnt < mtd->oobblock) {
1036 thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
Kyungmin Park532a37c2005-12-16 11:17:29 +09001037 memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001038 cnt += thislen;
1039 len += thislen;
1040
1041 /* Check, if we have to switch to the next tuple */
1042 if (len >= (int) vecs->iov_len) {
1043 vecs++;
1044 len = 0;
1045 count--;
1046 }
1047 }
1048 }
1049
1050 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
1051
1052 this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->oobblock);
1053 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1054
1055 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
1056
1057 onenand_update_bufferram(mtd, to, 1);
1058
1059 ret = this->wait(mtd, FL_WRITING);
1060 if (ret) {
1061 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
1062 goto out;
1063 }
1064
1065
1066 /* Only check verify write turn on */
Kyungmin Parkd36d63d2005-09-03 07:36:21 +01001067 ret = onenand_verify_page(mtd, (u_char *) pbuf, to);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001068 if (ret) {
1069 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
1070 goto out;
1071 }
1072
1073 written += mtd->oobblock;
1074
1075 to += mtd->oobblock;
1076 }
1077
1078out:
1079 /* Deselect and wakt up anyone waiting on the device */
1080 onenand_release_device(mtd);
1081
1082 *retlen = written;
1083
1084 return 0;
1085}
1086
1087/**
1088 * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
1089 * @param mtd MTD device structure
1090 * @param vecs the iovectors to write
1091 * @param count number of vectors
1092 * @param to offset to write to
1093 * @param retlen pointer to variable to store the number of written bytes
1094 *
1095 * OneNAND write with kvec. This just calls the ecc function
1096 */
1097static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
1098 unsigned long count, loff_t to, size_t *retlen)
1099{
1100 return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
1101}
1102
1103/**
Kyungmin Parkcdc00132005-09-03 07:15:48 +01001104 * onenand_block_checkbad - [GENERIC] Check if a block is marked bad
1105 * @param mtd MTD device structure
1106 * @param ofs offset from device start
1107 * @param getchip 0, if the chip is already selected
1108 * @param allowbbt 1, if its allowed to access the bbt area
1109 *
1110 * Check, if the block is bad. Either by reading the bad block table or
1111 * calling of the scan function.
1112 */
1113static int onenand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
1114{
1115 struct onenand_chip *this = mtd->priv;
1116 struct bbm_info *bbm = this->bbm;
1117
1118 /* Return info from the table */
1119 return bbm->isbad_bbt(mtd, ofs, allowbbt);
1120}
1121
1122/**
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001123 * onenand_erase - [MTD Interface] erase block(s)
1124 * @param mtd MTD device structure
1125 * @param instr erase instruction
1126 *
1127 * Erase one ore more blocks
1128 */
1129static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1130{
1131 struct onenand_chip *this = mtd->priv;
1132 unsigned int block_size;
1133 loff_t addr;
1134 int len;
1135 int ret = 0;
1136
1137 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
1138
1139 block_size = (1 << this->erase_shift);
1140
1141 /* Start address must align on block boundary */
1142 if (unlikely(instr->addr & (block_size - 1))) {
1143 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
1144 return -EINVAL;
1145 }
1146
1147 /* Length must align on block boundary */
1148 if (unlikely(instr->len & (block_size - 1))) {
1149 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n");
1150 return -EINVAL;
1151 }
1152
1153 /* Do not allow erase past end of device */
1154 if (unlikely((instr->len + instr->addr) > mtd->size)) {
1155 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n");
1156 return -EINVAL;
1157 }
1158
1159 instr->fail_addr = 0xffffffff;
1160
1161 /* Grab the lock and see if the device is available */
1162 onenand_get_device(mtd, FL_ERASING);
1163
1164 /* Loop throught the pages */
1165 len = instr->len;
1166 addr = instr->addr;
1167
1168 instr->state = MTD_ERASING;
1169
1170 while (len) {
1171
Kyungmin Parkcdc00132005-09-03 07:15:48 +01001172 /* Check if we have a bad block, we do not erase bad blocks */
1173 if (onenand_block_checkbad(mtd, addr, 0, 0)) {
1174 printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr);
1175 instr->state = MTD_ERASE_FAILED;
1176 goto erase_exit;
1177 }
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001178
1179 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
1180
1181 ret = this->wait(mtd, FL_ERASING);
1182 /* Check, if it is write protected */
1183 if (ret) {
1184 if (ret == -EPERM)
1185 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");
1186 else
1187 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
1188 instr->state = MTD_ERASE_FAILED;
1189 instr->fail_addr = addr;
1190 goto erase_exit;
1191 }
1192
1193 len -= block_size;
1194 addr += block_size;
1195 }
1196
1197 instr->state = MTD_ERASE_DONE;
1198
1199erase_exit:
1200
1201 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
1202 /* Do call back function */
1203 if (!ret)
1204 mtd_erase_callback(instr);
1205
1206 /* Deselect and wake up anyone waiting on the device */
1207 onenand_release_device(mtd);
1208
1209 return ret;
1210}
1211
1212/**
1213 * onenand_sync - [MTD Interface] sync
1214 * @param mtd MTD device structure
1215 *
1216 * Sync is actually a wait for chip ready function
1217 */
1218static void onenand_sync(struct mtd_info *mtd)
1219{
1220 DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
1221
1222 /* Grab the lock and see if the device is available */
1223 onenand_get_device(mtd, FL_SYNCING);
1224
1225 /* Release it and go back */
1226 onenand_release_device(mtd);
1227}
1228
Kyungmin Parkcdc00132005-09-03 07:15:48 +01001229
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001230/**
1231 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
1232 * @param mtd MTD device structure
1233 * @param ofs offset relative to mtd start
Kyungmin Parkcdc00132005-09-03 07:15:48 +01001234 *
1235 * Check whether the block is bad
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001236 */
1237static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
1238{
Kyungmin Parkcdc00132005-09-03 07:15:48 +01001239 /* Check for invalid offset */
1240 if (ofs > mtd->size)
1241 return -EINVAL;
1242
1243 return onenand_block_checkbad(mtd, ofs, 1, 0);
1244}
1245
1246/**
1247 * onenand_default_block_markbad - [DEFAULT] mark a block bad
1248 * @param mtd MTD device structure
1249 * @param ofs offset from device start
1250 *
1251 * This is the default implementation, which can be overridden by
1252 * a hardware specific driver.
1253 */
1254static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1255{
1256 struct onenand_chip *this = mtd->priv;
1257 struct bbm_info *bbm = this->bbm;
1258 u_char buf[2] = {0, 0};
1259 size_t retlen;
1260 int block;
1261
1262 /* Get block number */
1263 block = ((int) ofs) >> bbm->bbt_erase_shift;
1264 if (bbm->bbt)
1265 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
1266
1267 /* We write two bytes, so we dont have to mess with 16 bit access */
1268 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1269 return mtd->write_oob(mtd, ofs , 2, &retlen, buf);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001270}
1271
1272/**
1273 * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
1274 * @param mtd MTD device structure
1275 * @param ofs offset relative to mtd start
Kyungmin Parkcdc00132005-09-03 07:15:48 +01001276 *
1277 * Mark the block as bad
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001278 */
1279static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1280{
Kyungmin Parkcdc00132005-09-03 07:15:48 +01001281 struct onenand_chip *this = mtd->priv;
1282 int ret;
1283
1284 ret = onenand_block_isbad(mtd, ofs);
1285 if (ret) {
1286 /* If it was bad already, return success and do nothing */
1287 if (ret > 0)
1288 return 0;
1289 return ret;
1290 }
1291
1292 return this->block_markbad(mtd, ofs);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001293}
1294
1295/**
1296 * onenand_unlock - [MTD Interface] Unlock block(s)
1297 * @param mtd MTD device structure
1298 * @param ofs offset relative to mtd start
1299 * @param len number of bytes to unlock
1300 *
1301 * Unlock one or more blocks
1302 */
1303static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1304{
1305 struct onenand_chip *this = mtd->priv;
1306 int start, end, block, value, status;
1307
1308 start = ofs >> this->erase_shift;
1309 end = len >> this->erase_shift;
1310
1311 /* Continuous lock scheme */
1312 if (this->options & ONENAND_CONT_LOCK) {
1313 /* Set start block address */
1314 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1315 /* Set end block address */
1316 this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1317 /* Write unlock command */
1318 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1319
1320 /* There's no return value */
1321 this->wait(mtd, FL_UNLOCKING);
1322
1323 /* Sanity check */
1324 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1325 & ONENAND_CTRL_ONGO)
1326 continue;
1327
1328 /* Check lock status */
1329 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1330 if (!(status & ONENAND_WP_US))
1331 printk(KERN_ERR "wp status = 0x%x\n", status);
1332
1333 return 0;
1334 }
1335
1336 /* Block lock scheme */
1337 for (block = start; block < end; block++) {
Kyungmin Park20ba89a2005-12-16 11:17:29 +09001338 /* Set block address */
1339 value = onenand_block_address(this, block);
1340 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1341 /* Select DataRAM for DDP */
1342 value = onenand_bufferram_address(this, block);
1343 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001344 /* Set start block address */
1345 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1346 /* Write unlock command */
1347 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1348
1349 /* There's no return value */
1350 this->wait(mtd, FL_UNLOCKING);
1351
1352 /* Sanity check */
1353 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1354 & ONENAND_CTRL_ONGO)
1355 continue;
1356
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001357 /* Check lock status */
1358 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1359 if (!(status & ONENAND_WP_US))
1360 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
1361 }
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +00001362
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001363 return 0;
1364}
1365
1366/**
1367 * onenand_print_device_info - Print device ID
1368 * @param device device ID
1369 *
1370 * Print device ID
1371 */
1372static void onenand_print_device_info(int device)
1373{
1374 int vcc, demuxed, ddp, density;
1375
1376 vcc = device & ONENAND_DEVICE_VCC_MASK;
1377 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
1378 ddp = device & ONENAND_DEVICE_IS_DDP;
1379 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
1380 printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
1381 demuxed ? "" : "Muxed ",
1382 ddp ? "(DDP)" : "",
1383 (16 << density),
1384 vcc ? "2.65/3.3" : "1.8",
1385 device);
1386}
1387
1388static const struct onenand_manufacturers onenand_manuf_ids[] = {
1389 {ONENAND_MFR_SAMSUNG, "Samsung"},
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001390};
1391
1392/**
1393 * onenand_check_maf - Check manufacturer ID
1394 * @param manuf manufacturer ID
1395 *
1396 * Check manufacturer ID
1397 */
1398static int onenand_check_maf(int manuf)
1399{
Kyungmin Park37b1cc32005-12-16 11:17:29 +09001400 int size = ARRAY_SIZE(onenand_manuf_ids);
1401 char *name;
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001402 int i;
1403
Kyungmin Park37b1cc32005-12-16 11:17:29 +09001404 for (i = 0; i < size; i++)
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001405 if (manuf == onenand_manuf_ids[i].id)
1406 break;
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001407
Kyungmin Park37b1cc32005-12-16 11:17:29 +09001408 if (i < size)
1409 name = onenand_manuf_ids[i].name;
1410 else
1411 name = "Unknown";
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001412
Kyungmin Park37b1cc32005-12-16 11:17:29 +09001413 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
1414
1415 return (i == size);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001416}
1417
1418/**
1419 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
1420 * @param mtd MTD device structure
1421 *
1422 * OneNAND detection method:
1423 * Compare the the values from command with ones from register
1424 */
1425static int onenand_probe(struct mtd_info *mtd)
1426{
1427 struct onenand_chip *this = mtd->priv;
1428 int bram_maf_id, bram_dev_id, maf_id, dev_id;
1429 int version_id;
1430 int density;
1431
1432 /* Send the command for reading device ID from BootRAM */
1433 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
1434
1435 /* Read manufacturer and device IDs from BootRAM */
1436 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
1437 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
1438
1439 /* Check manufacturer ID */
1440 if (onenand_check_maf(bram_maf_id))
1441 return -ENXIO;
1442
1443 /* Reset OneNAND to read default register values */
1444 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
1445
1446 /* Read manufacturer and device IDs from Register */
1447 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
1448 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
1449
1450 /* Check OneNAND device */
1451 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
1452 return -ENXIO;
1453
1454 /* Flash device information */
1455 onenand_print_device_info(dev_id);
1456 this->device_id = dev_id;
1457
1458 density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1459 this->chipsize = (16 << density) << 20;
Kyungmin Park83a36832005-09-29 04:53:16 +01001460 /* Set density mask. it is used for DDP */
1461 this->density_mask = (1 << (density + 6));
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001462
1463 /* OneNAND page size & block size */
1464 /* The data buffer size is equal to page size */
1465 mtd->oobblock = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1466 mtd->oobsize = mtd->oobblock >> 5;
1467 /* Pagers per block is always 64 in OneNAND */
1468 mtd->erasesize = mtd->oobblock << 6;
1469
1470 this->erase_shift = ffs(mtd->erasesize) - 1;
1471 this->page_shift = ffs(mtd->oobblock) - 1;
1472 this->ppb_shift = (this->erase_shift - this->page_shift);
1473 this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
1474
1475 /* REVIST: Multichip handling */
1476
1477 mtd->size = this->chipsize;
1478
1479 /* Version ID */
1480 version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
1481 printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
1482
1483 /* Lock scheme */
1484 if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
1485 !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
1486 printk(KERN_INFO "Lock scheme is Continues Lock\n");
1487 this->options |= ONENAND_CONT_LOCK;
1488 }
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +00001489
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001490 return 0;
1491}
1492
Kyungmin Parka41371e2005-09-29 03:55:31 +01001493/**
1494 * onenand_suspend - [MTD Interface] Suspend the OneNAND flash
1495 * @param mtd MTD device structure
1496 */
1497static int onenand_suspend(struct mtd_info *mtd)
1498{
1499 return onenand_get_device(mtd, FL_PM_SUSPENDED);
1500}
1501
1502/**
1503 * onenand_resume - [MTD Interface] Resume the OneNAND flash
1504 * @param mtd MTD device structure
1505 */
1506static void onenand_resume(struct mtd_info *mtd)
1507{
1508 struct onenand_chip *this = mtd->priv;
1509
1510 if (this->state == FL_PM_SUSPENDED)
1511 onenand_release_device(mtd);
1512 else
1513 printk(KERN_ERR "resume() called for the chip which is not"
1514 "in suspended state\n");
1515}
1516
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001517
1518/**
1519 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
1520 * @param mtd MTD device structure
1521 * @param maxchips Number of chips to scan for
1522 *
1523 * This fills out all the not initialized function pointers
1524 * with the defaults.
1525 * The flash ID is read and the mtd/chip structures are
1526 * filled with the appropriate values.
1527 */
1528int onenand_scan(struct mtd_info *mtd, int maxchips)
1529{
1530 struct onenand_chip *this = mtd->priv;
1531
1532 if (!this->read_word)
1533 this->read_word = onenand_readw;
1534 if (!this->write_word)
1535 this->write_word = onenand_writew;
1536
1537 if (!this->command)
1538 this->command = onenand_command;
1539 if (!this->wait)
1540 this->wait = onenand_wait;
1541
1542 if (!this->read_bufferram)
1543 this->read_bufferram = onenand_read_bufferram;
1544 if (!this->write_bufferram)
1545 this->write_bufferram = onenand_write_bufferram;
1546
Kyungmin Parkcdc00132005-09-03 07:15:48 +01001547 if (!this->block_markbad)
1548 this->block_markbad = onenand_default_block_markbad;
1549 if (!this->scan_bbt)
1550 this->scan_bbt = onenand_default_bbt;
1551
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001552 if (onenand_probe(mtd))
1553 return -ENXIO;
1554
Kyungmin Park52b0eea2005-09-03 07:07:19 +01001555 /* Set Sync. Burst Read after probing */
1556 if (this->mmcontrol) {
1557 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
1558 this->read_bufferram = onenand_sync_read_bufferram;
1559 }
1560
Kyungmin Park532a37c2005-12-16 11:17:29 +09001561 /* Allocate buffers, if necessary */
1562 if (!this->page_buf) {
1563 size_t len;
1564 len = mtd->oobblock + mtd->oobsize;
1565 this->page_buf = kmalloc(len, GFP_KERNEL);
1566 if (!this->page_buf) {
1567 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
1568 return -ENOMEM;
1569 }
1570 this->options |= ONENAND_PAGEBUF_ALLOC;
1571 }
1572
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001573 this->state = FL_READY;
1574 init_waitqueue_head(&this->wq);
1575 spin_lock_init(&this->chip_lock);
1576
1577 switch (mtd->oobsize) {
1578 case 64:
1579 this->autooob = &onenand_oob_64;
1580 break;
1581
1582 case 32:
1583 this->autooob = &onenand_oob_32;
1584 break;
1585
1586 default:
1587 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
1588 mtd->oobsize);
1589 /* To prevent kernel oops */
1590 this->autooob = &onenand_oob_32;
1591 break;
1592 }
1593
1594 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
Thomas Gleixnerd5c5e782005-11-07 11:15:51 +00001595
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001596 /* Fill in remaining MTD driver data */
1597 mtd->type = MTD_NANDFLASH;
1598 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
1599 mtd->ecctype = MTD_ECC_SW;
1600 mtd->erase = onenand_erase;
1601 mtd->point = NULL;
1602 mtd->unpoint = NULL;
1603 mtd->read = onenand_read;
1604 mtd->write = onenand_write;
1605 mtd->read_ecc = onenand_read_ecc;
1606 mtd->write_ecc = onenand_write_ecc;
1607 mtd->read_oob = onenand_read_oob;
1608 mtd->write_oob = onenand_write_oob;
1609 mtd->readv = NULL;
1610 mtd->readv_ecc = NULL;
1611 mtd->writev = onenand_writev;
1612 mtd->writev_ecc = onenand_writev_ecc;
1613 mtd->sync = onenand_sync;
1614 mtd->lock = NULL;
1615 mtd->unlock = onenand_unlock;
Kyungmin Parka41371e2005-09-29 03:55:31 +01001616 mtd->suspend = onenand_suspend;
1617 mtd->resume = onenand_resume;
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001618 mtd->block_isbad = onenand_block_isbad;
1619 mtd->block_markbad = onenand_block_markbad;
1620 mtd->owner = THIS_MODULE;
1621
1622 /* Unlock whole block */
1623 mtd->unlock(mtd, 0x0, this->chipsize);
1624
Kyungmin Parkcdc00132005-09-03 07:15:48 +01001625 return this->scan_bbt(mtd);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001626}
1627
1628/**
1629 * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
1630 * @param mtd MTD device structure
1631 */
1632void onenand_release(struct mtd_info *mtd)
1633{
Kyungmin Park532a37c2005-12-16 11:17:29 +09001634 struct onenand_chip *this = mtd->priv;
1635
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001636#ifdef CONFIG_MTD_PARTITIONS
1637 /* Deregister partitions */
1638 del_mtd_partitions (mtd);
1639#endif
1640 /* Deregister the device */
1641 del_mtd_device (mtd);
Kyungmin Park532a37c2005-12-16 11:17:29 +09001642
1643 /* Free bad block table memory, if allocated */
1644 if (this->bbm)
1645 kfree(this->bbm);
1646 /* Buffer allocated by onenand_scan */
1647 if (this->options & ONENAND_PAGEBUF_ALLOC)
1648 kfree(this->page_buf);
Kyungmin Parkcd5f6342005-07-11 11:41:53 +01001649}
1650
1651EXPORT_SYMBOL_GPL(onenand_scan);
1652EXPORT_SYMBOL_GPL(onenand_release);
1653
1654MODULE_LICENSE("GPL");
1655MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
1656MODULE_DESCRIPTION("Generic OneNAND flash driver code");