aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand/onenand_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/onenand/onenand_base.c')
-rw-r--r--drivers/mtd/onenand/onenand_base.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 32f0ed33afe0..26caf2590dae 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -397,7 +397,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
397 value = onenand_bufferram_address(this, block); 397 value = onenand_bufferram_address(this, block);
398 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 398 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
399 399
400 if (ONENAND_IS_MLC(this) || ONENAND_IS_2PLANE(this)) 400 if (ONENAND_IS_MLC(this) || ONENAND_IS_2PLANE(this) ||
401 ONENAND_IS_4KB_PAGE(this))
401 /* It is always BufferRAM0 */ 402 /* It is always BufferRAM0 */
402 ONENAND_SET_BUFFERRAM0(this); 403 ONENAND_SET_BUFFERRAM0(this);
403 else 404 else
@@ -426,7 +427,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
426 case FLEXONENAND_CMD_RECOVER_LSB: 427 case FLEXONENAND_CMD_RECOVER_LSB:
427 case ONENAND_CMD_READ: 428 case ONENAND_CMD_READ:
428 case ONENAND_CMD_READOOB: 429 case ONENAND_CMD_READOOB:
429 if (ONENAND_IS_MLC(this)) 430 if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this))
430 /* It is always BufferRAM0 */ 431 /* It is always BufferRAM0 */
431 dataram = ONENAND_SET_BUFFERRAM0(this); 432 dataram = ONENAND_SET_BUFFERRAM0(this);
432 else 433 else
@@ -466,11 +467,11 @@ static inline int onenand_read_ecc(struct onenand_chip *this)
466{ 467{
467 int ecc, i, result = 0; 468 int ecc, i, result = 0;
468 469
469 if (!FLEXONENAND(this)) 470 if (!FLEXONENAND(this) && !ONENAND_IS_4KB_PAGE(this))
470 return this->read_word(this->base + ONENAND_REG_ECC_STATUS); 471 return this->read_word(this->base + ONENAND_REG_ECC_STATUS);
471 472
472 for (i = 0; i < 4; i++) { 473 for (i = 0; i < 4; i++) {
473 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS + i); 474 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS + i*2);
474 if (likely(!ecc)) 475 if (likely(!ecc))
475 continue; 476 continue;
476 if (ecc & FLEXONENAND_UNCORRECTABLE_ERROR) 477 if (ecc & FLEXONENAND_UNCORRECTABLE_ERROR)
@@ -1425,7 +1426,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1425 int ret; 1426 int ret;
1426 1427
1427 onenand_get_device(mtd, FL_READING); 1428 onenand_get_device(mtd, FL_READING);
1428 ret = ONENAND_IS_MLC(this) ? 1429 ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ?
1429 onenand_mlc_read_ops_nolock(mtd, from, &ops) : 1430 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
1430 onenand_read_ops_nolock(mtd, from, &ops); 1431 onenand_read_ops_nolock(mtd, from, &ops);
1431 onenand_release_device(mtd); 1432 onenand_release_device(mtd);
@@ -1460,7 +1461,7 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1460 1461
1461 onenand_get_device(mtd, FL_READING); 1462 onenand_get_device(mtd, FL_READING);
1462 if (ops->datbuf) 1463 if (ops->datbuf)
1463 ret = ONENAND_IS_MLC(this) ? 1464 ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ?
1464 onenand_mlc_read_ops_nolock(mtd, from, ops) : 1465 onenand_mlc_read_ops_nolock(mtd, from, ops) :
1465 onenand_read_ops_nolock(mtd, from, ops); 1466 onenand_read_ops_nolock(mtd, from, ops);
1466 else 1467 else
@@ -1634,7 +1635,6 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
1634static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len) 1635static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
1635{ 1636{
1636 struct onenand_chip *this = mtd->priv; 1637 struct onenand_chip *this = mtd->priv;
1637 void __iomem *dataram;
1638 int ret = 0; 1638 int ret = 0;
1639 int thislen, column; 1639 int thislen, column;
1640 1640
@@ -1654,10 +1654,9 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr,
1654 1654
1655 onenand_update_bufferram(mtd, addr, 1); 1655 onenand_update_bufferram(mtd, addr, 1);
1656 1656
1657 dataram = this->base + ONENAND_DATARAM; 1657 this->read_bufferram(mtd, ONENAND_DATARAM, this->verify_buf, 0, mtd->writesize);
1658 dataram += onenand_bufferram_offset(mtd, ONENAND_DATARAM);
1659 1658
1660 if (memcmp(buf, dataram + column, thislen)) 1659 if (memcmp(buf, this->verify_buf, thislen))
1661 return -EBADMSG; 1660 return -EBADMSG;
1662 1661
1663 len -= thislen; 1662 len -= thislen;
@@ -1926,7 +1925,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1926 * 2 PLANE, MLC, and Flex-OneNAND do not support 1925 * 2 PLANE, MLC, and Flex-OneNAND do not support
1927 * write-while-program feature. 1926 * write-while-program feature.
1928 */ 1927 */
1929 if (!ONENAND_IS_2PLANE(this) && !first) { 1928 if (!ONENAND_IS_2PLANE(this) && !ONENAND_IS_4KB_PAGE(this) && !first) {
1930 ONENAND_SET_PREV_BUFFERRAM(this); 1929 ONENAND_SET_PREV_BUFFERRAM(this);
1931 1930
1932 ret = this->wait(mtd, FL_WRITING); 1931 ret = this->wait(mtd, FL_WRITING);
@@ -1957,7 +1956,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1957 /* 1956 /*
1958 * 2 PLANE, MLC, and Flex-OneNAND wait here 1957 * 2 PLANE, MLC, and Flex-OneNAND wait here
1959 */ 1958 */
1960 if (ONENAND_IS_2PLANE(this)) { 1959 if (ONENAND_IS_2PLANE(this) || ONENAND_IS_4KB_PAGE(this)) {
1961 ret = this->wait(mtd, FL_WRITING); 1960 ret = this->wait(mtd, FL_WRITING);
1962 1961
1963 /* In partial page write we don't update bufferram */ 1962 /* In partial page write we don't update bufferram */
@@ -2084,7 +2083,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
2084 memcpy(oobbuf + column, buf, thislen); 2083 memcpy(oobbuf + column, buf, thislen);
2085 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); 2084 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
2086 2085
2087 if (ONENAND_IS_MLC(this)) { 2086 if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) {
2088 /* Set main area of DataRAM to 0xff*/ 2087 /* Set main area of DataRAM to 0xff*/
2089 memset(this->page_buf, 0xff, mtd->writesize); 2088 memset(this->page_buf, 0xff, mtd->writesize);
2090 this->write_bufferram(mtd, ONENAND_DATARAM, 2089 this->write_bufferram(mtd, ONENAND_DATARAM,
@@ -3027,7 +3026,7 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
3027 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 3026 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
3028 this->wait(mtd, FL_OTPING); 3027 this->wait(mtd, FL_OTPING);
3029 3028
3030 ret = ONENAND_IS_MLC(this) ? 3029 ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ?
3031 onenand_mlc_read_ops_nolock(mtd, from, &ops) : 3030 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
3032 onenand_read_ops_nolock(mtd, from, &ops); 3031 onenand_read_ops_nolock(mtd, from, &ops);
3033 3032
@@ -3372,7 +3371,10 @@ static void onenand_check_features(struct mtd_info *mtd)
3372 /* Lock scheme */ 3371 /* Lock scheme */
3373 switch (density) { 3372 switch (density) {
3374 case ONENAND_DEVICE_DENSITY_4Gb: 3373 case ONENAND_DEVICE_DENSITY_4Gb:
3375 this->options |= ONENAND_HAS_2PLANE; 3374 if (ONENAND_IS_DDP(this))
3375 this->options |= ONENAND_HAS_2PLANE;
3376 else
3377 this->options |= ONENAND_HAS_4KB_PAGE;
3376 3378
3377 case ONENAND_DEVICE_DENSITY_2Gb: 3379 case ONENAND_DEVICE_DENSITY_2Gb:
3378 /* 2Gb DDP does not have 2 plane */ 3380 /* 2Gb DDP does not have 2 plane */
@@ -3393,7 +3395,7 @@ static void onenand_check_features(struct mtd_info *mtd)
3393 break; 3395 break;
3394 } 3396 }
3395 3397
3396 if (ONENAND_IS_MLC(this)) 3398 if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this))
3397 this->options &= ~ONENAND_HAS_2PLANE; 3399 this->options &= ~ONENAND_HAS_2PLANE;
3398 3400
3399 if (FLEXONENAND(this)) { 3401 if (FLEXONENAND(this)) {
@@ -3407,6 +3409,8 @@ static void onenand_check_features(struct mtd_info *mtd)
3407 printk(KERN_DEBUG "Chip support all block unlock\n"); 3409 printk(KERN_DEBUG "Chip support all block unlock\n");
3408 if (this->options & ONENAND_HAS_2PLANE) 3410 if (this->options & ONENAND_HAS_2PLANE)
3409 printk(KERN_DEBUG "Chip has 2 plane\n"); 3411 printk(KERN_DEBUG "Chip has 2 plane\n");
3412 if (this->options & ONENAND_HAS_4KB_PAGE)
3413 printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
3410} 3414}
3411 3415
3412/** 3416/**
@@ -3759,6 +3763,12 @@ static int onenand_probe(struct mtd_info *mtd)
3759 /* Restore system configuration 1 */ 3763 /* Restore system configuration 1 */
3760 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1); 3764 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
3761 3765
3766 /* Workaround */
3767 if (syscfg & ONENAND_SYS_CFG1_SYNC_WRITE) {
3768 bram_maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
3769 bram_dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
3770 }
3771
3762 /* Check manufacturer ID */ 3772 /* Check manufacturer ID */
3763 if (onenand_check_maf(bram_maf_id)) 3773 if (onenand_check_maf(bram_maf_id))
3764 return -ENXIO; 3774 return -ENXIO;
@@ -3778,6 +3788,9 @@ static int onenand_probe(struct mtd_info *mtd)
3778 this->device_id = dev_id; 3788 this->device_id = dev_id;
3779 this->version_id = ver_id; 3789 this->version_id = ver_id;
3780 3790
3791 /* Check OneNAND features */
3792 onenand_check_features(mtd);
3793
3781 density = onenand_get_density(dev_id); 3794 density = onenand_get_density(dev_id);
3782 if (FLEXONENAND(this)) { 3795 if (FLEXONENAND(this)) {
3783 this->dies = ONENAND_IS_DDP(this) ? 2 : 1; 3796 this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
@@ -3799,7 +3812,7 @@ static int onenand_probe(struct mtd_info *mtd)
3799 /* The data buffer size is equal to page size */ 3812 /* The data buffer size is equal to page size */
3800 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); 3813 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
3801 /* We use the full BufferRAM */ 3814 /* We use the full BufferRAM */
3802 if (ONENAND_IS_MLC(this)) 3815 if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this))
3803 mtd->writesize <<= 1; 3816 mtd->writesize <<= 1;
3804 3817
3805 mtd->oobsize = mtd->writesize >> 5; 3818 mtd->oobsize = mtd->writesize >> 5;
@@ -3829,9 +3842,6 @@ static int onenand_probe(struct mtd_info *mtd)
3829 else 3842 else
3830 mtd->size = this->chipsize; 3843 mtd->size = this->chipsize;
3831 3844
3832 /* Check OneNAND features */
3833 onenand_check_features(mtd);
3834
3835 /* 3845 /*
3836 * We emulate the 4KiB page and 256KiB erase block size 3846 * We emulate the 4KiB page and 256KiB erase block size
3837 * But oobsize is still 64 bytes. 3847 * But oobsize is still 64 bytes.
@@ -3926,6 +3936,13 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
3926 __func__); 3936 __func__);
3927 return -ENOMEM; 3937 return -ENOMEM;
3928 } 3938 }
3939#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
3940 this->verify_buf = kzalloc(mtd->writesize, GFP_KERNEL);
3941 if (!this->verify_buf) {
3942 kfree(this->page_buf);
3943 return -ENOMEM;
3944 }
3945#endif
3929 this->options |= ONENAND_PAGEBUF_ALLOC; 3946 this->options |= ONENAND_PAGEBUF_ALLOC;
3930 } 3947 }
3931 if (!this->oob_buf) { 3948 if (!this->oob_buf) {
@@ -4053,8 +4070,12 @@ void onenand_release(struct mtd_info *mtd)
4053 kfree(this->bbm); 4070 kfree(this->bbm);
4054 } 4071 }
4055 /* Buffers allocated by onenand_scan */ 4072 /* Buffers allocated by onenand_scan */
4056 if (this->options & ONENAND_PAGEBUF_ALLOC) 4073 if (this->options & ONENAND_PAGEBUF_ALLOC) {
4057 kfree(this->page_buf); 4074 kfree(this->page_buf);
4075#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
4076 kfree(this->verify_buf);
4077#endif
4078 }
4058 if (this->options & ONENAND_OOBBUF_ALLOC) 4079 if (this->options & ONENAND_OOBBUF_ALLOC)
4059 kfree(this->oob_buf); 4080 kfree(this->oob_buf);
4060 kfree(mtd->eraseregions); 4081 kfree(mtd->eraseregions);