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