1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/slab.h>
27#include <linux/sched.h>
28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/jiffies.h>
31#include <linux/mtd/mtd.h>
32#include <linux/mtd/onenand.h>
33#include <linux/mtd/partitions.h>
34
35#include <asm/io.h>
36
37
38
39
40
41#define MB_ERASE_MIN_BLK_COUNT 2
42#define MB_ERASE_MAX_BLK_COUNT 64
43
44
45static int flex_bdry[MAX_DIES * 2] = { -1, 0, -1, 0 };
46
47module_param_array(flex_bdry, int, NULL, 0400);
48MODULE_PARM_DESC(flex_bdry, "SLC Boundary information for Flex-OneNAND"
49 "Syntax:flex_bdry=DIE_BDRY,LOCK,..."
50 "DIE_BDRY: SLC boundary of the die"
51 "LOCK: Locking information for SLC boundary"
52 " : 0->Set boundary in unlocked status"
53 " : 1->Set boundary in locked status");
54
55
56static int otp;
57
58module_param(otp, int, 0400);
59MODULE_PARM_DESC(otp, "Corresponding behaviour of OneNAND in OTP"
60 "Syntax : otp=LOCK_TYPE"
61 "LOCK_TYPE : Keys issued, for specific OTP Lock type"
62 " : 0 -> Default (No Blocks Locked)"
63 " : 1 -> OTP Block lock"
64 " : 2 -> 1st Block lock"
65 " : 3 -> BOTH OTP Block and 1st Block lock");
66
67
68
69
70
71static struct nand_ecclayout flexonenand_oob_128 = {
72 .eccbytes = 64,
73 .eccpos = {
74 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
75 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
76 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
77 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
78 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
79 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
80 102, 103, 104, 105
81 },
82 .oobfree = {
83 {2, 4}, {18, 4}, {34, 4}, {50, 4},
84 {66, 4}, {82, 4}, {98, 4}, {114, 4}
85 }
86};
87
88
89
90
91
92
93
94
95
96
97
98
99static struct nand_ecclayout onenand_oob_128 = {
100 .eccbytes = 64,
101 .eccpos = {
102 7, 8, 9, 10, 11, 12, 13, 14, 15,
103 23, 24, 25, 26, 27, 28, 29, 30, 31,
104 39, 40, 41, 42, 43, 44, 45, 46, 47,
105 55, 56, 57, 58, 59, 60, 61, 62, 63,
106 71, 72, 73, 74, 75, 76, 77, 78, 79,
107 87, 88, 89, 90, 91, 92, 93, 94, 95,
108 103, 104, 105, 106, 107, 108, 109, 110, 111,
109 119
110 },
111 .oobfree = {
112 {2, 3}, {18, 3}, {34, 3}, {50, 3},
113 {66, 3}, {82, 3}, {98, 3}, {114, 3}
114 }
115};
116
117
118
119
120static struct nand_ecclayout onenand_oob_64 = {
121 .eccbytes = 20,
122 .eccpos = {
123 8, 9, 10, 11, 12,
124 24, 25, 26, 27, 28,
125 40, 41, 42, 43, 44,
126 56, 57, 58, 59, 60,
127 },
128 .oobfree = {
129 {2, 3}, {14, 2}, {18, 3}, {30, 2},
130 {34, 3}, {46, 2}, {50, 3}, {62, 2}
131 }
132};
133
134
135
136
137static struct nand_ecclayout onenand_oob_32 = {
138 .eccbytes = 10,
139 .eccpos = {
140 8, 9, 10, 11, 12,
141 24, 25, 26, 27, 28,
142 },
143 .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
144};
145
146static const unsigned char ffchars[] = {
147 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
148 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
149 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
150 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
152 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
154 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
155 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
156 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
157 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
158 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
159 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
160 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
161 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
162 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
163};
164
165
166
167
168
169
170
171static unsigned short onenand_readw(void __iomem *addr)
172{
173 return readw(addr);
174}
175
176
177
178
179
180
181
182
183static void onenand_writew(unsigned short value, void __iomem *addr)
184{
185 writew(value, addr);
186}
187
188
189
190
191
192
193
194
195
196static int onenand_block_address(struct onenand_chip *this, int block)
197{
198
199 if (block & this->density_mask)
200 return ONENAND_DDP_CHIP1 | (block ^ this->density_mask);
201
202 return block;
203}
204
205
206
207
208
209
210
211
212
213static int onenand_bufferram_address(struct onenand_chip *this, int block)
214{
215
216 if (block & this->density_mask)
217 return ONENAND_DDP_CHIP1;
218
219 return ONENAND_DDP_CHIP0;
220}
221
222
223
224
225
226
227
228
229
230static int onenand_page_address(int page, int sector)
231{
232
233 int fpa, fsa;
234
235 fpa = page & ONENAND_FPA_MASK;
236 fsa = sector & ONENAND_FSA_MASK;
237
238 return ((fpa << ONENAND_FPA_SHIFT) | fsa);
239}
240
241
242
243
244
245
246
247
248
249
250static int onenand_buffer_address(int dataram1, int sectors, int count)
251{
252 int bsa, bsc;
253
254
255 bsa = sectors & ONENAND_BSA_MASK;
256
257 if (dataram1)
258 bsa |= ONENAND_BSA_DATARAM1;
259 else
260 bsa |= ONENAND_BSA_DATARAM0;
261
262
263 bsc = count & ONENAND_BSC_MASK;
264
265 return ((bsa << ONENAND_BSA_SHIFT) | bsc);
266}
267
268
269
270
271
272
273static unsigned flexonenand_block(struct onenand_chip *this, loff_t addr)
274{
275 unsigned boundary, blk, die = 0;
276
277 if (ONENAND_IS_DDP(this) && addr >= this->diesize[0]) {
278 die = 1;
279 addr -= this->diesize[0];
280 }
281
282 boundary = this->boundary[die];
283
284 blk = addr >> (this->erase_shift - 1);
285 if (blk > boundary)
286 blk = (blk + boundary + 1) >> 1;
287
288 blk += die ? this->density_mask : 0;
289 return blk;
290}
291
292inline unsigned onenand_block(struct onenand_chip *this, loff_t addr)
293{
294 if (!FLEXONENAND(this))
295 return addr >> this->erase_shift;
296 return flexonenand_block(this, addr);
297}
298
299
300
301
302
303
304
305
306static loff_t flexonenand_addr(struct onenand_chip *this, int block)
307{
308 loff_t ofs = 0;
309 int die = 0, boundary;
310
311 if (ONENAND_IS_DDP(this) && block >= this->density_mask) {
312 block -= this->density_mask;
313 die = 1;
314 ofs = this->diesize[0];
315 }
316
317 boundary = this->boundary[die];
318 ofs += (loff_t)block << (this->erase_shift - 1);
319 if (block > (boundary + 1))
320 ofs += (loff_t)(block - boundary - 1) << (this->erase_shift - 1);
321 return ofs;
322}
323
324loff_t onenand_addr(struct onenand_chip *this, int block)
325{
326 if (!FLEXONENAND(this))
327 return (loff_t)block << this->erase_shift;
328 return flexonenand_addr(this, block);
329}
330EXPORT_SYMBOL(onenand_addr);
331
332
333
334
335
336
337
338static inline int onenand_get_density(int dev_id)
339{
340 int density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
341 return (density & ONENAND_DEVICE_DENSITY_MASK);
342}
343
344
345
346
347
348
349int flexonenand_region(struct mtd_info *mtd, loff_t addr)
350{
351 int i;
352
353 for (i = 0; i < mtd->numeraseregions; i++)
354 if (addr < mtd->eraseregions[i].offset)
355 break;
356 return i - 1;
357}
358EXPORT_SYMBOL(flexonenand_region);
359
360
361
362
363
364
365
366
367
368
369
370static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
371{
372 struct onenand_chip *this = mtd->priv;
373 int value, block, page;
374
375
376 switch (cmd) {
377 case ONENAND_CMD_UNLOCK:
378 case ONENAND_CMD_LOCK:
379 case ONENAND_CMD_LOCK_TIGHT:
380 case ONENAND_CMD_UNLOCK_ALL:
381 block = -1;
382 page = -1;
383 break;
384
385 case FLEXONENAND_CMD_PI_ACCESS:
386
387 block = addr * this->density_mask;
388 page = -1;
389 break;
390
391 case ONENAND_CMD_ERASE:
392 case ONENAND_CMD_MULTIBLOCK_ERASE:
393 case ONENAND_CMD_ERASE_VERIFY:
394 case ONENAND_CMD_BUFFERRAM:
395 case ONENAND_CMD_OTP_ACCESS:
396 block = onenand_block(this, addr);
397 page = -1;
398 break;
399
400 case FLEXONENAND_CMD_READ_PI:
401 cmd = ONENAND_CMD_READ;
402 block = addr * this->density_mask;
403 page = 0;
404 break;
405
406 default:
407 block = onenand_block(this, addr);
408 if (FLEXONENAND(this))
409 page = (int) (addr - onenand_addr(this, block))>>\
410 this->page_shift;
411 else
412 page = (int) (addr >> this->page_shift);
413 if (ONENAND_IS_2PLANE(this)) {
414
415 block &= ~1;
416
417 if (addr & this->writesize)
418 block++;
419 page >>= 1;
420 }
421 page &= this->page_mask;
422 break;
423 }
424
425
426 if (cmd == ONENAND_CMD_BUFFERRAM) {
427
428 value = onenand_bufferram_address(this, block);
429 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
430
431 if (ONENAND_IS_2PLANE(this) || ONENAND_IS_4KB_PAGE(this))
432
433 ONENAND_SET_BUFFERRAM0(this);
434 else
435
436 ONENAND_SET_NEXT_BUFFERRAM(this);
437
438 return 0;
439 }
440
441 if (block != -1) {
442
443 value = onenand_block_address(this, block);
444 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
445
446
447 value = onenand_bufferram_address(this, block);
448 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
449 }
450
451 if (page != -1) {
452
453 int sectors = 0, count = 0;
454 int dataram;
455
456 switch (cmd) {
457 case FLEXONENAND_CMD_RECOVER_LSB:
458 case ONENAND_CMD_READ:
459 case ONENAND_CMD_READOOB:
460 if (ONENAND_IS_4KB_PAGE(this))
461
462 dataram = ONENAND_SET_BUFFERRAM0(this);
463 else
464 dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
465 break;
466
467 default:
468 if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG)
469 cmd = ONENAND_CMD_2X_PROG;
470 dataram = ONENAND_CURRENT_BUFFERRAM(this);
471 break;
472 }
473
474
475 value = onenand_page_address(page, sectors);
476 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS8);
477
478
479 value = onenand_buffer_address(dataram, sectors, count);
480 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
481 }
482
483
484 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
485
486
487 this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
488
489 return 0;
490}
491
492
493
494
495
496static inline int onenand_read_ecc(struct onenand_chip *this)
497{
498 int ecc, i, result = 0;
499
500 if (!FLEXONENAND(this) && !ONENAND_IS_4KB_PAGE(this))
501 return this->read_word(this->base + ONENAND_REG_ECC_STATUS);
502
503 for (i = 0; i < 4; i++) {
504 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS + i*2);
505 if (likely(!ecc))
506 continue;
507 if (ecc & FLEXONENAND_UNCORRECTABLE_ERROR)
508 return ONENAND_ECC_2BIT_ALL;
509 else
510 result = ONENAND_ECC_1BIT_ALL;
511 }
512
513 return result;
514}
515
516
517
518
519
520
521
522
523
524
525static int onenand_wait(struct mtd_info *mtd, int state)
526{
527 struct onenand_chip * this = mtd->priv;
528 unsigned long timeout;
529 unsigned int flags = ONENAND_INT_MASTER;
530 unsigned int interrupt = 0;
531 unsigned int ctrl;
532
533
534 timeout = jiffies + msecs_to_jiffies(20);
535 while (time_before(jiffies, timeout)) {
536 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
537
538 if (interrupt & flags)
539 break;
540
541 if (state != FL_READING && state != FL_PREPARING_ERASE)
542 cond_resched();
543 }
544
545 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
546
547 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
548
549
550
551
552
553
554 if (interrupt & ONENAND_INT_READ) {
555 int ecc = onenand_read_ecc(this);
556 if (ecc) {
557 if (ecc & ONENAND_ECC_2BIT_ALL) {
558 printk(KERN_ERR "%s: ECC error = 0x%04x\n",
559 __func__, ecc);
560 mtd->ecc_stats.failed++;
561 return -EBADMSG;
562 } else if (ecc & ONENAND_ECC_1BIT_ALL) {
563 printk(KERN_DEBUG "%s: correctable ECC error = 0x%04x\n",
564 __func__, ecc);
565 mtd->ecc_stats.corrected++;
566 }
567 }
568 } else if (state == FL_READING) {
569 printk(KERN_ERR "%s: read timeout! ctrl=0x%04x intr=0x%04x\n",
570 __func__, ctrl, interrupt);
571 return -EIO;
572 }
573
574 if (state == FL_PREPARING_ERASE && !(interrupt & ONENAND_INT_ERASE)) {
575 printk(KERN_ERR "%s: mb erase timeout! ctrl=0x%04x intr=0x%04x\n",
576 __func__, ctrl, interrupt);
577 return -EIO;
578 }
579
580 if (!(interrupt & ONENAND_INT_MASTER)) {
581 printk(KERN_ERR "%s: timeout! ctrl=0x%04x intr=0x%04x\n",
582 __func__, ctrl, interrupt);
583 return -EIO;
584 }
585
586
587 if (ctrl & ONENAND_CTRL_ERROR) {
588 printk(KERN_ERR "%s: controller error = 0x%04x\n",
589 __func__, ctrl);
590 if (ctrl & ONENAND_CTRL_LOCK)
591 printk(KERN_ERR "%s: it's locked error.\n", __func__);
592 return -EIO;
593 }
594
595 return 0;
596}
597
598
599
600
601
602
603
604
605static irqreturn_t onenand_interrupt(int irq, void *data)
606{
607 struct onenand_chip *this = data;
608
609
610 if (!this->complete.done)
611 complete(&this->complete);
612
613 return IRQ_HANDLED;
614}
615
616
617
618
619
620
621
622
623static int onenand_interrupt_wait(struct mtd_info *mtd, int state)
624{
625 struct onenand_chip *this = mtd->priv;
626
627 wait_for_completion(&this->complete);
628
629 return onenand_wait(mtd, state);
630}
631
632
633
634
635
636
637
638
639static int onenand_try_interrupt_wait(struct mtd_info *mtd, int state)
640{
641 struct onenand_chip *this = mtd->priv;
642 unsigned long remain, timeout;
643
644
645 this->wait = onenand_interrupt_wait;
646
647 timeout = msecs_to_jiffies(100);
648 remain = wait_for_completion_timeout(&this->complete, timeout);
649 if (!remain) {
650 printk(KERN_INFO "OneNAND: There's no interrupt. "
651 "We use the normal wait\n");
652
653
654 free_irq(this->irq, this);
655
656 this->wait = onenand_wait;
657 }
658
659 return onenand_wait(mtd, state);
660}
661
662
663
664
665
666
667
668
669
670static void onenand_setup_wait(struct mtd_info *mtd)
671{
672 struct onenand_chip *this = mtd->priv;
673 int syscfg;
674
675 init_completion(&this->complete);
676
677 if (this->irq <= 0) {
678 this->wait = onenand_wait;
679 return;
680 }
681
682 if (request_irq(this->irq, &onenand_interrupt,
683 IRQF_SHARED, "onenand", this)) {
684
685 this->wait = onenand_wait;
686 return;
687 }
688
689
690 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
691 syscfg |= ONENAND_SYS_CFG1_IOBE;
692 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
693
694 this->wait = onenand_try_interrupt_wait;
695}
696
697
698
699
700
701
702
703
704
705static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
706{
707 struct onenand_chip *this = mtd->priv;
708
709 if (ONENAND_CURRENT_BUFFERRAM(this)) {
710
711 if (area == ONENAND_DATARAM)
712 return this->writesize;
713 if (area == ONENAND_SPARERAM)
714 return mtd->oobsize;
715 }
716
717 return 0;
718}
719
720
721
722
723
724
725
726
727
728
729
730static int onenand_read_bufferram(struct mtd_info *mtd, int area,
731 unsigned char *buffer, int offset, size_t count)
732{
733 struct onenand_chip *this = mtd->priv;
734 void __iomem *bufferram;
735
736 bufferram = this->base + area;
737
738 bufferram += onenand_bufferram_offset(mtd, area);
739
740 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
741 unsigned short word;
742
743
744 count--;
745
746
747 word = this->read_word(bufferram + offset + count);
748 buffer[count] = (word & 0xff);
749 }
750
751 memcpy(buffer, bufferram + offset, count);
752
753 return 0;
754}
755
756
757
758
759
760
761
762
763
764
765
766static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
767 unsigned char *buffer, int offset, size_t count)
768{
769 struct onenand_chip *this = mtd->priv;
770 void __iomem *bufferram;
771
772 bufferram = this->base + area;
773
774 bufferram += onenand_bufferram_offset(mtd, area);
775
776 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
777
778 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
779 unsigned short word;
780
781
782 count--;
783
784
785 word = this->read_word(bufferram + offset + count);
786 buffer[count] = (word & 0xff);
787 }
788
789 memcpy(buffer, bufferram + offset, count);
790
791 this->mmcontrol(mtd, 0);
792
793 return 0;
794}
795
796
797
798
799
800
801
802
803
804
805
806static int onenand_write_bufferram(struct mtd_info *mtd, int area,
807 const unsigned char *buffer, int offset, size_t count)
808{
809 struct onenand_chip *this = mtd->priv;
810 void __iomem *bufferram;
811
812 bufferram = this->base + area;
813
814 bufferram += onenand_bufferram_offset(mtd, area);
815
816 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
817 unsigned short word;
818 int byte_offset;
819
820
821 count--;
822
823
824 byte_offset = offset + count;
825
826
827 word = this->read_word(bufferram + byte_offset);
828 word = (word & ~0xff) | buffer[count];
829 this->write_word(word, bufferram + byte_offset);
830 }
831
832 memcpy(bufferram + offset, buffer, count);
833
834 return 0;
835}
836
837
838
839
840
841
842
843
844
845static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr)
846{
847 struct onenand_chip *this = mtd->priv;
848 int blockpage, block, page;
849
850
851 block = (int) (addr >> this->erase_shift) & ~1;
852
853 if (addr & this->writesize)
854 block++;
855 page = (int) (addr >> (this->page_shift + 1)) & this->page_mask;
856 blockpage = (block << 7) | page;
857
858 return blockpage;
859}
860
861
862
863
864
865
866
867
868
869static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
870{
871 struct onenand_chip *this = mtd->priv;
872 int blockpage, found = 0;
873 unsigned int i;
874
875 if (ONENAND_IS_2PLANE(this))
876 blockpage = onenand_get_2x_blockpage(mtd, addr);
877 else
878 blockpage = (int) (addr >> this->page_shift);
879
880
881 i = ONENAND_CURRENT_BUFFERRAM(this);
882 if (this->bufferram[i].blockpage == blockpage)
883 found = 1;
884 else {
885
886 i = ONENAND_NEXT_BUFFERRAM(this);
887 if (this->bufferram[i].blockpage == blockpage) {
888 ONENAND_SET_NEXT_BUFFERRAM(this);
889 found = 1;
890 }
891 }
892
893 if (found && ONENAND_IS_DDP(this)) {
894
895 int block = onenand_block(this, addr);
896 int value = onenand_bufferram_address(this, block);
897 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
898 }
899
900 return found;
901}
902
903
904
905
906
907
908
909
910
911static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
912 int valid)
913{
914 struct onenand_chip *this = mtd->priv;
915 int blockpage;
916 unsigned int i;
917
918 if (ONENAND_IS_2PLANE(this))
919 blockpage = onenand_get_2x_blockpage(mtd, addr);
920 else
921 blockpage = (int) (addr >> this->page_shift);
922
923
924 i = ONENAND_NEXT_BUFFERRAM(this);
925 if (this->bufferram[i].blockpage == blockpage)
926 this->bufferram[i].blockpage = -1;
927
928
929 i = ONENAND_CURRENT_BUFFERRAM(this);
930 if (valid)
931 this->bufferram[i].blockpage = blockpage;
932 else
933 this->bufferram[i].blockpage = -1;
934}
935
936
937
938
939
940
941
942
943
944static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
945 unsigned int len)
946{
947 struct onenand_chip *this = mtd->priv;
948 int i;
949 loff_t end_addr = addr + len;
950
951
952 for (i = 0; i < MAX_BUFFERRAM; i++) {
953 loff_t buf_addr = this->bufferram[i].blockpage << this->page_shift;
954 if (buf_addr >= addr && buf_addr < end_addr)
955 this->bufferram[i].blockpage = -1;
956 }
957}
958
959
960
961
962
963
964
965
966static int onenand_get_device(struct mtd_info *mtd, int new_state)
967{
968 struct onenand_chip *this = mtd->priv;
969 DECLARE_WAITQUEUE(wait, current);
970
971
972
973
974 while (1) {
975 spin_lock(&this->chip_lock);
976 if (this->state == FL_READY) {
977 this->state = new_state;
978 spin_unlock(&this->chip_lock);
979 if (new_state != FL_PM_SUSPENDED && this->enable)
980 this->enable(mtd);
981 break;
982 }
983 if (new_state == FL_PM_SUSPENDED) {
984 spin_unlock(&this->chip_lock);
985 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
986 }
987 set_current_state(TASK_UNINTERRUPTIBLE);
988 add_wait_queue(&this->wq, &wait);
989 spin_unlock(&this->chip_lock);
990 schedule();
991 remove_wait_queue(&this->wq, &wait);
992 }
993
994 return 0;
995}
996
997
998
999
1000
1001
1002
1003static void onenand_release_device(struct mtd_info *mtd)
1004{
1005 struct onenand_chip *this = mtd->priv;
1006
1007 if (this->state != FL_PM_SUSPENDED && this->disable)
1008 this->disable(mtd);
1009
1010 spin_lock(&this->chip_lock);
1011 this->state = FL_READY;
1012 wake_up(&this->wq);
1013 spin_unlock(&this->chip_lock);
1014}
1015
1016
1017
1018
1019
1020
1021
1022
1023static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int column,
1024 int thislen)
1025{
1026 struct onenand_chip *this = mtd->priv;
1027 struct nand_oobfree *free;
1028 int readcol = column;
1029 int readend = column + thislen;
1030 int lastgap = 0;
1031 unsigned int i;
1032 uint8_t *oob_buf = this->oob_buf;
1033
1034 free = this->ecclayout->oobfree;
1035 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
1036 if (readcol >= lastgap)
1037 readcol += free->offset - lastgap;
1038 if (readend >= lastgap)
1039 readend += free->offset - lastgap;
1040 lastgap = free->offset + free->length;
1041 }
1042 this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
1043 free = this->ecclayout->oobfree;
1044 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
1045 int free_end = free->offset + free->length;
1046 if (free->offset < readend && free_end > readcol) {
1047 int st = max_t(int,free->offset,readcol);
1048 int ed = min_t(int,free_end,readend);
1049 int n = ed - st;
1050 memcpy(buf, oob_buf + st, n);
1051 buf += n;
1052 } else if (column == 0)
1053 break;
1054 }
1055 return 0;
1056}
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status)
1072{
1073 struct onenand_chip *this = mtd->priv;
1074 int i;
1075
1076
1077 if (!FLEXONENAND(this))
1078 return status;
1079
1080
1081 if (!mtd_is_eccerr(status) && status != ONENAND_BBT_READ_ECC_ERROR)
1082 return status;
1083
1084
1085 i = flexonenand_region(mtd, addr);
1086 if (mtd->eraseregions[i].erasesize < (1 << this->erase_shift))
1087 return status;
1088
1089
1090
1091
1092 printk(KERN_INFO "%s: Attempting to recover from uncorrectable read\n",
1093 __func__);
1094 mtd->ecc_stats.failed--;
1095
1096
1097 this->command(mtd, FLEXONENAND_CMD_RECOVER_LSB, addr, this->writesize);
1098 return this->wait(mtd, FL_READING);
1099}
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
1111 struct mtd_oob_ops *ops)
1112{
1113 struct onenand_chip *this = mtd->priv;
1114 struct mtd_ecc_stats stats;
1115 size_t len = ops->len;
1116 size_t ooblen = ops->ooblen;
1117 u_char *buf = ops->datbuf;
1118 u_char *oobbuf = ops->oobbuf;
1119 int read = 0, column, thislen;
1120 int oobread = 0, oobcolumn, thisooblen, oobsize;
1121 int ret = 0;
1122 int writesize = this->writesize;
1123
1124 pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
1125 (int)len);
1126
1127 if (ops->mode == MTD_OPS_AUTO_OOB)
1128 oobsize = this->ecclayout->oobavail;
1129 else
1130 oobsize = mtd->oobsize;
1131
1132 oobcolumn = from & (mtd->oobsize - 1);
1133
1134
1135 if (from + len > mtd->size) {
1136 printk(KERN_ERR "%s: Attempt read beyond end of device\n",
1137 __func__);
1138 ops->retlen = 0;
1139 ops->oobretlen = 0;
1140 return -EINVAL;
1141 }
1142
1143 stats = mtd->ecc_stats;
1144
1145 while (read < len) {
1146 cond_resched();
1147
1148 thislen = min_t(int, writesize, len - read);
1149
1150 column = from & (writesize - 1);
1151 if (column + thislen > writesize)
1152 thislen = writesize - column;
1153
1154 if (!onenand_check_bufferram(mtd, from)) {
1155 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1156
1157 ret = this->wait(mtd, FL_READING);
1158 if (unlikely(ret))
1159 ret = onenand_recover_lsb(mtd, from, ret);
1160 onenand_update_bufferram(mtd, from, !ret);
1161 if (mtd_is_eccerr(ret))
1162 ret = 0;
1163 if (ret)
1164 break;
1165 }
1166
1167 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
1168 if (oobbuf) {
1169 thisooblen = oobsize - oobcolumn;
1170 thisooblen = min_t(int, thisooblen, ooblen - oobread);
1171
1172 if (ops->mode == MTD_OPS_AUTO_OOB)
1173 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
1174 else
1175 this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
1176 oobread += thisooblen;
1177 oobbuf += thisooblen;
1178 oobcolumn = 0;
1179 }
1180
1181 read += thislen;
1182 if (read == len)
1183 break;
1184
1185 from += thislen;
1186 buf += thislen;
1187 }
1188
1189
1190
1191
1192
1193
1194 ops->retlen = read;
1195 ops->oobretlen = oobread;
1196
1197 if (ret)
1198 return ret;
1199
1200 if (mtd->ecc_stats.failed - stats.failed)
1201 return -EBADMSG;
1202
1203
1204 return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0;
1205}
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
1216 struct mtd_oob_ops *ops)
1217{
1218 struct onenand_chip *this = mtd->priv;
1219 struct mtd_ecc_stats stats;
1220 size_t len = ops->len;
1221 size_t ooblen = ops->ooblen;
1222 u_char *buf = ops->datbuf;
1223 u_char *oobbuf = ops->oobbuf;
1224 int read = 0, column, thislen;
1225 int oobread = 0, oobcolumn, thisooblen, oobsize;
1226 int ret = 0, boundary = 0;
1227 int writesize = this->writesize;
1228
1229 pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
1230 (int)len);
1231
1232 if (ops->mode == MTD_OPS_AUTO_OOB)
1233 oobsize = this->ecclayout->oobavail;
1234 else
1235 oobsize = mtd->oobsize;
1236
1237 oobcolumn = from & (mtd->oobsize - 1);
1238
1239
1240 if ((from + len) > mtd->size) {
1241 printk(KERN_ERR "%s: Attempt read beyond end of device\n",
1242 __func__);
1243 ops->retlen = 0;
1244 ops->oobretlen = 0;
1245 return -EINVAL;
1246 }
1247
1248 stats = mtd->ecc_stats;
1249
1250
1251
1252
1253 if (read < len) {
1254 if (!onenand_check_bufferram(mtd, from)) {
1255 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1256 ret = this->wait(mtd, FL_READING);
1257 onenand_update_bufferram(mtd, from, !ret);
1258 if (mtd_is_eccerr(ret))
1259 ret = 0;
1260 }
1261 }
1262
1263 thislen = min_t(int, writesize, len - read);
1264 column = from & (writesize - 1);
1265 if (column + thislen > writesize)
1266 thislen = writesize - column;
1267
1268 while (!ret) {
1269
1270 from += thislen;
1271 if (read + thislen < len) {
1272 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1273
1274
1275
1276
1277
1278 if (ONENAND_IS_DDP(this) &&
1279 unlikely(from == (this->chipsize >> 1))) {
1280 this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2);
1281 boundary = 1;
1282 } else
1283 boundary = 0;
1284 ONENAND_SET_PREV_BUFFERRAM(this);
1285 }
1286
1287 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
1288
1289
1290 if (oobbuf) {
1291 thisooblen = oobsize - oobcolumn;
1292 thisooblen = min_t(int, thisooblen, ooblen - oobread);
1293
1294 if (ops->mode == MTD_OPS_AUTO_OOB)
1295 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
1296 else
1297 this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
1298 oobread += thisooblen;
1299 oobbuf += thisooblen;
1300 oobcolumn = 0;
1301 }
1302
1303
1304 read += thislen;
1305 if (read == len)
1306 break;
1307
1308 if (unlikely(boundary))
1309 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
1310 ONENAND_SET_NEXT_BUFFERRAM(this);
1311 buf += thislen;
1312 thislen = min_t(int, writesize, len - read);
1313 column = 0;
1314 cond_resched();
1315
1316 ret = this->wait(mtd, FL_READING);
1317 onenand_update_bufferram(mtd, from, !ret);
1318 if (mtd_is_eccerr(ret))
1319 ret = 0;
1320 }
1321
1322
1323
1324
1325
1326
1327 ops->retlen = read;
1328 ops->oobretlen = oobread;
1329
1330 if (ret)
1331 return ret;
1332
1333 if (mtd->ecc_stats.failed - stats.failed)
1334 return -EBADMSG;
1335
1336
1337 return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0;
1338}
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
1349 struct mtd_oob_ops *ops)
1350{
1351 struct onenand_chip *this = mtd->priv;
1352 struct mtd_ecc_stats stats;
1353 int read = 0, thislen, column, oobsize;
1354 size_t len = ops->ooblen;
1355 unsigned int mode = ops->mode;
1356 u_char *buf = ops->oobbuf;
1357 int ret = 0, readcmd;
1358
1359 from += ops->ooboffs;
1360
1361 pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
1362 (int)len);
1363
1364
1365 ops->oobretlen = 0;
1366
1367 if (mode == MTD_OPS_AUTO_OOB)
1368 oobsize = this->ecclayout->oobavail;
1369 else
1370 oobsize = mtd->oobsize;
1371
1372 column = from & (mtd->oobsize - 1);
1373
1374 if (unlikely(column >= oobsize)) {
1375 printk(KERN_ERR "%s: Attempted to start read outside oob\n",
1376 __func__);
1377 return -EINVAL;
1378 }
1379
1380
1381 if (unlikely(from >= mtd->size ||
1382 column + len > ((mtd->size >> this->page_shift) -
1383 (from >> this->page_shift)) * oobsize)) {
1384 printk(KERN_ERR "%s: Attempted to read beyond end of device\n",
1385 __func__);
1386 return -EINVAL;
1387 }
1388
1389 stats = mtd->ecc_stats;
1390
1391 readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1392
1393 while (read < len) {
1394 cond_resched();
1395
1396 thislen = oobsize - column;
1397 thislen = min_t(int, thislen, len);
1398
1399 this->command(mtd, readcmd, from, mtd->oobsize);
1400
1401 onenand_update_bufferram(mtd, from, 0);
1402
1403 ret = this->wait(mtd, FL_READING);
1404 if (unlikely(ret))
1405 ret = onenand_recover_lsb(mtd, from, ret);
1406
1407 if (ret && !mtd_is_eccerr(ret)) {
1408 printk(KERN_ERR "%s: read failed = 0x%x\n",
1409 __func__, ret);
1410 break;
1411 }
1412
1413 if (mode == MTD_OPS_AUTO_OOB)
1414 onenand_transfer_auto_oob(mtd, buf, column, thislen);
1415 else
1416 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
1417
1418 read += thislen;
1419
1420 if (read == len)
1421 break;
1422
1423 buf += thislen;
1424
1425
1426 if (read < len) {
1427
1428 from += mtd->writesize;
1429 column = 0;
1430 }
1431 }
1432
1433 ops->oobretlen = read;
1434
1435 if (ret)
1436 return ret;
1437
1438 if (mtd->ecc_stats.failed - stats.failed)
1439 return -EBADMSG;
1440
1441 return 0;
1442}
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1455 size_t *retlen, u_char *buf)
1456{
1457 struct onenand_chip *this = mtd->priv;
1458 struct mtd_oob_ops ops = {
1459 .len = len,
1460 .ooblen = 0,
1461 .datbuf = buf,
1462 .oobbuf = NULL,
1463 };
1464 int ret;
1465
1466 onenand_get_device(mtd, FL_READING);
1467 ret = ONENAND_IS_4KB_PAGE(this) ?
1468 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
1469 onenand_read_ops_nolock(mtd, from, &ops);
1470 onenand_release_device(mtd);
1471
1472 *retlen = ops.retlen;
1473 return ret;
1474}
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1485 struct mtd_oob_ops *ops)
1486{
1487 struct onenand_chip *this = mtd->priv;
1488 int ret;
1489
1490 switch (ops->mode) {
1491 case MTD_OPS_PLACE_OOB:
1492 case MTD_OPS_AUTO_OOB:
1493 break;
1494 case MTD_OPS_RAW:
1495
1496 default:
1497 return -EINVAL;
1498 }
1499
1500 onenand_get_device(mtd, FL_READING);
1501 if (ops->datbuf)
1502 ret = ONENAND_IS_4KB_PAGE(this) ?
1503 onenand_mlc_read_ops_nolock(mtd, from, ops) :
1504 onenand_read_ops_nolock(mtd, from, ops);
1505 else
1506 ret = onenand_read_oob_nolock(mtd, from, ops);
1507 onenand_release_device(mtd);
1508
1509 return ret;
1510}
1511
1512
1513
1514
1515
1516
1517
1518
1519static int onenand_bbt_wait(struct mtd_info *mtd, int state)
1520{
1521 struct onenand_chip *this = mtd->priv;
1522 unsigned long timeout;
1523 unsigned int interrupt, ctrl, ecc, addr1, addr8;
1524
1525
1526 timeout = jiffies + msecs_to_jiffies(20);
1527 while (time_before(jiffies, timeout)) {
1528 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1529 if (interrupt & ONENAND_INT_MASTER)
1530 break;
1531 }
1532
1533 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1534 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
1535 addr1 = this->read_word(this->base + ONENAND_REG_START_ADDRESS1);
1536 addr8 = this->read_word(this->base + ONENAND_REG_START_ADDRESS8);
1537
1538 if (interrupt & ONENAND_INT_READ) {
1539 ecc = onenand_read_ecc(this);
1540 if (ecc & ONENAND_ECC_2BIT_ALL) {
1541 printk(KERN_DEBUG "%s: ecc 0x%04x ctrl 0x%04x "
1542 "intr 0x%04x addr1 %#x addr8 %#x\n",
1543 __func__, ecc, ctrl, interrupt, addr1, addr8);
1544 return ONENAND_BBT_READ_ECC_ERROR;
1545 }
1546 } else {
1547 printk(KERN_ERR "%s: read timeout! ctrl 0x%04x "
1548 "intr 0x%04x addr1 %#x addr8 %#x\n",
1549 __func__, ctrl, interrupt, addr1, addr8);
1550 return ONENAND_BBT_READ_FATAL_ERROR;
1551 }
1552
1553
1554 if (ctrl & ONENAND_CTRL_ERROR) {
1555 printk(KERN_DEBUG "%s: ctrl 0x%04x intr 0x%04x addr1 %#x "
1556 "addr8 %#x\n", __func__, ctrl, interrupt, addr1, addr8);
1557 return ONENAND_BBT_READ_ERROR;
1558 }
1559
1560 return 0;
1561}
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1572 struct mtd_oob_ops *ops)
1573{
1574 struct onenand_chip *this = mtd->priv;
1575 int read = 0, thislen, column;
1576 int ret = 0, readcmd;
1577 size_t len = ops->ooblen;
1578 u_char *buf = ops->oobbuf;
1579
1580 pr_debug("%s: from = 0x%08x, len = %zi\n", __func__, (unsigned int)from,
1581 len);
1582
1583
1584 ops->oobretlen = 0;
1585
1586
1587 if (unlikely((from + len) > mtd->size)) {
1588 printk(KERN_ERR "%s: Attempt read beyond end of device\n",
1589 __func__);
1590 return ONENAND_BBT_READ_FATAL_ERROR;
1591 }
1592
1593
1594 onenand_get_device(mtd, FL_READING);
1595
1596 column = from & (mtd->oobsize - 1);
1597
1598 readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1599
1600 while (read < len) {
1601 cond_resched();
1602
1603 thislen = mtd->oobsize - column;
1604 thislen = min_t(int, thislen, len);
1605
1606 this->command(mtd, readcmd, from, mtd->oobsize);
1607
1608 onenand_update_bufferram(mtd, from, 0);
1609
1610 ret = this->bbt_wait(mtd, FL_READING);
1611 if (unlikely(ret))
1612 ret = onenand_recover_lsb(mtd, from, ret);
1613
1614 if (ret)
1615 break;
1616
1617 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
1618 read += thislen;
1619 if (read == len)
1620 break;
1621
1622 buf += thislen;
1623
1624
1625 if (read < len) {
1626
1627 from += this->writesize;
1628 column = 0;
1629 }
1630 }
1631
1632
1633 onenand_release_device(mtd);
1634
1635 ops->oobretlen = read;
1636 return ret;
1637}
1638
1639#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
1640
1641
1642
1643
1644
1645
1646static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
1647{
1648 struct onenand_chip *this = mtd->priv;
1649 u_char *oob_buf = this->oob_buf;
1650 int status, i, readcmd;
1651
1652 readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1653
1654 this->command(mtd, readcmd, to, mtd->oobsize);
1655 onenand_update_bufferram(mtd, to, 0);
1656 status = this->wait(mtd, FL_READING);
1657 if (status)
1658 return status;
1659
1660 this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
1661 for (i = 0; i < mtd->oobsize; i++)
1662 if (buf[i] != 0xFF && buf[i] != oob_buf[i])
1663 return -EBADMSG;
1664
1665 return 0;
1666}
1667
1668
1669
1670
1671
1672
1673
1674
1675static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
1676{
1677 struct onenand_chip *this = mtd->priv;
1678 int ret = 0;
1679 int thislen, column;
1680
1681 column = addr & (this->writesize - 1);
1682
1683 while (len != 0) {
1684 thislen = min_t(int, this->writesize - column, len);
1685
1686 this->command(mtd, ONENAND_CMD_READ, addr, this->writesize);
1687
1688 onenand_update_bufferram(mtd, addr, 0);
1689
1690 ret = this->wait(mtd, FL_READING);
1691 if (ret)
1692 return ret;
1693
1694 onenand_update_bufferram(mtd, addr, 1);
1695
1696 this->read_bufferram(mtd, ONENAND_DATARAM, this->verify_buf, 0, mtd->writesize);
1697
1698 if (memcmp(buf, this->verify_buf + column, thislen))
1699 return -EBADMSG;
1700
1701 len -= thislen;
1702 buf += thislen;
1703 addr += thislen;
1704 column = 0;
1705 }
1706
1707 return 0;
1708}
1709#else
1710#define onenand_verify(...) (0)
1711#define onenand_verify_oob(...) (0)
1712#endif
1713
1714#define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0)
1715
1716static void onenand_panic_wait(struct mtd_info *mtd)
1717{
1718 struct onenand_chip *this = mtd->priv;
1719 unsigned int interrupt;
1720 int i;
1721
1722 for (i = 0; i < 2000; i++) {
1723 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1724 if (interrupt & ONENAND_INT_MASTER)
1725 break;
1726 udelay(10);
1727 }
1728}
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
1741 size_t *retlen, const u_char *buf)
1742{
1743 struct onenand_chip *this = mtd->priv;
1744 int column, subpage;
1745 int written = 0;
1746
1747 if (this->state == FL_PM_SUSPENDED)
1748 return -EBUSY;
1749
1750
1751 onenand_panic_wait(mtd);
1752
1753 pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
1754 (int)len);
1755
1756
1757 if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
1758 printk(KERN_ERR "%s: Attempt to write not page aligned data\n",
1759 __func__);
1760 return -EINVAL;
1761 }
1762
1763 column = to & (mtd->writesize - 1);
1764
1765
1766 while (written < len) {
1767 int thislen = min_t(int, mtd->writesize - column, len - written);
1768 u_char *wbuf = (u_char *) buf;
1769
1770 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1771
1772
1773 subpage = thislen < mtd->writesize;
1774 if (subpage) {
1775 memset(this->page_buf, 0xff, mtd->writesize);
1776 memcpy(this->page_buf + column, buf, thislen);
1777 wbuf = this->page_buf;
1778 }
1779
1780 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1781 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1782
1783 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1784
1785 onenand_panic_wait(mtd);
1786
1787
1788 onenand_update_bufferram(mtd, to, !subpage);
1789 if (ONENAND_IS_2PLANE(this)) {
1790 ONENAND_SET_BUFFERRAM1(this);
1791 onenand_update_bufferram(mtd, to + this->writesize, !subpage);
1792 }
1793
1794 written += thislen;
1795
1796 if (written == len)
1797 break;
1798
1799 column = 0;
1800 to += thislen;
1801 buf += thislen;
1802 }
1803
1804 *retlen = written;
1805 return 0;
1806}
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
1817 const u_char *buf, int column, int thislen)
1818{
1819 struct onenand_chip *this = mtd->priv;
1820 struct nand_oobfree *free;
1821 int writecol = column;
1822 int writeend = column + thislen;
1823 int lastgap = 0;
1824 unsigned int i;
1825
1826 free = this->ecclayout->oobfree;
1827 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
1828 if (writecol >= lastgap)
1829 writecol += free->offset - lastgap;
1830 if (writeend >= lastgap)
1831 writeend += free->offset - lastgap;
1832 lastgap = free->offset + free->length;
1833 }
1834 free = this->ecclayout->oobfree;
1835 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
1836 int free_end = free->offset + free->length;
1837 if (free->offset < writeend && free_end > writecol) {
1838 int st = max_t(int,free->offset,writecol);
1839 int ed = min_t(int,free_end,writeend);
1840 int n = ed - st;
1841 memcpy(oob_buf + st, buf, n);
1842 buf += n;
1843 } else if (column == 0)
1844 break;
1845 }
1846 return 0;
1847}
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1858 struct mtd_oob_ops *ops)
1859{
1860 struct onenand_chip *this = mtd->priv;
1861 int written = 0, column, thislen = 0, subpage = 0;
1862 int prev = 0, prevlen = 0, prev_subpage = 0, first = 1;
1863 int oobwritten = 0, oobcolumn, thisooblen, oobsize;
1864 size_t len = ops->len;
1865 size_t ooblen = ops->ooblen;
1866 const u_char *buf = ops->datbuf;
1867 const u_char *oob = ops->oobbuf;
1868 u_char *oobbuf;
1869 int ret = 0, cmd;
1870
1871 pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
1872 (int)len);
1873
1874
1875 ops->retlen = 0;
1876 ops->oobretlen = 0;
1877
1878
1879 if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
1880 printk(KERN_ERR "%s: Attempt to write not page aligned data\n",
1881 __func__);
1882 return -EINVAL;
1883 }
1884
1885
1886 if (!len)
1887 return 0;
1888
1889 if (ops->mode == MTD_OPS_AUTO_OOB)
1890 oobsize = this->ecclayout->oobavail;
1891 else
1892 oobsize = mtd->oobsize;
1893
1894 oobcolumn = to & (mtd->oobsize - 1);
1895
1896 column = to & (mtd->writesize - 1);
1897
1898
1899 while (1) {
1900 if (written < len) {
1901 u_char *wbuf = (u_char *) buf;
1902
1903 thislen = min_t(int, mtd->writesize - column, len - written);
1904 thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
1905
1906 cond_resched();
1907
1908 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1909
1910
1911 subpage = thislen < mtd->writesize;
1912 if (subpage) {
1913 memset(this->page_buf, 0xff, mtd->writesize);
1914 memcpy(this->page_buf + column, buf, thislen);
1915 wbuf = this->page_buf;
1916 }
1917
1918 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1919
1920 if (oob) {
1921 oobbuf = this->oob_buf;
1922
1923
1924
1925 memset(oobbuf, 0xff, mtd->oobsize);
1926 if (ops->mode == MTD_OPS_AUTO_OOB)
1927 onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
1928 else
1929 memcpy(oobbuf + oobcolumn, oob, thisooblen);
1930
1931 oobwritten += thisooblen;
1932 oob += thisooblen;
1933 oobcolumn = 0;
1934 } else
1935 oobbuf = (u_char *) ffchars;
1936
1937 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1938 } else
1939 ONENAND_SET_NEXT_BUFFERRAM(this);
1940
1941
1942
1943
1944
1945 if (!ONENAND_IS_2PLANE(this) && !ONENAND_IS_4KB_PAGE(this) && !first) {
1946 ONENAND_SET_PREV_BUFFERRAM(this);
1947
1948 ret = this->wait(mtd, FL_WRITING);
1949
1950
1951 onenand_update_bufferram(mtd, prev, !ret && !prev_subpage);
1952 if (ret) {
1953 written -= prevlen;
1954 printk(KERN_ERR "%s: write failed %d\n",
1955 __func__, ret);
1956 break;
1957 }
1958
1959 if (written == len) {
1960
1961 ret = onenand_verify(mtd, buf - len, to - len, len);
1962 if (ret)
1963 printk(KERN_ERR "%s: verify failed %d\n",
1964 __func__, ret);
1965 break;
1966 }
1967
1968 ONENAND_SET_NEXT_BUFFERRAM(this);
1969 }
1970
1971 this->ongoing = 0;
1972 cmd = ONENAND_CMD_PROG;
1973
1974
1975 if (ONENAND_IS_CACHE_PROGRAM(this) &&
1976 likely(onenand_block(this, to) != 0) &&
1977 ONENAND_IS_4KB_PAGE(this) &&
1978 ((written + thislen) < len)) {
1979 cmd = ONENAND_CMD_2X_CACHE_PROG;
1980 this->ongoing = 1;
1981 }
1982
1983 this->command(mtd, cmd, to, mtd->writesize);
1984
1985
1986
1987
1988 if (ONENAND_IS_2PLANE(this) || ONENAND_IS_4KB_PAGE(this)) {
1989 ret = this->wait(mtd, FL_WRITING);
1990
1991
1992 onenand_update_bufferram(mtd, to, !ret && !subpage);
1993 if (ret) {
1994 printk(KERN_ERR "%s: write failed %d\n",
1995 __func__, ret);
1996 break;
1997 }
1998
1999
2000 ret = onenand_verify(mtd, buf, to, thislen);
2001 if (ret) {
2002 printk(KERN_ERR "%s: verify failed %d\n",
2003 __func__, ret);
2004 break;
2005 }
2006
2007 written += thislen;
2008
2009 if (written == len)
2010 break;
2011
2012 } else
2013 written += thislen;
2014
2015 column = 0;
2016 prev_subpage = subpage;
2017 prev = to;
2018 prevlen = thislen;
2019 to += thislen;
2020 buf += thislen;
2021 first = 0;
2022 }
2023
2024
2025 if (written != len)
2026 onenand_invalidate_bufferram(mtd, 0, -1);
2027
2028 ops->retlen = written;
2029 ops->oobretlen = oobwritten;
2030
2031 return ret;
2032}
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
2047 struct mtd_oob_ops *ops)
2048{
2049 struct onenand_chip *this = mtd->priv;
2050 int column, ret = 0, oobsize;
2051 int written = 0, oobcmd;
2052 u_char *oobbuf;
2053 size_t len = ops->ooblen;
2054 const u_char *buf = ops->oobbuf;
2055 unsigned int mode = ops->mode;
2056
2057 to += ops->ooboffs;
2058
2059 pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
2060 (int)len);
2061
2062
2063 ops->oobretlen = 0;
2064
2065 if (mode == MTD_OPS_AUTO_OOB)
2066 oobsize = this->ecclayout->oobavail;
2067 else
2068 oobsize = mtd->oobsize;
2069
2070 column = to & (mtd->oobsize - 1);
2071
2072 if (unlikely(column >= oobsize)) {
2073 printk(KERN_ERR "%s: Attempted to start write outside oob\n",
2074 __func__);
2075 return -EINVAL;
2076 }
2077
2078
2079 if (unlikely(column + len > oobsize)) {
2080 printk(KERN_ERR "%s: Attempt to write past end of page\n",
2081 __func__);
2082 return -EINVAL;
2083 }
2084
2085
2086 if (unlikely(to >= mtd->size ||
2087 column + len > ((mtd->size >> this->page_shift) -
2088 (to >> this->page_shift)) * oobsize)) {
2089 printk(KERN_ERR "%s: Attempted to write past end of device\n",
2090 __func__);
2091 return -EINVAL;
2092 }
2093
2094 oobbuf = this->oob_buf;
2095
2096 oobcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
2097
2098
2099 while (written < len) {
2100 int thislen = min_t(int, oobsize, len - written);
2101
2102 cond_resched();
2103
2104 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
2105
2106
2107
2108 memset(oobbuf, 0xff, mtd->oobsize);
2109 if (mode == MTD_OPS_AUTO_OOB)
2110 onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
2111 else
2112 memcpy(oobbuf + column, buf, thislen);
2113 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
2114
2115 if (ONENAND_IS_4KB_PAGE(this)) {
2116
2117 memset(this->page_buf, 0xff, mtd->writesize);
2118 this->write_bufferram(mtd, ONENAND_DATARAM,
2119 this->page_buf, 0, mtd->writesize);
2120 }
2121
2122 this->command(mtd, oobcmd, to, mtd->oobsize);
2123
2124 onenand_update_bufferram(mtd, to, 0);
2125 if (ONENAND_IS_2PLANE(this)) {
2126 ONENAND_SET_BUFFERRAM1(this);
2127 onenand_update_bufferram(mtd, to + this->writesize, 0);
2128 }
2129
2130 ret = this->wait(mtd, FL_WRITING);
2131 if (ret) {
2132 printk(KERN_ERR "%s: write failed %d\n", __func__, ret);
2133 break;
2134 }
2135
2136 ret = onenand_verify_oob(mtd, oobbuf, to);
2137 if (ret) {
2138 printk(KERN_ERR "%s: verify failed %d\n",
2139 __func__, ret);
2140 break;
2141 }
2142
2143 written += thislen;
2144 if (written == len)
2145 break;
2146
2147 to += mtd->writesize;
2148 buf += thislen;
2149 column = 0;
2150 }
2151
2152 ops->oobretlen = written;
2153
2154 return ret;
2155}
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
2168 size_t *retlen, const u_char *buf)
2169{
2170 struct mtd_oob_ops ops = {
2171 .len = len,
2172 .ooblen = 0,
2173 .datbuf = (u_char *) buf,
2174 .oobbuf = NULL,
2175 };
2176 int ret;
2177
2178 onenand_get_device(mtd, FL_WRITING);
2179 ret = onenand_write_ops_nolock(mtd, to, &ops);
2180 onenand_release_device(mtd);
2181
2182 *retlen = ops.retlen;
2183 return ret;
2184}
2185
2186
2187
2188
2189
2190
2191
2192static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
2193 struct mtd_oob_ops *ops)
2194{
2195 int ret;
2196
2197 switch (ops->mode) {
2198 case MTD_OPS_PLACE_OOB:
2199 case MTD_OPS_AUTO_OOB:
2200 break;
2201 case MTD_OPS_RAW:
2202
2203 default:
2204 return -EINVAL;
2205 }
2206
2207 onenand_get_device(mtd, FL_WRITING);
2208 if (ops->datbuf)
2209 ret = onenand_write_ops_nolock(mtd, to, ops);
2210 else
2211 ret = onenand_write_oob_nolock(mtd, to, ops);
2212 onenand_release_device(mtd);
2213
2214 return ret;
2215}
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
2227{
2228 struct onenand_chip *this = mtd->priv;
2229 struct bbm_info *bbm = this->bbm;
2230
2231
2232 return bbm->isbad_bbt(mtd, ofs, allowbbt);
2233}
2234
2235
2236static int onenand_multiblock_erase_verify(struct mtd_info *mtd,
2237 struct erase_info *instr)
2238{
2239 struct onenand_chip *this = mtd->priv;
2240 loff_t addr = instr->addr;
2241 int len = instr->len;
2242 unsigned int block_size = (1 << this->erase_shift);
2243 int ret = 0;
2244
2245 while (len) {
2246 this->command(mtd, ONENAND_CMD_ERASE_VERIFY, addr, block_size);
2247 ret = this->wait(mtd, FL_VERIFYING_ERASE);
2248 if (ret) {
2249 printk(KERN_ERR "%s: Failed verify, block %d\n",
2250 __func__, onenand_block(this, addr));
2251 instr->state = MTD_ERASE_FAILED;
2252 instr->fail_addr = addr;
2253 return -1;
2254 }
2255 len -= block_size;
2256 addr += block_size;
2257 }
2258 return 0;
2259}
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269static int onenand_multiblock_erase(struct mtd_info *mtd,
2270 struct erase_info *instr,
2271 unsigned int block_size)
2272{
2273 struct onenand_chip *this = mtd->priv;
2274 loff_t addr = instr->addr;
2275 int len = instr->len;
2276 int eb_count = 0;
2277 int ret = 0;
2278 int bdry_block = 0;
2279
2280 instr->state = MTD_ERASING;
2281
2282 if (ONENAND_IS_DDP(this)) {
2283 loff_t bdry_addr = this->chipsize >> 1;
2284 if (addr < bdry_addr && (addr + len) > bdry_addr)
2285 bdry_block = bdry_addr >> this->erase_shift;
2286 }
2287
2288
2289 while (len) {
2290
2291 if (onenand_block_isbad_nolock(mtd, addr, 0)) {
2292 printk(KERN_WARNING "%s: attempt to erase a bad block "
2293 "at addr 0x%012llx\n",
2294 __func__, (unsigned long long) addr);
2295 instr->state = MTD_ERASE_FAILED;
2296 return -EIO;
2297 }
2298 len -= block_size;
2299 addr += block_size;
2300 }
2301
2302 len = instr->len;
2303 addr = instr->addr;
2304
2305
2306 while (len) {
2307 struct erase_info verify_instr = *instr;
2308 int max_eb_count = MB_ERASE_MAX_BLK_COUNT;
2309
2310 verify_instr.addr = addr;
2311 verify_instr.len = 0;
2312
2313
2314 if (bdry_block) {
2315 int this_block = (addr >> this->erase_shift);
2316
2317 if (this_block < bdry_block) {
2318 max_eb_count = min(max_eb_count,
2319 (bdry_block - this_block));
2320 }
2321 }
2322
2323 eb_count = 0;
2324
2325 while (len > block_size && eb_count < (max_eb_count - 1)) {
2326 this->command(mtd, ONENAND_CMD_MULTIBLOCK_ERASE,
2327 addr, block_size);
2328 onenand_invalidate_bufferram(mtd, addr, block_size);
2329
2330 ret = this->wait(mtd, FL_PREPARING_ERASE);
2331 if (ret) {
2332 printk(KERN_ERR "%s: Failed multiblock erase, "
2333 "block %d\n", __func__,
2334 onenand_block(this, addr));
2335 instr->state = MTD_ERASE_FAILED;
2336 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
2337 return -EIO;
2338 }
2339
2340 len -= block_size;
2341 addr += block_size;
2342 eb_count++;
2343 }
2344
2345
2346 cond_resched();
2347 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
2348 onenand_invalidate_bufferram(mtd, addr, block_size);
2349
2350 ret = this->wait(mtd, FL_ERASING);
2351
2352 if (ret) {
2353 printk(KERN_ERR "%s: Failed erase, block %d\n",
2354 __func__, onenand_block(this, addr));
2355 instr->state = MTD_ERASE_FAILED;
2356 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
2357 return -EIO;
2358 }
2359
2360 len -= block_size;
2361 addr += block_size;
2362 eb_count++;
2363
2364
2365 verify_instr.len = eb_count * block_size;
2366 if (onenand_multiblock_erase_verify(mtd, &verify_instr)) {
2367 instr->state = verify_instr.state;
2368 instr->fail_addr = verify_instr.fail_addr;
2369 return -EIO;
2370 }
2371
2372 }
2373 return 0;
2374}
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386static int onenand_block_by_block_erase(struct mtd_info *mtd,
2387 struct erase_info *instr,
2388 struct mtd_erase_region_info *region,
2389 unsigned int block_size)
2390{
2391 struct onenand_chip *this = mtd->priv;
2392 loff_t addr = instr->addr;
2393 int len = instr->len;
2394 loff_t region_end = 0;
2395 int ret = 0;
2396
2397 if (region) {
2398
2399 region_end = region->offset + region->erasesize * region->numblocks;
2400 }
2401
2402 instr->state = MTD_ERASING;
2403
2404
2405 while (len) {
2406 cond_resched();
2407
2408
2409 if (onenand_block_isbad_nolock(mtd, addr, 0)) {
2410 printk(KERN_WARNING "%s: attempt to erase a bad block "
2411 "at addr 0x%012llx\n",
2412 __func__, (unsigned long long) addr);
2413 instr->state = MTD_ERASE_FAILED;
2414 return -EIO;
2415 }
2416
2417 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
2418
2419 onenand_invalidate_bufferram(mtd, addr, block_size);
2420
2421 ret = this->wait(mtd, FL_ERASING);
2422
2423 if (ret) {
2424 printk(KERN_ERR "%s: Failed erase, block %d\n",
2425 __func__, onenand_block(this, addr));
2426 instr->state = MTD_ERASE_FAILED;
2427 instr->fail_addr = addr;
2428 return -EIO;
2429 }
2430
2431 len -= block_size;
2432 addr += block_size;
2433
2434 if (region && addr == region_end) {
2435 if (!len)
2436 break;
2437 region++;
2438
2439 block_size = region->erasesize;
2440 region_end = region->offset + region->erasesize * region->numblocks;
2441
2442 if (len & (block_size - 1)) {
2443
2444 printk(KERN_ERR "%s: Unaligned address\n",
2445 __func__);
2446 return -EIO;
2447 }
2448 }
2449 }
2450 return 0;
2451}
2452
2453
2454
2455
2456
2457
2458
2459
2460static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
2461{
2462 struct onenand_chip *this = mtd->priv;
2463 unsigned int block_size;
2464 loff_t addr = instr->addr;
2465 loff_t len = instr->len;
2466 int ret = 0;
2467 struct mtd_erase_region_info *region = NULL;
2468 loff_t region_offset = 0;
2469
2470 pr_debug("%s: start=0x%012llx, len=%llu\n", __func__,
2471 (unsigned long long)instr->addr,
2472 (unsigned long long)instr->len);
2473
2474 if (FLEXONENAND(this)) {
2475
2476 int i = flexonenand_region(mtd, addr);
2477
2478 region = &mtd->eraseregions[i];
2479 block_size = region->erasesize;
2480
2481
2482
2483
2484 region_offset = region->offset;
2485 } else
2486 block_size = 1 << this->erase_shift;
2487
2488
2489 if (unlikely((addr - region_offset) & (block_size - 1))) {
2490 printk(KERN_ERR "%s: Unaligned address\n", __func__);
2491 return -EINVAL;
2492 }
2493
2494
2495 if (unlikely(len & (block_size - 1))) {
2496 printk(KERN_ERR "%s: Length not block aligned\n", __func__);
2497 return -EINVAL;
2498 }
2499
2500
2501 onenand_get_device(mtd, FL_ERASING);
2502
2503 if (ONENAND_IS_4KB_PAGE(this) || region ||
2504 instr->len < MB_ERASE_MIN_BLK_COUNT * block_size) {
2505
2506 ret = onenand_block_by_block_erase(mtd, instr,
2507 region, block_size);
2508 } else {
2509 ret = onenand_multiblock_erase(mtd, instr, block_size);
2510 }
2511
2512
2513 onenand_release_device(mtd);
2514
2515
2516 if (!ret) {
2517 instr->state = MTD_ERASE_DONE;
2518 mtd_erase_callback(instr);
2519 }
2520
2521 return ret;
2522}
2523
2524
2525
2526
2527
2528
2529
2530static void onenand_sync(struct mtd_info *mtd)
2531{
2532 pr_debug("%s: called\n", __func__);
2533
2534
2535 onenand_get_device(mtd, FL_SYNCING);
2536
2537
2538 onenand_release_device(mtd);
2539}
2540
2541
2542
2543
2544
2545
2546
2547
2548static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
2549{
2550 int ret;
2551
2552 onenand_get_device(mtd, FL_READING);
2553 ret = onenand_block_isbad_nolock(mtd, ofs, 0);
2554 onenand_release_device(mtd);
2555 return ret;
2556}
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
2567{
2568 struct onenand_chip *this = mtd->priv;
2569 struct bbm_info *bbm = this->bbm;
2570 u_char buf[2] = {0, 0};
2571 struct mtd_oob_ops ops = {
2572 .mode = MTD_OPS_PLACE_OOB,
2573 .ooblen = 2,
2574 .oobbuf = buf,
2575 .ooboffs = 0,
2576 };
2577 int block;
2578
2579
2580 block = onenand_block(this, ofs);
2581 if (bbm->bbt)
2582 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
2583
2584
2585 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
2586
2587
2588
2589
2590 return onenand_write_oob_nolock(mtd, ofs, &ops);
2591}
2592
2593
2594
2595
2596
2597
2598
2599
2600static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
2601{
2602 int ret;
2603
2604 ret = onenand_block_isbad(mtd, ofs);
2605 if (ret) {
2606
2607 if (ret > 0)
2608 return 0;
2609 return ret;
2610 }
2611
2612 onenand_get_device(mtd, FL_WRITING);
2613 ret = mtd_block_markbad(mtd, ofs);
2614 onenand_release_device(mtd);
2615 return ret;
2616}
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
2628{
2629 struct onenand_chip *this = mtd->priv;
2630 int start, end, block, value, status;
2631 int wp_status_mask;
2632
2633 start = onenand_block(this, ofs);
2634 end = onenand_block(this, ofs + len) - 1;
2635
2636 if (cmd == ONENAND_CMD_LOCK)
2637 wp_status_mask = ONENAND_WP_LS;
2638 else
2639 wp_status_mask = ONENAND_WP_US;
2640
2641
2642 if (this->options & ONENAND_HAS_CONT_LOCK) {
2643
2644 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2645
2646 this->write_word(end, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
2647
2648 this->command(mtd, cmd, 0, 0);
2649
2650
2651 this->wait(mtd, FL_LOCKING);
2652
2653
2654 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2655 & ONENAND_CTRL_ONGO)
2656 continue;
2657
2658
2659 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2660 if (!(status & wp_status_mask))
2661 printk(KERN_ERR "%s: wp status = 0x%x\n",
2662 __func__, status);
2663
2664 return 0;
2665 }
2666
2667
2668 for (block = start; block < end + 1; block++) {
2669
2670 value = onenand_block_address(this, block);
2671 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
2672
2673 value = onenand_bufferram_address(this, block);
2674 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
2675
2676 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2677
2678 this->command(mtd, cmd, 0, 0);
2679
2680
2681 this->wait(mtd, FL_LOCKING);
2682
2683
2684 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2685 & ONENAND_CTRL_ONGO)
2686 continue;
2687
2688
2689 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2690 if (!(status & wp_status_mask))
2691 printk(KERN_ERR "%s: block = %d, wp status = 0x%x\n",
2692 __func__, block, status);
2693 }
2694
2695 return 0;
2696}
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706static int onenand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
2707{
2708 int ret;
2709
2710 onenand_get_device(mtd, FL_LOCKING);
2711 ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
2712 onenand_release_device(mtd);
2713 return ret;
2714}
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
2725{
2726 int ret;
2727
2728 onenand_get_device(mtd, FL_LOCKING);
2729 ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2730 onenand_release_device(mtd);
2731 return ret;
2732}
2733
2734
2735
2736
2737
2738
2739
2740static int onenand_check_lock_status(struct onenand_chip *this)
2741{
2742 unsigned int value, block, status;
2743 unsigned int end;
2744
2745 end = this->chipsize >> this->erase_shift;
2746 for (block = 0; block < end; block++) {
2747
2748 value = onenand_block_address(this, block);
2749 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
2750
2751 value = onenand_bufferram_address(this, block);
2752 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
2753
2754 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2755
2756
2757 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2758 if (!(status & ONENAND_WP_US)) {
2759 printk(KERN_ERR "%s: block = %d, wp status = 0x%x\n",
2760 __func__, block, status);
2761 return 0;
2762 }
2763 }
2764
2765 return 1;
2766}
2767
2768
2769
2770
2771
2772
2773
2774static void onenand_unlock_all(struct mtd_info *mtd)
2775{
2776 struct onenand_chip *this = mtd->priv;
2777 loff_t ofs = 0;
2778 loff_t len = mtd->size;
2779
2780 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
2781
2782 this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2783
2784 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
2785
2786
2787 this->wait(mtd, FL_LOCKING);
2788
2789
2790 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2791 & ONENAND_CTRL_ONGO)
2792 continue;
2793
2794
2795 if (this->options & ONENAND_SKIP_UNLOCK_CHECK)
2796 return;
2797
2798
2799 if (onenand_check_lock_status(this))
2800 return;
2801
2802
2803 if (ONENAND_IS_DDP(this) && !FLEXONENAND(this)) {
2804
2805 ofs = this->chipsize >> 1;
2806 len = this->chipsize >> 1;
2807 }
2808 }
2809
2810 onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2811}
2812
2813#ifdef CONFIG_MTD_ONENAND_OTP
2814
2815
2816
2817
2818
2819
2820
2821
2822static int onenand_otp_command(struct mtd_info *mtd, int cmd, loff_t addr,
2823 size_t len)
2824{
2825 struct onenand_chip *this = mtd->priv;
2826 int value, block, page;
2827
2828
2829 switch (cmd) {
2830 case ONENAND_CMD_OTP_ACCESS:
2831 block = (int) (addr >> this->erase_shift);
2832 page = -1;
2833 break;
2834
2835 default:
2836 block = (int) (addr >> this->erase_shift);
2837 page = (int) (addr >> this->page_shift);
2838
2839 if (ONENAND_IS_2PLANE(this)) {
2840
2841 block &= ~1;
2842
2843 if (addr & this->writesize)
2844 block++;
2845 page >>= 1;
2846 }
2847 page &= this->page_mask;
2848 break;
2849 }
2850
2851 if (block != -1) {
2852
2853 value = onenand_block_address(this, block);
2854 this->write_word(value, this->base +
2855 ONENAND_REG_START_ADDRESS1);
2856 }
2857
2858 if (page != -1) {
2859
2860 int sectors = 4, count = 4;
2861 int dataram;
2862
2863 switch (cmd) {
2864 default:
2865 if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG)
2866 cmd = ONENAND_CMD_2X_PROG;
2867 dataram = ONENAND_CURRENT_BUFFERRAM(this);
2868 break;
2869 }
2870
2871
2872 value = onenand_page_address(page, sectors);
2873 this->write_word(value, this->base +
2874 ONENAND_REG_START_ADDRESS8);
2875
2876
2877 value = onenand_buffer_address(dataram, sectors, count);
2878 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
2879 }
2880
2881
2882 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
2883
2884
2885 this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
2886
2887 return 0;
2888}
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900static int onenand_otp_write_oob_nolock(struct mtd_info *mtd, loff_t to,
2901 struct mtd_oob_ops *ops)
2902{
2903 struct onenand_chip *this = mtd->priv;
2904 int column, ret = 0, oobsize;
2905 int written = 0;
2906 u_char *oobbuf;
2907 size_t len = ops->ooblen;
2908 const u_char *buf = ops->oobbuf;
2909 int block, value, status;
2910
2911 to += ops->ooboffs;
2912
2913
2914 ops->oobretlen = 0;
2915
2916 oobsize = mtd->oobsize;
2917
2918 column = to & (mtd->oobsize - 1);
2919
2920 oobbuf = this->oob_buf;
2921
2922
2923 while (written < len) {
2924 int thislen = min_t(int, oobsize, len - written);
2925
2926 cond_resched();
2927
2928 block = (int) (to >> this->erase_shift);
2929
2930
2931
2932
2933
2934 value = onenand_block_address(this, block);
2935 this->write_word(value, this->base +
2936 ONENAND_REG_START_ADDRESS1);
2937
2938
2939
2940
2941
2942
2943 value = onenand_bufferram_address(this, block);
2944 this->write_word(value, this->base +
2945 ONENAND_REG_START_ADDRESS2);
2946 ONENAND_SET_NEXT_BUFFERRAM(this);
2947
2948
2949
2950
2951 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2952 this->wait(mtd, FL_OTPING);
2953
2954
2955
2956 memcpy(oobbuf + column, buf, thislen);
2957
2958
2959
2960
2961
2962
2963
2964 this->write_bufferram(mtd, ONENAND_SPARERAM,
2965 oobbuf, 0, mtd->oobsize);
2966
2967 onenand_otp_command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
2968 onenand_update_bufferram(mtd, to, 0);
2969 if (ONENAND_IS_2PLANE(this)) {
2970 ONENAND_SET_BUFFERRAM1(this);
2971 onenand_update_bufferram(mtd, to + this->writesize, 0);
2972 }
2973
2974 ret = this->wait(mtd, FL_WRITING);
2975 if (ret) {
2976 printk(KERN_ERR "%s: write failed %d\n", __func__, ret);
2977 break;
2978 }
2979
2980
2981 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
2982 this->wait(mtd, FL_RESETING);
2983
2984 status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
2985 status &= 0x60;
2986
2987 if (status == 0x60) {
2988 printk(KERN_DEBUG "\nBLOCK\tSTATUS\n");
2989 printk(KERN_DEBUG "1st Block\tLOCKED\n");
2990 printk(KERN_DEBUG "OTP Block\tLOCKED\n");
2991 } else if (status == 0x20) {
2992 printk(KERN_DEBUG "\nBLOCK\tSTATUS\n");
2993 printk(KERN_DEBUG "1st Block\tLOCKED\n");
2994 printk(KERN_DEBUG "OTP Block\tUN-LOCKED\n");
2995 } else if (status == 0x40) {
2996 printk(KERN_DEBUG "\nBLOCK\tSTATUS\n");
2997 printk(KERN_DEBUG "1st Block\tUN-LOCKED\n");
2998 printk(KERN_DEBUG "OTP Block\tLOCKED\n");
2999 } else {
3000 printk(KERN_DEBUG "Reboot to check\n");
3001 }
3002
3003 written += thislen;
3004 if (written == len)
3005 break;
3006
3007 to += mtd->writesize;
3008 buf += thislen;
3009 column = 0;
3010 }
3011
3012 ops->oobretlen = written;
3013
3014 return ret;
3015}
3016
3017
3018typedef int (*otp_op_t)(struct mtd_info *mtd, loff_t form, size_t len,
3019 size_t *retlen, u_char *buf);
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
3032 size_t *retlen, u_char *buf)
3033{
3034 struct onenand_chip *this = mtd->priv;
3035 struct mtd_oob_ops ops = {
3036 .len = len,
3037 .ooblen = 0,
3038 .datbuf = buf,
3039 .oobbuf = NULL,
3040 };
3041 int ret;
3042
3043
3044 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
3045 this->wait(mtd, FL_OTPING);
3046
3047 ret = ONENAND_IS_4KB_PAGE(this) ?
3048 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
3049 onenand_read_ops_nolock(mtd, from, &ops);
3050
3051
3052 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
3053 this->wait(mtd, FL_RESETING);
3054
3055 return ret;
3056}
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068static int do_otp_write(struct mtd_info *mtd, loff_t to, size_t len,
3069 size_t *retlen, u_char *buf)
3070{
3071 struct onenand_chip *this = mtd->priv;
3072 unsigned char *pbuf = buf;
3073 int ret;
3074 struct mtd_oob_ops ops;
3075
3076
3077 if (len < mtd->writesize) {
3078 memcpy(this->page_buf, buf, len);
3079 memset(this->page_buf + len, 0xff, mtd->writesize - len);
3080 pbuf = this->page_buf;
3081 len = mtd->writesize;
3082 }
3083
3084
3085 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
3086 this->wait(mtd, FL_OTPING);
3087
3088 ops.len = len;
3089 ops.ooblen = 0;
3090 ops.datbuf = pbuf;
3091 ops.oobbuf = NULL;
3092 ret = onenand_write_ops_nolock(mtd, to, &ops);
3093 *retlen = ops.retlen;
3094
3095
3096 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
3097 this->wait(mtd, FL_RESETING);
3098
3099 return ret;
3100}
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
3113 size_t *retlen, u_char *buf)
3114{
3115 struct onenand_chip *this = mtd->priv;
3116 struct mtd_oob_ops ops;
3117 int ret;
3118
3119 if (FLEXONENAND(this)) {
3120
3121
3122 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
3123 this->wait(mtd, FL_OTPING);
3124
3125
3126
3127
3128 ops.len = mtd->writesize;
3129 ops.ooblen = 0;
3130 ops.datbuf = buf;
3131 ops.oobbuf = NULL;
3132 ret = onenand_write_ops_nolock(mtd, mtd->writesize * 49, &ops);
3133 *retlen = ops.retlen;
3134
3135
3136 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
3137 this->wait(mtd, FL_RESETING);
3138 } else {
3139 ops.mode = MTD_OPS_PLACE_OOB;
3140 ops.ooblen = len;
3141 ops.oobbuf = buf;
3142 ops.ooboffs = 0;
3143 ret = onenand_otp_write_oob_nolock(mtd, from, &ops);
3144 *retlen = ops.oobretlen;
3145 }
3146
3147 return ret;
3148}
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
3163 size_t *retlen, u_char *buf,
3164 otp_op_t action, int mode)
3165{
3166 struct onenand_chip *this = mtd->priv;
3167 int otp_pages;
3168 int density;
3169 int ret = 0;
3170
3171 *retlen = 0;
3172
3173 density = onenand_get_density(this->device_id);
3174 if (density < ONENAND_DEVICE_DENSITY_512Mb)
3175 otp_pages = 20;
3176 else
3177 otp_pages = 50;
3178
3179 if (mode == MTD_OTP_FACTORY) {
3180 from += mtd->writesize * otp_pages;
3181 otp_pages = ONENAND_PAGES_PER_BLOCK - otp_pages;
3182 }
3183
3184
3185 if (mode == MTD_OTP_USER) {
3186 if (mtd->writesize * otp_pages < from + len)
3187 return 0;
3188 } else {
3189 if (mtd->writesize * otp_pages < len)
3190 return 0;
3191 }
3192
3193 onenand_get_device(mtd, FL_OTPING);
3194 while (len > 0 && otp_pages > 0) {
3195 if (!action) {
3196 struct otp_info *otpinfo;
3197
3198 len -= sizeof(struct otp_info);
3199 if (len <= 0) {
3200 ret = -ENOSPC;
3201 break;
3202 }
3203
3204 otpinfo = (struct otp_info *) buf;
3205 otpinfo->start = from;
3206 otpinfo->length = mtd->writesize;
3207 otpinfo->locked = 0;
3208
3209 from += mtd->writesize;
3210 buf += sizeof(struct otp_info);
3211 *retlen += sizeof(struct otp_info);
3212 } else {
3213 size_t tmp_retlen;
3214
3215 ret = action(mtd, from, len, &tmp_retlen, buf);
3216
3217 buf += tmp_retlen;
3218 len -= tmp_retlen;
3219 *retlen += tmp_retlen;
3220
3221 if (ret)
3222 break;
3223 }
3224 otp_pages--;
3225 }
3226 onenand_release_device(mtd);
3227
3228 return ret;
3229}
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240static int onenand_get_fact_prot_info(struct mtd_info *mtd, size_t len,
3241 size_t *retlen, struct otp_info *buf)
3242{
3243 return onenand_otp_walk(mtd, 0, len, retlen, (u_char *) buf, NULL,
3244 MTD_OTP_FACTORY);
3245}
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257static int onenand_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
3258 size_t len, size_t *retlen, u_char *buf)
3259{
3260 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_FACTORY);
3261}
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272static int onenand_get_user_prot_info(struct mtd_info *mtd, size_t len,
3273 size_t *retlen, struct otp_info *buf)
3274{
3275 return onenand_otp_walk(mtd, 0, len, retlen, (u_char *) buf, NULL,
3276 MTD_OTP_USER);
3277}
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289static int onenand_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
3290 size_t len, size_t *retlen, u_char *buf)
3291{
3292 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_USER);
3293}
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
3306 size_t len, size_t *retlen, u_char *buf)
3307{
3308 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, MTD_OTP_USER);
3309}
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
3320 size_t len)
3321{
3322 struct onenand_chip *this = mtd->priv;
3323 u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf;
3324 size_t retlen;
3325 int ret;
3326 unsigned int otp_lock_offset = ONENAND_OTP_LOCK_OFFSET;
3327
3328 memset(buf, 0xff, FLEXONENAND(this) ? this->writesize
3329 : mtd->oobsize);
3330
3331
3332
3333
3334
3335
3336
3337 from = 0;
3338 len = FLEXONENAND(this) ? mtd->writesize : 16;
3339
3340
3341
3342
3343
3344
3345
3346 if (FLEXONENAND(this))
3347 otp_lock_offset = FLEXONENAND_OTP_LOCK_OFFSET;
3348
3349
3350 if (otp == 1)
3351 buf[otp_lock_offset] = 0xFC;
3352 else if (otp == 2)
3353 buf[otp_lock_offset] = 0xF3;
3354 else if (otp == 3)
3355 buf[otp_lock_offset] = 0xF0;
3356 else if (otp != 0)
3357 printk(KERN_DEBUG "[OneNAND] Invalid option selected for OTP\n");
3358
3359 ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER);
3360
3361 return ret ? : retlen;
3362}
3363
3364#endif
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374static void onenand_check_features(struct mtd_info *mtd)
3375{
3376 struct onenand_chip *this = mtd->priv;
3377 unsigned int density, process, numbufs;
3378
3379
3380 density = onenand_get_density(this->device_id);
3381 process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
3382 numbufs = this->read_word(this->base + ONENAND_REG_NUM_BUFFERS) >> 8;
3383
3384
3385 switch (density) {
3386 case ONENAND_DEVICE_DENSITY_4Gb:
3387 if (ONENAND_IS_DDP(this))
3388 this->options |= ONENAND_HAS_2PLANE;
3389 else if (numbufs == 1) {
3390 this->options |= ONENAND_HAS_4KB_PAGE;
3391 this->options |= ONENAND_HAS_CACHE_PROGRAM;
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403 if ((this->version_id & 0xf) == 0xe)
3404 this->options |= ONENAND_HAS_NOP_1;
3405 }
3406
3407 case ONENAND_DEVICE_DENSITY_2Gb:
3408
3409 if (!ONENAND_IS_DDP(this))
3410 this->options |= ONENAND_HAS_2PLANE;
3411 this->options |= ONENAND_HAS_UNLOCK_ALL;
3412
3413 case ONENAND_DEVICE_DENSITY_1Gb:
3414
3415 if (process)
3416 this->options |= ONENAND_HAS_UNLOCK_ALL;
3417 break;
3418
3419 default:
3420
3421 if (!process)
3422 this->options |= ONENAND_HAS_CONT_LOCK;
3423 break;
3424 }
3425
3426
3427 if (ONENAND_IS_MLC(this))
3428 this->options |= ONENAND_HAS_4KB_PAGE;
3429
3430 if (ONENAND_IS_4KB_PAGE(this))
3431 this->options &= ~ONENAND_HAS_2PLANE;
3432
3433 if (FLEXONENAND(this)) {
3434 this->options &= ~ONENAND_HAS_CONT_LOCK;
3435 this->options |= ONENAND_HAS_UNLOCK_ALL;
3436 }
3437
3438 if (this->options & ONENAND_HAS_CONT_LOCK)
3439 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
3440 if (this->options & ONENAND_HAS_UNLOCK_ALL)
3441 printk(KERN_DEBUG "Chip support all block unlock\n");
3442 if (this->options & ONENAND_HAS_2PLANE)
3443 printk(KERN_DEBUG "Chip has 2 plane\n");
3444 if (this->options & ONENAND_HAS_4KB_PAGE)
3445 printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
3446 if (this->options & ONENAND_HAS_CACHE_PROGRAM)
3447 printk(KERN_DEBUG "Chip has cache program feature\n");
3448}
3449
3450
3451
3452
3453
3454
3455
3456
3457static void onenand_print_device_info(int device, int version)
3458{
3459 int vcc, demuxed, ddp, density, flexonenand;
3460
3461 vcc = device & ONENAND_DEVICE_VCC_MASK;
3462 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
3463 ddp = device & ONENAND_DEVICE_IS_DDP;
3464 density = onenand_get_density(device);
3465 flexonenand = device & DEVICE_IS_FLEXONENAND;
3466 printk(KERN_INFO "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
3467 demuxed ? "" : "Muxed ",
3468 flexonenand ? "Flex-" : "",
3469 ddp ? "(DDP)" : "",
3470 (16 << density),
3471 vcc ? "2.65/3.3" : "1.8",
3472 device);
3473 printk(KERN_INFO "OneNAND version = 0x%04x\n", version);
3474}
3475
3476static const struct onenand_manufacturers onenand_manuf_ids[] = {
3477 {ONENAND_MFR_SAMSUNG, "Samsung"},
3478 {ONENAND_MFR_NUMONYX, "Numonyx"},
3479};
3480
3481
3482
3483
3484
3485
3486
3487static int onenand_check_maf(int manuf)
3488{
3489 int size = ARRAY_SIZE(onenand_manuf_ids);
3490 char *name;
3491 int i;
3492
3493 for (i = 0; i < size; i++)
3494 if (manuf == onenand_manuf_ids[i].id)
3495 break;
3496
3497 if (i < size)
3498 name = onenand_manuf_ids[i].name;
3499 else
3500 name = "Unknown";
3501
3502 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
3503
3504 return (i == size);
3505}
3506
3507
3508
3509
3510
3511static int flexonenand_get_boundary(struct mtd_info *mtd)
3512{
3513 struct onenand_chip *this = mtd->priv;
3514 unsigned die, bdry;
3515 int syscfg, locked;
3516
3517
3518 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
3519 this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1);
3520
3521 for (die = 0; die < this->dies; die++) {
3522 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3523 this->wait(mtd, FL_SYNCING);
3524
3525 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3526 this->wait(mtd, FL_READING);
3527
3528 bdry = this->read_word(this->base + ONENAND_DATARAM);
3529 if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
3530 locked = 0;
3531 else
3532 locked = 1;
3533 this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
3534
3535 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
3536 this->wait(mtd, FL_RESETING);
3537
3538 printk(KERN_INFO "Die %d boundary: %d%s\n", die,
3539 this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
3540 }
3541
3542
3543 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
3544 return 0;
3545}
3546
3547
3548
3549
3550
3551
3552static void flexonenand_get_size(struct mtd_info *mtd)
3553{
3554 struct onenand_chip *this = mtd->priv;
3555 int die, i, eraseshift, density;
3556 int blksperdie, maxbdry;
3557 loff_t ofs;
3558
3559 density = onenand_get_density(this->device_id);
3560 blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift);
3561 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3562 maxbdry = blksperdie - 1;
3563 eraseshift = this->erase_shift - 1;
3564
3565 mtd->numeraseregions = this->dies << 1;
3566
3567
3568 flexonenand_get_boundary(mtd);
3569 die = ofs = 0;
3570 i = -1;
3571 for (; die < this->dies; die++) {
3572 if (!die || this->boundary[die-1] != maxbdry) {
3573 i++;
3574 mtd->eraseregions[i].offset = ofs;
3575 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3576 mtd->eraseregions[i].numblocks =
3577 this->boundary[die] + 1;
3578 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3579 eraseshift++;
3580 } else {
3581 mtd->numeraseregions -= 1;
3582 mtd->eraseregions[i].numblocks +=
3583 this->boundary[die] + 1;
3584 ofs += (this->boundary[die] + 1) << (eraseshift - 1);
3585 }
3586 if (this->boundary[die] != maxbdry) {
3587 i++;
3588 mtd->eraseregions[i].offset = ofs;
3589 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3590 mtd->eraseregions[i].numblocks = maxbdry ^
3591 this->boundary[die];
3592 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3593 eraseshift--;
3594 } else
3595 mtd->numeraseregions -= 1;
3596 }
3597
3598
3599 mtd->erasesize = 1 << this->erase_shift;
3600 if (mtd->numeraseregions == 1)
3601 mtd->erasesize >>= 1;
3602
3603 printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions);
3604 for (i = 0; i < mtd->numeraseregions; i++)
3605 printk(KERN_INFO "[offset: 0x%08x, erasesize: 0x%05x,"
3606 " numblocks: %04u]\n",
3607 (unsigned int) mtd->eraseregions[i].offset,
3608 mtd->eraseregions[i].erasesize,
3609 mtd->eraseregions[i].numblocks);
3610
3611 for (die = 0, mtd->size = 0; die < this->dies; die++) {
3612 this->diesize[die] = (loff_t)blksperdie << this->erase_shift;
3613 this->diesize[die] -= (loff_t)(this->boundary[die] + 1)
3614 << (this->erase_shift - 1);
3615 mtd->size += this->diesize[die];
3616 }
3617}
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int end)
3634{
3635 struct onenand_chip *this = mtd->priv;
3636 int i, ret;
3637 int block;
3638 struct mtd_oob_ops ops = {
3639 .mode = MTD_OPS_PLACE_OOB,
3640 .ooboffs = 0,
3641 .ooblen = mtd->oobsize,
3642 .datbuf = NULL,
3643 .oobbuf = this->oob_buf,
3644 };
3645 loff_t addr;
3646
3647 printk(KERN_DEBUG "Check blocks from %d to %d\n", start, end);
3648
3649 for (block = start; block <= end; block++) {
3650 addr = flexonenand_addr(this, block);
3651 if (onenand_block_isbad_nolock(mtd, addr, 0))
3652 continue;
3653
3654
3655
3656
3657
3658 ret = onenand_read_oob_nolock(mtd, addr, &ops);
3659 if (ret)
3660 return ret;
3661
3662 for (i = 0; i < mtd->oobsize; i++)
3663 if (this->oob_buf[i] != 0xff)
3664 break;
3665
3666 if (i != mtd->oobsize) {
3667 printk(KERN_WARNING "%s: Block %d not erased.\n",
3668 __func__, block);
3669 return 1;
3670 }
3671 }
3672
3673 return 0;
3674}
3675
3676
3677
3678
3679
3680static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
3681 int boundary, int lock)
3682{
3683 struct onenand_chip *this = mtd->priv;
3684 int ret, density, blksperdie, old, new, thisboundary;
3685 loff_t addr;
3686
3687
3688 if (die && (!ONENAND_IS_DDP(this)))
3689 return 0;
3690
3691
3692 if (boundary < 0 || boundary == this->boundary[die])
3693 return 0;
3694
3695 density = onenand_get_density(this->device_id);
3696 blksperdie = ((16 << density) << 20) >> this->erase_shift;
3697 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3698
3699 if (boundary >= blksperdie) {
3700 printk(KERN_ERR "%s: Invalid boundary value. "
3701 "Boundary not changed.\n", __func__);
3702 return -EINVAL;
3703 }
3704
3705
3706 old = this->boundary[die] + (die * this->density_mask);
3707 new = boundary + (die * this->density_mask);
3708 ret = flexonenand_check_blocks_erased(mtd, min(old, new) + 1, max(old, new));
3709 if (ret) {
3710 printk(KERN_ERR "%s: Please erase blocks "
3711 "before boundary change\n", __func__);
3712 return ret;
3713 }
3714
3715 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3716 this->wait(mtd, FL_SYNCING);
3717
3718
3719 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3720 this->wait(mtd, FL_READING);
3721
3722 thisboundary = this->read_word(this->base + ONENAND_DATARAM);
3723 if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
3724 printk(KERN_ERR "%s: boundary locked\n", __func__);
3725 ret = 1;
3726 goto out;
3727 }
3728
3729 printk(KERN_INFO "Changing die %d boundary: %d%s\n",
3730 die, boundary, lock ? "(Locked)" : "(Unlocked)");
3731
3732 addr = die ? this->diesize[0] : 0;
3733
3734 boundary &= FLEXONENAND_PI_MASK;
3735 boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT);
3736
3737 this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
3738 ret = this->wait(mtd, FL_ERASING);
3739 if (ret) {
3740 printk(KERN_ERR "%s: Failed PI erase for Die %d\n",
3741 __func__, die);
3742 goto out;
3743 }
3744
3745 this->write_word(boundary, this->base + ONENAND_DATARAM);
3746 this->command(mtd, ONENAND_CMD_PROG, addr, 0);
3747 ret = this->wait(mtd, FL_WRITING);
3748 if (ret) {
3749 printk(KERN_ERR "%s: Failed PI write for Die %d\n",
3750 __func__, die);
3751 goto out;
3752 }
3753
3754 this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0);
3755 ret = this->wait(mtd, FL_WRITING);
3756out:
3757 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND);
3758 this->wait(mtd, FL_RESETING);
3759 if (!ret)
3760
3761 flexonenand_get_size(mtd);
3762
3763 return ret;
3764}
3765
3766
3767
3768
3769
3770
3771
3772
3773static int onenand_chip_probe(struct mtd_info *mtd)
3774{
3775 struct onenand_chip *this = mtd->priv;
3776 int bram_maf_id, bram_dev_id, maf_id, dev_id;
3777 int syscfg;
3778
3779
3780 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
3781
3782 this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE), this->base + ONENAND_REG_SYS_CFG1);
3783
3784
3785 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
3786
3787
3788 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
3789 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
3790
3791
3792 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
3793
3794 this->wait(mtd, FL_RESETING);
3795
3796
3797 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
3798
3799
3800 if (onenand_check_maf(bram_maf_id))
3801 return -ENXIO;
3802
3803
3804 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
3805 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
3806
3807
3808 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
3809 return -ENXIO;
3810
3811 return 0;
3812}
3813
3814
3815
3816
3817
3818static int onenand_probe(struct mtd_info *mtd)
3819{
3820 struct onenand_chip *this = mtd->priv;
3821 int dev_id, ver_id;
3822 int density;
3823 int ret;
3824
3825 ret = this->chip_probe(mtd);
3826 if (ret)
3827 return ret;
3828
3829
3830 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
3831 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
3832 this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
3833
3834
3835 onenand_print_device_info(dev_id, ver_id);
3836 this->device_id = dev_id;
3837 this->version_id = ver_id;
3838
3839
3840 onenand_check_features(mtd);
3841
3842 density = onenand_get_density(dev_id);
3843 if (FLEXONENAND(this)) {
3844 this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
3845
3846 mtd->numeraseregions = this->dies << 1;
3847 mtd->eraseregions = kzalloc(sizeof(struct mtd_erase_region_info)
3848 * (this->dies << 1), GFP_KERNEL);
3849 if (!mtd->eraseregions)
3850 return -ENOMEM;
3851 }
3852
3853
3854
3855
3856
3857 this->chipsize = (16 << density) << 20;
3858
3859
3860
3861 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
3862
3863 if (ONENAND_IS_4KB_PAGE(this))
3864 mtd->writesize <<= 1;
3865
3866 mtd->oobsize = mtd->writesize >> 5;
3867
3868 mtd->erasesize = mtd->writesize << 6;
3869
3870
3871
3872
3873
3874 if (FLEXONENAND(this))
3875 mtd->erasesize <<= 1;
3876
3877 this->erase_shift = ffs(mtd->erasesize) - 1;
3878 this->page_shift = ffs(mtd->writesize) - 1;
3879 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
3880
3881 if (ONENAND_IS_DDP(this))
3882 this->density_mask = this->chipsize >> (this->erase_shift + 1);
3883
3884 this->writesize = mtd->writesize;
3885
3886
3887
3888 if (FLEXONENAND(this))
3889 flexonenand_get_size(mtd);
3890 else
3891 mtd->size = this->chipsize;
3892
3893
3894
3895
3896
3897
3898
3899 if (ONENAND_IS_2PLANE(this)) {
3900 mtd->writesize <<= 1;
3901 mtd->erasesize <<= 1;
3902 }
3903
3904 return 0;
3905}
3906
3907
3908
3909
3910
3911static int onenand_suspend(struct mtd_info *mtd)
3912{
3913 return onenand_get_device(mtd, FL_PM_SUSPENDED);
3914}
3915
3916
3917
3918
3919
3920static void onenand_resume(struct mtd_info *mtd)
3921{
3922 struct onenand_chip *this = mtd->priv;
3923
3924 if (this->state == FL_PM_SUSPENDED)
3925 onenand_release_device(mtd);
3926 else
3927 printk(KERN_ERR "%s: resume() called for the chip which is not "
3928 "in suspended state\n", __func__);
3929}
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941int onenand_scan(struct mtd_info *mtd, int maxchips)
3942{
3943 int i, ret;
3944 struct onenand_chip *this = mtd->priv;
3945
3946 if (!this->read_word)
3947 this->read_word = onenand_readw;
3948 if (!this->write_word)
3949 this->write_word = onenand_writew;
3950
3951 if (!this->command)
3952 this->command = onenand_command;
3953 if (!this->wait)
3954 onenand_setup_wait(mtd);
3955 if (!this->bbt_wait)
3956 this->bbt_wait = onenand_bbt_wait;
3957 if (!this->unlock_all)
3958 this->unlock_all = onenand_unlock_all;
3959
3960 if (!this->chip_probe)
3961 this->chip_probe = onenand_chip_probe;
3962
3963 if (!this->read_bufferram)
3964 this->read_bufferram = onenand_read_bufferram;
3965 if (!this->write_bufferram)
3966 this->write_bufferram = onenand_write_bufferram;
3967
3968 if (!this->block_markbad)
3969 this->block_markbad = onenand_default_block_markbad;
3970 if (!this->scan_bbt)
3971 this->scan_bbt = onenand_default_bbt;
3972
3973 if (onenand_probe(mtd))
3974 return -ENXIO;
3975
3976
3977 if (this->mmcontrol) {
3978 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
3979 this->read_bufferram = onenand_sync_read_bufferram;
3980 }
3981
3982
3983 if (!this->page_buf) {
3984 this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
3985 if (!this->page_buf)
3986 return -ENOMEM;
3987#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
3988 this->verify_buf = kzalloc(mtd->writesize, GFP_KERNEL);
3989 if (!this->verify_buf) {
3990 kfree(this->page_buf);
3991 return -ENOMEM;
3992 }
3993#endif
3994 this->options |= ONENAND_PAGEBUF_ALLOC;
3995 }
3996 if (!this->oob_buf) {
3997 this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
3998 if (!this->oob_buf) {
3999 if (this->options & ONENAND_PAGEBUF_ALLOC) {
4000 this->options &= ~ONENAND_PAGEBUF_ALLOC;
4001 kfree(this->page_buf);
4002 }
4003 return -ENOMEM;
4004 }
4005 this->options |= ONENAND_OOBBUF_ALLOC;
4006 }
4007
4008 this->state = FL_READY;
4009 init_waitqueue_head(&this->wq);
4010 spin_lock_init(&this->chip_lock);
4011
4012
4013
4014
4015 switch (mtd->oobsize) {
4016 case 128:
4017 if (FLEXONENAND(this)) {
4018 this->ecclayout = &flexonenand_oob_128;
4019 mtd->subpage_sft = 0;
4020 } else {
4021 this->ecclayout = &onenand_oob_128;
4022 mtd->subpage_sft = 2;
4023 }
4024 if (ONENAND_IS_NOP_1(this))
4025 mtd->subpage_sft = 0;
4026 break;
4027 case 64:
4028 this->ecclayout = &onenand_oob_64;
4029 mtd->subpage_sft = 2;
4030 break;
4031
4032 case 32:
4033 this->ecclayout = &onenand_oob_32;
4034 mtd->subpage_sft = 1;
4035 break;
4036
4037 default:
4038 printk(KERN_WARNING "%s: No OOB scheme defined for oobsize %d\n",
4039 __func__, mtd->oobsize);
4040 mtd->subpage_sft = 0;
4041
4042 this->ecclayout = &onenand_oob_32;
4043 break;
4044 }
4045
4046 this->subpagesize = mtd->writesize >> mtd->subpage_sft;
4047
4048
4049
4050
4051
4052 this->ecclayout->oobavail = 0;
4053 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES &&
4054 this->ecclayout->oobfree[i].length; i++)
4055 this->ecclayout->oobavail +=
4056 this->ecclayout->oobfree[i].length;
4057 mtd->oobavail = this->ecclayout->oobavail;
4058
4059 mtd->ecclayout = this->ecclayout;
4060 mtd->ecc_strength = 1;
4061
4062
4063 mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH;
4064 mtd->flags = MTD_CAP_NANDFLASH;
4065 mtd->_erase = onenand_erase;
4066 mtd->_point = NULL;
4067 mtd->_unpoint = NULL;
4068 mtd->_read = onenand_read;
4069 mtd->_write = onenand_write;
4070 mtd->_read_oob = onenand_read_oob;
4071 mtd->_write_oob = onenand_write_oob;
4072 mtd->_panic_write = onenand_panic_write;
4073#ifdef CONFIG_MTD_ONENAND_OTP
4074 mtd->_get_fact_prot_info = onenand_get_fact_prot_info;
4075 mtd->_read_fact_prot_reg = onenand_read_fact_prot_reg;
4076 mtd->_get_user_prot_info = onenand_get_user_prot_info;
4077 mtd->_read_user_prot_reg = onenand_read_user_prot_reg;
4078 mtd->_write_user_prot_reg = onenand_write_user_prot_reg;
4079 mtd->_lock_user_prot_reg = onenand_lock_user_prot_reg;
4080#endif
4081 mtd->_sync = onenand_sync;
4082 mtd->_lock = onenand_lock;
4083 mtd->_unlock = onenand_unlock;
4084 mtd->_suspend = onenand_suspend;
4085 mtd->_resume = onenand_resume;
4086 mtd->_block_isbad = onenand_block_isbad;
4087 mtd->_block_markbad = onenand_block_markbad;
4088 mtd->owner = THIS_MODULE;
4089 mtd->writebufsize = mtd->writesize;
4090
4091
4092 if (!(this->options & ONENAND_SKIP_INITIAL_UNLOCKING))
4093 this->unlock_all(mtd);
4094
4095 ret = this->scan_bbt(mtd);
4096 if ((!FLEXONENAND(this)) || ret)
4097 return ret;
4098
4099
4100 for (i = 0; i < MAX_DIES; i++)
4101 flexonenand_set_boundary(mtd, i, flex_bdry[2 * i],
4102 flex_bdry[(2 * i) + 1]);
4103
4104 return 0;
4105}
4106
4107
4108
4109
4110
4111void onenand_release(struct mtd_info *mtd)
4112{
4113 struct onenand_chip *this = mtd->priv;
4114
4115
4116 mtd_device_unregister(mtd);
4117
4118
4119 if (this->bbm) {
4120 struct bbm_info *bbm = this->bbm;
4121 kfree(bbm->bbt);
4122 kfree(this->bbm);
4123 }
4124
4125 if (this->options & ONENAND_PAGEBUF_ALLOC) {
4126 kfree(this->page_buf);
4127#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
4128 kfree(this->verify_buf);
4129#endif
4130 }
4131 if (this->options & ONENAND_OOBBUF_ALLOC)
4132 kfree(this->oob_buf);
4133 kfree(mtd->eraseregions);
4134}
4135
4136EXPORT_SYMBOL_GPL(onenand_scan);
4137EXPORT_SYMBOL_GPL(onenand_release);
4138
4139MODULE_LICENSE("GPL");
4140MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
4141MODULE_DESCRIPTION("Generic OneNAND flash driver code");
4142