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.c313
1 files changed, 310 insertions, 3 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 7c7dc0ae5a19..163c81135447 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -191,7 +191,7 @@ static int onenand_buffer_address(int dataram1, int sectors, int count)
191static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len) 191static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
192{ 192{
193 struct onenand_chip *this = mtd->priv; 193 struct onenand_chip *this = mtd->priv;
194 int value, readcmd = 0; 194 int value, readcmd = 0, block_cmd = 0;
195 int block, page; 195 int block, page;
196 /* Now we use page size operation */ 196 /* Now we use page size operation */
197 int sectors = 4, count = 4; 197 int sectors = 4, count = 4;
@@ -207,6 +207,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
207 207
208 case ONENAND_CMD_ERASE: 208 case ONENAND_CMD_ERASE:
209 case ONENAND_CMD_BUFFERRAM: 209 case ONENAND_CMD_BUFFERRAM:
210 case ONENAND_CMD_OTP_ACCESS:
211 block_cmd = 1;
210 block = (int) (addr >> this->erase_shift); 212 block = (int) (addr >> this->erase_shift);
211 page = -1; 213 page = -1;
212 break; 214 break;
@@ -235,7 +237,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
235 value = onenand_block_address(this, block); 237 value = onenand_block_address(this, block);
236 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); 238 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
237 239
238 if (cmd == ONENAND_CMD_ERASE) { 240 if (cmd == block_cmd) {
239 /* Select DataRAM for DDP */ 241 /* Select DataRAM for DDP */
240 value = onenand_bufferram_address(this, block); 242 value = onenand_bufferram_address(this, block);
241 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 243 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
@@ -1412,6 +1414,304 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1412 return 0; 1414 return 0;
1413} 1415}
1414 1416
1417#ifdef CONFIG_MTD_ONENAND_OTP
1418
1419/* Interal OTP operation */
1420typedef int (*otp_op_t)(struct mtd_info *mtd, loff_t form, size_t len,
1421 size_t *retlen, u_char *buf);
1422
1423/**
1424 * do_otp_read - [DEFAULT] Read OTP block area
1425 * @param mtd MTD device structure
1426 * @param from The offset to read
1427 * @param len number of bytes to read
1428 * @param retlen pointer to variable to store the number of readbytes
1429 * @param buf the databuffer to put/get data
1430 *
1431 * Read OTP block area.
1432 */
1433static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
1434 size_t *retlen, u_char *buf)
1435{
1436 struct onenand_chip *this = mtd->priv;
1437 int ret;
1438
1439 /* Enter OTP access mode */
1440 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1441 this->wait(mtd, FL_OTPING);
1442
1443 ret = mtd->read(mtd, from, len, retlen, buf);
1444
1445 /* Exit OTP access mode */
1446 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
1447 this->wait(mtd, FL_RESETING);
1448
1449 return ret;
1450}
1451
1452/**
1453 * do_otp_write - [DEFAULT] Write OTP block area
1454 * @param mtd MTD device structure
1455 * @param from The offset to write
1456 * @param len number of bytes to write
1457 * @param retlen pointer to variable to store the number of write bytes
1458 * @param buf the databuffer to put/get data
1459 *
1460 * Write OTP block area.
1461 */
1462static int do_otp_write(struct mtd_info *mtd, loff_t from, size_t len,
1463 size_t *retlen, u_char *buf)
1464{
1465 struct onenand_chip *this = mtd->priv;
1466 unsigned char *pbuf = buf;
1467 int ret;
1468
1469 /* Force buffer page aligned */
1470 if (len < mtd->oobblock) {
1471 memcpy(this->page_buf, buf, len);
1472 memset(this->page_buf + len, 0xff, mtd->oobblock - len);
1473 pbuf = this->page_buf;
1474 len = mtd->oobblock;
1475 }
1476
1477 /* Enter OTP access mode */
1478 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1479 this->wait(mtd, FL_OTPING);
1480
1481 ret = mtd->write(mtd, from, len, retlen, pbuf);
1482
1483 /* Exit OTP access mode */
1484 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
1485 this->wait(mtd, FL_RESETING);
1486
1487 return ret;
1488}
1489
1490/**
1491 * do_otp_lock - [DEFAULT] Lock OTP block area
1492 * @param mtd MTD device structure
1493 * @param from The offset to lock
1494 * @param len number of bytes to lock
1495 * @param retlen pointer to variable to store the number of lock bytes
1496 * @param buf the databuffer to put/get data
1497 *
1498 * Lock OTP block area.
1499 */
1500static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
1501 size_t *retlen, u_char *buf)
1502{
1503 struct onenand_chip *this = mtd->priv;
1504 int ret;
1505
1506 /* Enter OTP access mode */
1507 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1508 this->wait(mtd, FL_OTPING);
1509
1510 ret = mtd->write_oob(mtd, from, len, retlen, buf);
1511
1512 /* Exit OTP access mode */
1513 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
1514 this->wait(mtd, FL_RESETING);
1515
1516 return ret;
1517}
1518
1519/**
1520 * onenand_otp_walk - [DEFAULT] Handle OTP operation
1521 * @param mtd MTD device structure
1522 * @param from The offset to read/write
1523 * @param len number of bytes to read/write
1524 * @param retlen pointer to variable to store the number of read bytes
1525 * @param buf the databuffer to put/get data
1526 * @param action do given action
1527 * @param mode specify user and factory
1528 *
1529 * Handle OTP operation.
1530 */
1531static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
1532 size_t *retlen, u_char *buf,
1533 otp_op_t action, int mode)
1534{
1535 struct onenand_chip *this = mtd->priv;
1536 int otp_pages;
1537 int density;
1538 int ret = 0;
1539
1540 *retlen = 0;
1541
1542 density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1543 if (density < ONENAND_DEVICE_DENSITY_512Mb)
1544 otp_pages = 20;
1545 else
1546 otp_pages = 10;
1547
1548 if (mode == MTD_OTP_FACTORY) {
1549 from += mtd->oobblock * otp_pages;
1550 otp_pages = 64 - otp_pages;
1551 }
1552
1553 /* Check User/Factory boundary */
1554 if (((mtd->oobblock * otp_pages) - (from + len)) < 0)
1555 return 0;
1556
1557 while (len > 0 && otp_pages > 0) {
1558 if (!action) { /* OTP Info functions */
1559 struct otp_info *otpinfo;
1560
1561 len -= sizeof(struct otp_info);
1562 if (len <= 0)
1563 return -ENOSPC;
1564
1565 otpinfo = (struct otp_info *) buf;
1566 otpinfo->start = from;
1567 otpinfo->length = mtd->oobblock;
1568 otpinfo->locked = 0;
1569
1570 from += mtd->oobblock;
1571 buf += sizeof(struct otp_info);
1572 *retlen += sizeof(struct otp_info);
1573 } else {
1574 size_t tmp_retlen;
1575 int size = len;
1576
1577 ret = action(mtd, from, len, &tmp_retlen, buf);
1578
1579 buf += size;
1580 len -= size;
1581 *retlen += size;
1582
1583 if (ret < 0)
1584 return ret;
1585 }
1586 otp_pages--;
1587 }
1588
1589 return 0;
1590}
1591
1592/**
1593 * onenand_get_fact_prot_info - [MTD Interface] Read factory OTP info
1594 * @param mtd MTD device structure
1595 * @param buf the databuffer to put/get data
1596 * @param len number of bytes to read
1597 *
1598 * Read factory OTP info.
1599 */
1600static int onenand_get_fact_prot_info(struct mtd_info *mtd,
1601 struct otp_info *buf, size_t len)
1602{
1603 size_t retlen;
1604 int ret;
1605
1606 ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_FACTORY);
1607
1608 return ret ? : retlen;
1609}
1610
1611/**
1612 * onenand_read_fact_prot_reg - [MTD Interface] Read factory OTP area
1613 * @param mtd MTD device structure
1614 * @param from The offset to read
1615 * @param len number of bytes to read
1616 * @param retlen pointer to variable to store the number of read bytes
1617 * @param buf the databuffer to put/get data
1618 *
1619 * Read factory OTP area.
1620 */
1621static int onenand_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
1622 size_t len, size_t *retlen, u_char *buf)
1623{
1624 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_FACTORY);
1625}
1626
1627/**
1628 * onenand_get_user_prot_info - [MTD Interface] Read user OTP info
1629 * @param mtd MTD device structure
1630 * @param buf the databuffer to put/get data
1631 * @param len number of bytes to read
1632 *
1633 * Read user OTP info.
1634 */
1635static int onenand_get_user_prot_info(struct mtd_info *mtd,
1636 struct otp_info *buf, size_t len)
1637{
1638 size_t retlen;
1639 int ret;
1640
1641 ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_USER);
1642
1643 return ret ? : retlen;
1644}
1645
1646/**
1647 * onenand_read_user_prot_reg - [MTD Interface] Read user OTP area
1648 * @param mtd MTD device structure
1649 * @param from The offset to read
1650 * @param len number of bytes to read
1651 * @param retlen pointer to variable to store the number of read bytes
1652 * @param buf the databuffer to put/get data
1653 *
1654 * Read user OTP area.
1655 */
1656static int onenand_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
1657 size_t len, size_t *retlen, u_char *buf)
1658{
1659 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_USER);
1660}
1661
1662/**
1663 * onenand_write_user_prot_reg - [MTD Interface] Write user OTP area
1664 * @param mtd MTD device structure
1665 * @param from The offset to write
1666 * @param len number of bytes to write
1667 * @param retlen pointer to variable to store the number of write bytes
1668 * @param buf the databuffer to put/get data
1669 *
1670 * Write user OTP area.
1671 */
1672static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
1673 size_t len, size_t *retlen, u_char *buf)
1674{
1675 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, MTD_OTP_USER);
1676}
1677
1678/**
1679 * onenand_lock_user_prot_reg - [MTD Interface] Lock user OTP area
1680 * @param mtd MTD device structure
1681 * @param from The offset to lock
1682 * @param len number of bytes to unlock
1683 *
1684 * Write lock mark on spare area in page 0 in OTP block
1685 */
1686static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
1687 size_t len)
1688{
1689 unsigned char oob_buf[64];
1690 size_t retlen;
1691 int ret;
1692
1693 memset(oob_buf, 0xff, mtd->oobsize);
1694 /*
1695 * Note: OTP lock operation
1696 * OTP block : 0xXXFC
1697 * 1st block : 0xXXF3 (If chip support)
1698 * Both : 0xXXF0 (If chip support)
1699 */
1700 oob_buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC;
1701
1702 /*
1703 * Write lock mark to 8th word of sector0 of page0 of the spare0.
1704 * We write 16 bytes spare area instead of 2 bytes.
1705 */
1706 from = 0;
1707 len = 16;
1708
1709 ret = onenand_otp_walk(mtd, from, len, &retlen, oob_buf, do_otp_lock, MTD_OTP_USER);
1710
1711 return ret ? : retlen;
1712}
1713#endif /* CONFIG_MTD_ONENAND_OTP */
1714
1415/** 1715/**
1416 * onenand_print_device_info - Print device ID 1716 * onenand_print_device_info - Print device ID
1417 * @param device device ID 1717 * @param device device ID
@@ -1563,7 +1863,6 @@ static void onenand_resume(struct mtd_info *mtd)
1563 "in suspended state\n"); 1863 "in suspended state\n");
1564} 1864}
1565 1865
1566
1567/** 1866/**
1568 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device 1867 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
1569 * @param mtd MTD device structure 1868 * @param mtd MTD device structure
@@ -1655,6 +1954,14 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1655 mtd->write_ecc = onenand_write_ecc; 1954 mtd->write_ecc = onenand_write_ecc;
1656 mtd->read_oob = onenand_read_oob; 1955 mtd->read_oob = onenand_read_oob;
1657 mtd->write_oob = onenand_write_oob; 1956 mtd->write_oob = onenand_write_oob;
1957#ifdef CONFIG_MTD_ONENAND_OTP
1958 mtd->get_fact_prot_info = onenand_get_fact_prot_info;
1959 mtd->read_fact_prot_reg = onenand_read_fact_prot_reg;
1960 mtd->get_user_prot_info = onenand_get_user_prot_info;
1961 mtd->read_user_prot_reg = onenand_read_user_prot_reg;
1962 mtd->write_user_prot_reg = onenand_write_user_prot_reg;
1963 mtd->lock_user_prot_reg = onenand_lock_user_prot_reg;
1964#endif
1658 mtd->readv = NULL; 1965 mtd->readv = NULL;
1659 mtd->readv_ecc = NULL; 1966 mtd->readv_ecc = NULL;
1660 mtd->writev = onenand_writev; 1967 mtd->writev = onenand_writev;