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, u_char *buf)
3171{
3172 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, MTD_OTP_USER);
3173}
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
3184 size_t len)
3185{
3186 struct onenand_chip *this = mtd->priv;
3187 u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf;
3188 size_t retlen;
3189 int ret;
3190 unsigned int otp_lock_offset = ONENAND_OTP_LOCK_OFFSET;
3191
3192 memset(buf, 0xff, FLEXONENAND(this) ? this->writesize
3193 : mtd->oobsize);
3194
3195
3196
3197
3198
3199
3200
3201 from = 0;
3202 len = FLEXONENAND(this) ? mtd->writesize : 16;
3203
3204
3205
3206
3207
3208
3209
3210 if (FLEXONENAND(this))
3211 otp_lock_offset = FLEXONENAND_OTP_LOCK_OFFSET;
3212
3213
3214 if (otp == 1)
3215 buf[otp_lock_offset] = 0xFC;
3216 else if (otp == 2)
3217 buf[otp_lock_offset] = 0xF3;
3218 else if (otp == 3)
3219 buf[otp_lock_offset] = 0xF0;
3220 else if (otp != 0)
3221 printk(KERN_DEBUG "[OneNAND] Invalid option selected for OTP\n");
3222
3223 ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER);
3224
3225 return ret ? : retlen;
3226}
3227
3228#endif
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238static void onenand_check_features(struct mtd_info *mtd)
3239{
3240 struct onenand_chip *this = mtd->priv;
3241 unsigned int density, process, numbufs;
3242
3243
3244 density = onenand_get_density(this->device_id);
3245 process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
3246 numbufs = this->read_word(this->base + ONENAND_REG_NUM_BUFFERS) >> 8;
3247
3248
3249 switch (density) {
3250 case ONENAND_DEVICE_DENSITY_8Gb:
3251 this->options |= ONENAND_HAS_NOP_1;
3252 fallthrough;
3253 case ONENAND_DEVICE_DENSITY_4Gb:
3254 if (ONENAND_IS_DDP(this))
3255 this->options |= ONENAND_HAS_2PLANE;
3256 else if (numbufs == 1) {
3257 this->options |= ONENAND_HAS_4KB_PAGE;
3258 this->options |= ONENAND_HAS_CACHE_PROGRAM;
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270 if ((this->version_id & 0xf) == 0xe)
3271 this->options |= ONENAND_HAS_NOP_1;
3272 }
3273 this->options |= ONENAND_HAS_UNLOCK_ALL;
3274 break;
3275
3276 case ONENAND_DEVICE_DENSITY_2Gb:
3277
3278 if (!ONENAND_IS_DDP(this))
3279 this->options |= ONENAND_HAS_2PLANE;
3280 this->options |= ONENAND_HAS_UNLOCK_ALL;
3281 break;
3282
3283 case ONENAND_DEVICE_DENSITY_1Gb:
3284
3285 if (process)
3286 this->options |= ONENAND_HAS_UNLOCK_ALL;
3287 break;
3288
3289 default:
3290
3291 if (!process)
3292 this->options |= ONENAND_HAS_CONT_LOCK;
3293 break;
3294 }
3295
3296
3297 if (ONENAND_IS_MLC(this))
3298 this->options |= ONENAND_HAS_4KB_PAGE;
3299
3300 if (ONENAND_IS_4KB_PAGE(this))
3301 this->options &= ~ONENAND_HAS_2PLANE;
3302
3303 if (FLEXONENAND(this)) {
3304 this->options &= ~ONENAND_HAS_CONT_LOCK;
3305 this->options |= ONENAND_HAS_UNLOCK_ALL;
3306 }
3307
3308 if (this->options & ONENAND_HAS_CONT_LOCK)
3309 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
3310 if (this->options & ONENAND_HAS_UNLOCK_ALL)
3311 printk(KERN_DEBUG "Chip support all block unlock\n");
3312 if (this->options & ONENAND_HAS_2PLANE)
3313 printk(KERN_DEBUG "Chip has 2 plane\n");
3314 if (this->options & ONENAND_HAS_4KB_PAGE)
3315 printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
3316 if (this->options & ONENAND_HAS_CACHE_PROGRAM)
3317 printk(KERN_DEBUG "Chip has cache program feature\n");
3318}
3319
3320
3321
3322
3323
3324
3325
3326
3327static void onenand_print_device_info(int device, int version)
3328{
3329 int vcc, demuxed, ddp, density, flexonenand;
3330
3331 vcc = device & ONENAND_DEVICE_VCC_MASK;
3332 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
3333 ddp = device & ONENAND_DEVICE_IS_DDP;
3334 density = onenand_get_density(device);
3335 flexonenand = device & DEVICE_IS_FLEXONENAND;
3336 printk(KERN_INFO "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
3337 demuxed ? "" : "Muxed ",
3338 flexonenand ? "Flex-" : "",
3339 ddp ? "(DDP)" : "",
3340 (16 << density),
3341 vcc ? "2.65/3.3" : "1.8",
3342 device);
3343 printk(KERN_INFO "OneNAND version = 0x%04x\n", version);
3344}
3345
3346static const struct onenand_manufacturers onenand_manuf_ids[] = {
3347 {ONENAND_MFR_SAMSUNG, "Samsung"},
3348 {ONENAND_MFR_NUMONYX, "Numonyx"},
3349};
3350
3351
3352
3353
3354
3355
3356
3357static int onenand_check_maf(int manuf)
3358{
3359 int size = ARRAY_SIZE(onenand_manuf_ids);
3360 char *name;
3361 int i;
3362
3363 for (i = 0; i < size; i++)
3364 if (manuf == onenand_manuf_ids[i].id)
3365 break;
3366
3367 if (i < size)
3368 name = onenand_manuf_ids[i].name;
3369 else
3370 name = "Unknown";
3371
3372 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
3373
3374 return (i == size);
3375}
3376
3377
3378
3379
3380
3381static int flexonenand_get_boundary(struct mtd_info *mtd)
3382{
3383 struct onenand_chip *this = mtd->priv;
3384 unsigned die, bdry;
3385 int syscfg, locked;
3386
3387
3388 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
3389 this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1);
3390
3391 for (die = 0; die < this->dies; die++) {
3392 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3393 this->wait(mtd, FL_SYNCING);
3394
3395 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3396 this->wait(mtd, FL_READING);
3397
3398 bdry = this->read_word(this->base + ONENAND_DATARAM);
3399 if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
3400 locked = 0;
3401 else
3402 locked = 1;
3403 this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
3404
3405 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
3406 this->wait(mtd, FL_RESETTING);
3407
3408 printk(KERN_INFO "Die %d boundary: %d%s\n", die,
3409 this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
3410 }
3411
3412
3413 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
3414 return 0;
3415}
3416
3417
3418
3419
3420
3421
3422static void flexonenand_get_size(struct mtd_info *mtd)
3423{
3424 struct onenand_chip *this = mtd->priv;
3425 int die, i, eraseshift, density;
3426 int blksperdie, maxbdry;
3427 loff_t ofs;
3428
3429 density = onenand_get_density(this->device_id);
3430 blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift);
3431 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3432 maxbdry = blksperdie - 1;
3433 eraseshift = this->erase_shift - 1;
3434
3435 mtd->numeraseregions = this->dies << 1;
3436
3437
3438 flexonenand_get_boundary(mtd);
3439 die = ofs = 0;
3440 i = -1;
3441 for (; die < this->dies; die++) {
3442 if (!die || this->boundary[die-1] != maxbdry) {
3443 i++;
3444 mtd->eraseregions[i].offset = ofs;
3445 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3446 mtd->eraseregions[i].numblocks =
3447 this->boundary[die] + 1;
3448 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3449 eraseshift++;
3450 } else {
3451 mtd->numeraseregions -= 1;
3452 mtd->eraseregions[i].numblocks +=
3453 this->boundary[die] + 1;
3454 ofs += (this->boundary[die] + 1) << (eraseshift - 1);
3455 }
3456 if (this->boundary[die] != maxbdry) {
3457 i++;
3458 mtd->eraseregions[i].offset = ofs;
3459 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3460 mtd->eraseregions[i].numblocks = maxbdry ^
3461 this->boundary[die];
3462 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3463 eraseshift--;
3464 } else
3465 mtd->numeraseregions -= 1;
3466 }
3467
3468
3469 mtd->erasesize = 1 << this->erase_shift;
3470 if (mtd->numeraseregions == 1)
3471 mtd->erasesize >>= 1;
3472
3473 printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions);
3474 for (i = 0; i < mtd->numeraseregions; i++)
3475 printk(KERN_INFO "[offset: 0x%08x, erasesize: 0x%05x,"
3476 " numblocks: %04u]\n",
3477 (unsigned int) mtd->eraseregions[i].offset,
3478 mtd->eraseregions[i].erasesize,
3479 mtd->eraseregions[i].numblocks);
3480
3481 for (die = 0, mtd->size = 0; die < this->dies; die++) {
3482 this->diesize[die] = (loff_t)blksperdie << this->erase_shift;
3483 this->diesize[die] -= (loff_t)(this->boundary[die] + 1)
3484 << (this->erase_shift - 1);
3485 mtd->size += this->diesize[die];
3486 }
3487}
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int end)
3504{
3505 struct onenand_chip *this = mtd->priv;
3506 int i, ret;
3507 int block;
3508 struct mtd_oob_ops ops = {
3509 .mode = MTD_OPS_PLACE_OOB,
3510 .ooboffs = 0,
3511 .ooblen = mtd->oobsize,
3512 .datbuf = NULL,
3513 .oobbuf = this->oob_buf,
3514 };
3515 loff_t addr;
3516
3517 printk(KERN_DEBUG "Check blocks from %d to %d\n", start, end);
3518
3519 for (block = start; block <= end; block++) {
3520 addr = flexonenand_addr(this, block);
3521 if (onenand_block_isbad_nolock(mtd, addr, 0))
3522 continue;
3523
3524
3525
3526
3527
3528 ret = onenand_read_oob_nolock(mtd, addr, &ops);
3529 if (ret)
3530 return ret;
3531
3532 for (i = 0; i < mtd->oobsize; i++)
3533 if (this->oob_buf[i] != 0xff)
3534 break;
3535
3536 if (i != mtd->oobsize) {
3537 printk(KERN_WARNING "%s: Block %d not erased.\n",
3538 __func__, block);
3539 return 1;
3540 }
3541 }
3542
3543 return 0;
3544}
3545
3546
3547
3548
3549static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
3550 int boundary, int lock)
3551{
3552 struct onenand_chip *this = mtd->priv;
3553 int ret, density, blksperdie, old, new, thisboundary;
3554 loff_t addr;
3555
3556
3557 if (die && (!ONENAND_IS_DDP(this)))
3558 return 0;
3559
3560
3561 if (boundary < 0 || boundary == this->boundary[die])
3562 return 0;
3563
3564 density = onenand_get_density(this->device_id);
3565 blksperdie = ((16 << density) << 20) >> this->erase_shift;
3566 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3567
3568 if (boundary >= blksperdie) {
3569 printk(KERN_ERR "%s: Invalid boundary value. "
3570 "Boundary not changed.\n", __func__);
3571 return -EINVAL;
3572 }
3573
3574
3575 old = this->boundary[die] + (die * this->density_mask);
3576 new = boundary + (die * this->density_mask);
3577 ret = flexonenand_check_blocks_erased(mtd, min(old, new) + 1, max(old, new));
3578 if (ret) {
3579 printk(KERN_ERR "%s: Please erase blocks "
3580 "before boundary change\n", __func__);
3581 return ret;
3582 }
3583
3584 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3585 this->wait(mtd, FL_SYNCING);
3586
3587
3588 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3589 this->wait(mtd, FL_READING);
3590
3591 thisboundary = this->read_word(this->base + ONENAND_DATARAM);
3592 if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
3593 printk(KERN_ERR "%s: boundary locked\n", __func__);
3594 ret = 1;
3595 goto out;
3596 }
3597
3598 printk(KERN_INFO "Changing die %d boundary: %d%s\n",
3599 die, boundary, lock ? "(Locked)" : "(Unlocked)");
3600
3601 addr = die ? this->diesize[0] : 0;
3602
3603 boundary &= FLEXONENAND_PI_MASK;
3604 boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT);
3605
3606 this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
3607 ret = this->wait(mtd, FL_ERASING);
3608 if (ret) {
3609 printk(KERN_ERR "%s: Failed PI erase for Die %d\n",
3610 __func__, die);
3611 goto out;
3612 }
3613
3614 this->write_word(boundary, this->base + ONENAND_DATARAM);
3615 this->command(mtd, ONENAND_CMD_PROG, addr, 0);
3616 ret = this->wait(mtd, FL_WRITING);
3617 if (ret) {
3618 printk(KERN_ERR "%s: Failed PI write for Die %d\n",
3619 __func__, die);
3620 goto out;
3621 }
3622
3623 this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0);
3624 ret = this->wait(mtd, FL_WRITING);
3625out:
3626 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND);
3627 this->wait(mtd, FL_RESETTING);
3628 if (!ret)
3629
3630 flexonenand_get_size(mtd);
3631
3632 return ret;
3633}
3634
3635
3636
3637
3638
3639
3640
3641
3642static int onenand_chip_probe(struct mtd_info *mtd)
3643{
3644 struct onenand_chip *this = mtd->priv;
3645 int bram_maf_id, bram_dev_id, maf_id, dev_id;
3646 int syscfg;
3647
3648
3649 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
3650
3651 this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE), this->base + ONENAND_REG_SYS_CFG1);
3652
3653
3654 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
3655
3656
3657 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
3658 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
3659
3660
3661 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
3662
3663 this->wait(mtd, FL_RESETTING);
3664
3665
3666 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
3667
3668
3669 if (onenand_check_maf(bram_maf_id))
3670 return -ENXIO;
3671
3672
3673 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
3674 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
3675
3676
3677 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
3678 return -ENXIO;
3679
3680 return 0;
3681}
3682
3683
3684
3685
3686
3687static int onenand_probe(struct mtd_info *mtd)
3688{
3689 struct onenand_chip *this = mtd->priv;
3690 int dev_id, ver_id;
3691 int density;
3692 int ret;
3693
3694 ret = this->chip_probe(mtd);
3695 if (ret)
3696 return ret;
3697
3698
3699 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
3700 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
3701 this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
3702
3703
3704 onenand_print_device_info(dev_id, ver_id);
3705 this->device_id = dev_id;
3706 this->version_id = ver_id;
3707
3708
3709 onenand_check_features(mtd);
3710
3711 density = onenand_get_density(dev_id);
3712 if (FLEXONENAND(this)) {
3713 this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
3714
3715 mtd->numeraseregions = this->dies << 1;
3716 mtd->eraseregions =
3717 kcalloc(this->dies << 1,
3718 sizeof(struct mtd_erase_region_info),
3719 GFP_KERNEL);
3720 if (!mtd->eraseregions)
3721 return -ENOMEM;
3722 }
3723
3724
3725
3726
3727
3728 this->chipsize = (16 << density) << 20;
3729
3730
3731
3732 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
3733
3734 if (ONENAND_IS_4KB_PAGE(this))
3735 mtd->writesize <<= 1;
3736
3737 mtd->oobsize = mtd->writesize >> 5;
3738
3739 mtd->erasesize = mtd->writesize << 6;
3740
3741
3742
3743
3744
3745 if (FLEXONENAND(this))
3746 mtd->erasesize <<= 1;
3747
3748 this->erase_shift = ffs(mtd->erasesize) - 1;
3749 this->page_shift = ffs(mtd->writesize) - 1;
3750 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
3751
3752 if (ONENAND_IS_DDP(this))
3753 this->density_mask = this->chipsize >> (this->erase_shift + 1);
3754
3755 this->writesize = mtd->writesize;
3756
3757
3758
3759 if (FLEXONENAND(this))
3760 flexonenand_get_size(mtd);
3761 else
3762 mtd->size = this->chipsize;
3763
3764
3765
3766
3767
3768
3769
3770 if (ONENAND_IS_2PLANE(this)) {
3771 mtd->writesize <<= 1;
3772 mtd->erasesize <<= 1;
3773 }
3774
3775 return 0;
3776}
3777
3778
3779
3780
3781
3782static int onenand_suspend(struct mtd_info *mtd)
3783{
3784 return onenand_get_device(mtd, FL_PM_SUSPENDED);
3785}
3786
3787
3788
3789
3790
3791static void onenand_resume(struct mtd_info *mtd)
3792{
3793 struct onenand_chip *this = mtd->priv;
3794
3795 if (this->state == FL_PM_SUSPENDED)
3796 onenand_release_device(mtd);
3797 else
3798 printk(KERN_ERR "%s: resume() called for the chip which is not "
3799 "in suspended state\n", __func__);
3800}
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812int onenand_scan(struct mtd_info *mtd, int maxchips)
3813{
3814 int i, ret;
3815 struct onenand_chip *this = mtd->priv;
3816
3817 if (!this->read_word)
3818 this->read_word = onenand_readw;
3819 if (!this->write_word)
3820 this->write_word = onenand_writew;
3821
3822 if (!this->command)
3823 this->command = onenand_command;
3824 if (!this->wait)
3825 onenand_setup_wait(mtd);
3826 if (!this->bbt_wait)
3827 this->bbt_wait = onenand_bbt_wait;
3828 if (!this->unlock_all)
3829 this->unlock_all = onenand_unlock_all;
3830
3831 if (!this->chip_probe)
3832 this->chip_probe = onenand_chip_probe;
3833
3834 if (!this->read_bufferram)
3835 this->read_bufferram = onenand_read_bufferram;
3836 if (!this->write_bufferram)
3837 this->write_bufferram = onenand_write_bufferram;
3838
3839 if (!this->block_markbad)
3840 this->block_markbad = onenand_default_block_markbad;
3841 if (!this->scan_bbt)
3842 this->scan_bbt = onenand_default_bbt;
3843
3844 if (onenand_probe(mtd))
3845 return -ENXIO;
3846
3847
3848 if (this->mmcontrol) {
3849 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
3850 this->read_bufferram = onenand_sync_read_bufferram;
3851 }
3852
3853
3854 if (!this->page_buf) {
3855 this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
3856 if (!this->page_buf)
3857 return -ENOMEM;
3858#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
3859 this->verify_buf = kzalloc(mtd->writesize, GFP_KERNEL);
3860 if (!this->verify_buf) {
3861 kfree(this->page_buf);
3862 return -ENOMEM;
3863 }
3864#endif
3865 this->options |= ONENAND_PAGEBUF_ALLOC;
3866 }
3867 if (!this->oob_buf) {
3868 this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
3869 if (!this->oob_buf) {
3870 if (this->options & ONENAND_PAGEBUF_ALLOC) {
3871 this->options &= ~ONENAND_PAGEBUF_ALLOC;
3872#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
3873 kfree(this->verify_buf);
3874#endif
3875 kfree(this->page_buf);
3876 }
3877 return -ENOMEM;
3878 }
3879 this->options |= ONENAND_OOBBUF_ALLOC;
3880 }
3881
3882 this->state = FL_READY;
3883 init_waitqueue_head(&this->wq);
3884 spin_lock_init(&this->chip_lock);
3885
3886
3887
3888
3889 switch (mtd->oobsize) {
3890 case 128:
3891 if (FLEXONENAND(this)) {
3892 mtd_set_ooblayout(mtd, &flexonenand_ooblayout_ops);
3893 mtd->subpage_sft = 0;
3894 } else {
3895 mtd_set_ooblayout(mtd, &onenand_oob_128_ooblayout_ops);
3896 mtd->subpage_sft = 2;
3897 }
3898 if (ONENAND_IS_NOP_1(this))
3899 mtd->subpage_sft = 0;
3900 break;
3901 case 64:
3902 mtd_set_ooblayout(mtd, &onenand_oob_32_64_ooblayout_ops);
3903 mtd->subpage_sft = 2;
3904 break;
3905
3906 case 32:
3907 mtd_set_ooblayout(mtd, &onenand_oob_32_64_ooblayout_ops);
3908 mtd->subpage_sft = 1;
3909 break;
3910
3911 default:
3912 printk(KERN_WARNING "%s: No OOB scheme defined for oobsize %d\n",
3913 __func__, mtd->oobsize);
3914 mtd->subpage_sft = 0;
3915
3916 mtd_set_ooblayout(mtd, &onenand_oob_32_64_ooblayout_ops);
3917 break;
3918 }
3919
3920 this->subpagesize = mtd->writesize >> mtd->subpage_sft;
3921
3922
3923
3924
3925
3926 ret = mtd_ooblayout_count_freebytes(mtd);
3927 if (ret < 0)
3928 ret = 0;
3929
3930 mtd->oobavail = ret;
3931
3932 mtd->ecc_strength = 1;
3933
3934
3935 mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH;
3936 mtd->flags = MTD_CAP_NANDFLASH;
3937 mtd->_erase = onenand_erase;
3938 mtd->_point = NULL;
3939 mtd->_unpoint = NULL;
3940 mtd->_read_oob = onenand_read_oob;
3941 mtd->_write_oob = onenand_write_oob;
3942 mtd->_panic_write = onenand_panic_write;
3943#ifdef CONFIG_MTD_ONENAND_OTP
3944 mtd->_get_fact_prot_info = onenand_get_fact_prot_info;
3945 mtd->_read_fact_prot_reg = onenand_read_fact_prot_reg;
3946 mtd->_get_user_prot_info = onenand_get_user_prot_info;
3947 mtd->_read_user_prot_reg = onenand_read_user_prot_reg;
3948 mtd->_write_user_prot_reg = onenand_write_user_prot_reg;
3949 mtd->_lock_user_prot_reg = onenand_lock_user_prot_reg;
3950#endif
3951 mtd->_sync = onenand_sync;
3952 mtd->_lock = onenand_lock;
3953 mtd->_unlock = onenand_unlock;
3954 mtd->_suspend = onenand_suspend;
3955 mtd->_resume = onenand_resume;
3956 mtd->_block_isbad = onenand_block_isbad;
3957 mtd->_block_markbad = onenand_block_markbad;
3958 mtd->owner = THIS_MODULE;
3959 mtd->writebufsize = mtd->writesize;
3960
3961
3962 if (!(this->options & ONENAND_SKIP_INITIAL_UNLOCKING))
3963 this->unlock_all(mtd);
3964
3965
3966 this->badblockpos = ONENAND_BADBLOCK_POS;
3967
3968 ret = this->scan_bbt(mtd);
3969 if ((!FLEXONENAND(this)) || ret)
3970 return ret;
3971
3972
3973 for (i = 0; i < MAX_DIES; i++)
3974 flexonenand_set_boundary(mtd, i, flex_bdry[2 * i],
3975 flex_bdry[(2 * i) + 1]);
3976
3977 return 0;
3978}
3979
3980
3981
3982
3983
3984void onenand_release(struct mtd_info *mtd)
3985{
3986 struct onenand_chip *this = mtd->priv;
3987
3988
3989 mtd_device_unregister(mtd);
3990
3991
3992 if (this->bbm) {
3993 struct bbm_info *bbm = this->bbm;
3994 kfree(bbm->bbt);
3995 kfree(this->bbm);
3996 }
3997
3998 if (this->options & ONENAND_PAGEBUF_ALLOC) {
3999 kfree(this->page_buf);
4000#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
4001 kfree(this->verify_buf);
4002#endif
4003 }
4004 if (this->options & ONENAND_OOBBUF_ALLOC)
4005 kfree(this->oob_buf);
4006 kfree(mtd->eraseregions);
4007}
4008
4009EXPORT_SYMBOL_GPL(onenand_scan);
4010EXPORT_SYMBOL_GPL(onenand_release);
4011
4012MODULE_LICENSE("GPL");
4013MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
4014MODULE_DESCRIPTION("Generic OneNAND flash driver code");
4015