aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices/doc2000.c
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 /drivers/mtd/devices/doc2000.c
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>
Diffstat (limited to 'drivers/mtd/devices/doc2000.c')
-rw-r--r--drivers/mtd/devices/doc2000.c179
1 files changed, 73 insertions, 106 deletions
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index c54e40464d8..603a7951ac9 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);