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