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