at v2.6.18 1112 lines 32 kB view raw
1/* 2 * Linux driver for Disk-On-Chip Millennium Plus 3 * 4 * (c) 2002-2003 Greg Ungerer <gerg@snapgear.com> 5 * (c) 2002-2003 SnapGear Inc 6 * (c) 1999 Machine Vision Holdings, Inc. 7 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 8 * 9 * $Id: doc2001plus.c,v 1.14 2005/11/07 11:14:24 gleixner Exp $ 10 * 11 * Released under GPL 12 */ 13 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <asm/errno.h> 17#include <asm/io.h> 18#include <asm/uaccess.h> 19#include <linux/miscdevice.h> 20#include <linux/pci.h> 21#include <linux/delay.h> 22#include <linux/slab.h> 23#include <linux/sched.h> 24#include <linux/init.h> 25#include <linux/types.h> 26#include <linux/bitops.h> 27 28#include <linux/mtd/mtd.h> 29#include <linux/mtd/nand.h> 30#include <linux/mtd/doc2000.h> 31 32/* #define ECC_DEBUG */ 33 34/* I have no idea why some DoC chips can not use memcop_form|to_io(). 35 * This may be due to the different revisions of the ASIC controller built-in or 36 * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment 37 * this:*/ 38#undef USE_MEMCPY 39 40static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, 41 size_t *retlen, u_char *buf); 42static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, 43 size_t *retlen, const u_char *buf); 44static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, 45 struct mtd_oob_ops *ops); 46static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, 47 struct mtd_oob_ops *ops); 48static int doc_erase (struct mtd_info *mtd, struct erase_info *instr); 49 50static struct mtd_info *docmilpluslist = NULL; 51 52 53/* Perform the required delay cycles by writing to the NOP register */ 54static void DoC_Delay(void __iomem * docptr, int cycles) 55{ 56 int i; 57 58 for (i = 0; (i < cycles); i++) 59 WriteDOC(0, docptr, Mplus_NOP); 60} 61 62#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) 63 64/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ 65static int _DoC_WaitReady(void __iomem * docptr) 66{ 67 unsigned int c = 0xffff; 68 69 DEBUG(MTD_DEBUG_LEVEL3, 70 "_DoC_WaitReady called for out-of-line wait\n"); 71 72 /* Out-of-line routine to wait for chip response */ 73 while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c) 74 ; 75 76 if (c == 0) 77 DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n"); 78 79 return (c == 0); 80} 81 82static inline int DoC_WaitReady(void __iomem * docptr) 83{ 84 /* This is inline, to optimise the common case, where it's ready instantly */ 85 int ret = 0; 86 87 /* read form NOP register should be issued prior to the read from CDSNControl 88 see Software Requirement 11.4 item 2. */ 89 DoC_Delay(docptr, 4); 90 91 if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) 92 /* Call the out-of-line routine to wait */ 93 ret = _DoC_WaitReady(docptr); 94 95 return ret; 96} 97 98/* For some reason the Millennium Plus seems to occassionally put itself 99 * into reset mode. For me this happens randomly, with no pattern that I 100 * can detect. M-systems suggest always check this on any block level 101 * operation and setting to normal mode if in reset mode. 102 */ 103static inline void DoC_CheckASIC(void __iomem * docptr) 104{ 105 /* Make sure the DoC is in normal mode */ 106 if ((ReadDOC(docptr, Mplus_DOCControl) & DOC_MODE_NORMAL) == 0) { 107 WriteDOC((DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_DOCControl); 108 WriteDOC(~(DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_CtrlConfirm); 109 } 110} 111 112/* DoC_Command: Send a flash command to the flash chip through the Flash 113 * command register. Need 2 Write Pipeline Terminates to complete send. 114 */ 115static void DoC_Command(void __iomem * docptr, unsigned char command, 116 unsigned char xtraflags) 117{ 118 WriteDOC(command, docptr, Mplus_FlashCmd); 119 WriteDOC(command, docptr, Mplus_WritePipeTerm); 120 WriteDOC(command, docptr, Mplus_WritePipeTerm); 121} 122 123/* DoC_Address: Set the current address for the flash chip through the Flash 124 * Address register. Need 2 Write Pipeline Terminates to complete send. 125 */ 126static inline void DoC_Address(struct DiskOnChip *doc, int numbytes, 127 unsigned long ofs, unsigned char xtraflags1, 128 unsigned char xtraflags2) 129{ 130 void __iomem * docptr = doc->virtadr; 131 132 /* Allow for possible Mill Plus internal flash interleaving */ 133 ofs >>= doc->interleave; 134 135 switch (numbytes) { 136 case 1: 137 /* Send single byte, bits 0-7. */ 138 WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress); 139 break; 140 case 2: 141 /* Send bits 9-16 followed by 17-23 */ 142 WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress); 143 WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress); 144 break; 145 case 3: 146 /* Send 0-7, 9-16, then 17-23 */ 147 WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress); 148 WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress); 149 WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress); 150 break; 151 default: 152 return; 153 } 154 155 WriteDOC(0x00, docptr, Mplus_WritePipeTerm); 156 WriteDOC(0x00, docptr, Mplus_WritePipeTerm); 157} 158 159/* DoC_SelectChip: Select a given flash chip within the current floor */ 160static int DoC_SelectChip(void __iomem * docptr, int chip) 161{ 162 /* No choice for flash chip on Millennium Plus */ 163 return 0; 164} 165 166/* DoC_SelectFloor: Select a given floor (bank of flash chips) */ 167static int DoC_SelectFloor(void __iomem * docptr, int floor) 168{ 169 WriteDOC((floor & 0x3), docptr, Mplus_DeviceSelect); 170 return 0; 171} 172 173/* 174 * Translate the given offset into the appropriate command and offset. 175 * This does the mapping using the 16bit interleave layout defined by 176 * M-Systems, and looks like this for a sector pair: 177 * +-----------+-------+-------+-------+--------------+---------+-----------+ 178 * | 0 --- 511 |512-517|518-519|520-521| 522 --- 1033 |1034-1039|1040 - 1055| 179 * +-----------+-------+-------+-------+--------------+---------+-----------+ 180 * | Data 0 | ECC 0 |Flags0 |Flags1 | Data 1 |ECC 1 | OOB 1 + 2 | 181 * +-----------+-------+-------+-------+--------------+---------+-----------+ 182 */ 183/* FIXME: This lives in INFTL not here. Other users of flash devices 184 may not want it */ 185static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from) 186{ 187 struct DiskOnChip *this = mtd->priv; 188 189 if (this->interleave) { 190 unsigned int ofs = *from & 0x3ff; 191 unsigned int cmd; 192 193 if (ofs < 512) { 194 cmd = NAND_CMD_READ0; 195 ofs &= 0x1ff; 196 } else if (ofs < 1014) { 197 cmd = NAND_CMD_READ1; 198 ofs = (ofs & 0x1ff) + 10; 199 } else { 200 cmd = NAND_CMD_READOOB; 201 ofs = ofs - 1014; 202 } 203 204 *from = (*from & ~0x3ff) | ofs; 205 return cmd; 206 } else { 207 /* No interleave */ 208 if ((*from) & 0x100) 209 return NAND_CMD_READ1; 210 return NAND_CMD_READ0; 211 } 212} 213 214static unsigned int DoC_GetECCOffset(struct mtd_info *mtd, loff_t *from) 215{ 216 unsigned int ofs, cmd; 217 218 if (*from & 0x200) { 219 cmd = NAND_CMD_READOOB; 220 ofs = 10 + (*from & 0xf); 221 } else { 222 cmd = NAND_CMD_READ1; 223 ofs = (*from & 0xf); 224 } 225 226 *from = (*from & ~0x3ff) | ofs; 227 return cmd; 228} 229 230static unsigned int DoC_GetFlagsOffset(struct mtd_info *mtd, loff_t *from) 231{ 232 unsigned int ofs, cmd; 233 234 cmd = NAND_CMD_READ1; 235 ofs = (*from & 0x200) ? 8 : 6; 236 *from = (*from & ~0x3ff) | ofs; 237 return cmd; 238} 239 240static unsigned int DoC_GetHdrOffset(struct mtd_info *mtd, loff_t *from) 241{ 242 unsigned int ofs, cmd; 243 244 cmd = NAND_CMD_READOOB; 245 ofs = (*from & 0x200) ? 24 : 16; 246 *from = (*from & ~0x3ff) | ofs; 247 return cmd; 248} 249 250static inline void MemReadDOC(void __iomem * docptr, unsigned char *buf, int len) 251{ 252#ifndef USE_MEMCPY 253 int i; 254 for (i = 0; i < len; i++) 255 buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i); 256#else 257 memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len); 258#endif 259} 260 261static inline void MemWriteDOC(void __iomem * docptr, unsigned char *buf, int len) 262{ 263#ifndef USE_MEMCPY 264 int i; 265 for (i = 0; i < len; i++) 266 WriteDOC(buf[i], docptr, Mil_CDSN_IO + i); 267#else 268 memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len); 269#endif 270} 271 272/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */ 273static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip) 274{ 275 int mfr, id, i, j; 276 volatile char dummy; 277 void __iomem * docptr = doc->virtadr; 278 279 /* Page in the required floor/chip */ 280 DoC_SelectFloor(docptr, floor); 281 DoC_SelectChip(docptr, chip); 282 283 /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ 284 WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect); 285 286 /* Reset the chip, see Software Requirement 11.4 item 1. */ 287 DoC_Command(docptr, NAND_CMD_RESET, 0); 288 DoC_WaitReady(docptr); 289 290 /* Read the NAND chip ID: 1. Send ReadID command */ 291 DoC_Command(docptr, NAND_CMD_READID, 0); 292 293 /* Read the NAND chip ID: 2. Send address byte zero */ 294 DoC_Address(doc, 1, 0x00, 0, 0x00); 295 296 WriteDOC(0, docptr, Mplus_FlashControl); 297 DoC_WaitReady(docptr); 298 299 /* Read the manufacturer and device id codes of the flash device through 300 CDSN IO register see Software Requirement 11.4 item 5.*/ 301 dummy = ReadDOC(docptr, Mplus_ReadPipeInit); 302 dummy = ReadDOC(docptr, Mplus_ReadPipeInit); 303 304 mfr = ReadDOC(docptr, Mil_CDSN_IO); 305 if (doc->interleave) 306 dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */ 307 308 id = ReadDOC(docptr, Mil_CDSN_IO); 309 if (doc->interleave) 310 dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */ 311 312 dummy = ReadDOC(docptr, Mplus_LastDataRead); 313 dummy = ReadDOC(docptr, Mplus_LastDataRead); 314 315 /* Disable flash internally */ 316 WriteDOC(0, docptr, Mplus_FlashSelect); 317 318 /* No response - return failure */ 319 if (mfr == 0xff || mfr == 0) 320 return 0; 321 322 for (i = 0; nand_flash_ids[i].name != NULL; i++) { 323 if (id == nand_flash_ids[i].id) { 324 /* Try to identify manufacturer */ 325 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { 326 if (nand_manuf_ids[j].id == mfr) 327 break; 328 } 329 printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, " 330 "Chip ID: %2.2X (%s:%s)\n", mfr, id, 331 nand_manuf_ids[j].name, nand_flash_ids[i].name); 332 doc->mfr = mfr; 333 doc->id = id; 334 doc->chipshift = ffs((nand_flash_ids[i].chipsize << 20)) - 1; 335 doc->erasesize = nand_flash_ids[i].erasesize << doc->interleave; 336 break; 337 } 338 } 339 340 if (nand_flash_ids[i].name == NULL) 341 return 0; 342 return 1; 343} 344 345/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */ 346static void DoC_ScanChips(struct DiskOnChip *this) 347{ 348 int floor, chip; 349 int numchips[MAX_FLOORS_MPLUS]; 350 int ret; 351 352 this->numchips = 0; 353 this->mfr = 0; 354 this->id = 0; 355 356 /* Work out the intended interleave setting */ 357 this->interleave = 0; 358 if (this->ChipID == DOC_ChipID_DocMilPlus32) 359 this->interleave = 1; 360 361 /* Check the ASIC agrees */ 362 if ( (this->interleave << 2) != 363 (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) { 364 u_char conf = ReadDOC(this->virtadr, Mplus_Configuration); 365 printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n", 366 this->interleave?"on (16-bit)":"off (8-bit)"); 367 conf ^= 4; 368 WriteDOC(conf, this->virtadr, Mplus_Configuration); 369 } 370 371 /* For each floor, find the number of valid chips it contains */ 372 for (floor = 0,ret = 1; floor < MAX_FLOORS_MPLUS; floor++) { 373 numchips[floor] = 0; 374 for (chip = 0; chip < MAX_CHIPS_MPLUS && ret != 0; chip++) { 375 ret = DoC_IdentChip(this, floor, chip); 376 if (ret) { 377 numchips[floor]++; 378 this->numchips++; 379 } 380 } 381 } 382 /* If there are none at all that we recognise, bail */ 383 if (!this->numchips) { 384 printk("No flash chips recognised.\n"); 385 return; 386 } 387 388 /* Allocate an array to hold the information for each chip */ 389 this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL); 390 if (!this->chips){ 391 printk("MTD: No memory for allocating chip info structures\n"); 392 return; 393 } 394 395 /* Fill out the chip array with {floor, chipno} for each 396 * detected chip in the device. */ 397 for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) { 398 for (chip = 0 ; chip < numchips[floor] ; chip++) { 399 this->chips[ret].floor = floor; 400 this->chips[ret].chip = chip; 401 this->chips[ret].curadr = 0; 402 this->chips[ret].curmode = 0x50; 403 ret++; 404 } 405 } 406 407 /* Calculate and print the total size of the device */ 408 this->totlen = this->numchips * (1 << this->chipshift); 409 printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n", 410 this->numchips ,this->totlen >> 20); 411} 412 413static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2) 414{ 415 int tmp1, tmp2, retval; 416 417 if (doc1->physadr == doc2->physadr) 418 return 1; 419 420 /* Use the alias resolution register which was set aside for this 421 * purpose. If it's value is the same on both chips, they might 422 * be the same chip, and we write to one and check for a change in 423 * the other. It's unclear if this register is usuable in the 424 * DoC 2000 (it's in the Millennium docs), but it seems to work. */ 425 tmp1 = ReadDOC(doc1->virtadr, Mplus_AliasResolution); 426 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); 427 if (tmp1 != tmp2) 428 return 0; 429 430 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution); 431 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); 432 if (tmp2 == (tmp1+1) % 0xff) 433 retval = 1; 434 else 435 retval = 0; 436 437 /* Restore register contents. May not be necessary, but do it just to 438 * be safe. */ 439 WriteDOC(tmp1, doc1->virtadr, Mplus_AliasResolution); 440 441 return retval; 442} 443 444/* This routine is found from the docprobe code by symbol_get(), 445 * which will bump the use count of this module. */ 446void DoCMilPlus_init(struct mtd_info *mtd) 447{ 448 struct DiskOnChip *this = mtd->priv; 449 struct DiskOnChip *old = NULL; 450 451 /* We must avoid being called twice for the same device. */ 452 if (docmilpluslist) 453 old = docmilpluslist->priv; 454 455 while (old) { 456 if (DoCMilPlus_is_alias(this, old)) { 457 printk(KERN_NOTICE "Ignoring DiskOnChip Millennium " 458 "Plus at 0x%lX - already configured\n", 459 this->physadr); 460 iounmap(this->virtadr); 461 kfree(mtd); 462 return; 463 } 464 if (old->nextdoc) 465 old = old->nextdoc->priv; 466 else 467 old = NULL; 468 } 469 470 mtd->name = "DiskOnChip Millennium Plus"; 471 printk(KERN_NOTICE "DiskOnChip Millennium Plus found at " 472 "address 0x%lX\n", this->physadr); 473 474 mtd->type = MTD_NANDFLASH; 475 mtd->flags = MTD_CAP_NANDFLASH; 476 mtd->ecctype = MTD_ECC_RS_DiskOnChip; 477 mtd->size = 0; 478 479 mtd->erasesize = 0; 480 mtd->writesize = 512; 481 mtd->oobsize = 16; 482 mtd->owner = THIS_MODULE; 483 mtd->erase = doc_erase; 484 mtd->point = NULL; 485 mtd->unpoint = NULL; 486 mtd->read = doc_read; 487 mtd->write = doc_write; 488 mtd->read_oob = doc_read_oob; 489 mtd->write_oob = doc_write_oob; 490 mtd->sync = NULL; 491 492 this->totlen = 0; 493 this->numchips = 0; 494 this->curfloor = -1; 495 this->curchip = -1; 496 497 /* Ident all the chips present. */ 498 DoC_ScanChips(this); 499 500 if (!this->totlen) { 501 kfree(mtd); 502 iounmap(this->virtadr); 503 } else { 504 this->nextdoc = docmilpluslist; 505 docmilpluslist = mtd; 506 mtd->size = this->totlen; 507 mtd->erasesize = this->erasesize; 508 add_mtd_device(mtd); 509 return; 510 } 511} 512EXPORT_SYMBOL_GPL(DoCMilPlus_init); 513 514#if 0 515static int doc_dumpblk(struct mtd_info *mtd, loff_t from) 516{ 517 int i; 518 loff_t fofs; 519 struct DiskOnChip *this = mtd->priv; 520 void __iomem * docptr = this->virtadr; 521 struct Nand *mychip = &this->chips[from >> (this->chipshift)]; 522 unsigned char *bp, buf[1056]; 523 char c[32]; 524 525 from &= ~0x3ff; 526 527 /* Don't allow read past end of device */ 528 if (from >= this->totlen) 529 return -EINVAL; 530 531 DoC_CheckASIC(docptr); 532 533 /* Find the chip which is to be used and select it */ 534 if (this->curfloor != mychip->floor) { 535 DoC_SelectFloor(docptr, mychip->floor); 536 DoC_SelectChip(docptr, mychip->chip); 537 } else if (this->curchip != mychip->chip) { 538 DoC_SelectChip(docptr, mychip->chip); 539 } 540 this->curfloor = mychip->floor; 541 this->curchip = mychip->chip; 542 543 /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ 544 WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect); 545 546 /* Reset the chip, see Software Requirement 11.4 item 1. */ 547 DoC_Command(docptr, NAND_CMD_RESET, 0); 548 DoC_WaitReady(docptr); 549 550 fofs = from; 551 DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0); 552 DoC_Address(this, 3, fofs, 0, 0x00); 553 WriteDOC(0, docptr, Mplus_FlashControl); 554 DoC_WaitReady(docptr); 555 556 /* disable the ECC engine */ 557 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); 558 559 ReadDOC(docptr, Mplus_ReadPipeInit); 560 ReadDOC(docptr, Mplus_ReadPipeInit); 561 562 /* Read the data via the internal pipeline through CDSN IO 563 register, see Pipelined Read Operations 11.3 */ 564 MemReadDOC(docptr, buf, 1054); 565 buf[1054] = ReadDOC(docptr, Mplus_LastDataRead); 566 buf[1055] = ReadDOC(docptr, Mplus_LastDataRead); 567 568 memset(&c[0], 0, sizeof(c)); 569 printk("DUMP OFFSET=%x:\n", (int)from); 570 571 for (i = 0, bp = &buf[0]; (i < 1056); i++) { 572 if ((i % 16) == 0) 573 printk("%08x: ", i); 574 printk(" %02x", *bp); 575 c[(i & 0xf)] = ((*bp >= 0x20) && (*bp <= 0x7f)) ? *bp : '.'; 576 bp++; 577 if (((i + 1) % 16) == 0) 578 printk(" %s\n", c); 579 } 580 printk("\n"); 581 582 /* Disable flash internally */ 583 WriteDOC(0, docptr, Mplus_FlashSelect); 584 585 return 0; 586} 587#endif 588 589static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, 590 size_t *retlen, u_char *buf) 591{ 592 int ret, i; 593 volatile char dummy; 594 loff_t fofs; 595 unsigned char syndrome[6], eccbuf[6]; 596 struct DiskOnChip *this = mtd->priv; 597 void __iomem * docptr = this->virtadr; 598 struct Nand *mychip = &this->chips[from >> (this->chipshift)]; 599 600 /* Don't allow read past end of device */ 601 if (from >= this->totlen) 602 return -EINVAL; 603 604 /* Don't allow a single read to cross a 512-byte block boundary */ 605 if (from + len > ((from | 0x1ff) + 1)) 606 len = ((from | 0x1ff) + 1) - from; 607 608 DoC_CheckASIC(docptr); 609 610 /* Find the chip which is to be used and select it */ 611 if (this->curfloor != mychip->floor) { 612 DoC_SelectFloor(docptr, mychip->floor); 613 DoC_SelectChip(docptr, mychip->chip); 614 } else if (this->curchip != mychip->chip) { 615 DoC_SelectChip(docptr, mychip->chip); 616 } 617 this->curfloor = mychip->floor; 618 this->curchip = mychip->chip; 619 620 /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ 621 WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect); 622 623 /* Reset the chip, see Software Requirement 11.4 item 1. */ 624 DoC_Command(docptr, NAND_CMD_RESET, 0); 625 DoC_WaitReady(docptr); 626 627 fofs = from; 628 DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0); 629 DoC_Address(this, 3, fofs, 0, 0x00); 630 WriteDOC(0, docptr, Mplus_FlashControl); 631 DoC_WaitReady(docptr); 632 633 /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ 634 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); 635 WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); 636 637 /* Let the caller know we completed it */ 638 *retlen = len; 639 ret = 0; 640 641 ReadDOC(docptr, Mplus_ReadPipeInit); 642 ReadDOC(docptr, Mplus_ReadPipeInit); 643 644 /* Read the data via the internal pipeline through CDSN IO 645 register, see Pipelined Read Operations 11.3 */ 646 MemReadDOC(docptr, buf, len); 647 648 /* Read the ECC data following raw data */ 649 MemReadDOC(docptr, eccbuf, 4); 650 eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead); 651 eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead); 652 653 /* Flush the pipeline */ 654 dummy = ReadDOC(docptr, Mplus_ECCConf); 655 dummy = ReadDOC(docptr, Mplus_ECCConf); 656 657 /* Check the ECC Status */ 658 if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) { 659 int nb_errors; 660 /* There was an ECC error */ 661#ifdef ECC_DEBUG 662 printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); 663#endif 664 /* Read the ECC syndrom through the DiskOnChip ECC logic. 665 These syndrome will be all ZERO when there is no error */ 666 for (i = 0; i < 6; i++) 667 syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); 668 669 nb_errors = doc_decode_ecc(buf, syndrome); 670#ifdef ECC_DEBUG 671 printk("ECC Errors corrected: %x\n", nb_errors); 672#endif 673 if (nb_errors < 0) { 674 /* We return error, but have actually done the 675 read. Not that this can be told to user-space, via 676 sys_read(), but at least MTD-aware stuff can know 677 about it by checking *retlen */ 678#ifdef ECC_DEBUG 679 printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n", 680 __FILE__, __LINE__, (int)from); 681 printk(" syndrome= %02x:%02x:%02x:%02x:%02x:" 682 "%02x\n", 683 syndrome[0], syndrome[1], syndrome[2], 684 syndrome[3], syndrome[4], syndrome[5]); 685 printk(" eccbuf= %02x:%02x:%02x:%02x:%02x:" 686 "%02x\n", 687 eccbuf[0], eccbuf[1], eccbuf[2], 688 eccbuf[3], eccbuf[4], eccbuf[5]); 689#endif 690 ret = -EIO; 691 } 692 } 693 694#ifdef PSYCHO_DEBUG 695 printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 696 (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], 697 eccbuf[4], eccbuf[5]); 698#endif 699 /* disable the ECC engine */ 700 WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf); 701 702 /* Disable flash internally */ 703 WriteDOC(0, docptr, Mplus_FlashSelect); 704 705 return ret; 706} 707 708static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, 709 size_t *retlen, const u_char *buf) 710{ 711 int i, before, ret = 0; 712 loff_t fto; 713 volatile char dummy; 714 char eccbuf[6]; 715 struct DiskOnChip *this = mtd->priv; 716 void __iomem * docptr = this->virtadr; 717 struct Nand *mychip = &this->chips[to >> (this->chipshift)]; 718 719 /* Don't allow write past end of device */ 720 if (to >= this->totlen) 721 return -EINVAL; 722 723 /* Don't allow writes which aren't exactly one block (512 bytes) */ 724 if ((to & 0x1ff) || (len != 0x200)) 725 return -EINVAL; 726 727 /* Determine position of OOB flags, before or after data */ 728 before = (this->interleave && (to & 0x200)); 729 730 DoC_CheckASIC(docptr); 731 732 /* Find the chip which is to be used and select it */ 733 if (this->curfloor != mychip->floor) { 734 DoC_SelectFloor(docptr, mychip->floor); 735 DoC_SelectChip(docptr, mychip->chip); 736 } else if (this->curchip != mychip->chip) { 737 DoC_SelectChip(docptr, mychip->chip); 738 } 739 this->curfloor = mychip->floor; 740 this->curchip = mychip->chip; 741 742 /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ 743 WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect); 744 745 /* Reset the chip, see Software Requirement 11.4 item 1. */ 746 DoC_Command(docptr, NAND_CMD_RESET, 0); 747 DoC_WaitReady(docptr); 748 749 /* Set device to appropriate plane of flash */ 750 fto = to; 751 WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd); 752 753 /* On interleaved devices the flags for 2nd half 512 are before data */ 754 if (eccbuf && before) 755 fto -= 2; 756 757 /* issue the Serial Data In command to initial the Page Program process */ 758 DoC_Command(docptr, NAND_CMD_SEQIN, 0x00); 759 DoC_Address(this, 3, fto, 0x00, 0x00); 760 761 /* Disable the ECC engine */ 762 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); 763 764 if (before) { 765 /* Write the block status BLOCK_USED (0x5555) */ 766 WriteDOC(0x55, docptr, Mil_CDSN_IO); 767 WriteDOC(0x55, docptr, Mil_CDSN_IO); 768 } 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 773 MemWriteDOC(docptr, (unsigned char *) buf, len); 774 775 /* Write ECC data to flash, the ECC info is generated by 776 the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */ 777 DoC_Delay(docptr, 3); 778 779 /* Read the ECC data through the DiskOnChip ECC logic */ 780 for (i = 0; i < 6; i++) 781 eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); 782 783 /* disable the ECC engine */ 784 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); 785 786 /* Write the ECC data to flash */ 787 MemWriteDOC(docptr, eccbuf, 6); 788 789 if (!before) { 790 /* Write the block status BLOCK_USED (0x5555) */ 791 WriteDOC(0x55, docptr, Mil_CDSN_IO+6); 792 WriteDOC(0x55, docptr, Mil_CDSN_IO+7); 793 } 794 795#ifdef PSYCHO_DEBUG 796 printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 797 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], 798 eccbuf[4], eccbuf[5]); 799#endif 800 801 WriteDOC(0x00, docptr, Mplus_WritePipeTerm); 802 WriteDOC(0x00, docptr, Mplus_WritePipeTerm); 803 804 /* Commit the Page Program command and wait for ready 805 see Software Requirement 11.4 item 1.*/ 806 DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00); 807 DoC_WaitReady(docptr); 808 809 /* Read the status of the flash device through CDSN IO register 810 see Software Requirement 11.4 item 5.*/ 811 DoC_Command(docptr, NAND_CMD_STATUS, 0); 812 dummy = ReadDOC(docptr, Mplus_ReadPipeInit); 813 dummy = ReadDOC(docptr, Mplus_ReadPipeInit); 814 DoC_Delay(docptr, 2); 815 if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) { 816 printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to); 817 /* Error in programming 818 FIXME: implement Bad Block Replacement (in nftl.c ??) */ 819 *retlen = 0; 820 ret = -EIO; 821 } 822 dummy = ReadDOC(docptr, Mplus_LastDataRead); 823 824 /* Disable flash internally */ 825 WriteDOC(0, docptr, Mplus_FlashSelect); 826 827 /* Let the caller know we completed it */ 828 *retlen = len; 829 830 return ret; 831} 832 833static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, 834 struct mtd_oob_ops *ops) 835{ 836 loff_t fofs, base; 837 struct DiskOnChip *this = mtd->priv; 838 void __iomem * docptr = this->virtadr; 839 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 840 size_t i, size, got, want; 841 uint8_t *buf = ops->oobbuf; 842 size_t len = ops->len; 843 844 BUG_ON(ops->mode != MTD_OOB_PLACE); 845 846 ofs += ops->ooboffs; 847 848 DoC_CheckASIC(docptr); 849 850 /* Find the chip which is to be used and select it */ 851 if (this->curfloor != mychip->floor) { 852 DoC_SelectFloor(docptr, mychip->floor); 853 DoC_SelectChip(docptr, mychip->chip); 854 } else if (this->curchip != mychip->chip) { 855 DoC_SelectChip(docptr, mychip->chip); 856 } 857 this->curfloor = mychip->floor; 858 this->curchip = mychip->chip; 859 860 /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ 861 WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect); 862 863 /* disable the ECC engine */ 864 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); 865 DoC_WaitReady(docptr); 866 867 /* Maximum of 16 bytes in the OOB region, so limit read to that */ 868 if (len > 16) 869 len = 16; 870 got = 0; 871 want = len; 872 873 for (i = 0; ((i < 3) && (want > 0)); i++) { 874 /* Figure out which region we are accessing... */ 875 fofs = ofs; 876 base = ofs & 0xf; 877 if (!this->interleave) { 878 DoC_Command(docptr, NAND_CMD_READOOB, 0); 879 size = 16 - base; 880 } else if (base < 6) { 881 DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0); 882 size = 6 - base; 883 } else if (base < 8) { 884 DoC_Command(docptr, DoC_GetFlagsOffset(mtd, &fofs), 0); 885 size = 8 - base; 886 } else { 887 DoC_Command(docptr, DoC_GetHdrOffset(mtd, &fofs), 0); 888 size = 16 - base; 889 } 890 if (size > want) 891 size = want; 892 893 /* Issue read command */ 894 DoC_Address(this, 3, fofs, 0, 0x00); 895 WriteDOC(0, docptr, Mplus_FlashControl); 896 DoC_WaitReady(docptr); 897 898 ReadDOC(docptr, Mplus_ReadPipeInit); 899 ReadDOC(docptr, Mplus_ReadPipeInit); 900 MemReadDOC(docptr, &buf[got], size - 2); 901 buf[got + size - 2] = ReadDOC(docptr, Mplus_LastDataRead); 902 buf[got + size - 1] = ReadDOC(docptr, Mplus_LastDataRead); 903 904 ofs += size; 905 got += size; 906 want -= size; 907 } 908 909 /* Disable flash internally */ 910 WriteDOC(0, docptr, Mplus_FlashSelect); 911 912 ops->retlen = len; 913 return 0; 914} 915 916static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, 917 struct mtd_oob_ops *ops) 918{ 919 volatile char dummy; 920 loff_t fofs, base; 921 struct DiskOnChip *this = mtd->priv; 922 void __iomem * docptr = this->virtadr; 923 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 924 size_t i, size, got, want; 925 int ret = 0; 926 uint8_t *buf = ops->oobbuf; 927 size_t len = ops->len; 928 929 BUG_ON(ops->mode != MTD_OOB_PLACE); 930 931 ofs += ops->ooboffs; 932 933 DoC_CheckASIC(docptr); 934 935 /* Find the chip which is to be used and select it */ 936 if (this->curfloor != mychip->floor) { 937 DoC_SelectFloor(docptr, mychip->floor); 938 DoC_SelectChip(docptr, mychip->chip); 939 } else if (this->curchip != mychip->chip) { 940 DoC_SelectChip(docptr, mychip->chip); 941 } 942 this->curfloor = mychip->floor; 943 this->curchip = mychip->chip; 944 945 /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ 946 WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect); 947 948 949 /* Maximum of 16 bytes in the OOB region, so limit write to that */ 950 if (len > 16) 951 len = 16; 952 got = 0; 953 want = len; 954 955 for (i = 0; ((i < 3) && (want > 0)); i++) { 956 /* Reset the chip, see Software Requirement 11.4 item 1. */ 957 DoC_Command(docptr, NAND_CMD_RESET, 0); 958 DoC_WaitReady(docptr); 959 960 /* Figure out which region we are accessing... */ 961 fofs = ofs; 962 base = ofs & 0x0f; 963 if (!this->interleave) { 964 WriteDOC(NAND_CMD_READOOB, docptr, Mplus_FlashCmd); 965 size = 16 - base; 966 } else if (base < 6) { 967 WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd); 968 size = 6 - base; 969 } else if (base < 8) { 970 WriteDOC(DoC_GetFlagsOffset(mtd, &fofs), docptr, Mplus_FlashCmd); 971 size = 8 - base; 972 } else { 973 WriteDOC(DoC_GetHdrOffset(mtd, &fofs), docptr, Mplus_FlashCmd); 974 size = 16 - base; 975 } 976 if (size > want) 977 size = want; 978 979 /* Issue the Serial Data In command to initial the Page Program process */ 980 DoC_Command(docptr, NAND_CMD_SEQIN, 0x00); 981 DoC_Address(this, 3, fofs, 0, 0x00); 982 983 /* Disable the ECC engine */ 984 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); 985 986 /* Write the data via the internal pipeline through CDSN IO 987 register, see Pipelined Write Operations 11.2 */ 988 MemWriteDOC(docptr, (unsigned char *) &buf[got], size); 989 WriteDOC(0x00, docptr, Mplus_WritePipeTerm); 990 WriteDOC(0x00, docptr, Mplus_WritePipeTerm); 991 992 /* Commit the Page Program command and wait for ready 993 see Software Requirement 11.4 item 1.*/ 994 DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00); 995 DoC_WaitReady(docptr); 996 997 /* Read the status of the flash device through CDSN IO register 998 see Software Requirement 11.4 item 5.*/ 999 DoC_Command(docptr, NAND_CMD_STATUS, 0x00); 1000 dummy = ReadDOC(docptr, Mplus_ReadPipeInit); 1001 dummy = ReadDOC(docptr, Mplus_ReadPipeInit); 1002 DoC_Delay(docptr, 2); 1003 if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) { 1004 printk("MTD: Error 0x%x programming oob at 0x%x\n", 1005 dummy, (int)ofs); 1006 /* FIXME: implement Bad Block Replacement */ 1007 ops->retlen = 0; 1008 ret = -EIO; 1009 } 1010 dummy = ReadDOC(docptr, Mplus_LastDataRead); 1011 1012 ofs += size; 1013 got += size; 1014 want -= size; 1015 } 1016 1017 /* Disable flash internally */ 1018 WriteDOC(0, docptr, Mplus_FlashSelect); 1019 1020 ops->retlen = len; 1021 return ret; 1022} 1023 1024int doc_erase(struct mtd_info *mtd, struct erase_info *instr) 1025{ 1026 volatile char dummy; 1027 struct DiskOnChip *this = mtd->priv; 1028 __u32 ofs = instr->addr; 1029 __u32 len = instr->len; 1030 void __iomem * docptr = this->virtadr; 1031 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 1032 1033 DoC_CheckASIC(docptr); 1034 1035 if (len != mtd->erasesize) 1036 printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n", 1037 len, mtd->erasesize); 1038 1039 /* Find the chip which is to be used and select it */ 1040 if (this->curfloor != mychip->floor) { 1041 DoC_SelectFloor(docptr, mychip->floor); 1042 DoC_SelectChip(docptr, mychip->chip); 1043 } else if (this->curchip != mychip->chip) { 1044 DoC_SelectChip(docptr, mychip->chip); 1045 } 1046 this->curfloor = mychip->floor; 1047 this->curchip = mychip->chip; 1048 1049 instr->state = MTD_ERASE_PENDING; 1050 1051 /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ 1052 WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect); 1053 1054 DoC_Command(docptr, NAND_CMD_RESET, 0x00); 1055 DoC_WaitReady(docptr); 1056 1057 DoC_Command(docptr, NAND_CMD_ERASE1, 0); 1058 DoC_Address(this, 2, ofs, 0, 0x00); 1059 DoC_Command(docptr, NAND_CMD_ERASE2, 0); 1060 DoC_WaitReady(docptr); 1061 instr->state = MTD_ERASING; 1062 1063 /* Read the status of the flash device through CDSN IO register 1064 see Software Requirement 11.4 item 5. */ 1065 DoC_Command(docptr, NAND_CMD_STATUS, 0); 1066 dummy = ReadDOC(docptr, Mplus_ReadPipeInit); 1067 dummy = ReadDOC(docptr, Mplus_ReadPipeInit); 1068 if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) { 1069 printk("MTD: Error 0x%x erasing at 0x%x\n", dummy, ofs); 1070 /* FIXME: implement Bad Block Replacement (in nftl.c ??) */ 1071 instr->state = MTD_ERASE_FAILED; 1072 } else { 1073 instr->state = MTD_ERASE_DONE; 1074 } 1075 dummy = ReadDOC(docptr, Mplus_LastDataRead); 1076 1077 /* Disable flash internally */ 1078 WriteDOC(0, docptr, Mplus_FlashSelect); 1079 1080 mtd_erase_callback(instr); 1081 1082 return 0; 1083} 1084 1085/**************************************************************************** 1086 * 1087 * Module stuff 1088 * 1089 ****************************************************************************/ 1090 1091static void __exit cleanup_doc2001plus(void) 1092{ 1093 struct mtd_info *mtd; 1094 struct DiskOnChip *this; 1095 1096 while ((mtd=docmilpluslist)) { 1097 this = mtd->priv; 1098 docmilpluslist = this->nextdoc; 1099 1100 del_mtd_device(mtd); 1101 1102 iounmap(this->virtadr); 1103 kfree(this->chips); 1104 kfree(mtd); 1105 } 1106} 1107 1108module_exit(cleanup_doc2001plus); 1109 1110MODULE_LICENSE("GPL"); 1111MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al."); 1112MODULE_DESCRIPTION("Driver for DiskOnChip Millennium Plus");