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