1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <common.h>
23#include <log.h>
24#include <watchdog.h>
25#include <dm/devres.h>
26#include <linux/bitops.h>
27#include <linux/compat.h>
28#include <linux/mtd/mtd.h>
29#include "linux/mtd/flashchip.h"
30#include <linux/mtd/onenand.h>
31
32#include <asm/io.h>
33#include <linux/errno.h>
34#include <malloc.h>
35
36
37static void *memcpy_16(void *dst, const void *src, unsigned int len)
38{
39 void *ret = dst;
40 short *d = dst;
41 const short *s = src;
42
43 len >>= 1;
44 while (len-- > 0)
45 *d++ = *s++;
46 return ret;
47}
48
49
50
51
52
53static struct nand_ecclayout onenand_oob_128 = {
54 .eccbytes = 64,
55 .eccpos = {
56 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
57 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
58 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
59 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
60 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
61 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
62 102, 103, 104, 105
63 },
64 .oobfree = {
65 {2, 4}, {18, 4}, {34, 4}, {50, 4},
66 {66, 4}, {82, 4}, {98, 4}, {114, 4}
67 }
68};
69
70
71
72
73static struct nand_ecclayout onenand_oob_64 = {
74 .eccbytes = 20,
75 .eccpos = {
76 8, 9, 10, 11, 12,
77 24, 25, 26, 27, 28,
78 40, 41, 42, 43, 44,
79 56, 57, 58, 59, 60,
80 },
81 .oobfree = {
82 {2, 3}, {14, 2}, {18, 3}, {30, 2},
83 {34, 3}, {46, 2}, {50, 3}, {62, 2}
84 }
85};
86
87
88
89
90static struct nand_ecclayout onenand_oob_32 = {
91 .eccbytes = 10,
92 .eccpos = {
93 8, 9, 10, 11, 12,
94 24, 25, 26, 27, 28,
95 },
96 .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
97};
98
99
100
101
102
103
104
105static const unsigned char __aligned(2) ffchars[] = {
106 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
107 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
109 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
110 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
111 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
112 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
113 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
114 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
115 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
116 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
117 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
118 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
119 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
120 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
121 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
122};
123
124
125
126
127
128
129
130static unsigned short onenand_readw(void __iomem * addr)
131{
132 return readw(addr);
133}
134
135
136
137
138
139
140
141
142static void onenand_writew(unsigned short value, void __iomem * addr)
143{
144 writew(value, addr);
145}
146
147
148
149
150
151
152
153
154
155static int onenand_block_address(struct onenand_chip *this, int block)
156{
157
158 if (block & this->density_mask)
159 return ONENAND_DDP_CHIP1 | (block ^ this->density_mask);
160
161 return block;
162}
163
164
165
166
167
168
169
170
171
172static int onenand_bufferram_address(struct onenand_chip *this, int block)
173{
174
175 if (block & this->density_mask)
176 return ONENAND_DDP_CHIP1;
177
178 return ONENAND_DDP_CHIP0;
179}
180
181
182
183
184
185
186
187
188
189static int onenand_page_address(int page, int sector)
190{
191
192 int fpa, fsa;
193
194 fpa = page & ONENAND_FPA_MASK;
195 fsa = sector & ONENAND_FSA_MASK;
196
197 return ((fpa << ONENAND_FPA_SHIFT) | fsa);
198}
199
200
201
202
203
204
205
206
207
208
209static int onenand_buffer_address(int dataram1, int sectors, int count)
210{
211 int bsa, bsc;
212
213
214 bsa = sectors & ONENAND_BSA_MASK;
215
216 if (dataram1)
217 bsa |= ONENAND_BSA_DATARAM1;
218 else
219 bsa |= ONENAND_BSA_DATARAM0;
220
221
222 bsc = count & ONENAND_BSC_MASK;
223
224 return ((bsa << ONENAND_BSA_SHIFT) | bsc);
225}
226
227
228
229
230
231
232static unsigned int flexonenand_block(struct onenand_chip *this, loff_t addr)
233{
234 unsigned int boundary, blk, die = 0;
235
236 if (ONENAND_IS_DDP(this) && addr >= this->diesize[0]) {
237 die = 1;
238 addr -= this->diesize[0];
239 }
240
241 boundary = this->boundary[die];
242
243 blk = addr >> (this->erase_shift - 1);
244 if (blk > boundary)
245 blk = (blk + boundary + 1) >> 1;
246
247 blk += die ? this->density_mask : 0;
248 return blk;
249}
250
251unsigned int onenand_block(struct onenand_chip *this, loff_t addr)
252{
253 if (!FLEXONENAND(this))
254 return addr >> this->erase_shift;
255 return flexonenand_block(this, addr);
256}
257
258
259
260
261
262
263
264
265static loff_t flexonenand_addr(struct onenand_chip *this, int block)
266{
267 loff_t ofs = 0;
268 int die = 0, boundary;
269
270 if (ONENAND_IS_DDP(this) && block >= this->density_mask) {
271 block -= this->density_mask;
272 die = 1;
273 ofs = this->diesize[0];
274 }
275
276 boundary = this->boundary[die];
277 ofs += (loff_t) block << (this->erase_shift - 1);
278 if (block > (boundary + 1))
279 ofs += (loff_t) (block - boundary - 1)
280 << (this->erase_shift - 1);
281 return ofs;
282}
283
284loff_t onenand_addr(struct onenand_chip *this, int block)
285{
286 if (!FLEXONENAND(this))
287 return (loff_t) block << this->erase_shift;
288 return flexonenand_addr(this, block);
289}
290
291
292
293
294
295
296int flexonenand_region(struct mtd_info *mtd, loff_t addr)
297{
298 int i;
299
300 for (i = 0; i < mtd->numeraseregions; i++)
301 if (addr < mtd->eraseregions[i].offset)
302 break;
303 return i - 1;
304}
305
306
307
308
309
310
311
312static inline int onenand_get_density(int dev_id)
313{
314 int density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
315 return (density & ONENAND_DEVICE_DENSITY_MASK);
316}
317
318
319
320
321
322
323
324
325
326
327
328static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
329 size_t len)
330{
331 struct onenand_chip *this = mtd->priv;
332 int value;
333 int block, page;
334
335
336 int sectors = 0, count = 0;
337
338
339 switch (cmd) {
340 case ONENAND_CMD_UNLOCK:
341 case ONENAND_CMD_LOCK:
342 case ONENAND_CMD_LOCK_TIGHT:
343 case ONENAND_CMD_UNLOCK_ALL:
344 block = -1;
345 page = -1;
346 break;
347
348 case FLEXONENAND_CMD_PI_ACCESS:
349
350 block = addr * this->density_mask;
351 page = -1;
352 break;
353
354 case ONENAND_CMD_ERASE:
355 case ONENAND_CMD_BUFFERRAM:
356 block = onenand_block(this, addr);
357 page = -1;
358 break;
359
360 case FLEXONENAND_CMD_READ_PI:
361 cmd = ONENAND_CMD_READ;
362 block = addr * this->density_mask;
363 page = 0;
364 break;
365
366 default:
367 block = onenand_block(this, addr);
368 page = (int) (addr
369 - onenand_addr(this, block)) >> this->page_shift;
370 page &= this->page_mask;
371 break;
372 }
373
374
375 if (cmd == ONENAND_CMD_BUFFERRAM) {
376
377 value = onenand_bufferram_address(this, block);
378 this->write_word(value,
379 this->base + ONENAND_REG_START_ADDRESS2);
380
381 if (ONENAND_IS_4KB_PAGE(this))
382 ONENAND_SET_BUFFERRAM0(this);
383 else
384
385 ONENAND_SET_NEXT_BUFFERRAM(this);
386
387 return 0;
388 }
389
390 if (block != -1) {
391
392 value = onenand_block_address(this, block);
393 this->write_word(value,
394 this->base + ONENAND_REG_START_ADDRESS1);
395
396
397 value = onenand_bufferram_address(this, block);
398 this->write_word(value,
399 this->base + ONENAND_REG_START_ADDRESS2);
400 }
401
402 if (page != -1) {
403 int dataram;
404
405 switch (cmd) {
406 case FLEXONENAND_CMD_RECOVER_LSB:
407 case ONENAND_CMD_READ:
408 case ONENAND_CMD_READOOB:
409 if (ONENAND_IS_4KB_PAGE(this))
410 dataram = ONENAND_SET_BUFFERRAM0(this);
411 else
412 dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
413
414 break;
415
416 default:
417 dataram = ONENAND_CURRENT_BUFFERRAM(this);
418 break;
419 }
420
421
422 value = onenand_page_address(page, sectors);
423 this->write_word(value,
424 this->base + ONENAND_REG_START_ADDRESS8);
425
426
427 value = onenand_buffer_address(dataram, sectors, count);
428 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
429 }
430
431
432 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
433
434 this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
435
436 return 0;
437}
438
439
440
441
442
443static int onenand_read_ecc(struct onenand_chip *this)
444{
445 int ecc, i;
446
447 if (!FLEXONENAND(this))
448 return this->read_word(this->base + ONENAND_REG_ECC_STATUS);
449
450 for (i = 0; i < 4; i++) {
451 ecc = this->read_word(this->base
452 + ((ONENAND_REG_ECC_STATUS + i) << 1));
453 if (likely(!ecc))
454 continue;
455 if (ecc & FLEXONENAND_UNCORRECTABLE_ERROR)
456 return ONENAND_ECC_2BIT_ALL;
457 }
458
459 return 0;
460}
461
462
463
464
465
466
467
468
469
470
471static int onenand_wait(struct mtd_info *mtd, int state)
472{
473 struct onenand_chip *this = mtd->priv;
474 unsigned int interrupt = 0;
475 unsigned int ctrl;
476
477
478 u32 timeo = (CONFIG_SYS_HZ * 20) / 1000;
479 u32 time_start = get_timer(0);
480 do {
481 WATCHDOG_RESET();
482 if (get_timer(time_start) > timeo)
483 return -EIO;
484 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
485 } while ((interrupt & ONENAND_INT_MASTER) == 0);
486
487 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
488
489 if (interrupt & ONENAND_INT_READ) {
490 int ecc = onenand_read_ecc(this);
491 if (ecc & ONENAND_ECC_2BIT_ALL) {
492 printk("onenand_wait: ECC error = 0x%04x\n", ecc);
493 return -EBADMSG;
494 }
495 }
496
497 if (ctrl & ONENAND_CTRL_ERROR) {
498 printk("onenand_wait: controller error = 0x%04x\n", ctrl);
499 if (ctrl & ONENAND_CTRL_LOCK)
500 printk("onenand_wait: it's locked error = 0x%04x\n",
501 ctrl);
502
503 return -EIO;
504 }
505
506
507 return 0;
508}
509
510
511
512
513
514
515
516
517
518static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
519{
520 struct onenand_chip *this = mtd->priv;
521
522 if (ONENAND_CURRENT_BUFFERRAM(this)) {
523 if (area == ONENAND_DATARAM)
524 return mtd->writesize;
525 if (area == ONENAND_SPARERAM)
526 return mtd->oobsize;
527 }
528
529 return 0;
530}
531
532
533
534
535
536
537
538
539
540
541
542static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
543 unsigned char *buffer, int offset,
544 size_t count)
545{
546 struct onenand_chip *this = mtd->priv;
547 void __iomem *bufferram;
548
549 bufferram = this->base + area;
550 bufferram += onenand_bufferram_offset(mtd, area);
551
552 memcpy_16(buffer, bufferram + offset, count);
553
554 return 0;
555}
556
557
558
559
560
561
562
563
564
565
566
567static int onenand_sync_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
568 unsigned char *buffer, int offset,
569 size_t count)
570{
571 struct onenand_chip *this = mtd->priv;
572 void __iomem *bufferram;
573
574 bufferram = this->base + area;
575 bufferram += onenand_bufferram_offset(mtd, area);
576
577 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
578
579 memcpy_16(buffer, bufferram + offset, count);
580
581 this->mmcontrol(mtd, 0);
582
583 return 0;
584}
585
586
587
588
589
590
591
592
593
594
595
596static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
597 const unsigned char *buffer, int offset,
598 size_t count)
599{
600 struct onenand_chip *this = mtd->priv;
601 void __iomem *bufferram;
602
603 bufferram = this->base + area;
604 bufferram += onenand_bufferram_offset(mtd, area);
605
606 memcpy_16(bufferram + offset, buffer, count);
607
608 return 0;
609}
610
611
612
613
614
615
616
617
618
619static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr)
620{
621 struct onenand_chip *this = mtd->priv;
622 int blockpage, block, page;
623
624
625 block = (int) (addr >> this->erase_shift) & ~1;
626
627 if (addr & this->writesize)
628 block++;
629 page = (int) (addr >> (this->page_shift + 1)) & this->page_mask;
630 blockpage = (block << 7) | page;
631
632 return blockpage;
633}
634
635
636
637
638
639
640
641
642
643static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
644{
645 struct onenand_chip *this = mtd->priv;
646 int blockpage, found = 0;
647 unsigned int i;
648
649 if (ONENAND_IS_2PLANE(this))
650 blockpage = onenand_get_2x_blockpage(mtd, addr);
651 else
652 blockpage = (int) (addr >> this->page_shift);
653
654
655 i = ONENAND_CURRENT_BUFFERRAM(this);
656 if (this->bufferram[i].blockpage == blockpage)
657 found = 1;
658 else {
659
660 i = ONENAND_NEXT_BUFFERRAM(this);
661 if (this->bufferram[i].blockpage == blockpage) {
662 ONENAND_SET_NEXT_BUFFERRAM(this);
663 found = 1;
664 }
665 }
666
667 if (found && ONENAND_IS_DDP(this)) {
668
669 int block = onenand_block(this, addr);
670 int value = onenand_bufferram_address(this, block);
671 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
672 }
673
674 return found;
675}
676
677
678
679
680
681
682
683
684
685static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
686 int valid)
687{
688 struct onenand_chip *this = mtd->priv;
689 int blockpage;
690 unsigned int i;
691
692 if (ONENAND_IS_2PLANE(this))
693 blockpage = onenand_get_2x_blockpage(mtd, addr);
694 else
695 blockpage = (int)(addr >> this->page_shift);
696
697
698 i = ONENAND_NEXT_BUFFERRAM(this);
699 if (this->bufferram[i].blockpage == blockpage)
700 this->bufferram[i].blockpage = -1;
701
702
703 i = ONENAND_CURRENT_BUFFERRAM(this);
704 if (valid)
705 this->bufferram[i].blockpage = blockpage;
706 else
707 this->bufferram[i].blockpage = -1;
708
709 return 0;
710}
711
712
713
714
715
716
717
718
719
720static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
721 unsigned int len)
722{
723 struct onenand_chip *this = mtd->priv;
724 int i;
725 loff_t end_addr = addr + len;
726
727
728 for (i = 0; i < MAX_BUFFERRAM; i++) {
729 loff_t buf_addr = this->bufferram[i].blockpage << this->page_shift;
730
731 if (buf_addr >= addr && buf_addr < end_addr)
732 this->bufferram[i].blockpage = -1;
733 }
734}
735
736
737
738
739
740
741
742
743static void onenand_get_device(struct mtd_info *mtd, int new_state)
744{
745
746}
747
748
749
750
751
752
753
754static void onenand_release_device(struct mtd_info *mtd)
755{
756
757}
758
759
760
761
762
763
764
765
766static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf,
767 int column, int thislen)
768{
769 struct onenand_chip *this = mtd->priv;
770 struct nand_oobfree *free;
771 int readcol = column;
772 int readend = column + thislen;
773 int lastgap = 0;
774 unsigned int i;
775 uint8_t *oob_buf = this->oob_buf;
776
777 free = this->ecclayout->oobfree;
778 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
779 i++, free++) {
780 if (readcol >= lastgap)
781 readcol += free->offset - lastgap;
782 if (readend >= lastgap)
783 readend += free->offset - lastgap;
784 lastgap = free->offset + free->length;
785 }
786 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
787 free = this->ecclayout->oobfree;
788 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
789 i++, free++) {
790 int free_end = free->offset + free->length;
791 if (free->offset < readend && free_end > readcol) {
792 int st = max_t(int,free->offset,readcol);
793 int ed = min_t(int,free_end,readend);
794 int n = ed - st;
795 memcpy(buf, oob_buf + st, n);
796 buf += n;
797 } else if (column == 0)
798 break;
799 }
800 return 0;
801}
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status)
817{
818 struct onenand_chip *this = mtd->priv;
819 int i;
820
821
822 if (!FLEXONENAND(this))
823 return status;
824
825
826 if (!mtd_is_eccerr(status) && status != ONENAND_BBT_READ_ECC_ERROR)
827 return status;
828
829
830 i = flexonenand_region(mtd, addr);
831 if (mtd->eraseregions[i].erasesize < (1 << this->erase_shift))
832 return status;
833
834 printk("onenand_recover_lsb:"
835 "Attempting to recover from uncorrectable read\n");
836
837
838 this->command(mtd, FLEXONENAND_CMD_RECOVER_LSB, addr, this->writesize);
839 return this->wait(mtd, FL_READING);
840}
841
842
843
844
845
846
847
848
849
850static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
851 struct mtd_oob_ops *ops)
852{
853 struct onenand_chip *this = mtd->priv;
854 struct mtd_ecc_stats stats;
855 size_t len = ops->len;
856 size_t ooblen = ops->ooblen;
857 u_char *buf = ops->datbuf;
858 u_char *oobbuf = ops->oobbuf;
859 int read = 0, column, thislen;
860 int oobread = 0, oobcolumn, thisooblen, oobsize;
861 int ret = 0, boundary = 0;
862 int writesize = this->writesize;
863
864 pr_debug("onenand_read_ops_nolock: from = 0x%08x, len = %i\n",
865 (unsigned int) from, (int) len);
866
867 if (ops->mode == MTD_OPS_AUTO_OOB)
868 oobsize = this->ecclayout->oobavail;
869 else
870 oobsize = mtd->oobsize;
871
872 oobcolumn = from & (mtd->oobsize - 1);
873
874
875 if ((from + len) > mtd->size) {
876 printk(KERN_ERR "onenand_read_ops_nolock: Attempt read beyond end of device\n");
877 ops->retlen = 0;
878 ops->oobretlen = 0;
879 return -EINVAL;
880 }
881
882 stats = mtd->ecc_stats;
883
884
885
886
887
888 if (read < len) {
889 if (!onenand_check_bufferram(mtd, from)) {
890 this->main_buf = buf;
891 this->command(mtd, ONENAND_CMD_READ, from, writesize);
892 ret = this->wait(mtd, FL_READING);
893 if (unlikely(ret))
894 ret = onenand_recover_lsb(mtd, from, ret);
895 onenand_update_bufferram(mtd, from, !ret);
896 if (ret == -EBADMSG)
897 ret = 0;
898 }
899 }
900
901 thislen = min_t(int, writesize, len - read);
902 column = from & (writesize - 1);
903 if (column + thislen > writesize)
904 thislen = writesize - column;
905
906 while (!ret) {
907
908 from += thislen;
909 if (!ONENAND_IS_4KB_PAGE(this) && read + thislen < len) {
910 this->main_buf = buf + thislen;
911 this->command(mtd, ONENAND_CMD_READ, from, writesize);
912
913
914
915
916
917 if (ONENAND_IS_DDP(this) &&
918 unlikely(from == (this->chipsize >> 1))) {
919 this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2);
920 boundary = 1;
921 } else
922 boundary = 0;
923 ONENAND_SET_PREV_BUFFERRAM(this);
924 }
925
926
927 this->read_bufferram(mtd, from - thislen, ONENAND_DATARAM, buf, column, thislen);
928
929
930 if (oobbuf) {
931 thisooblen = oobsize - oobcolumn;
932 thisooblen = min_t(int, thisooblen, ooblen - oobread);
933
934 if (ops->mode == MTD_OPS_AUTO_OOB)
935 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
936 else
937 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
938 oobread += thisooblen;
939 oobbuf += thisooblen;
940 oobcolumn = 0;
941 }
942
943 if (ONENAND_IS_4KB_PAGE(this) && (read + thislen < len)) {
944 this->command(mtd, ONENAND_CMD_READ, from, writesize);
945 ret = this->wait(mtd, FL_READING);
946 if (unlikely(ret))
947 ret = onenand_recover_lsb(mtd, from, ret);
948 onenand_update_bufferram(mtd, from, !ret);
949 if (mtd_is_eccerr(ret))
950 ret = 0;
951 }
952
953
954 read += thislen;
955 if (read == len)
956 break;
957
958 if (unlikely(boundary))
959 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
960 if (!ONENAND_IS_4KB_PAGE(this))
961 ONENAND_SET_NEXT_BUFFERRAM(this);
962 buf += thislen;
963 thislen = min_t(int, writesize, len - read);
964 column = 0;
965
966 if (!ONENAND_IS_4KB_PAGE(this)) {
967
968 ret = this->wait(mtd, FL_READING);
969 onenand_update_bufferram(mtd, from, !ret);
970 if (mtd_is_eccerr(ret))
971 ret = 0;
972 }
973 }
974
975
976
977
978
979
980 ops->retlen = read;
981 ops->oobretlen = oobread;
982
983 if (ret)
984 return ret;
985
986 if (mtd->ecc_stats.failed - stats.failed)
987 return -EBADMSG;
988
989
990 return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0;
991}
992
993
994
995
996
997
998
999
1000
1001static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
1002 struct mtd_oob_ops *ops)
1003{
1004 struct onenand_chip *this = mtd->priv;
1005 struct mtd_ecc_stats stats;
1006 int read = 0, thislen, column, oobsize;
1007 size_t len = ops->ooblen;
1008 unsigned int mode = ops->mode;
1009 u_char *buf = ops->oobbuf;
1010 int ret = 0, readcmd;
1011
1012 from += ops->ooboffs;
1013
1014 pr_debug("onenand_read_oob_nolock: from = 0x%08x, len = %i\n",
1015 (unsigned int) from, (int) len);
1016
1017
1018 ops->oobretlen = 0;
1019
1020 if (mode == MTD_OPS_AUTO_OOB)
1021 oobsize = this->ecclayout->oobavail;
1022 else
1023 oobsize = mtd->oobsize;
1024
1025 column = from & (mtd->oobsize - 1);
1026
1027 if (unlikely(column >= oobsize)) {
1028 printk(KERN_ERR "onenand_read_oob_nolock: Attempted to start read outside oob\n");
1029 return -EINVAL;
1030 }
1031
1032
1033 if (unlikely(from >= mtd->size ||
1034 column + len > ((mtd->size >> this->page_shift) -
1035 (from >> this->page_shift)) * oobsize)) {
1036 printk(KERN_ERR "onenand_read_oob_nolock: Attempted to read beyond end of device\n");
1037 return -EINVAL;
1038 }
1039
1040 stats = mtd->ecc_stats;
1041
1042 readcmd = ONENAND_IS_4KB_PAGE(this) ?
1043 ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1044
1045 while (read < len) {
1046 thislen = oobsize - column;
1047 thislen = min_t(int, thislen, len);
1048
1049 this->spare_buf = buf;
1050 this->command(mtd, readcmd, from, mtd->oobsize);
1051
1052 onenand_update_bufferram(mtd, from, 0);
1053
1054 ret = this->wait(mtd, FL_READING);
1055 if (unlikely(ret))
1056 ret = onenand_recover_lsb(mtd, from, ret);
1057
1058 if (ret && ret != -EBADMSG) {
1059 printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
1060 break;
1061 }
1062
1063 if (mode == MTD_OPS_AUTO_OOB)
1064 onenand_transfer_auto_oob(mtd, buf, column, thislen);
1065 else
1066 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, buf, column, thislen);
1067
1068 read += thislen;
1069
1070 if (read == len)
1071 break;
1072
1073 buf += thislen;
1074
1075
1076 if (read < len) {
1077
1078 from += mtd->writesize;
1079 column = 0;
1080 }
1081 }
1082
1083 ops->oobretlen = read;
1084
1085 if (ret)
1086 return ret;
1087
1088 if (mtd->ecc_stats.failed - stats.failed)
1089 return -EBADMSG;
1090
1091 return 0;
1092}
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1105 size_t * retlen, u_char * buf)
1106{
1107 struct mtd_oob_ops ops = {
1108 .len = len,
1109 .ooblen = 0,
1110 .datbuf = buf,
1111 .oobbuf = NULL,
1112 };
1113 int ret;
1114
1115 onenand_get_device(mtd, FL_READING);
1116 ret = onenand_read_ops_nolock(mtd, from, &ops);
1117 onenand_release_device(mtd);
1118
1119 *retlen = ops.retlen;
1120 return ret;
1121}
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1132 struct mtd_oob_ops *ops)
1133{
1134 int ret;
1135
1136 switch (ops->mode) {
1137 case MTD_OPS_PLACE_OOB:
1138 case MTD_OPS_AUTO_OOB:
1139 break;
1140 case MTD_OPS_RAW:
1141
1142 default:
1143 return -EINVAL;
1144 }
1145
1146 onenand_get_device(mtd, FL_READING);
1147 if (ops->datbuf)
1148 ret = onenand_read_ops_nolock(mtd, from, ops);
1149 else
1150 ret = onenand_read_oob_nolock(mtd, from, ops);
1151 onenand_release_device(mtd);
1152
1153 return ret;
1154}
1155
1156
1157
1158
1159
1160
1161
1162
1163static int onenand_bbt_wait(struct mtd_info *mtd, int state)
1164{
1165 struct onenand_chip *this = mtd->priv;
1166 unsigned int interrupt;
1167 unsigned int ctrl;
1168
1169
1170 u32 timeo = (CONFIG_SYS_HZ * 20) / 1000;
1171 u32 time_start = get_timer(0);
1172 do {
1173 WATCHDOG_RESET();
1174 if (get_timer(time_start) > timeo)
1175 return ONENAND_BBT_READ_FATAL_ERROR;
1176 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1177 } while ((interrupt & ONENAND_INT_MASTER) == 0);
1178
1179
1180 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1181 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
1182
1183 if (interrupt & ONENAND_INT_READ) {
1184 int ecc = onenand_read_ecc(this);
1185 if (ecc & ONENAND_ECC_2BIT_ALL) {
1186 printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x"
1187 ", controller = 0x%04x\n", ecc, ctrl);
1188 return ONENAND_BBT_READ_ERROR;
1189 }
1190 } else {
1191 printk(KERN_ERR "onenand_bbt_wait: read timeout!"
1192 "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
1193 return ONENAND_BBT_READ_FATAL_ERROR;
1194 }
1195
1196
1197 if (ctrl & ONENAND_CTRL_ERROR) {
1198 printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl);
1199 return ONENAND_BBT_READ_ERROR;
1200 }
1201
1202 return 0;
1203}
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1214 struct mtd_oob_ops *ops)
1215{
1216 struct onenand_chip *this = mtd->priv;
1217 int read = 0, thislen, column;
1218 int ret = 0, readcmd;
1219 size_t len = ops->ooblen;
1220 u_char *buf = ops->oobbuf;
1221
1222 pr_debug("onenand_bbt_read_oob: from = 0x%08x, len = %zi\n",
1223 (unsigned int) from, len);
1224
1225 readcmd = ONENAND_IS_4KB_PAGE(this) ?
1226 ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1227
1228
1229 ops->oobretlen = 0;
1230
1231
1232 if (unlikely((from + len) > mtd->size)) {
1233 printk(KERN_ERR "onenand_bbt_read_oob: Attempt read beyond end of device\n");
1234 return ONENAND_BBT_READ_FATAL_ERROR;
1235 }
1236
1237
1238 onenand_get_device(mtd, FL_READING);
1239
1240 column = from & (mtd->oobsize - 1);
1241
1242 while (read < len) {
1243
1244 thislen = mtd->oobsize - column;
1245 thislen = min_t(int, thislen, len);
1246
1247 this->spare_buf = buf;
1248 this->command(mtd, readcmd, from, mtd->oobsize);
1249
1250 onenand_update_bufferram(mtd, from, 0);
1251
1252 ret = this->bbt_wait(mtd, FL_READING);
1253 if (unlikely(ret))
1254 ret = onenand_recover_lsb(mtd, from, ret);
1255
1256 if (ret)
1257 break;
1258
1259 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, buf, column, thislen);
1260 read += thislen;
1261 if (read == len)
1262 break;
1263
1264 buf += thislen;
1265
1266
1267 if (read < len) {
1268
1269 from += this->writesize;
1270 column = 0;
1271 }
1272 }
1273
1274
1275 onenand_release_device(mtd);
1276
1277 ops->oobretlen = read;
1278 return ret;
1279}
1280
1281
1282#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
1283
1284
1285
1286
1287
1288
1289static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
1290{
1291 struct onenand_chip *this = mtd->priv;
1292 u_char *oob_buf = this->oob_buf;
1293 int status, i, readcmd;
1294
1295 readcmd = ONENAND_IS_4KB_PAGE(this) ?
1296 ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1297
1298 this->command(mtd, readcmd, to, mtd->oobsize);
1299 onenand_update_bufferram(mtd, to, 0);
1300 status = this->wait(mtd, FL_READING);
1301 if (status)
1302 return status;
1303
1304 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
1305 for (i = 0; i < mtd->oobsize; i++)
1306 if (buf[i] != 0xFF && buf[i] != oob_buf[i])
1307 return -EBADMSG;
1308
1309 return 0;
1310}
1311
1312
1313
1314
1315
1316
1317
1318
1319static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
1320{
1321 struct onenand_chip *this = mtd->priv;
1322 void __iomem *dataram;
1323 int ret = 0;
1324 int thislen, column;
1325
1326 while (len != 0) {
1327 thislen = min_t(int, this->writesize, len);
1328 column = addr & (this->writesize - 1);
1329 if (column + thislen > this->writesize)
1330 thislen = this->writesize - column;
1331
1332 this->command(mtd, ONENAND_CMD_READ, addr, this->writesize);
1333
1334 onenand_update_bufferram(mtd, addr, 0);
1335
1336 ret = this->wait(mtd, FL_READING);
1337 if (ret)
1338 return ret;
1339
1340 onenand_update_bufferram(mtd, addr, 1);
1341
1342 dataram = this->base + ONENAND_DATARAM;
1343 dataram += onenand_bufferram_offset(mtd, ONENAND_DATARAM);
1344
1345 if (memcmp(buf, dataram + column, thislen))
1346 return -EBADMSG;
1347
1348 len -= thislen;
1349 buf += thislen;
1350 addr += thislen;
1351 }
1352
1353 return 0;
1354}
1355#else
1356#define onenand_verify(...) (0)
1357#define onenand_verify_oob(...) (0)
1358#endif
1359
1360#define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0)
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
1371 const u_char *buf, int column, int thislen)
1372{
1373 struct onenand_chip *this = mtd->priv;
1374 struct nand_oobfree *free;
1375 int writecol = column;
1376 int writeend = column + thislen;
1377 int lastgap = 0;
1378 unsigned int i;
1379
1380 free = this->ecclayout->oobfree;
1381 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
1382 i++, free++) {
1383 if (writecol >= lastgap)
1384 writecol += free->offset - lastgap;
1385 if (writeend >= lastgap)
1386 writeend += free->offset - lastgap;
1387 lastgap = free->offset + free->length;
1388 }
1389 free = this->ecclayout->oobfree;
1390 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
1391 i++, free++) {
1392 int free_end = free->offset + free->length;
1393 if (free->offset < writeend && free_end > writecol) {
1394 int st = max_t(int,free->offset,writecol);
1395 int ed = min_t(int,free_end,writeend);
1396 int n = ed - st;
1397 memcpy(oob_buf + st, buf, n);
1398 buf += n;
1399 } else if (column == 0)
1400 break;
1401 }
1402 return 0;
1403}
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1414 struct mtd_oob_ops *ops)
1415{
1416 struct onenand_chip *this = mtd->priv;
1417 int written = 0, column, thislen, subpage;
1418 int oobwritten = 0, oobcolumn, thisooblen, oobsize;
1419 size_t len = ops->len;
1420 size_t ooblen = ops->ooblen;
1421 const u_char *buf = ops->datbuf;
1422 const u_char *oob = ops->oobbuf;
1423 u_char *oobbuf;
1424 int ret = 0;
1425
1426 pr_debug("onenand_write_ops_nolock: to = 0x%08x, len = %i\n",
1427 (unsigned int) to, (int) len);
1428
1429
1430 ops->retlen = 0;
1431 ops->oobretlen = 0;
1432
1433
1434 if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
1435 printk(KERN_ERR "onenand_write_ops_nolock: Attempt to write not page aligned data\n");
1436 return -EINVAL;
1437 }
1438
1439 if (ops->mode == MTD_OPS_AUTO_OOB)
1440 oobsize = this->ecclayout->oobavail;
1441 else
1442 oobsize = mtd->oobsize;
1443
1444 oobcolumn = to & (mtd->oobsize - 1);
1445
1446 column = to & (mtd->writesize - 1);
1447
1448
1449 while (written < len) {
1450 u_char *wbuf = (u_char *) buf;
1451
1452 thislen = min_t(int, mtd->writesize - column, len - written);
1453 thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
1454
1455 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1456
1457
1458 subpage = thislen < mtd->writesize;
1459 if (subpage) {
1460 memset(this->page_buf, 0xff, mtd->writesize);
1461 memcpy(this->page_buf + column, buf, thislen);
1462 wbuf = this->page_buf;
1463 }
1464
1465 this->write_bufferram(mtd, to, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1466
1467 if (oob) {
1468 oobbuf = this->oob_buf;
1469
1470
1471
1472 memset(oobbuf, 0xff, mtd->oobsize);
1473 if (ops->mode == MTD_OPS_AUTO_OOB)
1474 onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
1475 else
1476 memcpy(oobbuf + oobcolumn, oob, thisooblen);
1477
1478 oobwritten += thisooblen;
1479 oob += thisooblen;
1480 oobcolumn = 0;
1481 } else
1482 oobbuf = (u_char *) ffchars;
1483
1484 this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1485
1486 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1487
1488 ret = this->wait(mtd, FL_WRITING);
1489
1490
1491 onenand_update_bufferram(mtd, to, !ret && !subpage);
1492 if (ONENAND_IS_2PLANE(this)) {
1493 ONENAND_SET_BUFFERRAM1(this);
1494 onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
1495 }
1496
1497 if (ret) {
1498 printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
1499 break;
1500 }
1501
1502
1503 ret = onenand_verify(mtd, buf, to, thislen);
1504 if (ret) {
1505 printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
1506 break;
1507 }
1508
1509 written += thislen;
1510
1511 if (written == len)
1512 break;
1513
1514 column = 0;
1515 to += thislen;
1516 buf += thislen;
1517 }
1518
1519 ops->retlen = written;
1520
1521 return ret;
1522}
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1536 struct mtd_oob_ops *ops)
1537{
1538 struct onenand_chip *this = mtd->priv;
1539 int column, ret = 0, oobsize;
1540 int written = 0, oobcmd;
1541 u_char *oobbuf;
1542 size_t len = ops->ooblen;
1543 const u_char *buf = ops->oobbuf;
1544 unsigned int mode = ops->mode;
1545
1546 to += ops->ooboffs;
1547
1548 pr_debug("onenand_write_oob_nolock: to = 0x%08x, len = %i\n",
1549 (unsigned int) to, (int) len);
1550
1551
1552 ops->oobretlen = 0;
1553
1554 if (mode == MTD_OPS_AUTO_OOB)
1555 oobsize = this->ecclayout->oobavail;
1556 else
1557 oobsize = mtd->oobsize;
1558
1559 column = to & (mtd->oobsize - 1);
1560
1561 if (unlikely(column >= oobsize)) {
1562 printk(KERN_ERR "onenand_write_oob_nolock: Attempted to start write outside oob\n");
1563 return -EINVAL;
1564 }
1565
1566
1567 if (unlikely(column + len > oobsize)) {
1568 printk(KERN_ERR "onenand_write_oob_nolock: "
1569 "Attempt to write past end of page\n");
1570 return -EINVAL;
1571 }
1572
1573
1574 if (unlikely(to >= mtd->size ||
1575 column + len > ((mtd->size >> this->page_shift) -
1576 (to >> this->page_shift)) * oobsize)) {
1577 printk(KERN_ERR "onenand_write_oob_nolock: Attempted to write past end of device\n");
1578 return -EINVAL;
1579 }
1580
1581 oobbuf = this->oob_buf;
1582
1583 oobcmd = ONENAND_IS_4KB_PAGE(this) ?
1584 ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
1585
1586
1587 while (written < len) {
1588 int thislen = min_t(int, oobsize, len - written);
1589
1590 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
1591
1592
1593
1594 memset(oobbuf, 0xff, mtd->oobsize);
1595 if (mode == MTD_OPS_AUTO_OOB)
1596 onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
1597 else
1598 memcpy(oobbuf + column, buf, thislen);
1599 this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1600
1601 if (ONENAND_IS_4KB_PAGE(this)) {
1602
1603 memset(this->page_buf, 0xff, mtd->writesize);
1604 this->write_bufferram(mtd, 0, ONENAND_DATARAM,
1605 this->page_buf, 0, mtd->writesize);
1606 }
1607
1608 this->command(mtd, oobcmd, to, mtd->oobsize);
1609
1610 onenand_update_bufferram(mtd, to, 0);
1611 if (ONENAND_IS_2PLANE(this)) {
1612 ONENAND_SET_BUFFERRAM1(this);
1613 onenand_update_bufferram(mtd, to + this->writesize, 0);
1614 }
1615
1616 ret = this->wait(mtd, FL_WRITING);
1617 if (ret) {
1618 printk(KERN_ERR "onenand_write_oob_nolock: write failed %d\n", ret);
1619 break;
1620 }
1621
1622 ret = onenand_verify_oob(mtd, oobbuf, to);
1623 if (ret) {
1624 printk(KERN_ERR "onenand_write_oob_nolock: verify failed %d\n", ret);
1625 break;
1626 }
1627
1628 written += thislen;
1629 if (written == len)
1630 break;
1631
1632 to += mtd->writesize;
1633 buf += thislen;
1634 column = 0;
1635 }
1636
1637 ops->oobretlen = written;
1638
1639 return ret;
1640}
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1653 size_t * retlen, const u_char * buf)
1654{
1655 struct mtd_oob_ops ops = {
1656 .len = len,
1657 .ooblen = 0,
1658 .datbuf = (u_char *) buf,
1659 .oobbuf = NULL,
1660 };
1661 int ret;
1662
1663 onenand_get_device(mtd, FL_WRITING);
1664 ret = onenand_write_ops_nolock(mtd, to, &ops);
1665 onenand_release_device(mtd);
1666
1667 *retlen = ops.retlen;
1668 return ret;
1669}
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679int onenand_write_oob(struct mtd_info *mtd, loff_t to,
1680 struct mtd_oob_ops *ops)
1681{
1682 int ret;
1683
1684 switch (ops->mode) {
1685 case MTD_OPS_PLACE_OOB:
1686 case MTD_OPS_AUTO_OOB:
1687 break;
1688 case MTD_OPS_RAW:
1689
1690 default:
1691 return -EINVAL;
1692 }
1693
1694 onenand_get_device(mtd, FL_WRITING);
1695 if (ops->datbuf)
1696 ret = onenand_write_ops_nolock(mtd, to, ops);
1697 else
1698 ret = onenand_write_oob_nolock(mtd, to, ops);
1699 onenand_release_device(mtd);
1700
1701 return ret;
1702
1703}
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
1715{
1716 struct onenand_chip *this = mtd->priv;
1717 struct bbm_info *bbm = this->bbm;
1718
1719
1720 return bbm->isbad_bbt(mtd, ofs, allowbbt);
1721}
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1732{
1733 struct onenand_chip *this = mtd->priv;
1734 unsigned int block_size;
1735 loff_t addr = instr->addr;
1736 unsigned int len = instr->len;
1737 int ret = 0, i;
1738 struct mtd_erase_region_info *region = NULL;
1739 unsigned int region_end = 0;
1740
1741 pr_debug("onenand_erase: start = 0x%08x, len = %i\n",
1742 (unsigned int) addr, len);
1743
1744 if (FLEXONENAND(this)) {
1745
1746 i = flexonenand_region(mtd, addr);
1747 region = &mtd->eraseregions[i];
1748
1749 block_size = region->erasesize;
1750 region_end = region->offset
1751 + region->erasesize * region->numblocks;
1752
1753
1754
1755
1756 if (unlikely((addr - region->offset) & (block_size - 1))) {
1757 pr_debug("onenand_erase:" " Unaligned address\n");
1758 return -EINVAL;
1759 }
1760 } else {
1761 block_size = 1 << this->erase_shift;
1762
1763
1764 if (unlikely(addr & (block_size - 1))) {
1765 pr_debug("onenand_erase:" "Unaligned address\n");
1766 return -EINVAL;
1767 }
1768 }
1769
1770
1771 if (unlikely(len & (block_size - 1))) {
1772 pr_debug("onenand_erase: Length not block aligned\n");
1773 return -EINVAL;
1774 }
1775
1776
1777 onenand_get_device(mtd, FL_ERASING);
1778
1779
1780 instr->state = MTD_ERASING;
1781
1782 while (len) {
1783
1784
1785 if (instr->priv == 0 && onenand_block_isbad_nolock(mtd, addr, 0)) {
1786 printk(KERN_WARNING "onenand_erase: attempt to erase"
1787 " a bad block at addr 0x%08x\n",
1788 (unsigned int) addr);
1789 instr->state = MTD_ERASE_FAILED;
1790 goto erase_exit;
1791 }
1792
1793 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
1794
1795 onenand_invalidate_bufferram(mtd, addr, block_size);
1796
1797 ret = this->wait(mtd, FL_ERASING);
1798
1799 if (ret) {
1800 if (ret == -EPERM)
1801 pr_debug("onenand_erase: "
1802 "Device is write protected!!!\n");
1803 else
1804 pr_debug("onenand_erase: "
1805 "Failed erase, block %d\n",
1806 onenand_block(this, addr));
1807 instr->state = MTD_ERASE_FAILED;
1808 instr->fail_addr = addr;
1809
1810 goto erase_exit;
1811 }
1812
1813 len -= block_size;
1814 addr += block_size;
1815
1816 if (addr == region_end) {
1817 if (!len)
1818 break;
1819 region++;
1820
1821 block_size = region->erasesize;
1822 region_end = region->offset
1823 + region->erasesize * region->numblocks;
1824
1825 if (len & (block_size - 1)) {
1826
1827
1828 printk("onenand_erase: Unaligned address\n");
1829 goto erase_exit;
1830 }
1831 }
1832 }
1833
1834 instr->state = MTD_ERASE_DONE;
1835
1836erase_exit:
1837
1838 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
1839
1840
1841 onenand_release_device(mtd);
1842
1843 return ret;
1844}
1845
1846
1847
1848
1849
1850
1851
1852void onenand_sync(struct mtd_info *mtd)
1853{
1854 pr_debug("onenand_sync: called\n");
1855
1856
1857 onenand_get_device(mtd, FL_SYNCING);
1858
1859
1860 onenand_release_device(mtd);
1861}
1862
1863
1864
1865
1866
1867
1868
1869
1870int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
1871{
1872 int ret;
1873
1874
1875 if (ofs > mtd->size)
1876 return -EINVAL;
1877
1878 onenand_get_device(mtd, FL_READING);
1879 ret = onenand_block_isbad_nolock(mtd,ofs, 0);
1880 onenand_release_device(mtd);
1881 return ret;
1882}
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1893{
1894 struct onenand_chip *this = mtd->priv;
1895 struct bbm_info *bbm = this->bbm;
1896 u_char buf[2] = {0, 0};
1897 struct mtd_oob_ops ops = {
1898 .mode = MTD_OPS_PLACE_OOB,
1899 .ooblen = 2,
1900 .oobbuf = buf,
1901 .ooboffs = 0,
1902 };
1903 int block;
1904
1905
1906 block = onenand_block(this, ofs);
1907 if (bbm->bbt)
1908 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
1909
1910
1911 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1912 return onenand_write_oob_nolock(mtd, ofs, &ops);
1913}
1914
1915
1916
1917
1918
1919
1920
1921
1922int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1923{
1924 struct onenand_chip *this = mtd->priv;
1925 int ret;
1926
1927 ret = onenand_block_isbad(mtd, ofs);
1928 if (ret) {
1929
1930 if (ret > 0)
1931 return 0;
1932 return ret;
1933 }
1934
1935 onenand_get_device(mtd, FL_WRITING);
1936 ret = this->block_markbad(mtd, ofs);
1937 onenand_release_device(mtd);
1938
1939 return ret;
1940}
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
1952{
1953 struct onenand_chip *this = mtd->priv;
1954 int start, end, block, value, status;
1955
1956 start = onenand_block(this, ofs);
1957 end = onenand_block(this, ofs + len);
1958
1959
1960 if (this->options & ONENAND_HAS_CONT_LOCK) {
1961
1962 this->write_word(start,
1963 this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1964
1965 this->write_word(end - 1,
1966 this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1967
1968 this->command(mtd, cmd, 0, 0);
1969
1970
1971 this->wait(mtd, FL_UNLOCKING);
1972
1973
1974 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1975 & ONENAND_CTRL_ONGO)
1976 continue;
1977
1978
1979 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1980 if (!(status & ONENAND_WP_US))
1981 printk(KERN_ERR "wp status = 0x%x\n", status);
1982
1983 return 0;
1984 }
1985
1986
1987 for (block = start; block < end; block++) {
1988
1989 value = onenand_block_address(this, block);
1990 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1991
1992 value = onenand_bufferram_address(this, block);
1993 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
1994
1995
1996 this->write_word(block,
1997 this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1998
1999 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
2000
2001
2002 this->wait(mtd, FL_UNLOCKING);
2003
2004
2005 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2006 & ONENAND_CTRL_ONGO)
2007 continue;
2008
2009
2010 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2011 if (!(status & ONENAND_WP_US))
2012 printk(KERN_ERR "block = %d, wp status = 0x%x\n",
2013 block, status);
2014 }
2015
2016 return 0;
2017}
2018
2019#ifdef ONENAND_LINUX
2020
2021
2022
2023
2024
2025
2026
2027
2028static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
2029{
2030 int ret;
2031
2032 onenand_get_device(mtd, FL_LOCKING);
2033 ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
2034 onenand_release_device(mtd);
2035 return ret;
2036}
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
2047{
2048 int ret;
2049
2050 onenand_get_device(mtd, FL_LOCKING);
2051 ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2052 onenand_release_device(mtd);
2053 return ret;
2054}
2055#endif
2056
2057
2058
2059
2060
2061
2062
2063static int onenand_check_lock_status(struct onenand_chip *this)
2064{
2065 unsigned int value, block, status;
2066 unsigned int end;
2067
2068 end = this->chipsize >> this->erase_shift;
2069 for (block = 0; block < end; block++) {
2070
2071 value = onenand_block_address(this, block);
2072 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
2073
2074 value = onenand_bufferram_address(this, block);
2075 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
2076
2077 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2078
2079
2080 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2081 if (!(status & ONENAND_WP_US)) {
2082 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
2083 return 0;
2084 }
2085 }
2086
2087 return 1;
2088}
2089
2090
2091
2092
2093
2094
2095
2096static void onenand_unlock_all(struct mtd_info *mtd)
2097{
2098 struct onenand_chip *this = mtd->priv;
2099 loff_t ofs = 0;
2100 size_t len = mtd->size;
2101
2102 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
2103
2104 this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2105
2106 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
2107
2108
2109 this->wait(mtd, FL_LOCKING);
2110
2111
2112 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2113 & ONENAND_CTRL_ONGO)
2114 continue;
2115
2116
2117 if (onenand_check_lock_status(this))
2118 return;
2119
2120
2121 if (ONENAND_IS_DDP(this) && !FLEXONENAND(this)) {
2122
2123 ofs = this->chipsize >> 1;
2124 len = this->chipsize >> 1;
2125 }
2126 }
2127
2128 onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2129}
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140static void onenand_check_features(struct mtd_info *mtd)
2141{
2142 struct onenand_chip *this = mtd->priv;
2143 unsigned int density, process;
2144
2145
2146 density = onenand_get_density(this->device_id);
2147 process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
2148
2149
2150 switch (density) {
2151 case ONENAND_DEVICE_DENSITY_4Gb:
2152 if (ONENAND_IS_DDP(this))
2153 this->options |= ONENAND_HAS_2PLANE;
2154 else
2155 this->options |= ONENAND_HAS_4KB_PAGE;
2156
2157 case ONENAND_DEVICE_DENSITY_2Gb:
2158
2159 if (!ONENAND_IS_DDP(this))
2160 this->options |= ONENAND_HAS_2PLANE;
2161 this->options |= ONENAND_HAS_UNLOCK_ALL;
2162
2163 case ONENAND_DEVICE_DENSITY_1Gb:
2164
2165 if (process)
2166 this->options |= ONENAND_HAS_UNLOCK_ALL;
2167 break;
2168
2169 default:
2170
2171 if (!process)
2172 this->options |= ONENAND_HAS_CONT_LOCK;
2173 break;
2174 }
2175
2176 if (ONENAND_IS_MLC(this))
2177 this->options |= ONENAND_HAS_4KB_PAGE;
2178
2179 if (ONENAND_IS_4KB_PAGE(this))
2180 this->options &= ~ONENAND_HAS_2PLANE;
2181
2182 if (FLEXONENAND(this)) {
2183 this->options &= ~ONENAND_HAS_CONT_LOCK;
2184 this->options |= ONENAND_HAS_UNLOCK_ALL;
2185 }
2186
2187 if (this->options & ONENAND_HAS_CONT_LOCK)
2188 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
2189 if (this->options & ONENAND_HAS_UNLOCK_ALL)
2190 printk(KERN_DEBUG "Chip support all block unlock\n");
2191 if (this->options & ONENAND_HAS_2PLANE)
2192 printk(KERN_DEBUG "Chip has 2 plane\n");
2193 if (this->options & ONENAND_HAS_4KB_PAGE)
2194 printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
2195
2196}
2197
2198
2199
2200
2201
2202
2203
2204char *onenand_print_device_info(int device, int version)
2205{
2206 int vcc, demuxed, ddp, density, flexonenand;
2207 char *dev_info = malloc(80);
2208 char *p = dev_info;
2209
2210 vcc = device & ONENAND_DEVICE_VCC_MASK;
2211 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
2212 ddp = device & ONENAND_DEVICE_IS_DDP;
2213 density = onenand_get_density(device);
2214 flexonenand = device & DEVICE_IS_FLEXONENAND;
2215 p += sprintf(dev_info, "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)",
2216 demuxed ? "" : "Muxed ",
2217 flexonenand ? "Flex-" : "",
2218 ddp ? "(DDP)" : "",
2219 (16 << density), vcc ? "2.65/3.3" : "1.8", device);
2220
2221 sprintf(p, "\nOneNAND version = 0x%04x", version);
2222 printk("%s\n", dev_info);
2223
2224 return dev_info;
2225}
2226
2227static const struct onenand_manufacturers onenand_manuf_ids[] = {
2228 {ONENAND_MFR_NUMONYX, "Numonyx"},
2229 {ONENAND_MFR_SAMSUNG, "Samsung"},
2230};
2231
2232
2233
2234
2235
2236
2237
2238static int onenand_check_maf(int manuf)
2239{
2240 int size = ARRAY_SIZE(onenand_manuf_ids);
2241 int i;
2242#ifdef ONENAND_DEBUG
2243 char *name;
2244#endif
2245
2246 for (i = 0; i < size; i++)
2247 if (manuf == onenand_manuf_ids[i].id)
2248 break;
2249
2250#ifdef ONENAND_DEBUG
2251 if (i < size)
2252 name = onenand_manuf_ids[i].name;
2253 else
2254 name = "Unknown";
2255
2256 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
2257#endif
2258
2259 return i == size;
2260}
2261
2262
2263
2264
2265
2266
2267
2268static int flexonenand_get_boundary(struct mtd_info *mtd)
2269{
2270 struct onenand_chip *this = mtd->priv;
2271 unsigned int die, bdry;
2272 int syscfg, locked;
2273
2274
2275 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
2276 this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1);
2277
2278 for (die = 0; die < this->dies; die++) {
2279 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
2280 this->wait(mtd, FL_SYNCING);
2281
2282 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
2283 this->wait(mtd, FL_READING);
2284
2285 bdry = this->read_word(this->base + ONENAND_DATARAM);
2286 if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
2287 locked = 0;
2288 else
2289 locked = 1;
2290 this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
2291
2292 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
2293 this->wait(mtd, FL_RESETING);
2294
2295 printk(KERN_INFO "Die %d boundary: %d%s\n", die,
2296 this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
2297 }
2298
2299
2300 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
2301 return 0;
2302}
2303
2304
2305
2306
2307
2308
2309
2310static void flexonenand_get_size(struct mtd_info *mtd)
2311{
2312 struct onenand_chip *this = mtd->priv;
2313 int die, i, eraseshift, density;
2314 int blksperdie, maxbdry;
2315 loff_t ofs;
2316
2317 density = onenand_get_density(this->device_id);
2318 blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift);
2319 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
2320 maxbdry = blksperdie - 1;
2321 eraseshift = this->erase_shift - 1;
2322
2323 mtd->numeraseregions = this->dies << 1;
2324
2325
2326 flexonenand_get_boundary(mtd);
2327 die = 0;
2328 ofs = 0;
2329 i = -1;
2330 for (; die < this->dies; die++) {
2331 if (!die || this->boundary[die-1] != maxbdry) {
2332 i++;
2333 mtd->eraseregions[i].offset = ofs;
2334 mtd->eraseregions[i].erasesize = 1 << eraseshift;
2335 mtd->eraseregions[i].numblocks =
2336 this->boundary[die] + 1;
2337 ofs += mtd->eraseregions[i].numblocks << eraseshift;
2338 eraseshift++;
2339 } else {
2340 mtd->numeraseregions -= 1;
2341 mtd->eraseregions[i].numblocks +=
2342 this->boundary[die] + 1;
2343 ofs += (this->boundary[die] + 1) << (eraseshift - 1);
2344 }
2345 if (this->boundary[die] != maxbdry) {
2346 i++;
2347 mtd->eraseregions[i].offset = ofs;
2348 mtd->eraseregions[i].erasesize = 1 << eraseshift;
2349 mtd->eraseregions[i].numblocks = maxbdry ^
2350 this->boundary[die];
2351 ofs += mtd->eraseregions[i].numblocks << eraseshift;
2352 eraseshift--;
2353 } else
2354 mtd->numeraseregions -= 1;
2355 }
2356
2357
2358 mtd->erasesize = 1 << this->erase_shift;
2359 if (mtd->numeraseregions == 1)
2360 mtd->erasesize >>= 1;
2361
2362 printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions);
2363 for (i = 0; i < mtd->numeraseregions; i++)
2364 printk(KERN_INFO "[offset: 0x%08llx, erasesize: 0x%05x,"
2365 " numblocks: %04u]\n", mtd->eraseregions[i].offset,
2366 mtd->eraseregions[i].erasesize,
2367 mtd->eraseregions[i].numblocks);
2368
2369 for (die = 0, mtd->size = 0; die < this->dies; die++) {
2370 this->diesize[die] = (loff_t) (blksperdie << this->erase_shift);
2371 this->diesize[die] -= (loff_t) (this->boundary[die] + 1)
2372 << (this->erase_shift - 1);
2373 mtd->size += this->diesize[die];
2374 }
2375}
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391static int flexonenand_check_blocks_erased(struct mtd_info *mtd,
2392 int start, int end)
2393{
2394 struct onenand_chip *this = mtd->priv;
2395 int i, ret;
2396 int block;
2397 struct mtd_oob_ops ops = {
2398 .mode = MTD_OPS_PLACE_OOB,
2399 .ooboffs = 0,
2400 .ooblen = mtd->oobsize,
2401 .datbuf = NULL,
2402 .oobbuf = this->oob_buf,
2403 };
2404 loff_t addr;
2405
2406 printk(KERN_DEBUG "Check blocks from %d to %d\n", start, end);
2407
2408 for (block = start; block <= end; block++) {
2409 addr = flexonenand_addr(this, block);
2410 if (onenand_block_isbad_nolock(mtd, addr, 0))
2411 continue;
2412
2413
2414
2415
2416
2417 ret = onenand_read_oob_nolock(mtd, addr, &ops);
2418 if (ret)
2419 return ret;
2420
2421 for (i = 0; i < mtd->oobsize; i++)
2422 if (this->oob_buf[i] != 0xff)
2423 break;
2424
2425 if (i != mtd->oobsize) {
2426 printk(KERN_WARNING "Block %d not erased.\n", block);
2427 return 1;
2428 }
2429 }
2430
2431 return 0;
2432}
2433
2434
2435
2436
2437
2438int flexonenand_set_boundary(struct mtd_info *mtd, int die,
2439 int boundary, int lock)
2440{
2441 struct onenand_chip *this = mtd->priv;
2442 int ret, density, blksperdie, old, new, thisboundary;
2443 loff_t addr;
2444
2445 if (die >= this->dies)
2446 return -EINVAL;
2447
2448 if (boundary == this->boundary[die])
2449 return 0;
2450
2451 density = onenand_get_density(this->device_id);
2452 blksperdie = ((16 << density) << 20) >> this->erase_shift;
2453 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
2454
2455 if (boundary >= blksperdie) {
2456 printk("flexonenand_set_boundary:"
2457 "Invalid boundary value. "
2458 "Boundary not changed.\n");
2459 return -EINVAL;
2460 }
2461
2462
2463 old = this->boundary[die] + (die * this->density_mask);
2464 new = boundary + (die * this->density_mask);
2465 ret = flexonenand_check_blocks_erased(mtd, min(old, new)
2466 + 1, max(old, new));
2467 if (ret) {
2468 printk(KERN_ERR "flexonenand_set_boundary: Please erase blocks before boundary change\n");
2469 return ret;
2470 }
2471
2472 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
2473 this->wait(mtd, FL_SYNCING);
2474
2475
2476 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
2477 ret = this->wait(mtd, FL_READING);
2478
2479 thisboundary = this->read_word(this->base + ONENAND_DATARAM);
2480 if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
2481 printk(KERN_ERR "flexonenand_set_boundary: boundary locked\n");
2482 goto out;
2483 }
2484
2485 printk(KERN_INFO "flexonenand_set_boundary: Changing die %d boundary: %d%s\n",
2486 die, boundary, lock ? "(Locked)" : "(Unlocked)");
2487
2488 boundary &= FLEXONENAND_PI_MASK;
2489 boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT);
2490
2491 addr = die ? this->diesize[0] : 0;
2492 this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
2493 ret = this->wait(mtd, FL_ERASING);
2494 if (ret) {
2495 printk("flexonenand_set_boundary:"
2496 "Failed PI erase for Die %d\n", die);
2497 goto out;
2498 }
2499
2500 this->write_word(boundary, this->base + ONENAND_DATARAM);
2501 this->command(mtd, ONENAND_CMD_PROG, addr, 0);
2502 ret = this->wait(mtd, FL_WRITING);
2503 if (ret) {
2504 printk("flexonenand_set_boundary:"
2505 "Failed PI write for Die %d\n", die);
2506 goto out;
2507 }
2508
2509 this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0);
2510 ret = this->wait(mtd, FL_WRITING);
2511out:
2512 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND);
2513 this->wait(mtd, FL_RESETING);
2514 if (!ret)
2515
2516 flexonenand_get_size(mtd);
2517
2518 return ret;
2519}
2520
2521
2522
2523
2524
2525
2526
2527
2528static int onenand_chip_probe(struct mtd_info *mtd)
2529{
2530 struct onenand_chip *this = mtd->priv;
2531 int bram_maf_id, bram_dev_id, maf_id, dev_id;
2532 int syscfg;
2533
2534
2535 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
2536
2537
2538 this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ),
2539 this->base + ONENAND_REG_SYS_CFG1);
2540
2541
2542 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
2543
2544
2545 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
2546 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
2547
2548
2549 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
2550
2551
2552 if (this->wait(mtd, FL_RESETING))
2553 return -ENXIO;
2554
2555
2556 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
2557
2558
2559 if (onenand_check_maf(bram_maf_id))
2560 return -ENXIO;
2561
2562
2563 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
2564 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
2565
2566
2567 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
2568 return -ENXIO;
2569
2570 return 0;
2571}
2572
2573
2574
2575
2576
2577
2578
2579
2580int onenand_probe(struct mtd_info *mtd)
2581{
2582 struct onenand_chip *this = mtd->priv;
2583 int dev_id, ver_id;
2584 int density;
2585 int ret;
2586
2587 ret = this->chip_probe(mtd);
2588 if (ret)
2589 return ret;
2590
2591
2592 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
2593 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
2594 this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
2595
2596
2597 mtd->name = onenand_print_device_info(dev_id, ver_id);
2598 this->device_id = dev_id;
2599 this->version_id = ver_id;
2600
2601
2602 onenand_check_features(mtd);
2603
2604 density = onenand_get_density(dev_id);
2605 if (FLEXONENAND(this)) {
2606 this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
2607
2608 mtd->numeraseregions = this->dies << 1;
2609 mtd->eraseregions = malloc(sizeof(struct mtd_erase_region_info)
2610 * (this->dies << 1));
2611 if (!mtd->eraseregions)
2612 return -ENOMEM;
2613 }
2614
2615
2616
2617
2618
2619 this->chipsize = (16 << density) << 20;
2620
2621
2622
2623 mtd->writesize =
2624 this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
2625
2626 if (ONENAND_IS_4KB_PAGE(this))
2627 mtd->writesize <<= 1;
2628
2629 mtd->oobsize = mtd->writesize >> 5;
2630
2631 mtd->erasesize = mtd->writesize << 6;
2632
2633
2634
2635
2636
2637 if (FLEXONENAND(this))
2638 mtd->erasesize <<= 1;
2639
2640 this->erase_shift = ffs(mtd->erasesize) - 1;
2641 this->page_shift = ffs(mtd->writesize) - 1;
2642 this->ppb_shift = (this->erase_shift - this->page_shift);
2643 this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
2644
2645 if (ONENAND_IS_DDP(this))
2646 this->density_mask = this->chipsize >> (this->erase_shift + 1);
2647
2648 this->writesize = mtd->writesize;
2649
2650
2651
2652 if (FLEXONENAND(this))
2653 flexonenand_get_size(mtd);
2654 else
2655 mtd->size = this->chipsize;
2656
2657 mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH;
2658 mtd->flags = MTD_CAP_NANDFLASH;
2659 mtd->_erase = onenand_erase;
2660 mtd->_read_oob = onenand_read_oob;
2661 mtd->_write_oob = onenand_write_oob;
2662 mtd->_sync = onenand_sync;
2663 mtd->_block_isbad = onenand_block_isbad;
2664 mtd->_block_markbad = onenand_block_markbad;
2665 mtd->writebufsize = mtd->writesize;
2666
2667 return 0;
2668}
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680int onenand_scan(struct mtd_info *mtd, int maxchips)
2681{
2682 int i;
2683 struct onenand_chip *this = mtd->priv;
2684
2685 if (!this->read_word)
2686 this->read_word = onenand_readw;
2687 if (!this->write_word)
2688 this->write_word = onenand_writew;
2689
2690 if (!this->command)
2691 this->command = onenand_command;
2692 if (!this->wait)
2693 this->wait = onenand_wait;
2694 if (!this->bbt_wait)
2695 this->bbt_wait = onenand_bbt_wait;
2696
2697 if (!this->read_bufferram)
2698 this->read_bufferram = onenand_read_bufferram;
2699 if (!this->write_bufferram)
2700 this->write_bufferram = onenand_write_bufferram;
2701
2702 if (!this->chip_probe)
2703 this->chip_probe = onenand_chip_probe;
2704
2705 if (!this->block_markbad)
2706 this->block_markbad = onenand_default_block_markbad;
2707 if (!this->scan_bbt)
2708 this->scan_bbt = onenand_default_bbt;
2709
2710 if (onenand_probe(mtd))
2711 return -ENXIO;
2712
2713
2714 if (this->mmcontrol) {
2715 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
2716 this->read_bufferram = onenand_sync_read_bufferram;
2717 }
2718
2719
2720 if (!this->page_buf) {
2721 this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
2722 if (!this->page_buf) {
2723 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
2724 return -ENOMEM;
2725 }
2726 this->options |= ONENAND_PAGEBUF_ALLOC;
2727 }
2728 if (!this->oob_buf) {
2729 this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
2730 if (!this->oob_buf) {
2731 printk(KERN_ERR "onenand_scan: Can't allocate oob_buf\n");
2732 if (this->options & ONENAND_PAGEBUF_ALLOC) {
2733 this->options &= ~ONENAND_PAGEBUF_ALLOC;
2734 kfree(this->page_buf);
2735 }
2736 return -ENOMEM;
2737 }
2738 this->options |= ONENAND_OOBBUF_ALLOC;
2739 }
2740
2741 this->state = FL_READY;
2742
2743
2744
2745
2746 switch (mtd->oobsize) {
2747 case 128:
2748 this->ecclayout = &onenand_oob_128;
2749 mtd->subpage_sft = 0;
2750 break;
2751
2752 case 64:
2753 this->ecclayout = &onenand_oob_64;
2754 mtd->subpage_sft = 2;
2755 break;
2756
2757 case 32:
2758 this->ecclayout = &onenand_oob_32;
2759 mtd->subpage_sft = 1;
2760 break;
2761
2762 default:
2763 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
2764 mtd->oobsize);
2765 mtd->subpage_sft = 0;
2766
2767 this->ecclayout = &onenand_oob_32;
2768 break;
2769 }
2770
2771 this->subpagesize = mtd->writesize >> mtd->subpage_sft;
2772
2773
2774
2775
2776
2777 this->ecclayout->oobavail = 0;
2778
2779 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE &&
2780 this->ecclayout->oobfree[i].length; i++)
2781 this->ecclayout->oobavail +=
2782 this->ecclayout->oobfree[i].length;
2783 mtd->oobavail = this->ecclayout->oobavail;
2784
2785 mtd->ecclayout = this->ecclayout;
2786
2787
2788 onenand_unlock_all(mtd);
2789
2790 return this->scan_bbt(mtd);
2791}
2792
2793
2794
2795
2796
2797void onenand_release(struct mtd_info *mtd)
2798{
2799}
2800