aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/denali.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/denali.c')
-rw-r--r--drivers/mtd/nand/denali.c107
1 files changed, 35 insertions, 72 deletions
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 0c76a16774c9..0f9fc5e7a520 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -549,7 +549,6 @@ static void get_samsung_nand_para(struct denali_nand_info *denali)
549 549
550static void get_toshiba_nand_para(struct denali_nand_info *denali) 550static void get_toshiba_nand_para(struct denali_nand_info *denali)
551{ 551{
552 void __iomem *scratch_reg;
553 uint32_t tmp; 552 uint32_t tmp;
554 553
555 /* Workaround to fix a controller bug which reports a wrong */ 554 /* Workaround to fix a controller bug which reports a wrong */
@@ -567,33 +566,14 @@ static void get_toshiba_nand_para(struct denali_nand_info *denali)
567 denali_write32(8, denali->flash_reg + ECC_CORRECTION); 566 denali_write32(8, denali->flash_reg + ECC_CORRECTION);
568#endif 567#endif
569 } 568 }
570
571 /* As Toshiba NAND can not provide it's block number, */
572 /* so here we need user to provide the correct block */
573 /* number in a scratch register before the Linux NAND */
574 /* driver is loaded. If no valid value found in the scratch */
575 /* register, then we use default block number value */
576 scratch_reg = ioremap_nocache(SCRATCH_REG_ADDR, SCRATCH_REG_SIZE);
577 if (!scratch_reg) {
578 printk(KERN_ERR "Spectra: ioremap failed in %s, Line %d",
579 __FILE__, __LINE__);
580 denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
581 } else {
582 nand_dbg_print(NAND_DBG_WARN,
583 "Spectra: ioremap reg address: 0x%p\n", scratch_reg);
584 denali->dev_info.wTotalBlocks = 1 << ioread8(scratch_reg);
585 if (denali->dev_info.wTotalBlocks < 512)
586 denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
587 iounmap(scratch_reg);
588 }
589} 569}
590 570
591static void get_hynix_nand_para(struct denali_nand_info *denali) 571static void get_hynix_nand_para(struct denali_nand_info *denali,
572 uint8_t device_id)
592{ 573{
593 void __iomem *scratch_reg;
594 uint32_t main_size, spare_size; 574 uint32_t main_size, spare_size;
595 575
596 switch (denali->dev_info.wDeviceID) { 576 switch (device_id) {
597 case 0xD5: /* Hynix H27UAG8T2A, H27UBG8U5A or H27UCG8VFA */ 577 case 0xD5: /* Hynix H27UAG8T2A, H27UBG8U5A or H27UCG8VFA */
598 case 0xD7: /* Hynix H27UDG8VEM, H27UCG8UDM or H27UCG8V5A */ 578 case 0xD7: /* Hynix H27UDG8VEM, H27UCG8UDM or H27UCG8V5A */
599 denali_write32(128, denali->flash_reg + PAGES_PER_BLOCK); 579 denali_write32(128, denali->flash_reg + PAGES_PER_BLOCK);
@@ -621,20 +601,6 @@ static void get_hynix_nand_para(struct denali_nand_info *denali)
621 "Will use default parameter values instead.\n", 601 "Will use default parameter values instead.\n",
622 denali->dev_info.wDeviceID); 602 denali->dev_info.wDeviceID);
623 } 603 }
624
625 scratch_reg = ioremap_nocache(SCRATCH_REG_ADDR, SCRATCH_REG_SIZE);
626 if (!scratch_reg) {
627 printk(KERN_ERR "Spectra: ioremap failed in %s, Line %d",
628 __FILE__, __LINE__);
629 denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
630 } else {
631 nand_dbg_print(NAND_DBG_WARN,
632 "Spectra: ioremap reg address: 0x%p\n", scratch_reg);
633 denali->dev_info.wTotalBlocks = 1 << ioread8(scratch_reg);
634 if (denali->dev_info.wTotalBlocks < 512)
635 denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
636 iounmap(scratch_reg);
637 }
638} 604}
639 605
640/* determines how many NAND chips are connected to the controller. Note for 606/* determines how many NAND chips are connected to the controller. Note for
@@ -807,34 +773,35 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali)
807{ 773{
808 uint16_t status = PASS; 774 uint16_t status = PASS;
809 uint8_t no_of_planes; 775 uint8_t no_of_planes;
776 uint32_t id_bytes[5], addr;
777 uint8_t i, maf_id, device_id;
810 778
811 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", 779 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
812 __FILE__, __LINE__, __func__); 780 __FILE__, __LINE__, __func__);
813 781
814 denali->dev_info.wDeviceMaker = 782 /* Use read id method to get device ID and other
815 ioread32(denali->flash_reg + MANUFACTURER_ID); 783 * params. For some NAND chips, controller can't
816 denali->dev_info.wDeviceID = 784 * report the correct device ID by reading from
817 ioread32(denali->flash_reg + DEVICE_ID); 785 * DEVICE_ID register
818 denali->dev_info.bDeviceParam0 = 786 * */
819 ioread32(denali->flash_reg + DEVICE_PARAM_0); 787 addr = (uint32_t)MODE_11 | BANK(denali->flash_bank);
820 denali->dev_info.bDeviceParam1 = 788 index_addr(denali, (uint32_t)addr | 0, 0x90);
821 ioread32(denali->flash_reg + DEVICE_PARAM_1); 789 index_addr(denali, (uint32_t)addr | 1, 0);
822 denali->dev_info.bDeviceParam2 = 790 for (i = 0; i < 5; i++)
823 ioread32(denali->flash_reg + DEVICE_PARAM_2); 791 index_addr_read_data(denali, addr | 2, &id_bytes[i]);
824 792 maf_id = id_bytes[0];
825 denali->dev_info.MLCDevice = 793 device_id = id_bytes[1];
826 ioread32(denali->flash_reg + DEVICE_PARAM_0) & 0x0c;
827 794
828 if (ioread32(denali->flash_reg + ONFI_DEVICE_NO_OF_LUNS) & 795 if (ioread32(denali->flash_reg + ONFI_DEVICE_NO_OF_LUNS) &
829 ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE) { /* ONFI 1.0 NAND */ 796 ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE) { /* ONFI 1.0 NAND */
830 if (FAIL == get_onfi_nand_para(denali)) 797 if (FAIL == get_onfi_nand_para(denali))
831 return FAIL; 798 return FAIL;
832 } else if (denali->dev_info.wDeviceMaker == 0xEC) { /* Samsung NAND */ 799 } else if (maf_id == 0xEC) { /* Samsung NAND */
833 get_samsung_nand_para(denali); 800 get_samsung_nand_para(denali);
834 } else if (denali->dev_info.wDeviceMaker == 0x98) { /* Toshiba NAND */ 801 } else if (maf_id == 0x98) { /* Toshiba NAND */
835 get_toshiba_nand_para(denali); 802 get_toshiba_nand_para(denali);
836 } else if (denali->dev_info.wDeviceMaker == 0xAD) { /* Hynix NAND */ 803 } else if (maf_id == 0xAD) { /* Hynix NAND */
837 get_hynix_nand_para(denali); 804 get_hynix_nand_para(denali, device_id);
838 } else { 805 } else {
839 denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS; 806 denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
840 } 807 }
@@ -1720,6 +1687,8 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
1720 int page) 1687 int page)
1721{ 1688{
1722 struct denali_nand_info *denali = mtd_to_denali(mtd); 1689 struct denali_nand_info *denali = mtd_to_denali(mtd);
1690 uint32_t addr, id;
1691 int i;
1723 1692
1724#if DEBUG_DENALI 1693#if DEBUG_DENALI
1725 printk(KERN_INFO "cmdfunc: 0x%x %d %d\n", cmd, col, page); 1694 printk(KERN_INFO "cmdfunc: 0x%x %d %d\n", cmd, col, page);
@@ -1732,24 +1701,18 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
1732 break; 1701 break;
1733 case NAND_CMD_READID: 1702 case NAND_CMD_READID:
1734 reset_buf(denali); 1703 reset_buf(denali);
1735 if (denali->flash_bank < denali->total_used_banks) { 1704 /*sometimes ManufactureId read from register is not right
1736 /* write manufacturer information into nand 1705 * e.g. some of Micron MT29F32G08QAA MLC NAND chips
1737 buffer for NAND subsystem to fetch. 1706 * So here we send READID cmd to NAND insteand
1738 */ 1707 * */
1739 write_byte_to_buf(denali, 1708 addr = (uint32_t)MODE_11 | BANK(denali->flash_bank);
1740 denali->dev_info.wDeviceMaker); 1709 index_addr(denali, (uint32_t)addr | 0, 0x90);
1741 write_byte_to_buf(denali, 1710 index_addr(denali, (uint32_t)addr | 1, 0);
1742 denali->dev_info.wDeviceID); 1711 for (i = 0; i < 5; i++) {
1743 write_byte_to_buf(denali, 1712 index_addr_read_data(denali,
1744 denali->dev_info.bDeviceParam0); 1713 (uint32_t)addr | 2,
1745 write_byte_to_buf(denali, 1714 &id);
1746 denali->dev_info.bDeviceParam1); 1715 write_byte_to_buf(denali, id);
1747 write_byte_to_buf(denali,
1748 denali->dev_info.bDeviceParam2);
1749 } else {
1750 int i;
1751 for (i = 0; i < 5; i++)
1752 write_byte_to_buf(denali, 0xff);
1753 } 1716 }
1754 break; 1717 break;
1755 case NAND_CMD_READ0: 1718 case NAND_CMD_READ0: