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
1056 this->read_bufferram(mtd, ONENAND_SPARERAM, this->oob_buf, 0,
1057 mtd->oobsize);
1058 return mtd_ooblayout_get_databytes(mtd, buf, this->oob_buf,
1059 column, thislen);
1060}
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status)
1076{
1077 struct onenand_chip *this = mtd->priv;
1078 int i;
1079
1080
1081 if (!FLEXONENAND(this))
1082 return status;
1083
1084
1085 if (!mtd_is_eccerr(status) && status != ONENAND_BBT_READ_ECC_ERROR)
1086 return status;
1087
1088
1089 i = flexonenand_region(mtd, addr);
1090 if (mtd->eraseregions[i].erasesize < (1 << this->erase_shift))
1091 return status;
1092
1093
1094
1095
1096 printk(KERN_INFO "%s: Attempting to recover from uncorrectable read\n",
1097 __func__);
1098 mtd->ecc_stats.failed--;
1099
1100
1101 this->command(mtd, FLEXONENAND_CMD_RECOVER_LSB, addr, this->writesize);
1102 return this->wait(mtd, FL_READING);
1103}
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
1115 struct mtd_oob_ops *ops)
1116{
1117 struct onenand_chip *this = mtd->priv;
1118 struct mtd_ecc_stats stats;
1119 size_t len = ops->len;
1120 size_t ooblen = ops->ooblen;
1121 u_char *buf = ops->datbuf;
1122 u_char *oobbuf = ops->oobbuf;
1123 int read = 0, column, thislen;
1124 int oobread = 0, oobcolumn, thisooblen, oobsize;
1125 int ret = 0;
1126 int writesize = this->writesize;
1127
1128 pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
1129 (int)len);
1130
1131 oobsize = mtd_oobavail(mtd, ops);
1132 oobcolumn = from & (mtd->oobsize - 1);
1133
1134
1135 if (from + len > mtd->size) {
1136 printk(KERN_ERR "%s: Attempt read beyond end of device\n",
1137 __func__);
1138 ops->retlen = 0;
1139 ops->oobretlen = 0;
1140 return -EINVAL;
1141 }
1142
1143 stats = mtd->ecc_stats;
1144
1145 while (read < len) {
1146 cond_resched();
1147
1148 thislen = min_t(int, writesize, len - read);
1149
1150 column = from & (writesize - 1);
1151 if (column + thislen > writesize)
1152 thislen = writesize - column;
1153
1154 if (!onenand_check_bufferram(mtd, from)) {
1155 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1156
1157 ret = this->wait(mtd, FL_READING);
1158 if (unlikely(ret))
1159 ret = onenand_recover_lsb(mtd, from, ret);
1160 onenand_update_bufferram(mtd, from, !ret);
1161 if (mtd_is_eccerr(ret))
1162 ret = 0;
1163 if (ret)
1164 break;
1165 }
1166
1167 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
1168 if (oobbuf) {
1169 thisooblen = oobsize - oobcolumn;
1170 thisooblen = min_t(int, thisooblen, ooblen - oobread);
1171
1172 if (ops->mode == MTD_OPS_AUTO_OOB)
1173 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
1174 else
1175 this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
1176 oobread += thisooblen;
1177 oobbuf += thisooblen;
1178 oobcolumn = 0;
1179 }
1180
1181 read += thislen;
1182 if (read == len)
1183 break;
1184
1185 from += thislen;
1186 buf += thislen;
1187 }
1188
1189
1190
1191
1192
1193
1194 ops->retlen = read;
1195 ops->oobretlen = oobread;
1196
1197 if (ret)
1198 return ret;
1199
1200 if (mtd->ecc_stats.failed - stats.failed)
1201 return -EBADMSG;
1202
1203
1204 return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0;
1205}
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
1216 struct mtd_oob_ops *ops)
1217{
1218 struct onenand_chip *this = mtd->priv;
1219 struct mtd_ecc_stats stats;
1220 size_t len = ops->len;
1221 size_t ooblen = ops->ooblen;
1222 u_char *buf = ops->datbuf;
1223 u_char *oobbuf = ops->oobbuf;
1224 int read = 0, column, thislen;
1225 int oobread = 0, oobcolumn, thisooblen, oobsize;
1226 int ret = 0, boundary = 0;
1227 int writesize = this->writesize;
1228
1229 pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
1230 (int)len);
1231
1232 oobsize = mtd_oobavail(mtd, ops);
1233 oobcolumn = from & (mtd->oobsize - 1);
1234
1235
1236 if ((from + len) > mtd->size) {
1237 printk(KERN_ERR "%s: Attempt read beyond end of device\n",
1238 __func__);
1239 ops->retlen = 0;
1240 ops->oobretlen = 0;
1241 return -EINVAL;
1242 }
1243
1244 stats = mtd->ecc_stats;
1245
1246
1247
1248
1249 if (read < len) {
1250 if (!onenand_check_bufferram(mtd, from)) {
1251 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1252 ret = this->wait(mtd, FL_READING);
1253 onenand_update_bufferram(mtd, from, !ret);
1254 if (mtd_is_eccerr(ret))
1255 ret = 0;
1256 }
1257 }
1258
1259 thislen = min_t(int, writesize, len - read);
1260 column = from & (writesize - 1);
1261 if (column + thislen > writesize)
1262 thislen = writesize - column;
1263
1264 while (!ret) {
1265
1266 from += thislen;
1267 if (read + thislen < len) {
1268 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1269
1270
1271
1272
1273
1274 if (ONENAND_IS_DDP(this) &&
1275 unlikely(from == (this->chipsize >> 1))) {
1276 this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2);
1277 boundary = 1;
1278 } else
1279 boundary = 0;
1280 ONENAND_SET_PREV_BUFFERRAM(this);
1281 }
1282
1283 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
1284
1285
1286 if (oobbuf) {
1287 thisooblen = oobsize - oobcolumn;
1288 thisooblen = min_t(int, thisooblen, ooblen - oobread);
1289
1290 if (ops->mode == MTD_OPS_AUTO_OOB)
1291 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
1292 else
1293 this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
1294 oobread += thisooblen;
1295 oobbuf += thisooblen;
1296 oobcolumn = 0;
1297 }
1298
1299
1300 read += thislen;
1301 if (read == len)
1302 break;
1303
1304 if (unlikely(boundary))
1305 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
1306 ONENAND_SET_NEXT_BUFFERRAM(this);
1307 buf += thislen;
1308 thislen = min_t(int, writesize, len - read);
1309 column = 0;
1310 cond_resched();
1311
1312 ret = this->wait(mtd, FL_READING);
1313 onenand_update_bufferram(mtd, from, !ret);
1314 if (mtd_is_eccerr(ret))
1315 ret = 0;
1316 }
1317
1318
1319
1320
1321
1322
1323 ops->retlen = read;
1324 ops->oobretlen = oobread;
1325
1326 if (ret)
1327 return ret;
1328
1329 if (mtd->ecc_stats.failed - stats.failed)
1330 return -EBADMSG;
1331
1332
1333 return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0;
1334}
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
1345 struct mtd_oob_ops *ops)
1346{
1347 struct onenand_chip *this = mtd->priv;
1348 struct mtd_ecc_stats stats;
1349 int read = 0, thislen, column, oobsize;
1350 size_t len = ops->ooblen;
1351 unsigned int mode = ops->mode;
1352 u_char *buf = ops->oobbuf;
1353 int ret = 0, readcmd;
1354
1355 from += ops->ooboffs;
1356
1357 pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
1358 (int)len);
1359
1360
1361 ops->oobretlen = 0;
1362
1363 if (mode == MTD_OPS_AUTO_OOB)
1364 oobsize = mtd->oobavail;
1365 else
1366 oobsize = mtd->oobsize;
1367
1368 column = from & (mtd->oobsize - 1);
1369
1370 if (unlikely(column >= oobsize)) {
1371 printk(KERN_ERR "%s: Attempted to start read outside oob\n",
1372 __func__);
1373 return -EINVAL;
1374 }
1375
1376 stats = mtd->ecc_stats;
1377
1378 readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1379
1380 while (read < len) {
1381 cond_resched();
1382
1383 thislen = oobsize - column;
1384 thislen = min_t(int, thislen, len);
1385
1386 this->command(mtd, readcmd, from, mtd->oobsize);
1387
1388 onenand_update_bufferram(mtd, from, 0);
1389
1390 ret = this->wait(mtd, FL_READING);
1391 if (unlikely(ret))
1392 ret = onenand_recover_lsb(mtd, from, ret);
1393
1394 if (ret && !mtd_is_eccerr(ret)) {
1395 printk(KERN_ERR "%s: read failed = 0x%x\n",
1396 __func__, ret);
1397 break;
1398 }
1399
1400 if (mode == MTD_OPS_AUTO_OOB)
1401 onenand_transfer_auto_oob(mtd, buf, column, thislen);
1402 else
1403 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
1404
1405 read += thislen;
1406
1407 if (read == len)
1408 break;
1409
1410 buf += thislen;
1411
1412
1413 if (read < len) {
1414
1415 from += mtd->writesize;
1416 column = 0;
1417 }
1418 }
1419
1420 ops->oobretlen = read;
1421
1422 if (ret)
1423 return ret;
1424
1425 if (mtd->ecc_stats.failed - stats.failed)
1426 return -EBADMSG;
1427
1428 return 0;
1429}
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1440 struct mtd_oob_ops *ops)
1441{
1442 struct onenand_chip *this = mtd->priv;
1443 int ret;
1444
1445 switch (ops->mode) {
1446 case MTD_OPS_PLACE_OOB:
1447 case MTD_OPS_AUTO_OOB:
1448 break;
1449 case MTD_OPS_RAW:
1450
1451 default:
1452 return -EINVAL;
1453 }
1454
1455 onenand_get_device(mtd, FL_READING);
1456 if (ops->datbuf)
1457 ret = ONENAND_IS_4KB_PAGE(this) ?
1458 onenand_mlc_read_ops_nolock(mtd, from, ops) :
1459 onenand_read_ops_nolock(mtd, from, ops);
1460 else
1461 ret = onenand_read_oob_nolock(mtd, from, ops);
1462 onenand_release_device(mtd);
1463
1464 return ret;
1465}
1466
1467
1468
1469
1470
1471
1472
1473
1474static int onenand_bbt_wait(struct mtd_info *mtd, int state)
1475{
1476 struct onenand_chip *this = mtd->priv;
1477 unsigned long timeout;
1478 unsigned int interrupt, ctrl, ecc, addr1, addr8;
1479
1480
1481 timeout = jiffies + msecs_to_jiffies(20);
1482 while (time_before(jiffies, timeout)) {
1483 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1484 if (interrupt & ONENAND_INT_MASTER)
1485 break;
1486 }
1487
1488 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1489 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
1490 addr1 = this->read_word(this->base + ONENAND_REG_START_ADDRESS1);
1491 addr8 = this->read_word(this->base + ONENAND_REG_START_ADDRESS8);
1492
1493 if (interrupt & ONENAND_INT_READ) {
1494 ecc = onenand_read_ecc(this);
1495 if (ecc & ONENAND_ECC_2BIT_ALL) {
1496 printk(KERN_DEBUG "%s: ecc 0x%04x ctrl 0x%04x "
1497 "intr 0x%04x addr1 %#x addr8 %#x\n",
1498 __func__, ecc, ctrl, interrupt, addr1, addr8);
1499 return ONENAND_BBT_READ_ECC_ERROR;
1500 }
1501 } else {
1502 printk(KERN_ERR "%s: read timeout! ctrl 0x%04x "
1503 "intr 0x%04x addr1 %#x addr8 %#x\n",
1504 __func__, ctrl, interrupt, addr1, addr8);
1505 return ONENAND_BBT_READ_FATAL_ERROR;
1506 }
1507
1508
1509 if (ctrl & ONENAND_CTRL_ERROR) {
1510 printk(KERN_DEBUG "%s: ctrl 0x%04x intr 0x%04x addr1 %#x "
1511 "addr8 %#x\n", __func__, ctrl, interrupt, addr1, addr8);
1512 return ONENAND_BBT_READ_ERROR;
1513 }
1514
1515 return 0;
1516}
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1527 struct mtd_oob_ops *ops)
1528{
1529 struct onenand_chip *this = mtd->priv;
1530 int read = 0, thislen, column;
1531 int ret = 0, readcmd;
1532 size_t len = ops->ooblen;
1533 u_char *buf = ops->oobbuf;
1534
1535 pr_debug("%s: from = 0x%08x, len = %zi\n", __func__, (unsigned int)from,
1536 len);
1537
1538
1539 ops->oobretlen = 0;
1540
1541
1542 if (unlikely((from + len) > mtd->size)) {
1543 printk(KERN_ERR "%s: Attempt read beyond end of device\n",
1544 __func__);
1545 return ONENAND_BBT_READ_FATAL_ERROR;
1546 }
1547
1548
1549 onenand_get_device(mtd, FL_READING);
1550
1551 column = from & (mtd->oobsize - 1);
1552
1553 readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1554
1555 while (read < len) {
1556 cond_resched();
1557
1558 thislen = mtd->oobsize - column;
1559 thislen = min_t(int, thislen, len);
1560
1561 this->command(mtd, readcmd, from, mtd->oobsize);
1562
1563 onenand_update_bufferram(mtd, from, 0);
1564
1565 ret = this->bbt_wait(mtd, FL_READING);
1566 if (unlikely(ret))
1567 ret = onenand_recover_lsb(mtd, from, ret);
1568
1569 if (ret)
1570 break;
1571
1572 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
1573 read += thislen;
1574 if (read == len)
1575 break;
1576
1577 buf += thislen;
1578
1579
1580 if (read < len) {
1581
1582 from += this->writesize;
1583 column = 0;
1584 }
1585 }
1586
1587
1588 onenand_release_device(mtd);
1589
1590 ops->oobretlen = read;
1591 return ret;
1592}
1593
1594#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
1595
1596
1597
1598
1599
1600
1601static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
1602{
1603 struct onenand_chip *this = mtd->priv;
1604 u_char *oob_buf = this->oob_buf;
1605 int status, i, readcmd;
1606
1607 readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1608
1609 this->command(mtd, readcmd, to, mtd->oobsize);
1610 onenand_update_bufferram(mtd, to, 0);
1611 status = this->wait(mtd, FL_READING);
1612 if (status)
1613 return status;
1614
1615 this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
1616 for (i = 0; i < mtd->oobsize; i++)
1617 if (buf[i] != 0xFF && buf[i] != oob_buf[i])
1618 return -EBADMSG;
1619
1620 return 0;
1621}
1622
1623
1624
1625
1626
1627
1628
1629
1630static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
1631{
1632 struct onenand_chip *this = mtd->priv;
1633 int ret = 0;
1634 int thislen, column;
1635
1636 column = addr & (this->writesize - 1);
1637
1638 while (len != 0) {
1639 thislen = min_t(int, this->writesize - column, len);
1640
1641 this->command(mtd, ONENAND_CMD_READ, addr, this->writesize);
1642
1643 onenand_update_bufferram(mtd, addr, 0);
1644
1645 ret = this->wait(mtd, FL_READING);
1646 if (ret)
1647 return ret;
1648
1649 onenand_update_bufferram(mtd, addr, 1);
1650
1651 this->read_bufferram(mtd, ONENAND_DATARAM, this->verify_buf, 0, mtd->writesize);
1652
1653 if (memcmp(buf, this->verify_buf + column, thislen))
1654 return -EBADMSG;
1655
1656 len -= thislen;
1657 buf += thislen;
1658 addr += thislen;
1659 column = 0;
1660 }
1661
1662 return 0;
1663}
1664#else
1665#define onenand_verify(...) (0)
1666#define onenand_verify_oob(...) (0)
1667#endif
1668
1669#define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0)
1670
1671static void onenand_panic_wait(struct mtd_info *mtd)
1672{
1673 struct onenand_chip *this = mtd->priv;
1674 unsigned int interrupt;
1675 int i;
1676
1677 for (i = 0; i < 2000; i++) {
1678 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1679 if (interrupt & ONENAND_INT_MASTER)
1680 break;
1681 udelay(10);
1682 }
1683}
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
1696 size_t *retlen, const u_char *buf)
1697{
1698 struct onenand_chip *this = mtd->priv;
1699 int column, subpage;
1700 int written = 0;
1701
1702 if (this->state == FL_PM_SUSPENDED)
1703 return -EBUSY;
1704
1705
1706 onenand_panic_wait(mtd);
1707
1708 pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
1709 (int)len);
1710
1711
1712 if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
1713 printk(KERN_ERR "%s: Attempt to write not page aligned data\n",
1714 __func__);
1715 return -EINVAL;
1716 }
1717
1718 column = to & (mtd->writesize - 1);
1719
1720
1721 while (written < len) {
1722 int thislen = min_t(int, mtd->writesize - column, len - written);
1723 u_char *wbuf = (u_char *) buf;
1724
1725 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1726
1727
1728 subpage = thislen < mtd->writesize;
1729 if (subpage) {
1730 memset(this->page_buf, 0xff, mtd->writesize);
1731 memcpy(this->page_buf + column, buf, thislen);
1732 wbuf = this->page_buf;
1733 }
1734
1735 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1736 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1737
1738 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1739
1740 onenand_panic_wait(mtd);
1741
1742
1743 onenand_update_bufferram(mtd, to, !subpage);
1744 if (ONENAND_IS_2PLANE(this)) {
1745 ONENAND_SET_BUFFERRAM1(this);
1746 onenand_update_bufferram(mtd, to + this->writesize, !subpage);
1747 }
1748
1749 written += thislen;
1750
1751 if (written == len)
1752 break;
1753
1754 column = 0;
1755 to += thislen;
1756 buf += thislen;
1757 }
1758
1759 *retlen = written;
1760 return 0;
1761}
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
1772 const u_char *buf, int column, int thislen)
1773{
1774 return mtd_ooblayout_set_databytes(mtd, buf, oob_buf, column, thislen);
1775}
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1786 struct mtd_oob_ops *ops)
1787{
1788 struct onenand_chip *this = mtd->priv;
1789 int written = 0, column, thislen = 0, subpage = 0;
1790 int prev = 0, prevlen = 0, prev_subpage = 0, first = 1;
1791 int oobwritten = 0, oobcolumn, thisooblen, oobsize;
1792 size_t len = ops->len;
1793 size_t ooblen = ops->ooblen;
1794 const u_char *buf = ops->datbuf;
1795 const u_char *oob = ops->oobbuf;
1796 u_char *oobbuf;
1797 int ret = 0, cmd;
1798
1799 pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
1800 (int)len);
1801
1802
1803 ops->retlen = 0;
1804 ops->oobretlen = 0;
1805
1806
1807 if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
1808 printk(KERN_ERR "%s: Attempt to write not page aligned data\n",
1809 __func__);
1810 return -EINVAL;
1811 }
1812
1813
1814 if (!len)
1815 return 0;
1816 oobsize = mtd_oobavail(mtd, ops);
1817 oobcolumn = to & (mtd->oobsize - 1);
1818
1819 column = to & (mtd->writesize - 1);
1820
1821
1822 while (1) {
1823 if (written < len) {
1824 u_char *wbuf = (u_char *) buf;
1825
1826 thislen = min_t(int, mtd->writesize - column, len - written);
1827 thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
1828
1829 cond_resched();
1830
1831 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1832
1833
1834 subpage = thislen < mtd->writesize;
1835 if (subpage) {
1836 memset(this->page_buf, 0xff, mtd->writesize);
1837 memcpy(this->page_buf + column, buf, thislen);
1838 wbuf = this->page_buf;
1839 }
1840
1841 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1842
1843 if (oob) {
1844 oobbuf = this->oob_buf;
1845
1846
1847
1848 memset(oobbuf, 0xff, mtd->oobsize);
1849 if (ops->mode == MTD_OPS_AUTO_OOB)
1850 onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
1851 else
1852 memcpy(oobbuf + oobcolumn, oob, thisooblen);
1853
1854 oobwritten += thisooblen;
1855 oob += thisooblen;
1856 oobcolumn = 0;
1857 } else
1858 oobbuf = (u_char *) ffchars;
1859
1860 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1861 } else
1862 ONENAND_SET_NEXT_BUFFERRAM(this);
1863
1864
1865
1866
1867
1868 if (!ONENAND_IS_2PLANE(this) && !ONENAND_IS_4KB_PAGE(this) && !first) {
1869 ONENAND_SET_PREV_BUFFERRAM(this);
1870
1871 ret = this->wait(mtd, FL_WRITING);
1872
1873
1874 onenand_update_bufferram(mtd, prev, !ret && !prev_subpage);
1875 if (ret) {
1876 written -= prevlen;
1877 printk(KERN_ERR "%s: write failed %d\n",
1878 __func__, ret);
1879 break;
1880 }
1881
1882 if (written == len) {
1883
1884 ret = onenand_verify(mtd, buf - len, to - len, len);
1885 if (ret)
1886 printk(KERN_ERR "%s: verify failed %d\n",
1887 __func__, ret);
1888 break;
1889 }
1890
1891 ONENAND_SET_NEXT_BUFFERRAM(this);
1892 }
1893
1894 this->ongoing = 0;
1895 cmd = ONENAND_CMD_PROG;
1896
1897
1898 if (ONENAND_IS_CACHE_PROGRAM(this) &&
1899 likely(onenand_block(this, to) != 0) &&
1900 ONENAND_IS_4KB_PAGE(this) &&
1901 ((written + thislen) < len)) {
1902 cmd = ONENAND_CMD_2X_CACHE_PROG;
1903 this->ongoing = 1;
1904 }
1905
1906 this->command(mtd, cmd, to, mtd->writesize);
1907
1908
1909
1910
1911 if (ONENAND_IS_2PLANE(this) || ONENAND_IS_4KB_PAGE(this)) {
1912 ret = this->wait(mtd, FL_WRITING);
1913
1914
1915 onenand_update_bufferram(mtd, to, !ret && !subpage);
1916 if (ret) {
1917 printk(KERN_ERR "%s: write failed %d\n",
1918 __func__, ret);
1919 break;
1920 }
1921
1922
1923 ret = onenand_verify(mtd, buf, to, thislen);
1924 if (ret) {
1925 printk(KERN_ERR "%s: verify failed %d\n",
1926 __func__, ret);
1927 break;
1928 }
1929
1930 written += thislen;
1931
1932 if (written == len)
1933 break;
1934
1935 } else
1936 written += thislen;
1937
1938 column = 0;
1939 prev_subpage = subpage;
1940 prev = to;
1941 prevlen = thislen;
1942 to += thislen;
1943 buf += thislen;
1944 first = 0;
1945 }
1946
1947
1948 if (written != len)
1949 onenand_invalidate_bufferram(mtd, 0, -1);
1950
1951 ops->retlen = written;
1952 ops->oobretlen = oobwritten;
1953
1954 return ret;
1955}
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1967 struct mtd_oob_ops *ops)
1968{
1969 struct onenand_chip *this = mtd->priv;
1970 int column, ret = 0, oobsize;
1971 int written = 0, oobcmd;
1972 u_char *oobbuf;
1973 size_t len = ops->ooblen;
1974 const u_char *buf = ops->oobbuf;
1975 unsigned int mode = ops->mode;
1976
1977 to += ops->ooboffs;
1978
1979 pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
1980 (int)len);
1981
1982
1983 ops->oobretlen = 0;
1984
1985 if (mode == MTD_OPS_AUTO_OOB)
1986 oobsize = mtd->oobavail;
1987 else
1988 oobsize = mtd->oobsize;
1989
1990 column = to & (mtd->oobsize - 1);
1991
1992 if (unlikely(column >= oobsize)) {
1993 printk(KERN_ERR "%s: Attempted to start write outside oob\n",
1994 __func__);
1995 return -EINVAL;
1996 }
1997
1998
1999 if (unlikely(column + len > oobsize)) {
2000 printk(KERN_ERR "%s: Attempt to write past end of page\n",
2001 __func__);
2002 return -EINVAL;
2003 }
2004
2005 oobbuf = this->oob_buf;
2006
2007 oobcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
2008
2009
2010 while (written < len) {
2011 int thislen = min_t(int, oobsize, len - written);
2012
2013 cond_resched();
2014
2015 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
2016
2017
2018
2019 memset(oobbuf, 0xff, mtd->oobsize);
2020 if (mode == MTD_OPS_AUTO_OOB)
2021 onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
2022 else
2023 memcpy(oobbuf + column, buf, thislen);
2024 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
2025
2026 if (ONENAND_IS_4KB_PAGE(this)) {
2027
2028 memset(this->page_buf, 0xff, mtd->writesize);
2029 this->write_bufferram(mtd, ONENAND_DATARAM,
2030 this->page_buf, 0, mtd->writesize);
2031 }
2032
2033 this->command(mtd, oobcmd, to, mtd->oobsize);
2034
2035 onenand_update_bufferram(mtd, to, 0);
2036 if (ONENAND_IS_2PLANE(this)) {
2037 ONENAND_SET_BUFFERRAM1(this);
2038 onenand_update_bufferram(mtd, to + this->writesize, 0);
2039 }
2040
2041 ret = this->wait(mtd, FL_WRITING);
2042 if (ret) {
2043 printk(KERN_ERR "%s: write failed %d\n", __func__, ret);
2044 break;
2045 }
2046
2047 ret = onenand_verify_oob(mtd, oobbuf, to);
2048 if (ret) {
2049 printk(KERN_ERR "%s: verify failed %d\n",
2050 __func__, ret);
2051 break;
2052 }
2053
2054 written += thislen;
2055 if (written == len)
2056 break;
2057
2058 to += mtd->writesize;
2059 buf += thislen;
2060 column = 0;
2061 }
2062
2063 ops->oobretlen = written;
2064
2065 return ret;
2066}
2067
2068
2069
2070
2071
2072
2073
2074static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
2075 struct mtd_oob_ops *ops)
2076{
2077 int ret;
2078
2079 switch (ops->mode) {
2080 case MTD_OPS_PLACE_OOB:
2081 case MTD_OPS_AUTO_OOB:
2082 break;
2083 case MTD_OPS_RAW:
2084
2085 default:
2086 return -EINVAL;
2087 }
2088
2089 onenand_get_device(mtd, FL_WRITING);
2090 if (ops->datbuf)
2091 ret = onenand_write_ops_nolock(mtd, to, ops);
2092 else
2093 ret = onenand_write_oob_nolock(mtd, to, ops);
2094 onenand_release_device(mtd);
2095
2096 return ret;
2097}
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
2109{
2110 struct onenand_chip *this = mtd->priv;
2111 struct bbm_info *bbm = this->bbm;
2112
2113
2114 return bbm->isbad_bbt(mtd, ofs, allowbbt);
2115}
2116
2117
2118static int onenand_multiblock_erase_verify(struct mtd_info *mtd,
2119 struct erase_info *instr)
2120{
2121 struct onenand_chip *this = mtd->priv;
2122 loff_t addr = instr->addr;
2123 int len = instr->len;
2124 unsigned int block_size = (1 << this->erase_shift);
2125 int ret = 0;
2126
2127 while (len) {
2128 this->command(mtd, ONENAND_CMD_ERASE_VERIFY, addr, block_size);
2129 ret = this->wait(mtd, FL_VERIFYING_ERASE);
2130 if (ret) {
2131 printk(KERN_ERR "%s: Failed verify, block %d\n",
2132 __func__, onenand_block(this, addr));
2133 instr->fail_addr = addr;
2134 return -1;
2135 }
2136 len -= block_size;
2137 addr += block_size;
2138 }
2139 return 0;
2140}
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150static int onenand_multiblock_erase(struct mtd_info *mtd,
2151 struct erase_info *instr,
2152 unsigned int block_size)
2153{
2154 struct onenand_chip *this = mtd->priv;
2155 loff_t addr = instr->addr;
2156 int len = instr->len;
2157 int eb_count = 0;
2158 int ret = 0;
2159 int bdry_block = 0;
2160
2161 if (ONENAND_IS_DDP(this)) {
2162 loff_t bdry_addr = this->chipsize >> 1;
2163 if (addr < bdry_addr && (addr + len) > bdry_addr)
2164 bdry_block = bdry_addr >> this->erase_shift;
2165 }
2166
2167
2168 while (len) {
2169
2170 if (onenand_block_isbad_nolock(mtd, addr, 0)) {
2171 printk(KERN_WARNING "%s: attempt to erase a bad block "
2172 "at addr 0x%012llx\n",
2173 __func__, (unsigned long long) addr);
2174 return -EIO;
2175 }
2176 len -= block_size;
2177 addr += block_size;
2178 }
2179
2180 len = instr->len;
2181 addr = instr->addr;
2182
2183
2184 while (len) {
2185 struct erase_info verify_instr = *instr;
2186 int max_eb_count = MB_ERASE_MAX_BLK_COUNT;
2187
2188 verify_instr.addr = addr;
2189 verify_instr.len = 0;
2190
2191
2192 if (bdry_block) {
2193 int this_block = (addr >> this->erase_shift);
2194
2195 if (this_block < bdry_block) {
2196 max_eb_count = min(max_eb_count,
2197 (bdry_block - this_block));
2198 }
2199 }
2200
2201 eb_count = 0;
2202
2203 while (len > block_size && eb_count < (max_eb_count - 1)) {
2204 this->command(mtd, ONENAND_CMD_MULTIBLOCK_ERASE,
2205 addr, block_size);
2206 onenand_invalidate_bufferram(mtd, addr, block_size);
2207
2208 ret = this->wait(mtd, FL_PREPARING_ERASE);
2209 if (ret) {
2210 printk(KERN_ERR "%s: Failed multiblock erase, "
2211 "block %d\n", __func__,
2212 onenand_block(this, addr));
2213 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
2214 return -EIO;
2215 }
2216
2217 len -= block_size;
2218 addr += block_size;
2219 eb_count++;
2220 }
2221
2222
2223 cond_resched();
2224 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
2225 onenand_invalidate_bufferram(mtd, addr, block_size);
2226
2227 ret = this->wait(mtd, FL_ERASING);
2228
2229 if (ret) {
2230 printk(KERN_ERR "%s: Failed erase, block %d\n",
2231 __func__, onenand_block(this, addr));
2232 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
2233 return -EIO;
2234 }
2235
2236 len -= block_size;
2237 addr += block_size;
2238 eb_count++;
2239
2240
2241 verify_instr.len = eb_count * block_size;
2242 if (onenand_multiblock_erase_verify(mtd, &verify_instr)) {
2243 instr->fail_addr = verify_instr.fail_addr;
2244 return -EIO;
2245 }
2246
2247 }
2248 return 0;
2249}
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261static int onenand_block_by_block_erase(struct mtd_info *mtd,
2262 struct erase_info *instr,
2263 struct mtd_erase_region_info *region,
2264 unsigned int block_size)
2265{
2266 struct onenand_chip *this = mtd->priv;
2267 loff_t addr = instr->addr;
2268 int len = instr->len;
2269 loff_t region_end = 0;
2270 int ret = 0;
2271
2272 if (region) {
2273
2274 region_end = region->offset + region->erasesize * region->numblocks;
2275 }
2276
2277
2278 while (len) {
2279 cond_resched();
2280
2281
2282 if (onenand_block_isbad_nolock(mtd, addr, 0)) {
2283 printk(KERN_WARNING "%s: attempt to erase a bad block "
2284 "at addr 0x%012llx\n",
2285 __func__, (unsigned long long) addr);
2286 return -EIO;
2287 }
2288
2289 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
2290
2291 onenand_invalidate_bufferram(mtd, addr, block_size);
2292
2293 ret = this->wait(mtd, FL_ERASING);
2294
2295 if (ret) {
2296 printk(KERN_ERR "%s: Failed erase, block %d\n",
2297 __func__, onenand_block(this, addr));
2298 instr->fail_addr = addr;
2299 return -EIO;
2300 }
2301
2302 len -= block_size;
2303 addr += block_size;
2304
2305 if (region && addr == region_end) {
2306 if (!len)
2307 break;
2308 region++;
2309
2310 block_size = region->erasesize;
2311 region_end = region->offset + region->erasesize * region->numblocks;
2312
2313 if (len & (block_size - 1)) {
2314
2315 printk(KERN_ERR "%s: Unaligned address\n",
2316 __func__);
2317 return -EIO;
2318 }
2319 }
2320 }
2321 return 0;
2322}
2323
2324
2325
2326
2327
2328
2329
2330
2331static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
2332{
2333 struct onenand_chip *this = mtd->priv;
2334 unsigned int block_size;
2335 loff_t addr = instr->addr;
2336 loff_t len = instr->len;
2337 int ret = 0;
2338 struct mtd_erase_region_info *region = NULL;
2339 loff_t region_offset = 0;
2340
2341 pr_debug("%s: start=0x%012llx, len=%llu\n", __func__,
2342 (unsigned long long)instr->addr,
2343 (unsigned long long)instr->len);
2344
2345 if (FLEXONENAND(this)) {
2346
2347 int i = flexonenand_region(mtd, addr);
2348
2349 region = &mtd->eraseregions[i];
2350 block_size = region->erasesize;
2351
2352
2353
2354
2355 region_offset = region->offset;
2356 } else
2357 block_size = 1 << this->erase_shift;
2358
2359
2360 if (unlikely((addr - region_offset) & (block_size - 1))) {
2361 printk(KERN_ERR "%s: Unaligned address\n", __func__);
2362 return -EINVAL;
2363 }
2364
2365
2366 if (unlikely(len & (block_size - 1))) {
2367 printk(KERN_ERR "%s: Length not block aligned\n", __func__);
2368 return -EINVAL;
2369 }
2370
2371
2372 onenand_get_device(mtd, FL_ERASING);
2373
2374 if (ONENAND_IS_4KB_PAGE(this) || region ||
2375 instr->len < MB_ERASE_MIN_BLK_COUNT * block_size) {
2376
2377 ret = onenand_block_by_block_erase(mtd, instr,
2378 region, block_size);
2379 } else {
2380 ret = onenand_multiblock_erase(mtd, instr, block_size);
2381 }
2382
2383
2384 onenand_release_device(mtd);
2385
2386 return ret;
2387}
2388
2389
2390
2391
2392
2393
2394
2395static void onenand_sync(struct mtd_info *mtd)
2396{
2397 pr_debug("%s: called\n", __func__);
2398
2399
2400 onenand_get_device(mtd, FL_SYNCING);
2401
2402
2403 onenand_release_device(mtd);
2404}
2405
2406
2407
2408
2409
2410
2411
2412
2413static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
2414{
2415 int ret;
2416
2417 onenand_get_device(mtd, FL_READING);
2418 ret = onenand_block_isbad_nolock(mtd, ofs, 0);
2419 onenand_release_device(mtd);
2420 return ret;
2421}
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
2432{
2433 struct onenand_chip *this = mtd->priv;
2434 struct bbm_info *bbm = this->bbm;
2435 u_char buf[2] = {0, 0};
2436 struct mtd_oob_ops ops = {
2437 .mode = MTD_OPS_PLACE_OOB,
2438 .ooblen = 2,
2439 .oobbuf = buf,
2440 .ooboffs = 0,
2441 };
2442 int block;
2443
2444
2445 block = onenand_block(this, ofs);
2446 if (bbm->bbt)
2447 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
2448
2449
2450 ofs += mtd->oobsize + (this->badblockpos & ~0x01);
2451
2452
2453
2454
2455 return onenand_write_oob_nolock(mtd, ofs, &ops);
2456}
2457
2458
2459
2460
2461
2462
2463
2464
2465static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
2466{
2467 struct onenand_chip *this = mtd->priv;
2468 int ret;
2469
2470 ret = onenand_block_isbad(mtd, ofs);
2471 if (ret) {
2472
2473 if (ret > 0)
2474 return 0;
2475 return ret;
2476 }
2477
2478 onenand_get_device(mtd, FL_WRITING);
2479 ret = this->block_markbad(mtd, ofs);
2480 onenand_release_device(mtd);
2481 return ret;
2482}
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
2494{
2495 struct onenand_chip *this = mtd->priv;
2496 int start, end, block, value, status;
2497 int wp_status_mask;
2498
2499 start = onenand_block(this, ofs);
2500 end = onenand_block(this, ofs + len) - 1;
2501
2502 if (cmd == ONENAND_CMD_LOCK)
2503 wp_status_mask = ONENAND_WP_LS;
2504 else
2505 wp_status_mask = ONENAND_WP_US;
2506
2507
2508 if (this->options & ONENAND_HAS_CONT_LOCK) {
2509
2510 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2511
2512 this->write_word(end, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
2513
2514 this->command(mtd, cmd, 0, 0);
2515
2516
2517 this->wait(mtd, FL_LOCKING);
2518
2519
2520 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2521 & ONENAND_CTRL_ONGO)
2522 continue;
2523
2524
2525 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2526 if (!(status & wp_status_mask))
2527 printk(KERN_ERR "%s: wp status = 0x%x\n",
2528 __func__, status);
2529
2530 return 0;
2531 }
2532
2533
2534 for (block = start; block < end + 1; block++) {
2535
2536 value = onenand_block_address(this, block);
2537 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
2538
2539 value = onenand_bufferram_address(this, block);
2540 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
2541
2542 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2543
2544 this->command(mtd, cmd, 0, 0);
2545
2546
2547 this->wait(mtd, FL_LOCKING);
2548
2549
2550 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2551 & ONENAND_CTRL_ONGO)
2552 continue;
2553
2554
2555 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2556 if (!(status & wp_status_mask))
2557 printk(KERN_ERR "%s: block = %d, wp status = 0x%x\n",
2558 __func__, block, status);
2559 }
2560
2561 return 0;
2562}
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572static int onenand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
2573{
2574 int ret;
2575
2576 onenand_get_device(mtd, FL_LOCKING);
2577 ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
2578 onenand_release_device(mtd);
2579 return ret;
2580}
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
2591{
2592 int ret;
2593
2594 onenand_get_device(mtd, FL_LOCKING);
2595 ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2596 onenand_release_device(mtd);
2597 return ret;
2598}
2599
2600
2601
2602
2603
2604
2605
2606static int onenand_check_lock_status(struct onenand_chip *this)
2607{
2608 unsigned int value, block, status;
2609 unsigned int end;
2610
2611 end = this->chipsize >> this->erase_shift;
2612 for (block = 0; block < end; block++) {
2613
2614 value = onenand_block_address(this, block);
2615 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
2616
2617 value = onenand_bufferram_address(this, block);
2618 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
2619
2620 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2621
2622
2623 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2624 if (!(status & ONENAND_WP_US)) {
2625 printk(KERN_ERR "%s: block = %d, wp status = 0x%x\n",
2626 __func__, block, status);
2627 return 0;
2628 }
2629 }
2630
2631 return 1;
2632}
2633
2634
2635
2636
2637
2638
2639
2640static void onenand_unlock_all(struct mtd_info *mtd)
2641{
2642 struct onenand_chip *this = mtd->priv;
2643 loff_t ofs = 0;
2644 loff_t len = mtd->size;
2645
2646 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
2647
2648 this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2649
2650 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
2651
2652
2653 this->wait(mtd, FL_LOCKING);
2654
2655
2656 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2657 & ONENAND_CTRL_ONGO)
2658 continue;
2659
2660
2661 if (this->options & ONENAND_SKIP_UNLOCK_CHECK)
2662 return;
2663
2664
2665 if (onenand_check_lock_status(this))
2666 return;
2667
2668
2669 if (ONENAND_IS_DDP(this) && !FLEXONENAND(this)) {
2670
2671 ofs = this->chipsize >> 1;
2672 len = this->chipsize >> 1;
2673 }
2674 }
2675
2676 onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2677}
2678
2679#ifdef CONFIG_MTD_ONENAND_OTP
2680
2681
2682
2683
2684
2685
2686
2687
2688static int onenand_otp_command(struct mtd_info *mtd, int cmd, loff_t addr,
2689 size_t len)
2690{
2691 struct onenand_chip *this = mtd->priv;
2692 int value, block, page;
2693
2694
2695 switch (cmd) {
2696 case ONENAND_CMD_OTP_ACCESS:
2697 block = (int) (addr >> this->erase_shift);
2698 page = -1;
2699 break;
2700
2701 default:
2702 block = (int) (addr >> this->erase_shift);
2703 page = (int) (addr >> this->page_shift);
2704
2705 if (ONENAND_IS_2PLANE(this)) {
2706
2707 block &= ~1;
2708
2709 if (addr & this->writesize)
2710 block++;
2711 page >>= 1;
2712 }
2713 page &= this->page_mask;
2714 break;
2715 }
2716
2717 if (block != -1) {
2718
2719 value = onenand_block_address(this, block);
2720 this->write_word(value, this->base +
2721 ONENAND_REG_START_ADDRESS1);
2722 }
2723
2724 if (page != -1) {
2725
2726 int sectors = 4, count = 4;
2727 int dataram;
2728
2729 switch (cmd) {
2730 default:
2731 if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG)
2732 cmd = ONENAND_CMD_2X_PROG;
2733 dataram = ONENAND_CURRENT_BUFFERRAM(this);
2734 break;
2735 }
2736
2737
2738 value = onenand_page_address(page, sectors);
2739 this->write_word(value, this->base +
2740 ONENAND_REG_START_ADDRESS8);
2741
2742
2743 value = onenand_buffer_address(dataram, sectors, count);
2744 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
2745 }
2746
2747
2748 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
2749
2750
2751 this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
2752
2753 return 0;
2754}
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764static int onenand_otp_write_oob_nolock(struct mtd_info *mtd, loff_t to,
2765 struct mtd_oob_ops *ops)
2766{
2767 struct onenand_chip *this = mtd->priv;
2768 int column, ret = 0, oobsize;
2769 int written = 0;
2770 u_char *oobbuf;
2771 size_t len = ops->ooblen;
2772 const u_char *buf = ops->oobbuf;
2773 int block, value, status;
2774
2775 to += ops->ooboffs;
2776
2777
2778 ops->oobretlen = 0;
2779
2780 oobsize = mtd->oobsize;
2781
2782 column = to & (mtd->oobsize - 1);
2783
2784 oobbuf = this->oob_buf;
2785
2786
2787 while (written < len) {
2788 int thislen = min_t(int, oobsize, len - written);
2789
2790 cond_resched();
2791
2792 block = (int) (to >> this->erase_shift);
2793
2794
2795
2796
2797
2798 value = onenand_block_address(this, block);
2799 this->write_word(value, this->base +
2800 ONENAND_REG_START_ADDRESS1);
2801
2802
2803
2804
2805
2806
2807 value = onenand_bufferram_address(this, block);
2808 this->write_word(value, this->base +
2809 ONENAND_REG_START_ADDRESS2);
2810 ONENAND_SET_NEXT_BUFFERRAM(this);
2811
2812
2813
2814
2815 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2816 this->wait(mtd, FL_OTPING);
2817
2818
2819
2820 memcpy(oobbuf + column, buf, thislen);
2821
2822
2823
2824
2825
2826
2827
2828 this->write_bufferram(mtd, ONENAND_SPARERAM,
2829 oobbuf, 0, mtd->oobsize);
2830
2831 onenand_otp_command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
2832 onenand_update_bufferram(mtd, to, 0);
2833 if (ONENAND_IS_2PLANE(this)) {
2834 ONENAND_SET_BUFFERRAM1(this);
2835 onenand_update_bufferram(mtd, to + this->writesize, 0);
2836 }
2837
2838 ret = this->wait(mtd, FL_WRITING);
2839 if (ret) {
2840 printk(KERN_ERR "%s: write failed %d\n", __func__, ret);
2841 break;
2842 }
2843
2844
2845 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
2846 this->wait(mtd, FL_RESETTING);
2847
2848 status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
2849 status &= 0x60;
2850
2851 if (status == 0x60) {
2852 printk(KERN_DEBUG "\nBLOCK\tSTATUS\n");
2853 printk(KERN_DEBUG "1st Block\tLOCKED\n");
2854 printk(KERN_DEBUG "OTP Block\tLOCKED\n");
2855 } else if (status == 0x20) {
2856 printk(KERN_DEBUG "\nBLOCK\tSTATUS\n");
2857 printk(KERN_DEBUG "1st Block\tLOCKED\n");
2858 printk(KERN_DEBUG "OTP Block\tUN-LOCKED\n");
2859 } else if (status == 0x40) {
2860 printk(KERN_DEBUG "\nBLOCK\tSTATUS\n");
2861 printk(KERN_DEBUG "1st Block\tUN-LOCKED\n");
2862 printk(KERN_DEBUG "OTP Block\tLOCKED\n");
2863 } else {
2864 printk(KERN_DEBUG "Reboot to check\n");
2865 }
2866
2867 written += thislen;
2868 if (written == len)
2869 break;
2870
2871 to += mtd->writesize;
2872 buf += thislen;
2873 column = 0;
2874 }
2875
2876 ops->oobretlen = written;
2877
2878 return ret;
2879}
2880
2881
2882typedef int (*otp_op_t)(struct mtd_info *mtd, loff_t form, size_t len,
2883 size_t *retlen, u_char *buf);
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
2896 size_t *retlen, u_char *buf)
2897{
2898 struct onenand_chip *this = mtd->priv;
2899 struct mtd_oob_ops ops = {
2900 .len = len,
2901 .ooblen = 0,
2902 .datbuf = buf,
2903 .oobbuf = NULL,
2904 };
2905 int ret;
2906
2907
2908 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2909 this->wait(mtd, FL_OTPING);
2910
2911 ret = ONENAND_IS_4KB_PAGE(this) ?
2912 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
2913 onenand_read_ops_nolock(mtd, from, &ops);
2914
2915
2916 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
2917 this->wait(mtd, FL_RESETTING);
2918
2919 return ret;
2920}
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932static int do_otp_write(struct mtd_info *mtd, loff_t to, size_t len,
2933 size_t *retlen, u_char *buf)
2934{
2935 struct onenand_chip *this = mtd->priv;
2936 unsigned char *pbuf = buf;
2937 int ret;
2938 struct mtd_oob_ops ops;
2939
2940
2941 if (len < mtd->writesize) {
2942 memcpy(this->page_buf, buf, len);
2943 memset(this->page_buf + len, 0xff, mtd->writesize - len);
2944 pbuf = this->page_buf;
2945 len = mtd->writesize;
2946 }
2947
2948
2949 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2950 this->wait(mtd, FL_OTPING);
2951
2952 ops.len = len;
2953 ops.ooblen = 0;
2954 ops.datbuf = pbuf;
2955 ops.oobbuf = NULL;
2956 ret = onenand_write_ops_nolock(mtd, to, &ops);
2957 *retlen = ops.retlen;
2958
2959
2960 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
2961 this->wait(mtd, FL_RESETTING);
2962
2963 return ret;
2964}
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
2977 size_t *retlen, u_char *buf)
2978{
2979 struct onenand_chip *this = mtd->priv;
2980 struct mtd_oob_ops ops;
2981 int ret;
2982
2983 if (FLEXONENAND(this)) {
2984
2985
2986 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2987 this->wait(mtd, FL_OTPING);
2988
2989
2990
2991
2992 ops.len = mtd->writesize;
2993 ops.ooblen = 0;
2994 ops.datbuf = buf;
2995 ops.oobbuf = NULL;
2996 ret = onenand_write_ops_nolock(mtd, mtd->writesize * 49, &ops);
2997 *retlen = ops.retlen;
2998
2999
3000 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
3001 this->wait(mtd, FL_RESETTING);
3002 } else {
3003 ops.mode = MTD_OPS_PLACE_OOB;
3004 ops.ooblen = len;
3005 ops.oobbuf = buf;
3006 ops.ooboffs = 0;
3007 ret = onenand_otp_write_oob_nolock(mtd, from, &ops);
3008 *retlen = ops.oobretlen;
3009 }
3010
3011 return ret;
3012}
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
3027 size_t *retlen, u_char *buf,
3028 otp_op_t action, int mode)
3029{
3030 struct onenand_chip *this = mtd->priv;
3031 int otp_pages;
3032 int density;
3033 int ret = 0;
3034
3035 *retlen = 0;
3036
3037 density = onenand_get_density(this->device_id);
3038 if (density < ONENAND_DEVICE_DENSITY_512Mb)
3039 otp_pages = 20;
3040 else
3041 otp_pages = 50;
3042
3043 if (mode == MTD_OTP_FACTORY) {
3044 from += mtd->writesize * otp_pages;
3045 otp_pages = ONENAND_PAGES_PER_BLOCK - otp_pages;
3046 }
3047
3048
3049 if (mode == MTD_OTP_USER) {
3050 if (mtd->writesize * otp_pages < from + len)
3051 return 0;
3052 } else {
3053 if (mtd->writesize * otp_pages < len)
3054 return 0;
3055 }
3056
3057 onenand_get_device(mtd, FL_OTPING);
3058 while (len > 0 && otp_pages > 0) {
3059 if (!action) {
3060 struct otp_info *otpinfo;
3061
3062 len -= sizeof(struct otp_info);
3063 if (len <= 0) {
3064 ret = -ENOSPC;
3065 break;
3066 }
3067
3068 otpinfo = (struct otp_info *) buf;
3069 otpinfo->start = from;
3070 otpinfo->length = mtd->writesize;
3071 otpinfo->locked = 0;
3072
3073 from += mtd->writesize;
3074 buf += sizeof(struct otp_info);
3075 *retlen += sizeof(struct otp_info);
3076 } else {
3077 size_t tmp_retlen;
3078
3079 ret = action(mtd, from, len, &tmp_retlen, buf);
3080 if (ret)
3081 break;
3082
3083 buf += tmp_retlen;
3084 len -= tmp_retlen;
3085 *retlen += tmp_retlen;
3086
3087 }
3088 otp_pages--;
3089 }
3090 onenand_release_device(mtd);
3091
3092 return ret;
3093}
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104static int onenand_get_fact_prot_info(struct mtd_info *mtd, size_t len,
3105 size_t *retlen, struct otp_info *buf)
3106{
3107 return onenand_otp_walk(mtd, 0, len, retlen, (u_char *) buf, NULL,
3108 MTD_OTP_FACTORY);
3109}
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121static int onenand_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
3122 size_t len, size_t *retlen, u_char *buf)
3123{
3124 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_FACTORY);
3125}
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136static int onenand_get_user_prot_info(struct mtd_info *mtd, size_t len,
3137 size_t *retlen, struct otp_info *buf)
3138{
3139 return onenand_otp_walk(mtd, 0, len, retlen, (u_char *) buf, NULL,
3140 MTD_OTP_USER);
3141}
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153static int onenand_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
3154 size_t len, size_t *retlen, u_char *buf)
3155{
3156 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_USER);
3157}
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
3170 size_t len, size_t *retlen, const u_char *buf)
3171{
3172 return onenand_otp_walk(mtd, from, len, retlen, (u_char *)buf,
3173 do_otp_write, MTD_OTP_USER);
3174}
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
3185 size_t len)
3186{
3187 struct onenand_chip *this = mtd->priv;
3188 u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf;
3189 size_t retlen;
3190 int ret;
3191 unsigned int otp_lock_offset = ONENAND_OTP_LOCK_OFFSET;
3192
3193 memset(buf, 0xff, FLEXONENAND(this) ? this->writesize
3194 : mtd->oobsize);
3195
3196
3197
3198
3199
3200
3201
3202 from = 0;
3203 len = FLEXONENAND(this) ? mtd->writesize : 16;
3204
3205
3206
3207
3208
3209
3210
3211 if (FLEXONENAND(this))
3212 otp_lock_offset = FLEXONENAND_OTP_LOCK_OFFSET;
3213
3214
3215 if (otp == 1)
3216 buf[otp_lock_offset] = 0xFC;
3217 else if (otp == 2)
3218 buf[otp_lock_offset] = 0xF3;
3219 else if (otp == 3)
3220 buf[otp_lock_offset] = 0xF0;
3221 else if (otp != 0)
3222 printk(KERN_DEBUG "[OneNAND] Invalid option selected for OTP\n");
3223
3224 ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER);
3225
3226 return ret ? : retlen;
3227}
3228
3229#endif
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239static void onenand_check_features(struct mtd_info *mtd)
3240{
3241 struct onenand_chip *this = mtd->priv;
3242 unsigned int density, process, numbufs;
3243
3244
3245 density = onenand_get_density(this->device_id);
3246 process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
3247 numbufs = this->read_word(this->base + ONENAND_REG_NUM_BUFFERS) >> 8;
3248
3249
3250 switch (density) {
3251 case ONENAND_DEVICE_DENSITY_8Gb:
3252 this->options |= ONENAND_HAS_NOP_1;
3253 fallthrough;
3254 case ONENAND_DEVICE_DENSITY_4Gb:
3255 if (ONENAND_IS_DDP(this))
3256 this->options |= ONENAND_HAS_2PLANE;
3257 else if (numbufs == 1) {
3258 this->options |= ONENAND_HAS_4KB_PAGE;
3259 this->options |= ONENAND_HAS_CACHE_PROGRAM;
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271 if ((this->version_id & 0xf) == 0xe)
3272 this->options |= ONENAND_HAS_NOP_1;
3273 }
3274 this->options |= ONENAND_HAS_UNLOCK_ALL;
3275 break;
3276
3277 case ONENAND_DEVICE_DENSITY_2Gb:
3278
3279 if (!ONENAND_IS_DDP(this))
3280 this->options |= ONENAND_HAS_2PLANE;
3281 this->options |= ONENAND_HAS_UNLOCK_ALL;
3282 break;
3283
3284 case ONENAND_DEVICE_DENSITY_1Gb:
3285
3286 if (process)
3287 this->options |= ONENAND_HAS_UNLOCK_ALL;
3288 break;
3289
3290 default:
3291
3292 if (!process)
3293 this->options |= ONENAND_HAS_CONT_LOCK;
3294 break;
3295 }
3296
3297
3298 if (ONENAND_IS_MLC(this))
3299 this->options |= ONENAND_HAS_4KB_PAGE;
3300
3301 if (ONENAND_IS_4KB_PAGE(this))
3302 this->options &= ~ONENAND_HAS_2PLANE;
3303
3304 if (FLEXONENAND(this)) {
3305 this->options &= ~ONENAND_HAS_CONT_LOCK;
3306 this->options |= ONENAND_HAS_UNLOCK_ALL;
3307 }
3308
3309 if (this->options & ONENAND_HAS_CONT_LOCK)
3310 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
3311 if (this->options & ONENAND_HAS_UNLOCK_ALL)
3312 printk(KERN_DEBUG "Chip support all block unlock\n");
3313 if (this->options & ONENAND_HAS_2PLANE)
3314 printk(KERN_DEBUG "Chip has 2 plane\n");
3315 if (this->options & ONENAND_HAS_4KB_PAGE)
3316 printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
3317 if (this->options & ONENAND_HAS_CACHE_PROGRAM)
3318 printk(KERN_DEBUG "Chip has cache program feature\n");
3319}
3320
3321
3322
3323
3324
3325
3326
3327
3328static void onenand_print_device_info(int device, int version)
3329{
3330 int vcc, demuxed, ddp, density, flexonenand;
3331
3332 vcc = device & ONENAND_DEVICE_VCC_MASK;
3333 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
3334 ddp = device & ONENAND_DEVICE_IS_DDP;
3335 density = onenand_get_density(device);
3336 flexonenand = device & DEVICE_IS_FLEXONENAND;
3337 printk(KERN_INFO "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
3338 demuxed ? "" : "Muxed ",
3339 flexonenand ? "Flex-" : "",
3340 ddp ? "(DDP)" : "",
3341 (16 << density),
3342 vcc ? "2.65/3.3" : "1.8",
3343 device);
3344 printk(KERN_INFO "OneNAND version = 0x%04x\n", version);
3345}
3346
3347static const struct onenand_manufacturers onenand_manuf_ids[] = {
3348 {ONENAND_MFR_SAMSUNG, "Samsung"},
3349 {ONENAND_MFR_NUMONYX, "Numonyx"},
3350};
3351
3352
3353
3354
3355
3356
3357
3358static int onenand_check_maf(int manuf)
3359{
3360 int size = ARRAY_SIZE(onenand_manuf_ids);
3361 char *name;
3362 int i;
3363
3364 for (i = 0; i < size; i++)
3365 if (manuf == onenand_manuf_ids[i].id)
3366 break;
3367
3368 if (i < size)
3369 name = onenand_manuf_ids[i].name;
3370 else
3371 name = "Unknown";
3372
3373 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
3374
3375 return (i == size);
3376}
3377
3378
3379
3380
3381
3382static int flexonenand_get_boundary(struct mtd_info *mtd)
3383{
3384 struct onenand_chip *this = mtd->priv;
3385 unsigned die, bdry;
3386 int syscfg, locked;
3387
3388
3389 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
3390 this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1);
3391
3392 for (die = 0; die < this->dies; die++) {
3393 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3394 this->wait(mtd, FL_SYNCING);
3395
3396 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3397 this->wait(mtd, FL_READING);
3398
3399 bdry = this->read_word(this->base + ONENAND_DATARAM);
3400 if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
3401 locked = 0;
3402 else
3403 locked = 1;
3404 this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
3405
3406 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
3407 this->wait(mtd, FL_RESETTING);
3408
3409 printk(KERN_INFO "Die %d boundary: %d%s\n", die,
3410 this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
3411 }
3412
3413
3414 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
3415 return 0;
3416}
3417
3418
3419
3420
3421
3422
3423static void flexonenand_get_size(struct mtd_info *mtd)
3424{
3425 struct onenand_chip *this = mtd->priv;
3426 int die, i, eraseshift, density;
3427 int blksperdie, maxbdry;
3428 loff_t ofs;
3429
3430 density = onenand_get_density(this->device_id);
3431 blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift);
3432 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3433 maxbdry = blksperdie - 1;
3434 eraseshift = this->erase_shift - 1;
3435
3436 mtd->numeraseregions = this->dies << 1;
3437
3438
3439 flexonenand_get_boundary(mtd);
3440 die = ofs = 0;
3441 i = -1;
3442 for (; die < this->dies; die++) {
3443 if (!die || this->boundary[die-1] != maxbdry) {
3444 i++;
3445 mtd->eraseregions[i].offset = ofs;
3446 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3447 mtd->eraseregions[i].numblocks =
3448 this->boundary[die] + 1;
3449 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3450 eraseshift++;
3451 } else {
3452 mtd->numeraseregions -= 1;
3453 mtd->eraseregions[i].numblocks +=
3454 this->boundary[die] + 1;
3455 ofs += (this->boundary[die] + 1) << (eraseshift - 1);
3456 }
3457 if (this->boundary[die] != maxbdry) {
3458 i++;
3459 mtd->eraseregions[i].offset = ofs;
3460 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3461 mtd->eraseregions[i].numblocks = maxbdry ^
3462 this->boundary[die];
3463 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3464 eraseshift--;
3465 } else
3466 mtd->numeraseregions -= 1;
3467 }
3468
3469
3470 mtd->erasesize = 1 << this->erase_shift;
3471 if (mtd->numeraseregions == 1)
3472 mtd->erasesize >>= 1;
3473
3474 printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions);
3475 for (i = 0; i < mtd->numeraseregions; i++)
3476 printk(KERN_INFO "[offset: 0x%08x, erasesize: 0x%05x,"
3477 " numblocks: %04u]\n",
3478 (unsigned int) mtd->eraseregions[i].offset,
3479 mtd->eraseregions[i].erasesize,
3480 mtd->eraseregions[i].numblocks);
3481
3482 for (die = 0, mtd->size = 0; die < this->dies; die++) {
3483 this->diesize[die] = (loff_t)blksperdie << this->erase_shift;
3484 this->diesize[die] -= (loff_t)(this->boundary[die] + 1)
3485 << (this->erase_shift - 1);
3486 mtd->size += this->diesize[die];
3487 }
3488}
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int end)
3505{
3506 struct onenand_chip *this = mtd->priv;
3507 int i, ret;
3508 int block;
3509 struct mtd_oob_ops ops = {
3510 .mode = MTD_OPS_PLACE_OOB,
3511 .ooboffs = 0,
3512 .ooblen = mtd->oobsize,
3513 .datbuf = NULL,
3514 .oobbuf = this->oob_buf,
3515 };
3516 loff_t addr;
3517
3518 printk(KERN_DEBUG "Check blocks from %d to %d\n", start, end);
3519
3520 for (block = start; block <= end; block++) {
3521 addr = flexonenand_addr(this, block);
3522 if (onenand_block_isbad_nolock(mtd, addr, 0))
3523 continue;
3524
3525
3526
3527
3528
3529 ret = onenand_read_oob_nolock(mtd, addr, &ops);
3530 if (ret)
3531 return ret;
3532
3533 for (i = 0; i < mtd->oobsize; i++)
3534 if (this->oob_buf[i] != 0xff)
3535 break;
3536
3537 if (i != mtd->oobsize) {
3538 printk(KERN_WARNING "%s: Block %d not erased.\n",
3539 __func__, block);
3540 return 1;
3541 }
3542 }
3543
3544 return 0;
3545}
3546
3547
3548
3549
3550static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
3551 int boundary, int lock)
3552{
3553 struct onenand_chip *this = mtd->priv;
3554 int ret, density, blksperdie, old, new, thisboundary;
3555 loff_t addr;
3556
3557
3558 if (die && (!ONENAND_IS_DDP(this)))
3559 return 0;
3560
3561
3562 if (boundary < 0 || boundary == this->boundary[die])
3563 return 0;
3564
3565 density = onenand_get_density(this->device_id);
3566 blksperdie = ((16 << density) << 20) >> this->erase_shift;
3567 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3568
3569 if (boundary >= blksperdie) {
3570 printk(KERN_ERR "%s: Invalid boundary value. "
3571 "Boundary not changed.\n", __func__);
3572 return -EINVAL;
3573 }
3574
3575
3576 old = this->boundary[die] + (die * this->density_mask);
3577 new = boundary + (die * this->density_mask);
3578 ret = flexonenand_check_blocks_erased(mtd, min(old, new) + 1, max(old, new));
3579 if (ret) {
3580 printk(KERN_ERR "%s: Please erase blocks "
3581 "before boundary change\n", __func__);
3582 return ret;
3583 }
3584
3585 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3586 this->wait(mtd, FL_SYNCING);
3587
3588
3589 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3590 this->wait(mtd, FL_READING);
3591
3592 thisboundary = this->read_word(this->base + ONENAND_DATARAM);
3593 if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
3594 printk(KERN_ERR "%s: boundary locked\n", __func__);
3595 ret = 1;
3596 goto out;
3597 }
3598
3599 printk(KERN_INFO "Changing die %d boundary: %d%s\n",
3600 die, boundary, lock ? "(Locked)" : "(Unlocked)");
3601
3602 addr = die ? this->diesize[0] : 0;
3603
3604 boundary &= FLEXONENAND_PI_MASK;
3605 boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT);
3606
3607 this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
3608 ret = this->wait(mtd, FL_ERASING);
3609 if (ret) {
3610 printk(KERN_ERR "%s: Failed PI erase for Die %d\n",
3611 __func__, die);
3612 goto out;
3613 }
3614
3615 this->write_word(boundary, this->base + ONENAND_DATARAM);
3616 this->command(mtd, ONENAND_CMD_PROG, addr, 0);
3617 ret = this->wait(mtd, FL_WRITING);
3618 if (ret) {
3619 printk(KERN_ERR "%s: Failed PI write for Die %d\n",
3620 __func__, die);
3621 goto out;
3622 }
3623
3624 this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0);
3625 ret = this->wait(mtd, FL_WRITING);
3626out:
3627 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND);
3628 this->wait(mtd, FL_RESETTING);
3629 if (!ret)
3630
3631 flexonenand_get_size(mtd);
3632
3633 return ret;
3634}
3635
3636
3637
3638
3639
3640
3641
3642
3643static int onenand_chip_probe(struct mtd_info *mtd)
3644{
3645 struct onenand_chip *this = mtd->priv;
3646 int bram_maf_id, bram_dev_id, maf_id, dev_id;
3647 int syscfg;
3648
3649
3650 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
3651
3652 this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE), this->base + ONENAND_REG_SYS_CFG1);
3653
3654
3655 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
3656
3657
3658 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
3659 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
3660
3661
3662 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
3663
3664 this->wait(mtd, FL_RESETTING);
3665
3666
3667 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
3668
3669
3670 if (onenand_check_maf(bram_maf_id))
3671 return -ENXIO;
3672
3673
3674 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
3675 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
3676
3677
3678 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
3679 return -ENXIO;
3680
3681 return 0;
3682}
3683
3684
3685
3686
3687
3688static int onenand_probe(struct mtd_info *mtd)
3689{
3690 struct onenand_chip *this = mtd->priv;
3691 int dev_id, ver_id;
3692 int density;
3693 int ret;
3694
3695 ret = this->chip_probe(mtd);
3696 if (ret)
3697 return ret;
3698
3699
3700 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
3701 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
3702 this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
3703
3704
3705 onenand_print_device_info(dev_id, ver_id);
3706 this->device_id = dev_id;
3707 this->version_id = ver_id;
3708
3709
3710 onenand_check_features(mtd);
3711
3712 density = onenand_get_density(dev_id);
3713 if (FLEXONENAND(this)) {
3714 this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
3715
3716 mtd->numeraseregions = this->dies << 1;
3717 mtd->eraseregions =
3718 kcalloc(this->dies << 1,
3719 sizeof(struct mtd_erase_region_info),
3720 GFP_KERNEL);
3721 if (!mtd->eraseregions)
3722 return -ENOMEM;
3723 }
3724
3725
3726
3727
3728
3729 this->chipsize = (16 << density) << 20;
3730
3731
3732
3733 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
3734
3735 if (ONENAND_IS_4KB_PAGE(this))
3736 mtd->writesize <<= 1;
3737
3738 mtd->oobsize = mtd->writesize >> 5;
3739
3740 mtd->erasesize = mtd->writesize << 6;
3741
3742
3743
3744
3745
3746 if (FLEXONENAND(this))
3747 mtd->erasesize <<= 1;
3748
3749 this->erase_shift = ffs(mtd->erasesize) - 1;
3750 this->page_shift = ffs(mtd->writesize) - 1;
3751 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
3752
3753 if (ONENAND_IS_DDP(this))
3754 this->density_mask = this->chipsize >> (this->erase_shift + 1);
3755
3756 this->writesize = mtd->writesize;
3757
3758
3759
3760 if (FLEXONENAND(this))
3761 flexonenand_get_size(mtd);
3762 else
3763 mtd->size = this->chipsize;
3764
3765
3766
3767
3768
3769
3770
3771 if (ONENAND_IS_2PLANE(this)) {
3772 mtd->writesize <<= 1;
3773 mtd->erasesize <<= 1;
3774 }
3775
3776 return 0;
3777}
3778
3779
3780
3781
3782
3783static int onenand_suspend(struct mtd_info *mtd)
3784{
3785 return onenand_get_device(mtd, FL_PM_SUSPENDED);
3786}
3787
3788
3789
3790
3791
3792static void onenand_resume(struct mtd_info *mtd)
3793{
3794 struct onenand_chip *this = mtd->priv;
3795
3796 if (this->state == FL_PM_SUSPENDED)
3797 onenand_release_device(mtd);
3798 else
3799 printk(KERN_ERR "%s: resume() called for the chip which is not "
3800 "in suspended state\n", __func__);
3801}
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813int onenand_scan(struct mtd_info *mtd, int maxchips)
3814{
3815 int i, ret;
3816 struct onenand_chip *this = mtd->priv;
3817
3818 if (!this->read_word)
3819 this->read_word = onenand_readw;
3820 if (!this->write_word)
3821 this->write_word = onenand_writew;
3822
3823 if (!this->command)
3824 this->command = onenand_command;
3825 if (!this->wait)
3826 onenand_setup_wait(mtd);
3827 if (!this->bbt_wait)
3828 this->bbt_wait = onenand_bbt_wait;
3829 if (!this->unlock_all)
3830 this->unlock_all = onenand_unlock_all;
3831
3832 if (!this->chip_probe)
3833 this->chip_probe = onenand_chip_probe;
3834
3835 if (!this->read_bufferram)
3836 this->read_bufferram = onenand_read_bufferram;
3837 if (!this->write_bufferram)
3838 this->write_bufferram = onenand_write_bufferram;
3839
3840 if (!this->block_markbad)
3841 this->block_markbad = onenand_default_block_markbad;
3842 if (!this->scan_bbt)
3843 this->scan_bbt = onenand_default_bbt;
3844
3845 if (onenand_probe(mtd))
3846 return -ENXIO;
3847
3848
3849 if (this->mmcontrol) {
3850 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
3851 this->read_bufferram = onenand_sync_read_bufferram;
3852 }
3853
3854
3855 if (!this->page_buf) {
3856 this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
3857 if (!this->page_buf)
3858 return -ENOMEM;
3859#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
3860 this->verify_buf = kzalloc(mtd->writesize, GFP_KERNEL);
3861 if (!this->verify_buf) {
3862 kfree(this->page_buf);
3863 return -ENOMEM;
3864 }
3865#endif
3866 this->options |= ONENAND_PAGEBUF_ALLOC;
3867 }
3868 if (!this->oob_buf) {
3869 this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
3870 if (!this->oob_buf) {
3871 if (this->options & ONENAND_PAGEBUF_ALLOC) {
3872 this->options &= ~ONENAND_PAGEBUF_ALLOC;
3873#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
3874 kfree(this->verify_buf);
3875#endif
3876 kfree(this->page_buf);
3877 }
3878 return -ENOMEM;
3879 }
3880 this->options |= ONENAND_OOBBUF_ALLOC;
3881 }
3882
3883 this->state = FL_READY;
3884 init_waitqueue_head(&this->wq);
3885 spin_lock_init(&this->chip_lock);
3886
3887
3888
3889
3890 switch (mtd->oobsize) {
3891 case 128:
3892 if (FLEXONENAND(this)) {
3893 mtd_set_ooblayout(mtd, &flexonenand_ooblayout_ops);
3894 mtd->subpage_sft = 0;
3895 } else {
3896 mtd_set_ooblayout(mtd, &onenand_oob_128_ooblayout_ops);
3897 mtd->subpage_sft = 2;
3898 }
3899 if (ONENAND_IS_NOP_1(this))
3900 mtd->subpage_sft = 0;
3901 break;
3902 case 64:
3903 mtd_set_ooblayout(mtd, &onenand_oob_32_64_ooblayout_ops);
3904 mtd->subpage_sft = 2;
3905 break;
3906
3907 case 32:
3908 mtd_set_ooblayout(mtd, &onenand_oob_32_64_ooblayout_ops);
3909 mtd->subpage_sft = 1;
3910 break;
3911
3912 default:
3913 printk(KERN_WARNING "%s: No OOB scheme defined for oobsize %d\n",
3914 __func__, mtd->oobsize);
3915 mtd->subpage_sft = 0;
3916
3917 mtd_set_ooblayout(mtd, &onenand_oob_32_64_ooblayout_ops);
3918 break;
3919 }
3920
3921 this->subpagesize = mtd->writesize >> mtd->subpage_sft;
3922
3923
3924
3925
3926
3927 ret = mtd_ooblayout_count_freebytes(mtd);
3928 if (ret < 0)
3929 ret = 0;
3930
3931 mtd->oobavail = ret;
3932
3933 mtd->ecc_strength = 1;
3934
3935
3936 mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH;
3937 mtd->flags = MTD_CAP_NANDFLASH;
3938 mtd->_erase = onenand_erase;
3939 mtd->_point = NULL;
3940 mtd->_unpoint = NULL;
3941 mtd->_read_oob = onenand_read_oob;
3942 mtd->_write_oob = onenand_write_oob;
3943 mtd->_panic_write = onenand_panic_write;
3944#ifdef CONFIG_MTD_ONENAND_OTP
3945 mtd->_get_fact_prot_info = onenand_get_fact_prot_info;
3946 mtd->_read_fact_prot_reg = onenand_read_fact_prot_reg;
3947 mtd->_get_user_prot_info = onenand_get_user_prot_info;
3948 mtd->_read_user_prot_reg = onenand_read_user_prot_reg;
3949 mtd->_write_user_prot_reg = onenand_write_user_prot_reg;
3950 mtd->_lock_user_prot_reg = onenand_lock_user_prot_reg;
3951#endif
3952 mtd->_sync = onenand_sync;
3953 mtd->_lock = onenand_lock;
3954 mtd->_unlock = onenand_unlock;
3955 mtd->_suspend = onenand_suspend;
3956 mtd->_resume = onenand_resume;
3957 mtd->_block_isbad = onenand_block_isbad;
3958 mtd->_block_markbad = onenand_block_markbad;
3959 mtd->owner = THIS_MODULE;
3960 mtd->writebufsize = mtd->writesize;
3961
3962
3963 if (!(this->options & ONENAND_SKIP_INITIAL_UNLOCKING))
3964 this->unlock_all(mtd);
3965
3966
3967 this->badblockpos = ONENAND_BADBLOCK_POS;
3968
3969 ret = this->scan_bbt(mtd);
3970 if ((!FLEXONENAND(this)) || ret)
3971 return ret;
3972
3973
3974 for (i = 0; i < MAX_DIES; i++)
3975 flexonenand_set_boundary(mtd, i, flex_bdry[2 * i],
3976 flex_bdry[(2 * i) + 1]);
3977
3978 return 0;
3979}
3980
3981
3982
3983
3984
3985void onenand_release(struct mtd_info *mtd)
3986{
3987 struct onenand_chip *this = mtd->priv;
3988
3989
3990 mtd_device_unregister(mtd);
3991
3992
3993 if (this->bbm) {
3994 struct bbm_info *bbm = this->bbm;
3995 kfree(bbm->bbt);
3996 kfree(this->bbm);
3997 }
3998
3999 if (this->options & ONENAND_PAGEBUF_ALLOC) {
4000 kfree(this->page_buf);
4001#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
4002 kfree(this->verify_buf);
4003#endif
4004 }
4005 if (this->options & ONENAND_OOBBUF_ALLOC)
4006 kfree(this->oob_buf);
4007 kfree(mtd->eraseregions);
4008}
4009
4010EXPORT_SYMBOL_GPL(onenand_scan);
4011EXPORT_SYMBOL_GPL(onenand_release);
4012
4013MODULE_LICENSE("GPL");
4014MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
4015MODULE_DESCRIPTION("Generic OneNAND flash driver code");
4016