12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <asm/errno.h>
16 #include <asm/uaccess.h>
18 #include <linux/slab.h>
20 #include <linux/types.h>
21 #include <linux/bitops.h>
35 static int doc_read(
struct mtd_info *mtd, loff_t
from,
size_t len,
37 static int doc_write(
struct mtd_info *mtd, loff_t to,
size_t len,
39 static int doc_read_oob(
struct mtd_info *mtd, loff_t ofs,
41 static int doc_write_oob(
struct mtd_info *mtd, loff_t ofs,
49 static void DoC_Delay(
void __iomem * docptr,
int cycles)
53 for (i = 0; (i < cycles); i++)
57 #define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
60 static int _DoC_WaitReady(
void __iomem * docptr)
62 unsigned int c = 0xffff;
64 pr_debug(
"_DoC_WaitReady called for out-of-line wait\n");
71 pr_debug(
"_DoC_WaitReady timed out.\n");
76 static inline int DoC_WaitReady(
void __iomem * docptr)
87 ret = _DoC_WaitReady(docptr);
97 static inline void DoC_CheckASIC(
void __iomem * docptr)
109 static void DoC_Command(
void __iomem * docptr,
unsigned char command,
110 unsigned char xtraflags)
112 WriteDOC(command, docptr, Mplus_FlashCmd);
113 WriteDOC(command, docptr, Mplus_WritePipeTerm);
114 WriteDOC(command, docptr, Mplus_WritePipeTerm);
120 static inline void DoC_Address(
struct DiskOnChip *doc,
int numbytes,
121 unsigned long ofs,
unsigned char xtraflags1,
122 unsigned char xtraflags2)
132 WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
136 WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress);
137 WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
141 WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
142 WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress);
143 WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
149 WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
150 WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
154 static int DoC_SelectChip(
void __iomem * docptr,
int chip)
161 static int DoC_SelectFloor(
void __iomem * docptr,
int floor)
163 WriteDOC((floor & 0x3), docptr, Mplus_DeviceSelect);
179 static unsigned int DoC_GetDataOffset(
struct mtd_info *mtd, loff_t *
from)
184 unsigned int ofs = *from & 0x3ff;
190 }
else if (ofs < 1014) {
192 ofs = (ofs & 0x1ff) + 10;
198 *from = (*from & ~0x3ff) | ofs;
208 static unsigned int DoC_GetECCOffset(
struct mtd_info *mtd, loff_t *from)
210 unsigned int ofs,
cmd;
214 ofs = 10 + (*from & 0xf);
220 *from = (*from & ~0x3ff) | ofs;
224 static unsigned int DoC_GetFlagsOffset(
struct mtd_info *mtd, loff_t *from)
226 unsigned int ofs,
cmd;
229 ofs = (*from & 0x200) ? 8 : 6;
230 *from = (*from & ~0x3ff) | ofs;
234 static unsigned int DoC_GetHdrOffset(
struct mtd_info *mtd, loff_t *from)
236 unsigned int ofs,
cmd;
239 ofs = (*from & 0x200) ? 24 : 16;
240 *from = (*from & ~0x3ff) | ofs;
244 static inline void MemReadDOC(
void __iomem * docptr,
unsigned char *
buf,
int len)
248 for (i = 0; i < len; i++)
249 buf[i] =
ReadDOC(docptr, Mil_CDSN_IO + i);
255 static inline void MemWriteDOC(
void __iomem * docptr,
unsigned char *buf,
int len)
259 for (i = 0; i < len; i++)
260 WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
267 static int DoC_IdentChip(
struct DiskOnChip *doc,
int floor,
int chip)
274 DoC_SelectFloor(docptr, floor);
275 DoC_SelectChip(docptr, chip);
282 DoC_WaitReady(docptr);
288 DoC_Address(doc, 1, 0x00, 0, 0x00);
290 WriteDOC(0, docptr, Mplus_FlashControl);
291 DoC_WaitReady(docptr);
295 dummy =
ReadDOC(docptr, Mplus_ReadPipeInit);
296 dummy =
ReadDOC(docptr, Mplus_ReadPipeInit);
298 mfr =
ReadDOC(docptr, Mil_CDSN_IO);
300 dummy =
ReadDOC(docptr, Mil_CDSN_IO);
302 id =
ReadDOC(docptr, Mil_CDSN_IO);
304 dummy =
ReadDOC(docptr, Mil_CDSN_IO);
306 dummy =
ReadDOC(docptr, Mplus_LastDataRead);
307 dummy =
ReadDOC(docptr, Mplus_LastDataRead);
310 WriteDOC(0, docptr, Mplus_FlashSelect);
313 if (mfr == 0xff || mfr == 0)
324 "Chip ID: %2.2X (%s:%s)\n", mfr,
id,
340 static void DoC_ScanChips(
struct DiskOnChip *
this)
360 this->
interleave?
"on (16-bit)":
"off (8-bit)");
369 ret = DoC_IdentChip(
this, floor, chip);
377 if (!this->numchips) {
378 printk(
"No flash chips recognised.\n");
385 printk(
"MTD: No memory for allocating chip info structures\n");
392 for (chip = 0 ; chip < numchips[
floor] ; chip++) {
403 printk(
KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
404 this->numchips ,this->
totlen >> 20);
426 if (tmp2 == (tmp1+1) % 0xff)
447 old = docmilpluslist->
priv;
450 if (DoCMilPlus_is_alias(
this, old)) {
452 "Plus at 0x%lX - already configured\n",
464 mtd->
name =
"DiskOnChip Millennium Plus";
466 "address 0x%lX\n", this->
physadr);
475 mtd->
_read = doc_read;
489 this->
nextdoc = docmilpluslist;
490 docmilpluslist = mtd;
500 static int doc_dumpblk(
struct mtd_info *mtd, loff_t from)
507 unsigned char *bp, buf[1056];
516 DoC_CheckASIC(docptr);
519 if (this->curfloor != mychip->
floor) {
520 DoC_SelectFloor(docptr, mychip->
floor);
521 DoC_SelectChip(docptr, mychip->
chip);
522 }
else if (this->curchip != mychip->
chip) {
523 DoC_SelectChip(docptr, mychip->
chip);
525 this->curfloor = mychip->
floor;
526 this->curchip = mychip->
chip;
533 DoC_WaitReady(docptr);
536 DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
537 DoC_Address(
this, 3, fofs, 0, 0x00);
538 WriteDOC(0, docptr, Mplus_FlashControl);
539 DoC_WaitReady(docptr);
544 ReadDOC(docptr, Mplus_ReadPipeInit);
545 ReadDOC(docptr, Mplus_ReadPipeInit);
549 MemReadDOC(docptr, buf, 1054);
550 buf[1054] =
ReadDOC(docptr, Mplus_LastDataRead);
551 buf[1055] =
ReadDOC(docptr, Mplus_LastDataRead);
553 memset(&c[0], 0,
sizeof(c));
554 printk(
"DUMP OFFSET=%x:\n", (
int)from);
556 for (i = 0, bp = &buf[0]; (i < 1056); i++) {
560 c[(i & 0xf)] = ((*bp >= 0x20) && (*bp <= 0x7f)) ? *bp :
'.';
562 if (((i + 1) % 16) == 0)
568 WriteDOC(0, docptr, Mplus_FlashSelect);
574 static int doc_read(
struct mtd_info *mtd, loff_t from,
size_t len,
575 size_t *retlen,
u_char *buf)
580 unsigned char syndrome[6], eccbuf[6];
583 struct Nand *mychip = &this->
chips[from >> (this->chipshift)];
586 if (from + len > ((from | 0x1ff) + 1))
587 len = ((from | 0x1ff) + 1) - from;
589 DoC_CheckASIC(docptr);
592 if (this->curfloor != mychip->
floor) {
593 DoC_SelectFloor(docptr, mychip->
floor);
594 DoC_SelectChip(docptr, mychip->
chip);
595 }
else if (this->curchip != mychip->
chip) {
596 DoC_SelectChip(docptr, mychip->
chip);
598 this->curfloor = mychip->
floor;
599 this->curchip = mychip->
chip;
606 DoC_WaitReady(docptr);
609 DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
610 DoC_Address(
this, 3, fofs, 0, 0x00);
611 WriteDOC(0, docptr, Mplus_FlashControl);
612 DoC_WaitReady(docptr);
622 ReadDOC(docptr, Mplus_ReadPipeInit);
623 ReadDOC(docptr, Mplus_ReadPipeInit);
627 MemReadDOC(docptr, buf, len);
630 MemReadDOC(docptr, eccbuf, 4);
631 eccbuf[4] =
ReadDOC(docptr, Mplus_LastDataRead);
632 eccbuf[5] =
ReadDOC(docptr, Mplus_LastDataRead);
635 dummy =
ReadDOC(docptr, Mplus_ECCConf);
636 dummy =
ReadDOC(docptr, Mplus_ECCConf);
639 if (
ReadDOC(docptr, Mplus_ECCConf) & 0x80) {
643 printk(
"DiskOnChip ECC Error: Read at %lx\n", (
long)from);
647 for (i = 0; i < 6; i++)
648 syndrome[i] =
ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
652 printk(
"ECC Errors corrected: %x\n", nb_errors);
660 printk(
"%s(%d): Millennium Plus ECC error (from=0x%x:\n",
661 __FILE__, __LINE__, (
int)from);
662 printk(
" syndrome= %*phC\n", 6, syndrome);
663 printk(
" eccbuf= %*phC\n", 6, eccbuf);
670 printk(
"ECC DATA at %lx: %*ph\n", (
long)from, 6, eccbuf);
676 WriteDOC(0, docptr, Mplus_FlashSelect);
681 static int doc_write(
struct mtd_info *mtd, loff_t to,
size_t len,
682 size_t *retlen,
const u_char *buf)
684 int i, before, ret = 0;
690 struct Nand *mychip = &this->
chips[to >> (this->chipshift)];
693 if ((to & 0x1ff) || (len != 0x200))
699 DoC_CheckASIC(docptr);
702 if (this->curfloor != mychip->
floor) {
703 DoC_SelectFloor(docptr, mychip->
floor);
704 DoC_SelectChip(docptr, mychip->
chip);
705 }
else if (this->curchip != mychip->
chip) {
706 DoC_SelectChip(docptr, mychip->
chip);
708 this->curfloor = mychip->
floor;
709 this->curchip = mychip->
chip;
716 DoC_WaitReady(docptr);
720 WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
728 DoC_Address(
this, 3, fto, 0x00, 0x00);
735 WriteDOC(0x55, docptr, Mil_CDSN_IO);
736 WriteDOC(0x55, docptr, Mil_CDSN_IO);
742 MemWriteDOC(docptr, (
unsigned char *) buf, len);
746 DoC_Delay(docptr, 3);
749 for (i = 0; i < 6; i++)
750 eccbuf[i] =
ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
756 MemWriteDOC(docptr, eccbuf, 6);
760 WriteDOC(0x55, docptr, Mil_CDSN_IO+6);
761 WriteDOC(0x55, docptr, Mil_CDSN_IO+7);
765 printk(
"OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
766 (
long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
767 eccbuf[4], eccbuf[5]);
770 WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
771 WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
776 DoC_WaitReady(docptr);
781 dummy =
ReadDOC(docptr, Mplus_ReadPipeInit);
782 dummy =
ReadDOC(docptr, Mplus_ReadPipeInit);
783 DoC_Delay(docptr, 2);
784 if ((dummy =
ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
785 printk(
"MTD: Error 0x%x programming at 0x%x\n", dummy, (
int)to);
790 dummy =
ReadDOC(docptr, Mplus_LastDataRead);
793 WriteDOC(0, docptr, Mplus_FlashSelect);
801 static int doc_read_oob(
struct mtd_info *mtd, loff_t ofs,
807 struct Nand *mychip = &this->
chips[ofs >> this->chipshift];
808 size_t i,
size, got, want;
810 size_t len = ops->
len;
816 DoC_CheckASIC(docptr);
819 if (this->curfloor != mychip->
floor) {
820 DoC_SelectFloor(docptr, mychip->
floor);
821 DoC_SelectChip(docptr, mychip->
chip);
822 }
else if (this->curchip != mychip->
chip) {
823 DoC_SelectChip(docptr, mychip->
chip);
825 this->curfloor = mychip->
floor;
826 this->curchip = mychip->
chip;
833 DoC_WaitReady(docptr);
841 for (i = 0; ((i < 3) && (want > 0)); i++) {
848 }
else if (base < 6) {
849 DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0);
851 }
else if (base < 8) {
852 DoC_Command(docptr, DoC_GetFlagsOffset(mtd, &fofs), 0);
855 DoC_Command(docptr, DoC_GetHdrOffset(mtd, &fofs), 0);
862 DoC_Address(
this, 3, fofs, 0, 0x00);
863 WriteDOC(0, docptr, Mplus_FlashControl);
864 DoC_WaitReady(docptr);
866 ReadDOC(docptr, Mplus_ReadPipeInit);
867 ReadDOC(docptr, Mplus_ReadPipeInit);
868 MemReadDOC(docptr, &buf[got], size - 2);
869 buf[got + size - 2] =
ReadDOC(docptr, Mplus_LastDataRead);
870 buf[got + size - 1] =
ReadDOC(docptr, Mplus_LastDataRead);
878 WriteDOC(0, docptr, Mplus_FlashSelect);
884 static int doc_write_oob(
struct mtd_info *mtd, loff_t ofs,
891 struct Nand *mychip = &this->
chips[ofs >> this->chipshift];
892 size_t i,
size, got, want;
895 size_t len = ops->
len;
901 DoC_CheckASIC(docptr);
904 if (this->curfloor != mychip->
floor) {
905 DoC_SelectFloor(docptr, mychip->
floor);
906 DoC_SelectChip(docptr, mychip->
chip);
907 }
else if (this->curchip != mychip->
chip) {
908 DoC_SelectChip(docptr, mychip->
chip);
910 this->curfloor = mychip->
floor;
911 this->curchip = mychip->
chip;
923 for (i = 0; ((i < 3) && (want > 0)); i++) {
926 DoC_WaitReady(docptr);
934 }
else if (base < 6) {
935 WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
937 }
else if (base < 8) {
938 WriteDOC(DoC_GetFlagsOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
941 WriteDOC(DoC_GetHdrOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
949 DoC_Address(
this, 3, fofs, 0, 0x00);
956 MemWriteDOC(docptr, (
unsigned char *) &buf[got], size);
957 WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
958 WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
963 DoC_WaitReady(docptr);
968 dummy =
ReadDOC(docptr, Mplus_ReadPipeInit);
969 dummy =
ReadDOC(docptr, Mplus_ReadPipeInit);
970 DoC_Delay(docptr, 2);
971 if ((dummy =
ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
972 printk(
"MTD: Error 0x%x programming oob at 0x%x\n",
978 dummy =
ReadDOC(docptr, Mplus_LastDataRead);
986 WriteDOC(0, docptr, Mplus_FlashSelect);
999 struct Nand *mychip = &this->
chips[ofs >> this->chipshift];
1001 DoC_CheckASIC(docptr);
1008 if (this->curfloor != mychip->
floor) {
1009 DoC_SelectFloor(docptr, mychip->
floor);
1010 DoC_SelectChip(docptr, mychip->
chip);
1011 }
else if (this->curchip != mychip->
chip) {
1012 DoC_SelectChip(docptr, mychip->
chip);
1014 this->curfloor = mychip->
floor;
1015 this->curchip = mychip->
chip;
1023 DoC_WaitReady(docptr);
1026 DoC_Address(
this, 2, ofs, 0, 0x00);
1028 DoC_WaitReady(docptr);
1034 dummy =
ReadDOC(docptr, Mplus_ReadPipeInit);
1035 dummy =
ReadDOC(docptr, Mplus_ReadPipeInit);
1036 if ((dummy =
ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
1037 printk(
"MTD: Error 0x%x erasing at 0x%x\n", dummy, ofs);
1043 dummy =
ReadDOC(docptr, Mplus_LastDataRead);
1046 WriteDOC(0, docptr, Mplus_FlashSelect);
1059 static void __exit cleanup_doc2001plus(
void)
1064 while ((mtd=docmilpluslist)) {
1066 docmilpluslist = this->
nextdoc;