aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@cruncher.tec.linutronix.de>2006-06-28 04:11:33 -0400
committerThomas Gleixner <tglx@cruncher.tec.linutronix.de>2006-06-28 04:11:33 -0400
commit7f8a894066b826a4baea49c2a3adbba0a56a192f (patch)
tree94833927f58f47a2b29b026ed1839b90a3ef29cf
parenta39727f212426b9d5f9267b3318a2afaf9922d3b (diff)
[MTD] DOC: Fixup read functions and do a little cleanup
The NAND rework resulted in non ECC based reads. Fix it up and do a bit of cleanup while at it. Pointed out by Adrian Bunk. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--drivers/mtd/devices/doc2000.c179
-rw-r--r--drivers/mtd/devices/doc2001.c179
-rw-r--r--drivers/mtd/devices/doc2001plus.c164
3 files changed, 207 insertions, 315 deletions
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index c54e40464d82..603a7951ac9b 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -55,10 +55,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
55 size_t *retlen, u_char *buf); 55 size_t *retlen, u_char *buf);
56static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, 56static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
57 size_t *retlen, const u_char *buf); 57 size_t *retlen, const u_char *buf);
58static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
59 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
60static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
61 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
62static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, 58static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
63 struct mtd_oob_ops *ops); 59 struct mtd_oob_ops *ops);
64static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, 60static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
@@ -615,17 +611,10 @@ EXPORT_SYMBOL_GPL(DoC2k_init);
615static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, 611static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
616 size_t * retlen, u_char * buf) 612 size_t * retlen, u_char * buf)
617{ 613{
618 /* Just a special case of doc_read_ecc */
619 return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
620}
621
622static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
623 size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
624{
625 struct DiskOnChip *this = mtd->priv; 614 struct DiskOnChip *this = mtd->priv;
626 void __iomem *docptr = this->virtadr; 615 void __iomem *docptr = this->virtadr;
627 struct Nand *mychip; 616 struct Nand *mychip;
628 unsigned char syndrome[6]; 617 unsigned char syndrome[6], eccbuf[6];
629 volatile char dummy; 618 volatile char dummy;
630 int i, len256 = 0, ret=0; 619 int i, len256 = 0, ret=0;
631 size_t left = len; 620 size_t left = len;
@@ -673,15 +662,9 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
673 DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP, 662 DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
674 CDSN_CTRL_ECC_IO); 663 CDSN_CTRL_ECC_IO);
675 664
676 if (eccbuf) { 665 /* Prime the ECC engine */
677 /* Prime the ECC engine */ 666 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
678 WriteDOC(DOC_ECC_RESET, docptr, ECCConf); 667 WriteDOC(DOC_ECC_EN, docptr, ECCConf);
679 WriteDOC(DOC_ECC_EN, docptr, ECCConf);
680 } else {
681 /* disable the ECC engine */
682 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
683 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
684 }
685 668
686 /* treat crossing 256-byte sector for 2M x 8bits devices */ 669 /* treat crossing 256-byte sector for 2M x 8bits devices */
687 if (this->page256 && from + len > (from | 0xff) + 1) { 670 if (this->page256 && from + len > (from | 0xff) + 1) {
@@ -698,58 +681,59 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
698 /* Let the caller know we completed it */ 681 /* Let the caller know we completed it */
699 *retlen += len; 682 *retlen += len;
700 683
701 if (eccbuf) { 684 /* Read the ECC data through the DiskOnChip ECC logic */
702 /* Read the ECC data through the DiskOnChip ECC logic */ 685 /* Note: this will work even with 2M x 8bit devices as */
703 /* Note: this will work even with 2M x 8bit devices as */ 686 /* they have 8 bytes of OOB per 256 page. mf. */
704 /* they have 8 bytes of OOB per 256 page. mf. */ 687 DoC_ReadBuf(this, eccbuf, 6);
705 DoC_ReadBuf(this, eccbuf, 6);
706
707 /* Flush the pipeline */
708 if (DoC_is_Millennium(this)) {
709 dummy = ReadDOC(docptr, ECCConf);
710 dummy = ReadDOC(docptr, ECCConf);
711 i = ReadDOC(docptr, ECCConf);
712 } else {
713 dummy = ReadDOC(docptr, 2k_ECCStatus);
714 dummy = ReadDOC(docptr, 2k_ECCStatus);
715 i = ReadDOC(docptr, 2k_ECCStatus);
716 }
717 688
718 /* Check the ECC Status */ 689 /* Flush the pipeline */
719 if (i & 0x80) { 690 if (DoC_is_Millennium(this)) {
720 int nb_errors; 691 dummy = ReadDOC(docptr, ECCConf);
721 /* There was an ECC error */ 692 dummy = ReadDOC(docptr, ECCConf);
693 i = ReadDOC(docptr, ECCConf);
694 } else {
695 dummy = ReadDOC(docptr, 2k_ECCStatus);
696 dummy = ReadDOC(docptr, 2k_ECCStatus);
697 i = ReadDOC(docptr, 2k_ECCStatus);
698 }
699
700 /* Check the ECC Status */
701 if (i & 0x80) {
702 int nb_errors;
703 /* There was an ECC error */
722#ifdef ECC_DEBUG 704#ifdef ECC_DEBUG
723 printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from); 705 printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
724#endif 706#endif
725 /* Read the ECC syndrom through the DiskOnChip ECC logic. 707 /* Read the ECC syndrom through the DiskOnChip ECC
726 These syndrome will be all ZERO when there is no error */ 708 logic. These syndrome will be all ZERO when there
727 for (i = 0; i < 6; i++) { 709 is no error */
728 syndrome[i] = 710 for (i = 0; i < 6; i++) {
729 ReadDOC(docptr, ECCSyndrome0 + i); 711 syndrome[i] =
730 } 712 ReadDOC(docptr, ECCSyndrome0 + i);
731 nb_errors = doc_decode_ecc(buf, syndrome); 713 }
714 nb_errors = doc_decode_ecc(buf, syndrome);
732 715
733#ifdef ECC_DEBUG 716#ifdef ECC_DEBUG
734 printk(KERN_ERR "Errors corrected: %x\n", nb_errors); 717 printk(KERN_ERR "Errors corrected: %x\n", nb_errors);
735#endif 718#endif
736 if (nb_errors < 0) { 719 if (nb_errors < 0) {
737 /* We return error, but have actually done the read. Not that 720 /* We return error, but have actually done the
738 this can be told to user-space, via sys_read(), but at least 721 read. Not that this can be told to
739 MTD-aware stuff can know about it by checking *retlen */ 722 user-space, via sys_read(), but at least
740 ret = -EIO; 723 MTD-aware stuff can know about it by
741 } 724 checking *retlen */
725 ret = -EIO;
742 } 726 }
727 }
743 728
744#ifdef PSYCHO_DEBUG 729#ifdef PSYCHO_DEBUG
745 printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 730 printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
746 (long)from, eccbuf[0], eccbuf[1], eccbuf[2], 731 (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
747 eccbuf[3], eccbuf[4], eccbuf[5]); 732 eccbuf[3], eccbuf[4], eccbuf[5]);
748#endif 733#endif
749 734
750 /* disable the ECC engine */ 735 /* disable the ECC engine */
751 WriteDOC(DOC_ECC_DIS, docptr , ECCConf); 736 WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
752 }
753 737
754 /* according to 11.4.1, we need to wait for the busy line 738 /* according to 11.4.1, we need to wait for the busy line
755 * drop if we read to the end of the page. */ 739 * drop if we read to the end of the page. */
@@ -771,17 +755,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
771static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, 755static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
772 size_t * retlen, const u_char * buf) 756 size_t * retlen, const u_char * buf)
773{ 757{
774 char eccbuf[6];
775 return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL);
776}
777
778static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
779 size_t * retlen, const u_char * buf,
780 u_char * eccbuf, struct nand_oobinfo *oobsel)
781{
782 struct DiskOnChip *this = mtd->priv; 758 struct DiskOnChip *this = mtd->priv;
783 int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */ 759 int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
784 void __iomem *docptr = this->virtadr; 760 void __iomem *docptr = this->virtadr;
761 unsigned char eccbuf[6];
785 volatile char dummy; 762 volatile char dummy;
786 int len256 = 0; 763 int len256 = 0;
787 struct Nand *mychip; 764 struct Nand *mychip;
@@ -835,15 +812,9 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
835 DoC_Command(this, NAND_CMD_SEQIN, 0); 812 DoC_Command(this, NAND_CMD_SEQIN, 0);
836 DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO); 813 DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
837 814
838 if (eccbuf) { 815 /* Prime the ECC engine */
839 /* Prime the ECC engine */ 816 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
840 WriteDOC(DOC_ECC_RESET, docptr, ECCConf); 817 WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
841 WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
842 } else {
843 /* disable the ECC engine */
844 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
845 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
846 }
847 818
848 /* treat crossing 256-byte sector for 2M x 8bits devices */ 819 /* treat crossing 256-byte sector for 2M x 8bits devices */
849 if (this->page256 && to + len > (to | 0xff) + 1) { 820 if (this->page256 && to + len > (to | 0xff) + 1) {
@@ -873,39 +844,35 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
873 844
874 DoC_WriteBuf(this, &buf[len256], len - len256); 845 DoC_WriteBuf(this, &buf[len256], len - len256);
875 846
876 if (eccbuf) { 847 WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, CDSNControl);
877 WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
878 CDSNControl);
879
880 if (DoC_is_Millennium(this)) {
881 WriteDOC(0, docptr, NOP);
882 WriteDOC(0, docptr, NOP);
883 WriteDOC(0, docptr, NOP);
884 } else {
885 WriteDOC_(0, docptr, this->ioreg);
886 WriteDOC_(0, docptr, this->ioreg);
887 WriteDOC_(0, docptr, this->ioreg);
888 }
889 848
890 WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr, 849 if (DoC_is_Millennium(this)) {
891 CDSNControl); 850 WriteDOC(0, docptr, NOP);
851 WriteDOC(0, docptr, NOP);
852 WriteDOC(0, docptr, NOP);
853 } else {
854 WriteDOC_(0, docptr, this->ioreg);
855 WriteDOC_(0, docptr, this->ioreg);
856 WriteDOC_(0, docptr, this->ioreg);
857 }
892 858
893 /* Read the ECC data through the DiskOnChip ECC logic */ 859 WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr,
894 for (di = 0; di < 6; di++) { 860 CDSNControl);
895 eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
896 }
897 861
898 /* Reset the ECC engine */ 862 /* Read the ECC data through the DiskOnChip ECC logic */
899 WriteDOC(DOC_ECC_DIS, docptr, ECCConf); 863 for (di = 0; di < 6; di++) {
864 eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
865 }
866
867 /* Reset the ECC engine */
868 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
900 869
901#ifdef PSYCHO_DEBUG 870#ifdef PSYCHO_DEBUG
902 printk 871 printk
903 ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 872 ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
904 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], 873 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
905 eccbuf[4], eccbuf[5]); 874 eccbuf[4], eccbuf[5]);
906#endif 875#endif
907 }
908
909 DoC_Command(this, NAND_CMD_PAGEPROG, 0); 876 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
910 877
911 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); 878 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 0cf022a69e65..0e2a9326f717 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -37,12 +37,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
37 size_t *retlen, u_char *buf); 37 size_t *retlen, u_char *buf);
38static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, 38static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
39 size_t *retlen, const u_char *buf); 39 size_t *retlen, const u_char *buf);
40static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
41 size_t *retlen, u_char *buf, u_char *eccbuf,
42 struct nand_oobinfo *oobsel);
43static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
44 size_t *retlen, const u_char *buf, u_char *eccbuf,
45 struct nand_oobinfo *oobsel);
46static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, 40static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
47 struct mtd_oob_ops *ops); 41 struct mtd_oob_ops *ops);
48static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, 42static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
@@ -397,17 +391,9 @@ EXPORT_SYMBOL_GPL(DoCMil_init);
397static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, 391static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
398 size_t *retlen, u_char *buf) 392 size_t *retlen, u_char *buf)
399{ 393{
400 /* Just a special case of doc_read_ecc */
401 return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
402}
403
404static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
405 size_t *retlen, u_char *buf, u_char *eccbuf,
406 struct nand_oobinfo *oobsel)
407{
408 int i, ret; 394 int i, ret;
409 volatile char dummy; 395 volatile char dummy;
410 unsigned char syndrome[6]; 396 unsigned char syndrome[6], eccbuf[6];
411 struct DiskOnChip *this = mtd->priv; 397 struct DiskOnChip *this = mtd->priv;
412 void __iomem *docptr = this->virtadr; 398 void __iomem *docptr = this->virtadr;
413 struct Nand *mychip = &this->chips[from >> (this->chipshift)]; 399 struct Nand *mychip = &this->chips[from >> (this->chipshift)];
@@ -437,15 +423,9 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
437 DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00); 423 DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00);
438 DoC_WaitReady(docptr); 424 DoC_WaitReady(docptr);
439 425
440 if (eccbuf) { 426 /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
441 /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ 427 WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
442 WriteDOC (DOC_ECC_RESET, docptr, ECCConf); 428 WriteDOC (DOC_ECC_EN, docptr, ECCConf);
443 WriteDOC (DOC_ECC_EN, docptr, ECCConf);
444 } else {
445 /* disable the ECC engine */
446 WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
447 WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
448 }
449 429
450 /* Read the data via the internal pipeline through CDSN IO register, 430 /* Read the data via the internal pipeline through CDSN IO register,
451 see Pipelined Read Operations 11.3 */ 431 see Pipelined Read Operations 11.3 */
@@ -465,58 +445,56 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
465 *retlen = len; 445 *retlen = len;
466 ret = 0; 446 ret = 0;
467 447
468 if (eccbuf) { 448 /* Read the ECC data from Spare Data Area,
469 /* Read the ECC data from Spare Data Area, 449 see Reed-Solomon EDC/ECC 11.1 */
470 see Reed-Solomon EDC/ECC 11.1 */ 450 dummy = ReadDOC(docptr, ReadPipeInit);
471 dummy = ReadDOC(docptr, ReadPipeInit);
472#ifndef USE_MEMCPY 451#ifndef USE_MEMCPY
473 for (i = 0; i < 5; i++) { 452 for (i = 0; i < 5; i++) {
474 /* N.B. you have to increase the source address in this way or the 453 /* N.B. you have to increase the source address in this way or the
475 ECC logic will not work properly */ 454 ECC logic will not work properly */
476 eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i); 455 eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
477 } 456 }
478#else 457#else
479 memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5); 458 memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5);
480#endif 459#endif
481 eccbuf[5] = ReadDOC(docptr, LastDataRead); 460 eccbuf[5] = ReadDOC(docptr, LastDataRead);
482 461
483 /* Flush the pipeline */ 462 /* Flush the pipeline */
484 dummy = ReadDOC(docptr, ECCConf); 463 dummy = ReadDOC(docptr, ECCConf);
485 dummy = ReadDOC(docptr, ECCConf); 464 dummy = ReadDOC(docptr, ECCConf);
486 465
487 /* Check the ECC Status */ 466 /* Check the ECC Status */
488 if (ReadDOC(docptr, ECCConf) & 0x80) { 467 if (ReadDOC(docptr, ECCConf) & 0x80) {
489 int nb_errors; 468 int nb_errors;
490 /* There was an ECC error */ 469 /* There was an ECC error */
491#ifdef ECC_DEBUG 470#ifdef ECC_DEBUG
492 printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); 471 printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
493#endif 472#endif
494 /* Read the ECC syndrom through the DiskOnChip ECC logic. 473 /* Read the ECC syndrom through the DiskOnChip ECC logic.
495 These syndrome will be all ZERO when there is no error */ 474 These syndrome will be all ZERO when there is no error */
496 for (i = 0; i < 6; i++) { 475 for (i = 0; i < 6; i++) {
497 syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i); 476 syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
498 } 477 }
499 nb_errors = doc_decode_ecc(buf, syndrome); 478 nb_errors = doc_decode_ecc(buf, syndrome);
500#ifdef ECC_DEBUG 479#ifdef ECC_DEBUG
501 printk("ECC Errors corrected: %x\n", nb_errors); 480 printk("ECC Errors corrected: %x\n", nb_errors);
502#endif 481#endif
503 if (nb_errors < 0) { 482 if (nb_errors < 0) {
504 /* We return error, but have actually done the read. Not that 483 /* We return error, but have actually done the read. Not that
505 this can be told to user-space, via sys_read(), but at least 484 this can be told to user-space, via sys_read(), but at least
506 MTD-aware stuff can know about it by checking *retlen */ 485 MTD-aware stuff can know about it by checking *retlen */
507 ret = -EIO; 486 ret = -EIO;
508 }
509 } 487 }
488 }
510 489
511#ifdef PSYCHO_DEBUG 490#ifdef PSYCHO_DEBUG
512 printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 491 printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
513 (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], 492 (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
514 eccbuf[4], eccbuf[5]); 493 eccbuf[4], eccbuf[5]);
515#endif 494#endif
516 495
517 /* disable the ECC engine */ 496 /* disable the ECC engine */
518 WriteDOC(DOC_ECC_DIS, docptr , ECCConf); 497 WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
519 }
520 498
521 return ret; 499 return ret;
522} 500}
@@ -524,15 +502,8 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
524static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, 502static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
525 size_t *retlen, const u_char *buf) 503 size_t *retlen, const u_char *buf)
526{ 504{
527 char eccbuf[6];
528 return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL);
529}
530
531static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
532 size_t *retlen, const u_char *buf, u_char *eccbuf,
533 struct nand_oobinfo *oobsel)
534{
535 int i,ret = 0; 505 int i,ret = 0;
506 char eccbuf[6];
536 volatile char dummy; 507 volatile char dummy;
537 struct DiskOnChip *this = mtd->priv; 508 struct DiskOnChip *this = mtd->priv;
538 void __iomem *docptr = this->virtadr; 509 void __iomem *docptr = this->virtadr;
@@ -573,15 +544,9 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
573 DoC_Address(docptr, 3, to, 0x00, 0x00); 544 DoC_Address(docptr, 3, to, 0x00, 0x00);
574 DoC_WaitReady(docptr); 545 DoC_WaitReady(docptr);
575 546
576 if (eccbuf) { 547 /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
577 /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ 548 WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
578 WriteDOC (DOC_ECC_RESET, docptr, ECCConf); 549 WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
579 WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
580 } else {
581 /* disable the ECC engine */
582 WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
583 WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
584 }
585 550
586 /* Write the data via the internal pipeline through CDSN IO register, 551 /* Write the data via the internal pipeline through CDSN IO register,
587 see Pipelined Write Operations 11.2 */ 552 see Pipelined Write Operations 11.2 */
@@ -596,46 +561,44 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
596#endif 561#endif
597 WriteDOC(0x00, docptr, WritePipeTerm); 562 WriteDOC(0x00, docptr, WritePipeTerm);
598 563
599 if (eccbuf) { 564 /* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
600 /* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic 565 see Reed-Solomon EDC/ECC 11.1 */
601 see Reed-Solomon EDC/ECC 11.1 */ 566 WriteDOC(0, docptr, NOP);
602 WriteDOC(0, docptr, NOP); 567 WriteDOC(0, docptr, NOP);
603 WriteDOC(0, docptr, NOP); 568 WriteDOC(0, docptr, NOP);
604 WriteDOC(0, docptr, NOP);
605 569
606 /* Read the ECC data through the DiskOnChip ECC logic */ 570 /* Read the ECC data through the DiskOnChip ECC logic */
607 for (i = 0; i < 6; i++) { 571 for (i = 0; i < 6; i++) {
608 eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i); 572 eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i);
609 } 573 }
610 574
611 /* ignore the ECC engine */ 575 /* ignore the ECC engine */
612 WriteDOC(DOC_ECC_DIS, docptr , ECCConf); 576 WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
613 577
614#ifndef USE_MEMCPY 578#ifndef USE_MEMCPY
615 /* Write the ECC data to flash */ 579 /* Write the ECC data to flash */
616 for (i = 0; i < 6; i++) { 580 for (i = 0; i < 6; i++) {
617 /* N.B. you have to increase the source address in this way or the 581 /* N.B. you have to increase the source address in this way or the
618 ECC logic will not work properly */ 582 ECC logic will not work properly */
619 WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i); 583 WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i);
620 } 584 }
621#else 585#else
622 memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6); 586 memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6);
623#endif 587#endif
624 588
625 /* write the block status BLOCK_USED (0x5555) at the end of ECC data 589 /* write the block status BLOCK_USED (0x5555) at the end of ECC data
626 FIXME: this is only a hack for programming the IPL area for LinuxBIOS 590 FIXME: this is only a hack for programming the IPL area for LinuxBIOS
627 and should be replace with proper codes in user space utilities */ 591 and should be replace with proper codes in user space utilities */
628 WriteDOC(0x55, docptr, Mil_CDSN_IO); 592 WriteDOC(0x55, docptr, Mil_CDSN_IO);
629 WriteDOC(0x55, docptr, Mil_CDSN_IO + 1); 593 WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
630 594
631 WriteDOC(0x00, docptr, WritePipeTerm); 595 WriteDOC(0x00, docptr, WritePipeTerm);
632 596
633#ifdef PSYCHO_DEBUG 597#ifdef PSYCHO_DEBUG
634 printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 598 printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
635 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], 599 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
636 eccbuf[4], eccbuf[5]); 600 eccbuf[4], eccbuf[5]);
637#endif 601#endif
638 }
639 602
640 /* Commit the Page Program command and wait for ready 603 /* Commit the Page Program command and wait for ready
641 see Software Requirement 11.4 item 1.*/ 604 see Software Requirement 11.4 item 1.*/
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index 66cb1e50469a..92dbb47f2ac3 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -41,12 +41,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
41 size_t *retlen, u_char *buf); 41 size_t *retlen, u_char *buf);
42static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, 42static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
43 size_t *retlen, const u_char *buf); 43 size_t *retlen, const u_char *buf);
44static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
45 size_t *retlen, u_char *buf, u_char *eccbuf,
46 struct nand_oobinfo *oobsel);
47static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
48 size_t *retlen, const u_char *buf, u_char *eccbuf,
49 struct nand_oobinfo *oobsel);
50static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, 44static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
51 struct mtd_oob_ops *ops); 45 struct mtd_oob_ops *ops);
52static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, 46static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
@@ -595,18 +589,10 @@ static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
595static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, 589static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
596 size_t *retlen, u_char *buf) 590 size_t *retlen, u_char *buf)
597{ 591{
598 /* Just a special case of doc_read_ecc */
599 return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
600}
601
602static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
603 size_t *retlen, u_char *buf, u_char *eccbuf,
604 struct nand_oobinfo *oobsel)
605{
606 int ret, i; 592 int ret, i;
607 volatile char dummy; 593 volatile char dummy;
608 loff_t fofs; 594 loff_t fofs;
609 unsigned char syndrome[6]; 595 unsigned char syndrome[6], eccbuf[6];
610 struct DiskOnChip *this = mtd->priv; 596 struct DiskOnChip *this = mtd->priv;
611 void __iomem * docptr = this->virtadr; 597 void __iomem * docptr = this->virtadr;
612 struct Nand *mychip = &this->chips[from >> (this->chipshift)]; 598 struct Nand *mychip = &this->chips[from >> (this->chipshift)];
@@ -644,56 +630,51 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
644 WriteDOC(0, docptr, Mplus_FlashControl); 630 WriteDOC(0, docptr, Mplus_FlashControl);
645 DoC_WaitReady(docptr); 631 DoC_WaitReady(docptr);
646 632
647 if (eccbuf) { 633 /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
648 /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ 634 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
649 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); 635 WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
650 WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
651 } else {
652 /* disable the ECC engine */
653 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
654 }
655 636
656 /* Let the caller know we completed it */ 637 /* Let the caller know we completed it */
657 *retlen = len; 638 *retlen = len;
658 ret = 0; 639 ret = 0;
659 640
660 ReadDOC(docptr, Mplus_ReadPipeInit); 641 ReadDOC(docptr, Mplus_ReadPipeInit);
661 ReadDOC(docptr, Mplus_ReadPipeInit); 642 ReadDOC(docptr, Mplus_ReadPipeInit);
662 643
663 if (eccbuf) { 644 /* Read the data via the internal pipeline through CDSN IO
664 /* Read the data via the internal pipeline through CDSN IO 645 register, see Pipelined Read Operations 11.3 */
665 register, see Pipelined Read Operations 11.3 */ 646 MemReadDOC(docptr, buf, len);
666 MemReadDOC(docptr, buf, len);
667 647
668 /* Read the ECC data following raw data */ 648 /* Read the ECC data following raw data */
669 MemReadDOC(docptr, eccbuf, 4); 649 MemReadDOC(docptr, eccbuf, 4);
670 eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead); 650 eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead);
671 eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead); 651 eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead);
672 652
673 /* Flush the pipeline */ 653 /* Flush the pipeline */
674 dummy = ReadDOC(docptr, Mplus_ECCConf); 654 dummy = ReadDOC(docptr, Mplus_ECCConf);
675 dummy = ReadDOC(docptr, Mplus_ECCConf); 655 dummy = ReadDOC(docptr, Mplus_ECCConf);
676 656
677 /* Check the ECC Status */ 657 /* Check the ECC Status */
678 if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) { 658 if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) {
679 int nb_errors; 659 int nb_errors;
680 /* There was an ECC error */ 660 /* There was an ECC error */
681#ifdef ECC_DEBUG 661#ifdef ECC_DEBUG
682 printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); 662 printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
683#endif 663#endif
684 /* Read the ECC syndrom through the DiskOnChip ECC logic. 664 /* Read the ECC syndrom through the DiskOnChip ECC logic.
685 These syndrome will be all ZERO when there is no error */ 665 These syndrome will be all ZERO when there is no error */
686 for (i = 0; i < 6; i++) 666 for (i = 0; i < 6; i++)
687 syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); 667 syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
688 668
689 nb_errors = doc_decode_ecc(buf, syndrome); 669 nb_errors = doc_decode_ecc(buf, syndrome);
690#ifdef ECC_DEBUG 670#ifdef ECC_DEBUG
691 printk("ECC Errors corrected: %x\n", nb_errors); 671 printk("ECC Errors corrected: %x\n", nb_errors);
692#endif 672#endif
693 if (nb_errors < 0) { 673 if (nb_errors < 0) {
694 /* We return error, but have actually done the read. Not that 674 /* We return error, but have actually done the
695 this can be told to user-space, via sys_read(), but at least 675 read. Not that this can be told to user-space, via
696 MTD-aware stuff can know about it by checking *retlen */ 676 sys_read(), but at least MTD-aware stuff can know
677 about it by checking *retlen */
697#ifdef ECC_DEBUG 678#ifdef ECC_DEBUG
698 printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n", 679 printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
699 __FILE__, __LINE__, (int)from); 680 __FILE__, __LINE__, (int)from);
@@ -707,24 +688,16 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
707 eccbuf[3], eccbuf[4], eccbuf[5]); 688 eccbuf[3], eccbuf[4], eccbuf[5]);
708#endif 689#endif
709 ret = -EIO; 690 ret = -EIO;
710 }
711 } 691 }
692 }
712 693
713#ifdef PSYCHO_DEBUG 694#ifdef PSYCHO_DEBUG
714 printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 695 printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
715 (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], 696 (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
716 eccbuf[4], eccbuf[5]); 697 eccbuf[4], eccbuf[5]);
717#endif 698#endif
718 699 /* disable the ECC engine */
719 /* disable the ECC engine */ 700 WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
720 WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
721 } else {
722 /* Read the data via the internal pipeline through CDSN IO
723 register, see Pipelined Read Operations 11.3 */
724 MemReadDOC(docptr, buf, len-2);
725 buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
726 buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
727 }
728 701
729 /* Disable flash internally */ 702 /* Disable flash internally */
730 WriteDOC(0, docptr, Mplus_FlashSelect); 703 WriteDOC(0, docptr, Mplus_FlashSelect);
@@ -735,17 +708,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
735static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, 708static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
736 size_t *retlen, const u_char *buf) 709 size_t *retlen, const u_char *buf)
737{ 710{
738 char eccbuf[6];
739 return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL);
740}
741
742static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
743 size_t *retlen, const u_char *buf, u_char *eccbuf,
744 struct nand_oobinfo *oobsel)
745{
746 int i, before, ret = 0; 711 int i, before, ret = 0;
747 loff_t fto; 712 loff_t fto;
748 volatile char dummy; 713 volatile char dummy;
714 char eccbuf[6];
749 struct DiskOnChip *this = mtd->priv; 715 struct DiskOnChip *this = mtd->priv;
750 void __iomem * docptr = this->virtadr; 716 void __iomem * docptr = this->virtadr;
751 struct Nand *mychip = &this->chips[to >> (this->chipshift)]; 717 struct Nand *mychip = &this->chips[to >> (this->chipshift)];
@@ -795,46 +761,42 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
795 /* Disable the ECC engine */ 761 /* Disable the ECC engine */
796 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); 762 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
797 763
798 if (eccbuf) { 764 if (before) {
799 if (before) { 765 /* Write the block status BLOCK_USED (0x5555) */
800 /* Write the block status BLOCK_USED (0x5555) */ 766 WriteDOC(0x55, docptr, Mil_CDSN_IO);
801 WriteDOC(0x55, docptr, Mil_CDSN_IO); 767 WriteDOC(0x55, docptr, Mil_CDSN_IO);
802 WriteDOC(0x55, docptr, Mil_CDSN_IO);
803 }
804
805 /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
806 WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
807 } 768 }
808 769
770 /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
771 WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
772
809 MemWriteDOC(docptr, (unsigned char *) buf, len); 773 MemWriteDOC(docptr, (unsigned char *) buf, len);
810 774
811 if (eccbuf) { 775 /* Write ECC data to flash, the ECC info is generated by
812 /* Write ECC data to flash, the ECC info is generated by 776 the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
813 the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */ 777 DoC_Delay(docptr, 3);
814 DoC_Delay(docptr, 3);
815 778
816 /* Read the ECC data through the DiskOnChip ECC logic */ 779 /* Read the ECC data through the DiskOnChip ECC logic */
817 for (i = 0; i < 6; i++) 780 for (i = 0; i < 6; i++)
818 eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); 781 eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
819 782
820 /* disable the ECC engine */ 783 /* disable the ECC engine */
821 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); 784 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
822 785
823 /* Write the ECC data to flash */ 786 /* Write the ECC data to flash */
824 MemWriteDOC(docptr, eccbuf, 6); 787 MemWriteDOC(docptr, eccbuf, 6);
825 788
826 if (!before) { 789 if (!before) {
827 /* Write the block status BLOCK_USED (0x5555) */ 790 /* Write the block status BLOCK_USED (0x5555) */
828 WriteDOC(0x55, docptr, Mil_CDSN_IO+6); 791 WriteDOC(0x55, docptr, Mil_CDSN_IO+6);
829 WriteDOC(0x55, docptr, Mil_CDSN_IO+7); 792 WriteDOC(0x55, docptr, Mil_CDSN_IO+7);
830 } 793 }
831 794
832#ifdef PSYCHO_DEBUG 795#ifdef PSYCHO_DEBUG
833 printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 796 printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
834 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], 797 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
835 eccbuf[4], eccbuf[5]); 798 eccbuf[4], eccbuf[5]);
836#endif 799#endif
837 }
838 800
839 WriteDOC(0x00, docptr, Mplus_WritePipeTerm); 801 WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
840 WriteDOC(0x00, docptr, Mplus_WritePipeTerm); 802 WriteDOC(0x00, docptr, Mplus_WritePipeTerm);