]> git.sur5r.net Git - u-boot/blob - drivers/mtd/onenand/onenand_base.c
Add Flex-OneNAND booting support
[u-boot] / drivers / mtd / onenand / onenand_base.c
1 /*
2  *  linux/drivers/mtd/onenand/onenand_base.c
3  *
4  *  Copyright (C) 2005-2007 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 <common.h>
13
14 #ifdef CONFIG_CMD_ONENAND
15
16 #include <linux/mtd/compat.h>
17 #include <linux/mtd/mtd.h>
18 #include <linux/mtd/onenand.h>
19
20 #include <asm/io.h>
21 #include <asm/errno.h>
22
23 static const unsigned char ffchars[] = {
24         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
25         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
26         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
27         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
28         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
29         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
30         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
31         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
32 };
33
34 /**
35  * onenand_readw - [OneNAND Interface] Read OneNAND register
36  * @param addr          address to read
37  *
38  * Read OneNAND register
39  */
40 static unsigned short onenand_readw(void __iomem * addr)
41 {
42         return readw(addr);
43 }
44
45 /**
46  * onenand_writew - [OneNAND Interface] Write OneNAND register with value
47  * @param value         value to write
48  * @param addr          address to write
49  *
50  * Write OneNAND register with value
51  */
52 static void onenand_writew(unsigned short value, void __iomem * addr)
53 {
54         writew(value, addr);
55 }
56
57 /**
58  * onenand_block_address - [DEFAULT] Get block address
59  * @param device        the device id
60  * @param block         the block
61  * @return              translated block address if DDP, otherwise same
62  *
63  * Setup Start Address 1 Register (F100h)
64  */
65 static int onenand_block_address(int device, int block)
66 {
67         if (device & ONENAND_DEVICE_IS_DDP) {
68                 /* Device Flash Core select, NAND Flash Block Address */
69                 int dfs = 0, density, mask;
70
71                 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
72                 mask = (1 << (density + 6));
73
74                 if (block & mask)
75                         dfs = 1;
76
77                 return (dfs << ONENAND_DDP_SHIFT) | (block & (mask - 1));
78         }
79
80         return block;
81 }
82
83 /**
84  * onenand_bufferram_address - [DEFAULT] Get bufferram address
85  * @param device        the device id
86  * @param block         the block
87  * @return              set DBS value if DDP, otherwise 0
88  *
89  * Setup Start Address 2 Register (F101h) for DDP
90  */
91 static int onenand_bufferram_address(int device, int block)
92 {
93         if (device & ONENAND_DEVICE_IS_DDP) {
94                 /* Device BufferRAM Select */
95                 int dbs = 0, density, mask;
96
97                 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
98                 mask = (1 << (density + 6));
99
100                 if (block & mask)
101                         dbs = 1;
102
103                 return (dbs << ONENAND_DDP_SHIFT);
104         }
105
106         return 0;
107 }
108
109 /**
110  * onenand_page_address - [DEFAULT] Get page address
111  * @param page          the page address
112  * @param sector        the sector address
113  * @return              combined page and sector address
114  *
115  * Setup Start Address 8 Register (F107h)
116  */
117 static int onenand_page_address(int page, int sector)
118 {
119         /* Flash Page Address, Flash Sector Address */
120         int fpa, fsa;
121
122         fpa = page & ONENAND_FPA_MASK;
123         fsa = sector & ONENAND_FSA_MASK;
124
125         return ((fpa << ONENAND_FPA_SHIFT) | fsa);
126 }
127
128 /**
129  * onenand_buffer_address - [DEFAULT] Get buffer address
130  * @param dataram1      DataRAM index
131  * @param sectors       the sector address
132  * @param count         the number of sectors
133  * @return              the start buffer value
134  *
135  * Setup Start Buffer Register (F200h)
136  */
137 static int onenand_buffer_address(int dataram1, int sectors, int count)
138 {
139         int bsa, bsc;
140
141         /* BufferRAM Sector Address */
142         bsa = sectors & ONENAND_BSA_MASK;
143
144         if (dataram1)
145                 bsa |= ONENAND_BSA_DATARAM1;    /* DataRAM1 */
146         else
147                 bsa |= ONENAND_BSA_DATARAM0;    /* DataRAM0 */
148
149         /* BufferRAM Sector Count */
150         bsc = count & ONENAND_BSC_MASK;
151
152         return ((bsa << ONENAND_BSA_SHIFT) | bsc);
153 }
154
155 /**
156  * onenand_command - [DEFAULT] Send command to OneNAND device
157  * @param mtd           MTD device structure
158  * @param cmd           the command to be sent
159  * @param addr          offset to read from or write to
160  * @param len           number of bytes to read or write
161  *
162  * Send command to OneNAND device. This function is used for middle/large page
163  * devices (1KB/2KB Bytes per page)
164  */
165 static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
166                            size_t len)
167 {
168         struct onenand_chip *this = mtd->priv;
169         int value, readcmd = 0;
170         int block, page;
171         /* Now we use page size operation */
172         int sectors = 4, count = 4;
173
174         /* Address translation */
175         switch (cmd) {
176         case ONENAND_CMD_UNLOCK:
177         case ONENAND_CMD_LOCK:
178         case ONENAND_CMD_LOCK_TIGHT:
179                 block = -1;
180                 page = -1;
181                 break;
182
183         case ONENAND_CMD_ERASE:
184         case ONENAND_CMD_BUFFERRAM:
185                 block = (int)(addr >> this->erase_shift);
186                 page = -1;
187                 break;
188
189         default:
190                 block = (int)(addr >> this->erase_shift);
191                 page = (int)(addr >> this->page_shift);
192                 page &= this->page_mask;
193                 break;
194         }
195
196         /* NOTE: The setting order of the registers is very important! */
197         if (cmd == ONENAND_CMD_BUFFERRAM) {
198                 /* Select DataRAM for DDP */
199                 value = onenand_bufferram_address(this->device_id, block);
200                 this->write_word(value,
201                                  this->base + ONENAND_REG_START_ADDRESS2);
202
203                 /* Switch to the next data buffer */
204                 ONENAND_SET_NEXT_BUFFERRAM(this);
205
206                 return 0;
207         }
208
209         if (block != -1) {
210                 /* Write 'DFS, FBA' of Flash */
211                 value = onenand_block_address(this->device_id, block);
212                 this->write_word(value,
213                                  this->base + ONENAND_REG_START_ADDRESS1);
214         }
215
216         if (page != -1) {
217                 int dataram;
218
219                 switch (cmd) {
220                 case ONENAND_CMD_READ:
221                 case ONENAND_CMD_READOOB:
222                         dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
223                         readcmd = 1;
224                         break;
225
226                 default:
227                         dataram = ONENAND_CURRENT_BUFFERRAM(this);
228                         break;
229                 }
230
231                 /* Write 'FPA, FSA' of Flash */
232                 value = onenand_page_address(page, sectors);
233                 this->write_word(value,
234                                  this->base + ONENAND_REG_START_ADDRESS8);
235
236                 /* Write 'BSA, BSC' of DataRAM */
237                 value = onenand_buffer_address(dataram, sectors, count);
238                 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
239
240                 if (readcmd) {
241                         /* Select DataRAM for DDP */
242                         value =
243                             onenand_bufferram_address(this->device_id, block);
244                         this->write_word(value,
245                                          this->base +
246                                          ONENAND_REG_START_ADDRESS2);
247                 }
248         }
249
250         /* Interrupt clear */
251         this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
252         /* Write command */
253         this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
254
255         return 0;
256 }
257
258 /**
259  * onenand_wait - [DEFAULT] wait until the command is done
260  * @param mtd           MTD device structure
261  * @param state         state to select the max. timeout value
262  *
263  * Wait for command done. This applies to all OneNAND command
264  * Read can take up to 30us, erase up to 2ms and program up to 350us
265  * according to general OneNAND specs
266  */
267 static int onenand_wait(struct mtd_info *mtd, int state)
268 {
269         struct onenand_chip *this = mtd->priv;
270         unsigned int flags = ONENAND_INT_MASTER;
271         unsigned int interrupt = 0;
272         unsigned int ctrl, ecc;
273
274         while (1) {
275                 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
276                 if (interrupt & flags)
277                         break;
278         }
279
280         ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
281
282         if (ctrl & ONENAND_CTRL_ERROR) {
283                 DEBUG(MTD_DEBUG_LEVEL0,
284                       "onenand_wait: controller error = 0x%04x\n", ctrl);
285                 return -EAGAIN;
286         }
287
288         if (ctrl & ONENAND_CTRL_LOCK) {
289                 DEBUG(MTD_DEBUG_LEVEL0,
290                       "onenand_wait: it's locked error = 0x%04x\n", ctrl);
291                 return -EIO;
292         }
293
294         if (interrupt & ONENAND_INT_READ) {
295                 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
296                 if (ecc & ONENAND_ECC_2BIT_ALL) {
297                         DEBUG(MTD_DEBUG_LEVEL0,
298                               "onenand_wait: ECC error = 0x%04x\n", ecc);
299                         return -EBADMSG;
300                 }
301         }
302
303         return 0;
304 }
305
306 /**
307  * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
308  * @param mtd           MTD data structure
309  * @param area          BufferRAM area
310  * @return              offset given area
311  *
312  * Return BufferRAM offset given area
313  */
314 static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
315 {
316         struct onenand_chip *this = mtd->priv;
317
318         if (ONENAND_CURRENT_BUFFERRAM(this)) {
319                 if (area == ONENAND_DATARAM)
320                         return mtd->oobblock;
321                 if (area == ONENAND_SPARERAM)
322                         return mtd->oobsize;
323         }
324
325         return 0;
326 }
327
328 /**
329  * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
330  * @param mtd           MTD data structure
331  * @param area          BufferRAM area
332  * @param buffer        the databuffer to put/get data
333  * @param offset        offset to read from or write to
334  * @param count         number of bytes to read/write
335  *
336  * Read the BufferRAM area
337  */
338 static int onenand_read_bufferram(struct mtd_info *mtd, int area,
339                                   unsigned char *buffer, int offset,
340                                   size_t count)
341 {
342         struct onenand_chip *this = mtd->priv;
343         void __iomem *bufferram;
344
345         bufferram = this->base + area;
346         bufferram += onenand_bufferram_offset(mtd, area);
347
348         memcpy(buffer, bufferram + offset, count);
349
350         return 0;
351 }
352
353 /**
354  * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
355  * @param mtd           MTD data structure
356  * @param area          BufferRAM area
357  * @param buffer        the databuffer to put/get data
358  * @param offset        offset to read from or write to
359  * @param count         number of bytes to read/write
360  *
361  * Read the BufferRAM area with Sync. Burst Mode
362  */
363 static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
364                                        unsigned char *buffer, int offset,
365                                        size_t count)
366 {
367         struct onenand_chip *this = mtd->priv;
368         void __iomem *bufferram;
369
370         bufferram = this->base + area;
371         bufferram += onenand_bufferram_offset(mtd, area);
372
373         this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
374
375         memcpy(buffer, bufferram + offset, count);
376
377         this->mmcontrol(mtd, 0);
378
379         return 0;
380 }
381
382 /**
383  * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
384  * @param mtd           MTD data structure
385  * @param area          BufferRAM area
386  * @param buffer        the databuffer to put/get data
387  * @param offset        offset to read from or write to
388  * @param count         number of bytes to read/write
389  *
390  * Write the BufferRAM area
391  */
392 static int onenand_write_bufferram(struct mtd_info *mtd, int area,
393                                    const unsigned char *buffer, int offset,
394                                    size_t count)
395 {
396         struct onenand_chip *this = mtd->priv;
397         void __iomem *bufferram;
398
399         bufferram = this->base + area;
400         bufferram += onenand_bufferram_offset(mtd, area);
401
402         memcpy(bufferram + offset, buffer, count);
403
404         return 0;
405 }
406
407 /**
408  * onenand_check_bufferram - [GENERIC] Check BufferRAM information
409  * @param mtd           MTD data structure
410  * @param addr          address to check
411  * @return              1 if there are valid data, otherwise 0
412  *
413  * Check bufferram if there is data we required
414  */
415 static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
416 {
417         struct onenand_chip *this = mtd->priv;
418         int block, page;
419         int i;
420
421         block = (int)(addr >> this->erase_shift);
422         page = (int)(addr >> this->page_shift);
423         page &= this->page_mask;
424
425         i = ONENAND_CURRENT_BUFFERRAM(this);
426
427         /* Is there valid data? */
428         if (this->bufferram[i].block == block &&
429             this->bufferram[i].page == page && 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  */
443 static 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  */
477 static void onenand_get_device(struct mtd_info *mtd, int new_state)
478 {
479         /* Do nothing */
480 }
481
482 /**
483  * onenand_release_device - [GENERIC] release chip
484  * @param mtd           MTD device structure
485  *
486  * Deselect, release chip lock and wake up anyone waiting on the device
487  */
488 static void onenand_release_device(struct mtd_info *mtd)
489 {
490         /* Do nothing */
491 }
492
493 /**
494  * onenand_read_ecc - [MTD Interface] Read data with ECC
495  * @param mtd           MTD device structure
496  * @param from          offset to read from
497  * @param len           number of bytes to read
498  * @param retlen        pointer to variable to store the number of read bytes
499  * @param buf           the databuffer to put data
500  * @param oob_buf       filesystem supplied oob data buffer
501  * @param oobsel        oob selection structure
502  *
503  * OneNAND read with ECC
504  */
505 static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
506                             size_t * retlen, u_char * buf,
507                             u_char * oob_buf, struct nand_oobinfo *oobsel)
508 {
509         struct onenand_chip *this = mtd->priv;
510         int read = 0, column;
511         int thislen;
512         int ret = 0;
513
514         DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n",
515               (unsigned int)from, (int)len);
516
517         /* Do not allow reads past end of device */
518         if ((from + len) > mtd->size) {
519                 DEBUG(MTD_DEBUG_LEVEL0,
520                       "onenand_read_ecc: Attempt read beyond end of device\n");
521                 *retlen = 0;
522                 return -EINVAL;
523         }
524
525         /* Grab the lock and see if the device is available */
526         onenand_get_device(mtd, FL_READING);
527
528         while (read < len) {
529                 thislen = min_t(int, mtd->oobblock, len - read);
530
531                 column = from & (mtd->oobblock - 1);
532                 if (column + thislen > mtd->oobblock)
533                         thislen = mtd->oobblock - column;
534
535                 if (!onenand_check_bufferram(mtd, from)) {
536                         this->command(mtd, ONENAND_CMD_READ, from,
537                                       mtd->oobblock);
538                         ret = this->wait(mtd, FL_READING);
539                         /* First copy data and check return value for ECC handling */
540                         onenand_update_bufferram(mtd, from, 1);
541                 }
542
543                 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column,
544                                      thislen);
545
546                 read += thislen;
547                 if (read == len)
548                         break;
549
550                 if (ret) {
551                         DEBUG(MTD_DEBUG_LEVEL0,
552                               "onenand_read_ecc: read failed = %d\n", ret);
553                         break;
554                 }
555
556                 from += thislen;
557                 buf += thislen;
558         }
559
560         /* Deselect and wake up anyone waiting on the device */
561         onenand_release_device(mtd);
562
563         /*
564          * Return success, if no ECC failures, else -EBADMSG
565          * fs driver will take care of that, because
566          * retlen == desired len and result == -EBADMSG
567          */
568         *retlen = read;
569         return ret;
570 }
571
572 /**
573  * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
574  * @param mtd           MTD device structure
575  * @param from          offset to read from
576  * @param len           number of bytes to read
577  * @param retlen        pointer to variable to store the number of read bytes
578  * @param buf           the databuffer to put data
579  *
580  * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
581 */
582 int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
583                  size_t * retlen, u_char * buf)
584 {
585         return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
586 }
587
588 /**
589  * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
590  * @param mtd           MTD device structure
591  * @param from          offset to read from
592  * @param len           number of bytes to read
593  * @param retlen        pointer to variable to store the number of read bytes
594  * @param buf           the databuffer to put data
595  *
596  * OneNAND read out-of-band data from the spare area
597  */
598 int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
599                      size_t * retlen, u_char * buf)
600 {
601         struct onenand_chip *this = mtd->priv;
602         int read = 0, thislen, column;
603         int ret = 0;
604
605         DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n",
606               (unsigned int)from, (int)len);
607
608         /* Initialize return length value */
609         *retlen = 0;
610
611         /* Do not allow reads past end of device */
612         if (unlikely((from + len) > mtd->size)) {
613                 DEBUG(MTD_DEBUG_LEVEL0,
614                       "onenand_read_oob: Attempt read beyond end of device\n");
615                 return -EINVAL;
616         }
617
618         /* Grab the lock and see if the device is available */
619         onenand_get_device(mtd, FL_READING);
620
621         column = from & (mtd->oobsize - 1);
622
623         while (read < len) {
624                 thislen = mtd->oobsize - column;
625                 thislen = min_t(int, thislen, len);
626
627                 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
628
629                 onenand_update_bufferram(mtd, from, 0);
630
631                 ret = this->wait(mtd, FL_READING);
632                 /* First copy data and check return value for ECC handling */
633
634                 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column,
635                                      thislen);
636
637                 read += thislen;
638                 if (read == len)
639                         break;
640
641                 if (ret) {
642                         DEBUG(MTD_DEBUG_LEVEL0,
643                               "onenand_read_oob: read failed = %d\n", ret);
644                         break;
645                 }
646
647                 buf += thislen;
648                 /* Read more? */
649                 if (read < len) {
650                         /* Page size */
651                         from += mtd->oobblock;
652                         column = 0;
653                 }
654         }
655
656         /* Deselect and wake up anyone waiting on the device */
657         onenand_release_device(mtd);
658
659         *retlen = read;
660         return ret;
661 }
662
663 #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
664 /**
665  * onenand_verify_page - [GENERIC] verify the chip contents after a write
666  * @param mtd           MTD device structure
667  * @param buf           the databuffer to verify
668  * @param block         block address
669  * @param page          page address
670  *
671  * Check DataRAM area directly
672  */
673 static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
674                                loff_t addr, int block, int page)
675 {
676         struct onenand_chip *this = mtd->priv;
677         void __iomem *dataram0, *dataram1;
678         int ret = 0;
679
680         this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
681
682         ret = this->wait(mtd, FL_READING);
683         if (ret)
684                 return ret;
685
686         onenand_update_bufferram(mtd, addr, 1);
687
688         /* Check, if the two dataram areas are same */
689         dataram0 = this->base + ONENAND_DATARAM;
690         dataram1 = dataram0 + mtd->oobblock;
691
692         if (memcmp(dataram0, dataram1, mtd->oobblock))
693                 return -EBADMSG;
694
695         return 0;
696 }
697 #else
698 #define onenand_verify_page(...)        (0)
699 #endif
700
701 #define NOTALIGNED(x)   ((x & (mtd->oobblock - 1)) != 0)
702
703 /**
704  * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
705  * @param mtd           MTD device structure
706  * @param to            offset to write to
707  * @param len           number of bytes to write
708  * @param retlen        pointer to variable to store the number of written bytes
709  * @param buf           the data to write
710  * @param eccbuf        filesystem supplied oob data buffer
711  * @param oobsel        oob selection structure
712  *
713  * OneNAND write with ECC
714  */
715 static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
716                              size_t * retlen, const u_char * buf,
717                              u_char * eccbuf, struct nand_oobinfo *oobsel)
718 {
719         struct onenand_chip *this = mtd->priv;
720         int written = 0;
721         int ret = 0;
722
723         DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n",
724               (unsigned int)to, (int)len);
725
726         /* Initialize retlen, in case of early exit */
727         *retlen = 0;
728
729         /* Do not allow writes past end of device */
730         if (unlikely((to + len) > mtd->size)) {
731                 DEBUG(MTD_DEBUG_LEVEL0,
732                       "onenand_write_ecc: Attempt write to past end of device\n");
733                 return -EINVAL;
734         }
735
736         /* Reject writes, which are not page aligned */
737         if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
738                 DEBUG(MTD_DEBUG_LEVEL0,
739                       "onenand_write_ecc: Attempt to write not page aligned data\n");
740                 return -EINVAL;
741         }
742
743         /* Grab the lock and see if the device is available */
744         onenand_get_device(mtd, FL_WRITING);
745
746         /* Loop until all data write */
747         while (written < len) {
748                 int thislen = min_t(int, mtd->oobblock, len - written);
749
750                 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
751
752                 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
753                 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
754                                       mtd->oobsize);
755
756                 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
757
758                 onenand_update_bufferram(mtd, to, 1);
759
760                 ret = this->wait(mtd, FL_WRITING);
761                 if (ret) {
762                         DEBUG(MTD_DEBUG_LEVEL0,
763                               "onenand_write_ecc: write filaed %d\n", ret);
764                         break;
765                 }
766
767                 written += thislen;
768
769                 /* Only check verify write turn on */
770                 ret = onenand_verify_page(mtd, (u_char *) buf, to, block, page);
771                 if (ret) {
772                         DEBUG(MTD_DEBUG_LEVEL0,
773                               "onenand_write_ecc: verify failed %d\n", ret);
774                         break;
775                 }
776
777                 if (written == len)
778                         break;
779
780                 to += thislen;
781                 buf += thislen;
782         }
783
784         /* Deselect and wake up anyone waiting on the device */
785         onenand_release_device(mtd);
786
787         *retlen = written;
788
789         return ret;
790 }
791
792 /**
793  * onenand_write - [MTD Interface] compability function for onenand_write_ecc
794  * @param mtd           MTD device structure
795  * @param to            offset to write to
796  * @param len           number of bytes to write
797  * @param retlen        pointer to variable to store the number of written bytes
798  * @param buf           the data to write
799  *
800  * This function simply calls onenand_write_ecc
801  * with oob buffer and oobsel = NULL
802  */
803 int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
804                   size_t * retlen, const u_char * buf)
805 {
806         return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
807 }
808
809 /**
810  * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
811  * @param mtd           MTD device structure
812  * @param to            offset to write to
813  * @param len           number of bytes to write
814  * @param retlen        pointer to variable to store the number of written bytes
815  * @param buf           the data to write
816  *
817  * OneNAND write out-of-band
818  */
819 int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
820                       size_t * retlen, const u_char * buf)
821 {
822         struct onenand_chip *this = mtd->priv;
823         int column, status;
824         int written = 0;
825
826         DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n",
827               (unsigned int)to, (int)len);
828
829         /* Initialize retlen, in case of early exit */
830         *retlen = 0;
831
832         /* Do not allow writes past end of device */
833         if (unlikely((to + len) > mtd->size)) {
834                 DEBUG(MTD_DEBUG_LEVEL0,
835                       "onenand_write_oob: Attempt write to past end of device\n");
836                 return -EINVAL;
837         }
838
839         /* Grab the lock and see if the device is available */
840         onenand_get_device(mtd, FL_WRITING);
841
842         /* Loop until all data write */
843         while (written < len) {
844                 int thislen = min_t(int, mtd->oobsize, len - written);
845
846                 column = to & (mtd->oobsize - 1);
847
848                 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
849
850                 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
851                                       mtd->oobsize);
852                 this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column,
853                                       thislen);
854
855                 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
856
857                 onenand_update_bufferram(mtd, to, 0);
858
859                 status = this->wait(mtd, FL_WRITING);
860                 if (status)
861                         break;
862
863                 written += thislen;
864                 if (written == len)
865                         break;
866
867                 to += thislen;
868                 buf += thislen;
869         }
870
871         /* Deselect and wake up anyone waiting on the device */
872         onenand_release_device(mtd);
873
874         *retlen = written;
875
876         return 0;
877 }
878
879 /**
880  * onenand_erase - [MTD Interface] erase block(s)
881  * @param mtd           MTD device structure
882  * @param instr         erase instruction
883  *
884  * Erase one ore more blocks
885  */
886 int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
887 {
888         struct onenand_chip *this = mtd->priv;
889         unsigned int block_size;
890         loff_t addr;
891         int len;
892         int ret = 0;
893
894         DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n",
895               (unsigned int)instr->addr, (unsigned int)instr->len);
896
897         block_size = (1 << this->erase_shift);
898
899         /* Start address must align on block boundary */
900         if (unlikely(instr->addr & (block_size - 1))) {
901                 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
902                 return -EINVAL;
903         }
904
905         /* Length must align on block boundary */
906         if (unlikely(instr->len & (block_size - 1))) {
907                 DEBUG(MTD_DEBUG_LEVEL0,
908                       "onenand_erase: Length not block aligned\n");
909                 return -EINVAL;
910         }
911
912         /* Do not allow erase past end of device */
913         if (unlikely((instr->len + instr->addr) > mtd->size)) {
914                 DEBUG(MTD_DEBUG_LEVEL0,
915                       "onenand_erase: Erase past end of device\n");
916                 return -EINVAL;
917         }
918
919         instr->fail_addr = 0xffffffff;
920
921         /* Grab the lock and see if the device is available */
922         onenand_get_device(mtd, FL_ERASING);
923
924         /* Loop throught the pages */
925         len = instr->len;
926         addr = instr->addr;
927
928         instr->state = MTD_ERASING;
929
930         while (len) {
931
932                 /* TODO Check badblock */
933
934                 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
935
936                 ret = this->wait(mtd, FL_ERASING);
937                 /* Check, if it is write protected */
938                 if (ret) {
939                         if (ret == -EPERM)
940                                 DEBUG(MTD_DEBUG_LEVEL0,
941                                       "onenand_erase: Device is write protected!!!\n");
942                         else
943                                 DEBUG(MTD_DEBUG_LEVEL0,
944                                       "onenand_erase: Failed erase, block %d\n",
945                                       (unsigned)(addr >> this->erase_shift));
946                         instr->state = MTD_ERASE_FAILED;
947                         instr->fail_addr = addr;
948                         goto erase_exit;
949                 }
950
951                 len -= block_size;
952                 addr += block_size;
953         }
954
955         instr->state = MTD_ERASE_DONE;
956
957       erase_exit:
958
959         ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
960         /* Do call back function */
961         if (!ret)
962                 mtd_erase_callback(instr);
963
964         /* Deselect and wake up anyone waiting on the device */
965         onenand_release_device(mtd);
966
967         return ret;
968 }
969
970 /**
971  * onenand_sync - [MTD Interface] sync
972  * @param mtd           MTD device structure
973  *
974  * Sync is actually a wait for chip ready function
975  */
976 void onenand_sync(struct mtd_info *mtd)
977 {
978         DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
979
980         /* Grab the lock and see if the device is available */
981         onenand_get_device(mtd, FL_SYNCING);
982
983         /* Release it and go back */
984         onenand_release_device(mtd);
985 }
986
987 /**
988  * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
989  * @param mtd           MTD device structure
990  * @param ofs           offset relative to mtd start
991  */
992 int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
993 {
994         /*
995          * TODO
996          * 1. Bad block table (BBT)
997          *   -> using NAND BBT to support JFFS2
998          * 2. Bad block management (BBM)
999          *   -> bad block replace scheme
1000          *
1001          * Currently we do nothing
1002          */
1003         return 0;
1004 }
1005
1006 /**
1007  * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
1008  * @param mtd           MTD device structure
1009  * @param ofs           offset relative to mtd start
1010  */
1011 int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1012 {
1013         /* see above */
1014         return 0;
1015 }
1016
1017 /**
1018  * onenand_unlock - [MTD Interface] Unlock block(s)
1019  * @param mtd           MTD device structure
1020  * @param ofs           offset relative to mtd start
1021  * @param len           number of bytes to unlock
1022  *
1023  * Unlock one or more blocks
1024  */
1025 int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1026 {
1027         struct onenand_chip *this = mtd->priv;
1028         int start, end, block, value, status;
1029
1030         start = ofs >> this->erase_shift;
1031         end = len >> this->erase_shift;
1032
1033         /* Continuous lock scheme */
1034         if (this->options & ONENAND_CONT_LOCK) {
1035                 /* Set start block address */
1036                 this->write_word(start,
1037                                  this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1038                 /* Set end block address */
1039                 this->write_word(end - 1,
1040                                  this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1041                 /* Write unlock command */
1042                 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1043
1044                 /* There's no return value */
1045                 this->wait(mtd, FL_UNLOCKING);
1046
1047                 /* Sanity check */
1048                 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1049                        & ONENAND_CTRL_ONGO)
1050                         continue;
1051
1052                 /* Check lock status */
1053                 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1054                 if (!(status & ONENAND_WP_US))
1055                         printk(KERN_ERR "wp status = 0x%x\n", status);
1056
1057                 return 0;
1058         }
1059
1060         /* Block lock scheme */
1061         for (block = start; block < end; block++) {
1062                 /* Set start block address */
1063                 this->write_word(block,
1064                                  this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1065                 /* Write unlock command */
1066                 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1067
1068                 /* There's no return value */
1069                 this->wait(mtd, FL_UNLOCKING);
1070
1071                 /* Sanity check */
1072                 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1073                        & ONENAND_CTRL_ONGO)
1074                         continue;
1075
1076                 /* Set block address for read block status */
1077                 value = onenand_block_address(this->device_id, block);
1078                 this->write_word(value,
1079                                  this->base + ONENAND_REG_START_ADDRESS1);
1080
1081                 /* Check lock status */
1082                 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1083                 if (!(status & ONENAND_WP_US))
1084                         printk(KERN_ERR "block = %d, wp status = 0x%x\n",
1085                                block, status);
1086         }
1087
1088         return 0;
1089 }
1090
1091 /**
1092  * onenand_print_device_info - Print device ID
1093  * @param device        device ID
1094  *
1095  * Print device ID
1096  */
1097 void onenand_print_device_info(int device, int verbose)
1098 {
1099         int vcc, demuxed, ddp, density;
1100
1101         if (!verbose)
1102                 return;
1103
1104         vcc = device & ONENAND_DEVICE_VCC_MASK;
1105         demuxed = device & ONENAND_DEVICE_IS_DEMUX;
1106         ddp = device & ONENAND_DEVICE_IS_DDP;
1107         density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
1108         printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
1109                demuxed ? "" : "Muxed ",
1110                ddp ? "(DDP)" : "",
1111                (16 << density), vcc ? "2.65/3.3" : "1.8", device);
1112 }
1113
1114 static const struct onenand_manufacturers onenand_manuf_ids[] = {
1115         {ONENAND_MFR_SAMSUNG, "Samsung"},
1116         {ONENAND_MFR_UNKNOWN, "Unknown"}
1117 };
1118
1119 /**
1120  * onenand_check_maf - Check manufacturer ID
1121  * @param manuf         manufacturer ID
1122  *
1123  * Check manufacturer ID
1124  */
1125 static int onenand_check_maf(int manuf)
1126 {
1127         int i;
1128
1129         for (i = 0; onenand_manuf_ids[i].id; i++) {
1130                 if (manuf == onenand_manuf_ids[i].id)
1131                         break;
1132         }
1133
1134 #ifdef ONENAND_DEBUG
1135         printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
1136                onenand_manuf_ids[i].name, manuf);
1137 #endif
1138
1139         return (i != ONENAND_MFR_UNKNOWN);
1140 }
1141
1142 /**
1143  * onenand_probe - [OneNAND Interface] Probe the OneNAND device
1144  * @param mtd           MTD device structure
1145  *
1146  * OneNAND detection method:
1147  *   Compare the the values from command with ones from register
1148  */
1149 static int onenand_probe(struct mtd_info *mtd)
1150 {
1151         struct onenand_chip *this = mtd->priv;
1152         int bram_maf_id, bram_dev_id, maf_id, dev_id;
1153         int version_id;
1154         int density;
1155
1156         /* Send the command for reading device ID from BootRAM */
1157         this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
1158
1159         /* Read manufacturer and device IDs from BootRAM */
1160         bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
1161         bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
1162
1163         /* Check manufacturer ID */
1164         if (onenand_check_maf(bram_maf_id))
1165                 return -ENXIO;
1166
1167         /* Reset OneNAND to read default register values */
1168         this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
1169
1170         {
1171                 int i;
1172                 for (i = 0; i < 10000; i++) ;
1173         }
1174
1175         /* Read manufacturer and device IDs from Register */
1176         maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
1177         dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
1178
1179         /* Check OneNAND device */
1180         if (maf_id != bram_maf_id || dev_id != bram_dev_id)
1181                 return -ENXIO;
1182
1183         /* FIXME : Current OneNAND MTD doesn't support Flex-OneNAND */
1184         if (dev_id & (1 << 9)) {
1185                 printk("Not yet support Flex-OneNAND\n");
1186                 return -ENXIO;
1187         }
1188
1189         /* Flash device information */
1190         onenand_print_device_info(dev_id, 0);
1191         this->device_id = dev_id;
1192
1193         density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1194         this->chipsize = (16 << density) << 20;
1195
1196         /* OneNAND page size & block size */
1197         /* The data buffer size is equal to page size */
1198         mtd->oobblock =
1199             this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1200         mtd->oobsize = mtd->oobblock >> 5;
1201         /* Pagers per block is always 64 in OneNAND */
1202         mtd->erasesize = mtd->oobblock << 6;
1203
1204         this->erase_shift = ffs(mtd->erasesize) - 1;
1205         this->page_shift = ffs(mtd->oobblock) - 1;
1206         this->ppb_shift = (this->erase_shift - this->page_shift);
1207         this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
1208
1209         /* REVIST: Multichip handling */
1210
1211         mtd->size = this->chipsize;
1212
1213         /* Version ID */
1214         version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
1215 #ifdef ONENAND_DEBUG
1216         printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
1217 #endif
1218
1219         /* Lock scheme */
1220         if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
1221             !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
1222                 printk(KERN_INFO "Lock scheme is Continues Lock\n");
1223                 this->options |= ONENAND_CONT_LOCK;
1224         }
1225
1226         return 0;
1227 }
1228
1229 /**
1230  * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
1231  * @param mtd           MTD device structure
1232  * @param maxchips      Number of chips to scan for
1233  *
1234  * This fills out all the not initialized function pointers
1235  * with the defaults.
1236  * The flash ID is read and the mtd/chip structures are
1237  * filled with the appropriate values.
1238  */
1239 int onenand_scan(struct mtd_info *mtd, int maxchips)
1240 {
1241         struct onenand_chip *this = mtd->priv;
1242
1243         if (!this->read_word)
1244                 this->read_word = onenand_readw;
1245         if (!this->write_word)
1246                 this->write_word = onenand_writew;
1247
1248         if (!this->command)
1249                 this->command = onenand_command;
1250         if (!this->wait)
1251                 this->wait = onenand_wait;
1252
1253         if (!this->read_bufferram)
1254                 this->read_bufferram = onenand_read_bufferram;
1255         if (!this->write_bufferram)
1256                 this->write_bufferram = onenand_write_bufferram;
1257
1258         if (onenand_probe(mtd))
1259                 return -ENXIO;
1260
1261         /* Set Sync. Burst Read after probing */
1262         if (this->mmcontrol) {
1263                 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
1264                 this->read_bufferram = onenand_sync_read_bufferram;
1265         }
1266
1267         onenand_unlock(mtd, 0, mtd->size);
1268
1269         return onenand_default_bbt(mtd);
1270 }
1271
1272 /**
1273  * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
1274  * @param mtd           MTD device structure
1275  */
1276 void onenand_release(struct mtd_info *mtd)
1277 {
1278 }
1279
1280 #endif /* CONFIG_CMD_ONENAND */