Commit ef0921d6b05aeb9034158f9bef5323d6da9c925e

Authored by Kyungmin Park
Committed by Scott Wood
1 parent 4d0b54685c

Sync with 2.6.27

Sync with OneNAND kernel codes

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

Showing 6 changed files with 406 additions and 179 deletions Side-by-side Diff

drivers/mtd/onenand/onenand_base.c
... ... @@ -78,21 +78,12 @@
78 78 *
79 79 * Setup Start Address 1 Register (F100h)
80 80 */
81   -static int onenand_block_address(int device, int block)
  81 +static int onenand_block_address(struct onenand_chip *this, int block)
82 82 {
83   - if (device & ONENAND_DEVICE_IS_DDP) {
84   - /* Device Flash Core select, NAND Flash Block Address */
85   - int dfs = 0, density, mask;
  83 + /* Device Flash Core select, NAND Flash Block Address */
  84 + if (block & this->density_mask)
  85 + return ONENAND_DDP_CHIP1 | (block ^ this->density_mask);
86 86  
87   - density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
88   - mask = (1 << (density + 6));
89   -
90   - if (block & mask)
91   - dfs = 1;
92   -
93   - return (dfs << ONENAND_DDP_SHIFT) | (block & (mask - 1));
94   - }
95   -
96 87 return block;
97 88 }
98 89  
99 90  
100 91  
... ... @@ -104,22 +95,13 @@
104 95 *
105 96 * Setup Start Address 2 Register (F101h) for DDP
106 97 */
107   -static int onenand_bufferram_address(int device, int block)
  98 +static int onenand_bufferram_address(struct onenand_chip *this, int block)
108 99 {
109   - if (device & ONENAND_DEVICE_IS_DDP) {
110   - /* Device BufferRAM Select */
111   - int dbs = 0, density, mask;
  100 + /* Device BufferRAM Select */
  101 + if (block & this->density_mask)
  102 + return ONENAND_DDP_CHIP1;
112 103  
113   - density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
114   - mask = (1 << (density + 6));
115   -
116   - if (block & mask)
117   - dbs = 1;
118   -
119   - return (dbs << ONENAND_DDP_SHIFT);
120   - }
121   -
122   - return 0;
  104 + return ONENAND_DDP_CHIP0;
123 105 }
124 106  
125 107 /**
... ... @@ -169,6 +151,18 @@
169 151 }
170 152  
171 153 /**
  154 + * onenand_get_density - [DEFAULT] Get OneNAND density
  155 + * @param dev_id OneNAND device ID
  156 + *
  157 + * Get OneNAND density from device ID
  158 + */
  159 +static inline int onenand_get_density(int dev_id)
  160 +{
  161 + int density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
  162 + return (density & ONENAND_DEVICE_DENSITY_MASK);
  163 +}
  164 +
  165 +/**
172 166 * onenand_command - [DEFAULT] Send command to OneNAND device
173 167 * @param mtd MTD device structure
174 168 * @param cmd the command to be sent
... ... @@ -192,6 +186,7 @@
192 186 case ONENAND_CMD_UNLOCK:
193 187 case ONENAND_CMD_LOCK:
194 188 case ONENAND_CMD_LOCK_TIGHT:
  189 + case ONENAND_CMD_UNLOCK_ALL:
195 190 block = -1;
196 191 page = -1;
197 192 break;
... ... @@ -212,7 +207,7 @@
212 207 /* NOTE: The setting order of the registers is very important! */
213 208 if (cmd == ONENAND_CMD_BUFFERRAM) {
214 209 /* Select DataRAM for DDP */
215   - value = onenand_bufferram_address(this->device_id, block);
  210 + value = onenand_bufferram_address(this, block);
216 211 this->write_word(value,
217 212 this->base + ONENAND_REG_START_ADDRESS2);
218 213  
219 214  
... ... @@ -224,9 +219,14 @@
224 219  
225 220 if (block != -1) {
226 221 /* Write 'DFS, FBA' of Flash */
227   - value = onenand_block_address(this->device_id, block);
  222 + value = onenand_block_address(this, block);
228 223 this->write_word(value,
229 224 this->base + ONENAND_REG_START_ADDRESS1);
  225 +
  226 + /* Write 'DFS, FBA' of Flash */
  227 + value = onenand_bufferram_address(this, block);
  228 + this->write_word(value,
  229 + this->base + ONENAND_REG_START_ADDRESS2);
230 230 }
231 231  
232 232 if (page != -1) {
... ... @@ -252,15 +252,6 @@
252 252 /* Write 'BSA, BSC' of DataRAM */
253 253 value = onenand_buffer_address(dataram, sectors, count);
254 254 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
255   -
256   - if (readcmd) {
257   - /* Select DataRAM for DDP */
258   - value =
259   - onenand_bufferram_address(this->device_id, block);
260   - this->write_word(value,
261   - this->base +
262   - ONENAND_REG_START_ADDRESS2);
263   - }
264 255 }
265 256  
266 257 /* Interrupt clear */
267 258  
... ... @@ -296,14 +287,11 @@
296 287 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
297 288  
298 289 if (ctrl & ONENAND_CTRL_ERROR) {
299   - MTDDEBUG (MTD_DEBUG_LEVEL0,
300   - "onenand_wait: controller error = 0x%04x\n", ctrl);
301   - return -EAGAIN;
302   - }
  290 + printk("onenand_wait: controller error = 0x%04x\n", ctrl);
  291 + if (ctrl & ONENAND_CTRL_LOCK)
  292 + printk("onenand_wait: it's locked error = 0x%04x\n",
  293 + ctrl);
303 294  
304   - if (ctrl & ONENAND_CTRL_LOCK) {
305   - MTDDEBUG (MTD_DEBUG_LEVEL0,
306   - "onenand_wait: it's locked error = 0x%04x\n", ctrl);
307 295 return -EIO;
308 296 }
309 297  
... ... @@ -351,7 +339,7 @@
351 339 *
352 340 * Read the BufferRAM area
353 341 */
354   -static int onenand_read_bufferram(struct mtd_info *mtd, int area,
  342 +static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
355 343 unsigned char *buffer, int offset,
356 344 size_t count)
357 345 {
... ... @@ -376,7 +364,7 @@
376 364 *
377 365 * Read the BufferRAM area with Sync. Burst Mode
378 366 */
379   -static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
  367 +static int onenand_sync_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
380 368 unsigned char *buffer, int offset,
381 369 size_t count)
382 370 {
... ... @@ -405,7 +393,7 @@
405 393 *
406 394 * Write the BufferRAM area
407 395 */
408   -static int onenand_write_bufferram(struct mtd_info *mtd, int area,
  396 +static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
409 397 const unsigned char *buffer, int offset,
410 398 size_t count)
411 399 {
412 400  
413 401  
414 402  
415 403  
... ... @@ -431,21 +419,39 @@
431 419 static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
432 420 {
433 421 struct onenand_chip *this = mtd->priv;
434   - int block, page;
435   - int i;
  422 + int blockpage, found = 0;
  423 + unsigned int i;
436 424  
437   - block = (int)(addr >> this->erase_shift);
438   - page = (int)(addr >> this->page_shift);
439   - page &= this->page_mask;
  425 +#ifdef CONFIG_S3C64XX
  426 + return 0;
  427 +#endif
440 428  
441   - i = ONENAND_CURRENT_BUFFERRAM(this);
  429 + if (ONENAND_IS_2PLANE(this))
  430 + blockpage = onenand_get_2x_blockpage(mtd, addr);
  431 + else
  432 + blockpage = (int) (addr >> this->page_shift);
442 433  
443 434 /* Is there valid data? */
444   - if (this->bufferram[i].block == block &&
445   - this->bufferram[i].page == page && this->bufferram[i].valid)
446   - return 1;
  435 + i = ONENAND_CURRENT_BUFFERRAM(this);
  436 + if (this->bufferram[i].blockpage == blockpage)
  437 + found = 1;
  438 + else {
  439 + /* Check another BufferRAM */
  440 + i = ONENAND_NEXT_BUFFERRAM(this);
  441 + if (this->bufferram[i].blockpage == blockpage) {
  442 + ONENAND_SET_NEXT_BUFFERRAM(this);
  443 + found = 1;
  444 + }
  445 + }
447 446  
448   - return 0;
  447 + if (found && ONENAND_IS_DDP(this)) {
  448 + /* Select DataRAM for DDP */
  449 + int block = (int) (addr >> this->erase_shift);
  450 + int value = onenand_bufferram_address(this, block);
  451 + this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
  452 + }
  453 +
  454 + return found;
449 455 }
450 456  
451 457 /**
452 458  
453 459  
454 460  
... ... @@ -460,25 +466,25 @@
460 466 int valid)
461 467 {
462 468 struct onenand_chip *this = mtd->priv;
463   - int block, page;
464   - int i;
  469 + int blockpage;
  470 + unsigned int i;
465 471  
466   - block = (int)(addr >> this->erase_shift);
467   - page = (int)(addr >> this->page_shift);
468   - page &= this->page_mask;
  472 + if (ONENAND_IS_2PLANE(this))
  473 + blockpage = onenand_get_2x_blockpage(mtd, addr);
  474 + else
  475 + blockpage = (int)(addr >> this->page_shift);
469 476  
470   - /* Invalidate BufferRAM */
471   - for (i = 0; i < MAX_BUFFERRAM; i++) {
472   - if (this->bufferram[i].block == block &&
473   - this->bufferram[i].page == page)
474   - this->bufferram[i].valid = 0;
475   - }
  477 + /* Invalidate another BufferRAM */
  478 + i = ONENAND_NEXT_BUFFERRAM(this);
  479 + if (this->bufferram[i].blockpage == blockpage)
  480 + this->bufferram[i].blockpage = -1;
476 481  
477 482 /* Update BufferRAM */
478 483 i = ONENAND_CURRENT_BUFFERRAM(this);
479   - this->bufferram[i].block = block;
480   - this->bufferram[i].page = page;
481   - this->bufferram[i].valid = valid;
  484 + if (valid)
  485 + this->bufferram[i].blockpage = blockpage;
  486 + else
  487 + this->bufferram[i].blockpage = -1;
482 488  
483 489 return 0;
484 490 }
485 491  
... ... @@ -500,10 +506,10 @@
500 506  
501 507 /* Invalidate BufferRAM */
502 508 for (i = 0; i < MAX_BUFFERRAM; i++) {
503   - loff_t buf_addr = this->bufferram[i].block << this->erase_shift;
  509 + loff_t buf_addr = this->bufferram[i].blockpage << this->page_shift;
504 510  
505 511 if (buf_addr >= addr && buf_addr < end_addr)
506   - this->bufferram[i].valid = 0;
  512 + this->bufferram[i].blockpage = -1;
507 513 }
508 514 }
509 515  
... ... @@ -556,7 +562,7 @@
556 562 readend += free->offset - lastgap;
557 563 lastgap = free->offset + free->length;
558 564 }
559   - this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
  565 + this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
560 566 free = this->ecclayout->oobfree;
561 567 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
562 568 int free_end = free->offset + free->length;
... ... @@ -594,9 +600,7 @@
594 600 int ret = 0, boundary = 0;
595 601 int writesize = this->writesize;
596 602  
597   - MTDDEBUG(MTD_DEBUG_LEVEL3,
598   - "onenand_read_ops_nolock: from = 0x%08x, len = %i\n",
599   - (unsigned int) from, (int) len);
  603 + MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
600 604  
601 605 if (ops->mode == MTD_OOB_AUTO)
602 606 oobsize = this->ecclayout->oobavail;
... ... @@ -620,6 +624,7 @@
620 624 /* Do first load to bufferRAM */
621 625 if (read < len) {
622 626 if (!onenand_check_bufferram(mtd, from)) {
  627 + this->main_buf = buf;
623 628 this->command(mtd, ONENAND_CMD_READ, from, writesize);
624 629 ret = this->wait(mtd, FL_READING);
625 630 onenand_update_bufferram(mtd, from, !ret);
... ... @@ -637,6 +642,7 @@
637 642 /* If there is more to load then start next load */
638 643 from += thislen;
639 644 if (read + thislen < len) {
  645 + this->main_buf = buf + thislen;
640 646 this->command(mtd, ONENAND_CMD_READ, from, writesize);
641 647 /*
642 648 * Chip boundary handling in DDP
... ... @@ -653,7 +659,7 @@
653 659 }
654 660  
655 661 /* While load is going, read from last bufferRAM */
656   - this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
  662 + this->read_bufferram(mtd, from - thislen, ONENAND_DATARAM, buf, column, thislen);
657 663  
658 664 /* Read oob area if needed */
659 665 if (oobbuf) {
... ... @@ -663,7 +669,7 @@
663 669 if (ops->mode == MTD_OOB_AUTO)
664 670 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
665 671 else
666   - this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
  672 + this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
667 673 oobread += thisooblen;
668 674 oobbuf += thisooblen;
669 675 oobcolumn = 0;
... ... @@ -726,9 +732,7 @@
726 732  
727 733 from += ops->ooboffs;
728 734  
729   - MTDDEBUG(MTD_DEBUG_LEVEL3,
730   - "onenand_read_oob_nolock: from = 0x%08x, len = %i\n",
731   - (unsigned int) from, (int) len);
  735 + MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
732 736  
733 737 /* Initialize return length value */
734 738 ops->oobretlen = 0;
... ... @@ -759,6 +763,7 @@
759 763 thislen = oobsize - column;
760 764 thislen = min_t(int, thislen, len);
761 765  
  766 + this->spare_buf = buf;
762 767 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
763 768  
764 769 onenand_update_bufferram(mtd, from, 0);
... ... @@ -772,7 +777,7 @@
772 777 if (mode == MTD_OOB_AUTO)
773 778 onenand_transfer_auto_oob(mtd, buf, column, thislen);
774 779 else
775   - this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
  780 + this->read_bufferram(mtd, 0, ONENAND_SPARERAM, buf, column, thislen);
776 781  
777 782 read += thislen;
778 783  
... ... @@ -886,12 +891,6 @@
886 891 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
887 892 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
888 893  
889   - /* Initial bad block case: 0x2400 or 0x0400 */
890   - if (ctrl & ONENAND_CTRL_ERROR) {
891   - printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl);
892   - return ONENAND_BBT_READ_ERROR;
893   - }
894   -
895 894 if (interrupt & ONENAND_INT_READ) {
896 895 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
897 896 if (ecc & ONENAND_ECC_2BIT_ALL)
... ... @@ -902,6 +901,12 @@
902 901 return ONENAND_BBT_READ_FATAL_ERROR;
903 902 }
904 903  
  904 + /* Initial bad block case: 0x2400 or 0x0400 */
  905 + if (ctrl & ONENAND_CTRL_ERROR) {
  906 + printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl);
  907 + return ONENAND_BBT_READ_ERROR;
  908 + }
  909 +
905 910 return 0;
906 911 }
907 912  
... ... @@ -922,9 +927,7 @@
922 927 size_t len = ops->ooblen;
923 928 u_char *buf = ops->oobbuf;
924 929  
925   - MTDDEBUG(MTD_DEBUG_LEVEL3,
926   - "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n",
927   - (unsigned int) from, len);
  930 + MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n", (unsigned int) from, len);
928 931  
929 932 /* Initialize return value */
930 933 ops->oobretlen = 0;
931 934  
932 935  
... ... @@ -945,15 +948,16 @@
945 948 thislen = mtd->oobsize - column;
946 949 thislen = min_t(int, thislen, len);
947 950  
  951 + this->spare_buf = buf;
948 952 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
949 953  
950 954 onenand_update_bufferram(mtd, from, 0);
951 955  
952   - ret = onenand_bbt_wait(mtd, FL_READING);
  956 + ret = this->bbt_wait(mtd, FL_READING);
953 957 if (ret)
954 958 break;
955 959  
956   - this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
  960 + this->read_spareram(mtd, 0, ONENAND_SPARERAM, buf, column, thislen);
957 961 read += thislen;
958 962 if (read == len)
959 963 break;
... ... @@ -995,7 +999,7 @@
995 999 if (status)
996 1000 return status;
997 1001  
998   - this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
  1002 + this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
999 1003 for (i = 0; i < mtd->oobsize; i++)
1000 1004 if (buf[i] != 0xFF && buf[i] != oob_buf[i])
1001 1005 return -EBADMSG;
... ... @@ -1115,9 +1119,7 @@
1115 1119 u_char *oobbuf;
1116 1120 int ret = 0;
1117 1121  
1118   - MTDDEBUG(MTD_DEBUG_LEVEL3,
1119   - "onenand_write_ops_nolock: to = 0x%08x, len = %i\n",
1120   - (unsigned int) to, (int) len);
  1122 + MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ops_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
1121 1123  
1122 1124 /* Initialize retlen, in case of early exit */
1123 1125 ops->retlen = 0;
... ... @@ -1161,7 +1163,7 @@
1161 1163 wbuf = this->page_buf;
1162 1164 }
1163 1165  
1164   - this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
  1166 + this->write_bufferram(mtd, to, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1165 1167  
1166 1168 if (oob) {
1167 1169 oobbuf = this->oob_buf;
... ... @@ -1180,7 +1182,7 @@
1180 1182 } else
1181 1183 oobbuf = (u_char *) ffchars;
1182 1184  
1183   - this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
  1185 + this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1184 1186  
1185 1187 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1186 1188  
... ... @@ -1244,9 +1246,7 @@
1244 1246  
1245 1247 to += ops->ooboffs;
1246 1248  
1247   - MTDDEBUG(MTD_DEBUG_LEVEL3,
1248   - "onenand_write_oob_nolock: to = 0x%08x, len = %i\n",
1249   - (unsigned int) to, (int) len);
  1249 + MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
1250 1250  
1251 1251 /* Initialize retlen, in case of early exit */
1252 1252 ops->oobretlen = 0;
... ... @@ -1293,7 +1293,7 @@
1293 1293 onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
1294 1294 else
1295 1295 memcpy(oobbuf + column, buf, thislen);
1296   - this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
  1296 + this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1297 1297  
1298 1298 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
1299 1299  
... ... @@ -1466,7 +1466,14 @@
1466 1466  
1467 1467 while (len) {
1468 1468  
1469   - /* TODO Check badblock */
  1469 + /* Check if we have a bad block, we do not erase bad blocks */
  1470 + if (instr->priv == 0 && onenand_block_isbad_nolock(mtd, addr, 0)) {
  1471 + printk(KERN_WARNING "onenand_erase: attempt to erase"
  1472 + " a bad block at addr 0x%08x\n",
  1473 + (unsigned int) addr);
  1474 + instr->state = MTD_ERASE_FAILED;
  1475 + goto erase_exit;
  1476 + }
1470 1477  
1471 1478 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
1472 1479  
1473 1480  
... ... @@ -1482,8 +1489,16 @@
1482 1489 MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_erase: "
1483 1490 "Failed erase, block %d\n",
1484 1491 (unsigned)(addr >> this->erase_shift));
  1492 + if (ret == -EPERM)
  1493 + printk("onenand_erase: "
  1494 + "Device is write protected!!!\n");
  1495 + else
  1496 + printk("onenand_erase: "
  1497 + "Failed erase, block %d\n",
  1498 + (unsigned)(addr >> this->erase_shift));
1485 1499 instr->state = MTD_ERASE_FAILED;
1486 1500 instr->fail_addr = addr;
  1501 +
1487 1502 goto erase_exit;
1488 1503 }
1489 1504  
... ... @@ -1493,7 +1508,7 @@
1493 1508  
1494 1509 instr->state = MTD_ERASE_DONE;
1495 1510  
1496   - erase_exit:
  1511 +erase_exit:
1497 1512  
1498 1513 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
1499 1514 /* Do call back function */
1500 1515  
1501 1516  
1502 1517  
1503 1518  
1504 1519  
... ... @@ -1569,23 +1584,30 @@
1569 1584 }
1570 1585  
1571 1586 /**
1572   - * onenand_unlock - [MTD Interface] Unlock block(s)
1573   - * @param mtd MTD device structure
1574   - * @param ofs offset relative to mtd start
1575   - * @param len number of bytes to unlock
  1587 + * onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s)
  1588 + * @param mtd MTD device structure
  1589 + * @param ofs offset relative to mtd start
  1590 + * @param len number of bytes to lock or unlock
  1591 + * @param cmd lock or unlock command
1576 1592 *
1577   - * Unlock one or more blocks
  1593 + * Lock or unlock one or more blocks
1578 1594 */
1579   -int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
  1595 +static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
1580 1596 {
1581 1597 struct onenand_chip *this = mtd->priv;
1582 1598 int start, end, block, value, status;
  1599 + int wp_status_mask;
1583 1600  
1584 1601 start = ofs >> this->erase_shift;
1585 1602 end = len >> this->erase_shift;
1586 1603  
  1604 + if (cmd == ONENAND_CMD_LOCK)
  1605 + wp_status_mask = ONENAND_WP_LS;
  1606 + else
  1607 + wp_status_mask = ONENAND_WP_US;
  1608 +
1587 1609 /* Continuous lock scheme */
1588   - if (this->options & ONENAND_CONT_LOCK) {
  1610 + if (this->options & ONENAND_HAS_CONT_LOCK) {
1589 1611 /* Set start block address */
1590 1612 this->write_word(start,
1591 1613 this->base + ONENAND_REG_START_BLOCK_ADDRESS);
... ... @@ -1593,7 +1615,7 @@
1593 1615 this->write_word(end - 1,
1594 1616 this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1595 1617 /* Write unlock command */
1596   - this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
  1618 + this->command(mtd, cmd, 0, 0);
1597 1619  
1598 1620 /* There's no return value */
1599 1621 this->wait(mtd, FL_UNLOCKING);
... ... @@ -1612,7 +1634,14 @@
1612 1634 }
1613 1635  
1614 1636 /* Block lock scheme */
1615   - for (block = start; block < end; block++) {
  1637 + for (block = start; block < start + end; block++) {
  1638 + /* Set block address */
  1639 + value = onenand_block_address(this, block);
  1640 + this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
  1641 + /* Select DataRAM for DDP */
  1642 + value = onenand_bufferram_address(this, block);
  1643 + this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
  1644 +
1616 1645 /* Set start block address */
1617 1646 this->write_word(block,
1618 1647 this->base + ONENAND_REG_START_BLOCK_ADDRESS);
... ... @@ -1627,11 +1656,6 @@
1627 1656 & ONENAND_CTRL_ONGO)
1628 1657 continue;
1629 1658  
1630   - /* Set block address for read block status */
1631   - value = onenand_block_address(this->device_id, block);
1632   - this->write_word(value,
1633   - this->base + ONENAND_REG_START_ADDRESS1);
1634   -
1635 1659 /* Check lock status */
1636 1660 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1637 1661 if (!(status & ONENAND_WP_US))
1638 1662  
1639 1663  
1640 1664  
1641 1665  
1642 1666  
... ... @@ -1643,31 +1667,196 @@
1643 1667 }
1644 1668  
1645 1669 /**
  1670 + * onenand_lock - [MTD Interface] Lock block(s)
  1671 + * @param mtd MTD device structure
  1672 + * @param ofs offset relative to mtd start
  1673 + * @param len number of bytes to unlock
  1674 + *
  1675 + * Lock one or more blocks
  1676 + */
  1677 +static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
  1678 +{
  1679 + int ret;
  1680 +
  1681 + onenand_get_device(mtd, FL_LOCKING);
  1682 + ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
  1683 + onenand_release_device(mtd);
  1684 + return ret;
  1685 +}
  1686 +
  1687 +/**
  1688 + * onenand_unlock - [MTD Interface] Unlock block(s)
  1689 + * @param mtd MTD device structure
  1690 + * @param ofs offset relative to mtd start
  1691 + * @param len number of bytes to unlock
  1692 + *
  1693 + * Unlock one or more blocks
  1694 + */
  1695 +static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
  1696 +{
  1697 + int ret;
  1698 +
  1699 + onenand_get_device(mtd, FL_LOCKING);
  1700 + ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
  1701 + onenand_release_device(mtd);
  1702 + return ret;
  1703 +}
  1704 +
  1705 +/**
  1706 + * onenand_check_lock_status - [OneNAND Interface] Check lock status
  1707 + * @param this onenand chip data structure
  1708 + *
  1709 + * Check lock status
  1710 + */
  1711 +static int onenand_check_lock_status(struct onenand_chip *this)
  1712 +{
  1713 + unsigned int value, block, status;
  1714 + unsigned int end;
  1715 +
  1716 + end = this->chipsize >> this->erase_shift;
  1717 + for (block = 0; block < end; block++) {
  1718 + /* Set block address */
  1719 + value = onenand_block_address(this, block);
  1720 + this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
  1721 + /* Select DataRAM for DDP */
  1722 + value = onenand_bufferram_address(this, block);
  1723 + this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
  1724 + /* Set start block address */
  1725 + this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
  1726 +
  1727 + /* Check lock status */
  1728 + status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
  1729 + if (!(status & ONENAND_WP_US)) {
  1730 + printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
  1731 + return 0;
  1732 + }
  1733 + }
  1734 +
  1735 + return 1;
  1736 +}
  1737 +
  1738 +/**
  1739 + * onenand_unlock_all - [OneNAND Interface] unlock all blocks
  1740 + * @param mtd MTD device structure
  1741 + *
  1742 + * Unlock all blocks
  1743 + */
  1744 +static void onenand_unlock_all(struct mtd_info *mtd)
  1745 +{
  1746 + struct onenand_chip *this = mtd->priv;
  1747 + loff_t ofs = 0;
  1748 + size_t len = this->chipsize;
  1749 +
  1750 + if (this->options & ONENAND_HAS_UNLOCK_ALL) {
  1751 + /* Set start block address */
  1752 + this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
  1753 + /* Write unlock command */
  1754 + this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
  1755 +
  1756 + /* There's no return value */
  1757 + this->wait(mtd, FL_LOCKING);
  1758 +
  1759 + /* Sanity check */
  1760 + while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
  1761 + & ONENAND_CTRL_ONGO)
  1762 + continue;
  1763 +
  1764 + return;
  1765 +
  1766 + /* Check lock status */
  1767 + if (onenand_check_lock_status(this))
  1768 + return;
  1769 +
  1770 + /* Workaround for all block unlock in DDP */
  1771 + if (ONENAND_IS_DDP(this)) {
  1772 + /* All blocks on another chip */
  1773 + ofs = this->chipsize >> 1;
  1774 + len = this->chipsize >> 1;
  1775 + }
  1776 + }
  1777 +
  1778 + onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
  1779 +}
  1780 +
  1781 +
  1782 +/**
  1783 + * onenand_check_features - Check and set OneNAND features
  1784 + * @param mtd MTD data structure
  1785 + *
  1786 + * Check and set OneNAND features
  1787 + * - lock scheme
  1788 + * - two plane
  1789 + */
  1790 +static void onenand_check_features(struct mtd_info *mtd)
  1791 +{
  1792 + struct onenand_chip *this = mtd->priv;
  1793 + unsigned int density, process;
  1794 +
  1795 + /* Lock scheme depends on density and process */
  1796 + density = onenand_get_density(this->device_id);
  1797 + process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
  1798 +
  1799 + /* Lock scheme */
  1800 + switch (density) {
  1801 + case ONENAND_DEVICE_DENSITY_4Gb:
  1802 + this->options |= ONENAND_HAS_2PLANE;
  1803 +
  1804 + case ONENAND_DEVICE_DENSITY_2Gb:
  1805 + /* 2Gb DDP don't have 2 plane */
  1806 + if (!ONENAND_IS_DDP(this))
  1807 + this->options |= ONENAND_HAS_2PLANE;
  1808 + this->options |= ONENAND_HAS_UNLOCK_ALL;
  1809 +
  1810 + case ONENAND_DEVICE_DENSITY_1Gb:
  1811 + /* A-Die has all block unlock */
  1812 + if (process)
  1813 + this->options |= ONENAND_HAS_UNLOCK_ALL;
  1814 + break;
  1815 +
  1816 + default:
  1817 + /* Some OneNAND has continuous lock scheme */
  1818 + if (!process)
  1819 + this->options |= ONENAND_HAS_CONT_LOCK;
  1820 + break;
  1821 + }
  1822 +
  1823 + if (this->options & ONENAND_HAS_CONT_LOCK)
  1824 + printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
  1825 + if (this->options & ONENAND_HAS_UNLOCK_ALL)
  1826 + printk(KERN_DEBUG "Chip support all block unlock\n");
  1827 + if (this->options & ONENAND_HAS_2PLANE)
  1828 + printk(KERN_DEBUG "Chip has 2 plane\n");
  1829 +}
  1830 +
  1831 +/**
1646 1832 * onenand_print_device_info - Print device ID
1647 1833 * @param device device ID
1648 1834 *
1649 1835 * Print device ID
1650 1836 */
1651   -char * onenand_print_device_info(int device)
  1837 +char *onenand_print_device_info(int device, int version)
1652 1838 {
1653 1839 int vcc, demuxed, ddp, density;
1654 1840 char *dev_info = malloc(80);
  1841 + char *p = dev_info;
1655 1842  
1656 1843 vcc = device & ONENAND_DEVICE_VCC_MASK;
1657 1844 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
1658 1845 ddp = device & ONENAND_DEVICE_IS_DDP;
1659 1846 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
1660   - sprintf(dev_info, "%sOneNAND%s %dMB %sV 16-bit (0x%02x)",
  1847 + p += sprintf(dev_info, "%sOneNAND%s %dMB %sV 16-bit (0x%02x)",
1661 1848 demuxed ? "" : "Muxed ",
1662 1849 ddp ? "(DDP)" : "",
1663 1850 (16 << density), vcc ? "2.65/3.3" : "1.8", device);
1664 1851  
  1852 + sprintf(p, "\nOneNAND version = 0x%04x", version);
  1853 + printk("%s\n", dev_info);
  1854 +
1665 1855 return dev_info;
1666 1856 }
1667 1857  
1668 1858 static const struct onenand_manufacturers onenand_manuf_ids[] = {
1669 1859 {ONENAND_MFR_SAMSUNG, "Samsung"},
1670   - {ONENAND_MFR_UNKNOWN, "Unknown"}
1671 1860 };
1672 1861  
1673 1862 /**
1674 1863  
1675 1864  
1676 1865  
1677 1866  
1678 1867  
... ... @@ -1678,19 +1867,24 @@
1678 1867 */
1679 1868 static int onenand_check_maf(int manuf)
1680 1869 {
  1870 + int size = ARRAY_SIZE(onenand_manuf_ids);
  1871 + char *name;
1681 1872 int i;
1682 1873  
1683   - for (i = 0; onenand_manuf_ids[i].id; i++) {
  1874 + for (i = 0; size; i++)
1684 1875 if (manuf == onenand_manuf_ids[i].id)
1685 1876 break;
1686   - }
1687 1877  
  1878 + if (i < size)
  1879 + name = onenand_manuf_ids[i].name;
  1880 + else
  1881 + name = "Unknown";
  1882 +
1688 1883 #ifdef ONENAND_DEBUG
1689   - printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
1690   - onenand_manuf_ids[i].name, manuf);
  1884 + printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
1691 1885 #endif
1692 1886  
1693   - return (i != ONENAND_MFR_UNKNOWN);
  1887 + return i == size;
1694 1888 }
1695 1889  
1696 1890 /**
1697 1891  
1698 1892  
... ... @@ -1703,10 +1897,15 @@
1703 1897 static int onenand_probe(struct mtd_info *mtd)
1704 1898 {
1705 1899 struct onenand_chip *this = mtd->priv;
1706   - int bram_maf_id, bram_dev_id, maf_id, dev_id;
1707   - int version_id;
  1900 + int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
1708 1901 int density;
  1902 + int syscfg;
1709 1903  
  1904 + /* Save system configuration 1 */
  1905 + syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
  1906 + /* Clear Sync. Burst Read mode to read BootRAM */
  1907 + this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1);
  1908 +
1710 1909 /* Send the command for reading device ID from BootRAM */
1711 1910 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
1712 1911  
1713 1912  
1714 1913  
... ... @@ -1714,19 +1913,23 @@
1714 1913 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
1715 1914 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
1716 1915  
1717   - /* Check manufacturer ID */
1718   - if (onenand_check_maf(bram_maf_id))
1719   - return -ENXIO;
1720   -
1721 1916 /* Reset OneNAND to read default register values */
1722 1917 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
1723 1918  
1724 1919 /* Wait reset */
1725 1920 this->wait(mtd, FL_RESETING);
1726 1921  
  1922 + /* Restore system configuration 1 */
  1923 + this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
  1924 +
  1925 + /* Check manufacturer ID */
  1926 + if (onenand_check_maf(bram_maf_id))
  1927 + return -ENXIO;
  1928 +
1727 1929 /* Read manufacturer and device IDs from Register */
1728 1930 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
1729 1931 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
  1932 + ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
1730 1933  
1731 1934 /* Check OneNAND device */
1732 1935 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
1733 1936  
1734 1937  
... ... @@ -1739,11 +1942,16 @@
1739 1942 }
1740 1943  
1741 1944 /* Flash device information */
1742   - mtd->name = onenand_print_device_info(dev_id);
  1945 + mtd->name = onenand_print_device_info(dev_id, ver_id);
1743 1946 this->device_id = dev_id;
1744 1947  
1745   - density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
  1948 + density = onenand_get_density(dev_id);
1746 1949 this->chipsize = (16 << density) << 20;
  1950 + /* Set density mask. it is used for DDP */
  1951 + if (ONENAND_IS_DDP(this))
  1952 + this->density_mask = (1 << (density + 6));
  1953 + else
  1954 + this->density_mask = 0;
1747 1955  
1748 1956 /* OneNAND page size & block size */
1749 1957 /* The data buffer size is equal to page size */
1750 1958  
... ... @@ -1764,19 +1972,9 @@
1764 1972  
1765 1973 mtd->size = this->chipsize;
1766 1974  
1767   - /* Version ID */
1768   - version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
1769   -#ifdef ONENAND_DEBUG
1770   - printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
1771   -#endif
  1975 + /* Check OneNAND features */
  1976 + onenand_check_features(mtd);
1772 1977  
1773   - /* Lock scheme */
1774   - if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
1775   - !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
1776   - printk(KERN_INFO "Lock scheme is Continues Lock\n");
1777   - this->options |= ONENAND_CONT_LOCK;
1778   - }
1779   -
1780 1978 mtd->flags = MTD_CAP_NANDFLASH;
1781 1979 mtd->erase = onenand_erase;
1782 1980 mtd->read = onenand_read;
1783 1981  
1784 1982  
... ... @@ -1813,12 +2011,19 @@
1813 2011 this->command = onenand_command;
1814 2012 if (!this->wait)
1815 2013 this->wait = onenand_wait;
  2014 + if (!this->bbt_wait)
  2015 + this->bbt_wait = onenand_bbt_wait;
1816 2016  
1817 2017 if (!this->read_bufferram)
1818 2018 this->read_bufferram = onenand_read_bufferram;
  2019 + if (!this->read_spareram)
  2020 + this->read_spareram = onenand_read_bufferram;
1819 2021 if (!this->write_bufferram)
1820 2022 this->write_bufferram = onenand_write_bufferram;
1821 2023  
  2024 + if (!this->scan_bbt)
  2025 + this->scan_bbt = onenand_default_bbt;
  2026 +
1822 2027 if (onenand_probe(mtd))
1823 2028 return -ENXIO;
1824 2029  
1825 2030  
... ... @@ -1850,9 +2055,10 @@
1850 2055 this->options |= ONENAND_OOBBUF_ALLOC;
1851 2056 }
1852 2057  
1853   - onenand_unlock(mtd, 0, mtd->size);
  2058 + /* Unlock whole block */
  2059 + onenand_unlock_all(mtd);
1854 2060  
1855   - return onenand_default_bbt(mtd);
  2061 + return this->scan_bbt(mtd);
1856 2062 }
1857 2063  
1858 2064 /**
drivers/mtd/onenand/onenand_bbt.c
... ... @@ -3,7 +3,7 @@
3 3 *
4 4 * Bad Block Table support for the OneNAND driver
5 5 *
6   - * Copyright(c) 2005-2007 Samsung Electronics
  6 + * Copyright(c) 2005-2008 Samsung Electronics
7 7 * Kyungmin Park <kyungmin.park@samsung.com>
8 8 *
9 9 * TODO:
... ... @@ -54,7 +54,7 @@
54 54 * @param buf temporary buffer
55 55 * @param bd descriptor for the good/bad block search pattern
56 56 * @param chip create the table for a specific chip, -1 read all chips.
57   - * Applies only if NAND_BBT_PERCHIP option is set
  57 + * Applies only if NAND_BBT_PERCHIP option is set
58 58 *
59 59 * Create a bad block table by scanning the device
60 60 * for the given good/bad block identify pattern
... ... @@ -156,8 +156,8 @@
156 156 res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
157 157  
158 158 MTDDEBUG (MTD_DEBUG_LEVEL2,
159   - "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
160   - (unsigned int)offs, block >> 1, res);
  159 + "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
  160 + (unsigned int)offs, block >> 1, res);
161 161  
162 162 switch ((int)res) {
163 163 case 0x00:
drivers/mtd/onenand/onenand_uboot.c
... ... @@ -26,8 +26,16 @@
26 26 memset(&onenand_mtd, 0, sizeof(struct mtd_info));
27 27 memset(&onenand_chip, 0, sizeof(struct onenand_chip));
28 28  
29   - onenand_chip.base = (void *) CONFIG_SYS_ONENAND_BASE;
30 29 onenand_mtd.priv = &onenand_chip;
  30 +
  31 +#ifdef CONFIG_USE_ONENAND_BOARD_INIT
  32 + /*
  33 + * It's used for some board init required
  34 + */
  35 + onenand_board_init(&onenand_mtd);
  36 +#else
  37 + onenand_chip.base = (void *) CONFIG_SYS_ONENAND_BASE;
  38 +#endif
31 39  
32 40 onenand_scan(&onenand_mtd, 1);
33 41  
include/linux/mtd/onenand.h
... ... @@ -30,14 +30,10 @@
30 30  
31 31 /**
32 32 * struct onenand_bufferram - OneNAND BufferRAM Data
33   - * @param block block address in BufferRAM
34   - * @param page page address in BufferRAM
35   - * @param valid valid flag
  33 + * @param blockpage block & page address in BufferRAM
36 34 */
37 35 struct onenand_bufferram {
38   - int block;
39   - int page;
40   - int valid;
  36 + int blockpage;
41 37 };
42 38  
43 39 /**
... ... @@ -70,6 +66,8 @@
70 66 void __iomem *base;
71 67 unsigned int chipsize;
72 68 unsigned int device_id;
  69 + unsigned int version_id;
  70 + unsigned int density_mask;
73 71 unsigned int options;
74 72  
75 73 unsigned int erase_shift;
76 74  
77 75  
78 76  
79 77  
80 78  
81 79  
... ... @@ -81,26 +79,35 @@
81 79 unsigned int bufferram_index;
82 80 struct onenand_bufferram bufferram[MAX_BUFFERRAM];
83 81  
84   - int (*command) (struct mtd_info * mtd, int cmd, loff_t address,
  82 + int (*command) (struct mtd_info *mtd, int cmd, loff_t address,
85 83 size_t len);
86   - int (*wait) (struct mtd_info * mtd, int state);
87   - int (*read_bufferram) (struct mtd_info * mtd, int area,
  84 + int (*wait) (struct mtd_info *mtd, int state);
  85 + int (*bbt_wait) (struct mtd_info *mtd, int state);
  86 + int (*read_bufferram) (struct mtd_info *mtd, loff_t addr, int area,
88 87 unsigned char *buffer, int offset, size_t count);
89   - int (*write_bufferram) (struct mtd_info * mtd, int area,
  88 + int (*read_spareram) (struct mtd_info *mtd, loff_t addr, int area,
  89 + unsigned char *buffer, int offset, size_t count);
  90 + int (*write_bufferram) (struct mtd_info *mtd, loff_t addr, int area,
90 91 const unsigned char *buffer, int offset,
91 92 size_t count);
92   - unsigned short (*read_word) (void __iomem * addr);
93   - void (*write_word) (unsigned short value, void __iomem * addr);
94   - void (*mmcontrol) (struct mtd_info * mtd, int sync_read);
  93 + unsigned short (*read_word) (void __iomem *addr);
  94 + void (*write_word) (unsigned short value, void __iomem *addr);
  95 + void (*mmcontrol) (struct mtd_info *mtd, int sync_read);
95 96 int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
96 97 int (*scan_bbt)(struct mtd_info *mtd);
97 98  
  99 + unsigned char *main_buf;
  100 + unsigned char *spare_buf;
  101 +#ifdef DONT_USE_UBOOT
  102 + spinlock_t chip_lock;
  103 + wait_queue_head_t wq;
  104 +#endif
98 105 int state;
99   - unsigned char *page_buf;
100   - unsigned char *oob_buf;
  106 + unsigned char *page_buf;
  107 + unsigned char *oob_buf;
101 108  
102 109 struct nand_oobinfo *autooob;
103   - struct nand_ecclayout *ecclayout;
  110 + struct nand_ecclayout *ecclayout;
104 111  
105 112 void *bbm;
106 113  
... ... @@ -125,7 +132,9 @@
125 132 /*
126 133 * Options bits
127 134 */
128   -#define ONENAND_CONT_LOCK (0x0001)
  135 +#define ONENAND_HAS_CONT_LOCK (0x0001)
  136 +#define ONENAND_HAS_UNLOCK_ALL (0x0002)
  137 +#define ONENAND_HAS_2PLANE (0x0004)
129 138 #define ONENAND_PAGEBUF_ALLOC (0x1000)
130 139 #define ONENAND_OOBBUF_ALLOC (0x2000)
131 140  
... ... @@ -133,7 +142,6 @@
133 142 * OneNAND Flash Manufacturer ID Codes
134 143 */
135 144 #define ONENAND_MFR_SAMSUNG 0xec
136   -#define ONENAND_MFR_UNKNOWN 0x00
137 145  
138 146 /**
139 147 * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
include/linux/mtd/onenand_regs.h
... ... @@ -119,6 +119,7 @@
119 119 #define ONENAND_CMD_UNLOCK (0x23)
120 120 #define ONENAND_CMD_LOCK (0x2A)
121 121 #define ONENAND_CMD_LOCK_TIGHT (0x2C)
  122 +#define ONENAND_CMD_UNLOCK_ALL (0x27)
122 123 #define ONENAND_CMD_ERASE (0x94)
123 124 #define ONENAND_CMD_RESET (0xF0)
124 125 #define ONENAND_CMD_READID (0x90)
include/onenand_uboot.h
... ... @@ -15,26 +15,30 @@
15 15 #define __UBOOT_ONENAND_H
16 16  
17 17 #include <linux/types.h>
18   -#include <linux/mtd/mtd.h>
19 18  
20 19 struct mtd_info;
21 20 struct erase_info;
  21 +struct onenand_chip;
22 22  
23 23 extern struct mtd_info onenand_mtd;
24 24  
  25 +/* board */
  26 +extern void onenand_board_init(struct mtd_info *);
  27 +
25 28 /* Functions */
26 29 extern void onenand_init(void);
27 30 extern int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
28 31 size_t * retlen, u_char * buf);
29   -extern int onenand_read_oob(struct mtd_info *mtd, loff_t from,
30   - struct mtd_oob_ops *ops);
  32 +extern int onenand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
31 33 extern int onenand_write(struct mtd_info *mtd, loff_t from, size_t len,
32 34 size_t * retlen, const u_char * buf);
33 35 extern int onenand_erase(struct mtd_info *mtd, struct erase_info *instr);
34 36  
35   -extern int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
  37 +extern char *onenand_print_device_info(int device, int version);
36 38  
37   -extern char *onenand_print_device_info(int device);
  39 +/* S3C64xx */
  40 +extern void s3c64xx_onenand_init(struct mtd_info *);
  41 +extern void s3c64xx_set_width_regs(struct onenand_chip *);
38 42  
39 43 #endif /* __UBOOT_ONENAND_H */