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