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