aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIvo Clarysse <ivo.clarysse@gmail.com>2010-04-08 10:14:44 -0400
committerSascha Hauer <s.hauer@pengutronix.de>2010-04-14 02:58:36 -0400
commit7422f27a8ad7f6a7474e324a61e5a7f8be166c25 (patch)
tree3e53f34417610eb66bcce7728428a02ab27d5df3 /drivers
parent8bcc84ad61a601f4d8fc960d5e6495d6fc88177b (diff)
MXC: mxc_nand: set NFC registers after reset
This patch allows the mxc_nand driver to reset the NAND flash controller. NFC registers are (re-)set after completion of the reset, as a reset will have reverted the NFC registers to their default values. Signed-off-by: Ivo Clarysse <ivo.clarysse@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/mxc_nand.c90
1 files changed, 48 insertions, 42 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index b2900d8406d3..ed27d38de27a 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -542,6 +542,41 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
542 } 542 }
543} 543}
544 544
545static void preset(struct mtd_info *mtd)
546{
547 struct nand_chip *nand_chip = mtd->priv;
548 struct mxc_nand_host *host = nand_chip->priv;
549 uint16_t tmp;
550
551 /* disable interrupt, disable spare enable */
552 tmp = readw(host->regs + NFC_CONFIG1);
553 tmp |= NFC_INT_MSK;
554 tmp &= ~NFC_SP_EN;
555 if (nand_chip->ecc.mode == NAND_ECC_HW) {
556 tmp |= NFC_ECC_EN;
557 } else {
558 tmp &= ~NFC_ECC_EN;
559 }
560 writew(tmp, host->regs + NFC_CONFIG1);
561 /* preset operation */
562
563 /* Unlock the internal RAM Buffer */
564 writew(0x2, host->regs + NFC_CONFIG);
565
566 /* Blocks to be unlocked */
567 if (nfc_is_v21()) {
568 writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
569 writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
570 } else if (nfc_is_v1()) {
571 writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
572 writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
573 } else
574 BUG();
575
576 /* Unlock Block Command for given address range */
577 writew(0x4, host->regs + NFC_WRPROT);
578}
579
545/* Used by the upper layer to write command to NAND Flash for 580/* Used by the upper layer to write command to NAND Flash for
546 * different operations to be carried out on NAND Flash */ 581 * different operations to be carried out on NAND Flash */
547static void mxc_nand_command(struct mtd_info *mtd, unsigned command, 582static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
@@ -559,6 +594,10 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
559 594
560 /* Command pre-processing step */ 595 /* Command pre-processing step */
561 switch (command) { 596 switch (command) {
597 case NAND_CMD_RESET:
598 send_cmd(host, command, false);
599 preset(mtd);
600 break;
562 601
563 case NAND_CMD_STATUS: 602 case NAND_CMD_STATUS:
564 host->buf_start = 0; 603 host->buf_start = 0;
@@ -679,7 +718,6 @@ static int __init mxcnd_probe(struct platform_device *pdev)
679 struct mxc_nand_platform_data *pdata = pdev->dev.platform_data; 718 struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
680 struct mxc_nand_host *host; 719 struct mxc_nand_host *host;
681 struct resource *res; 720 struct resource *res;
682 uint16_t tmp;
683 int err = 0, nr_parts = 0; 721 int err = 0, nr_parts = 0;
684 struct nand_ecclayout *oob_smallpage, *oob_largepage; 722 struct nand_ecclayout *oob_smallpage, *oob_largepage;
685 723
@@ -743,51 +781,17 @@ static int __init mxcnd_probe(struct platform_device *pdev)
743 host->spare_len = 64; 781 host->spare_len = 64;
744 oob_smallpage = &nandv2_hw_eccoob_smallpage; 782 oob_smallpage = &nandv2_hw_eccoob_smallpage;
745 oob_largepage = &nandv2_hw_eccoob_largepage; 783 oob_largepage = &nandv2_hw_eccoob_largepage;
784 this->ecc.bytes = 9;
746 } else if (nfc_is_v1()) { 785 } else if (nfc_is_v1()) {
747 host->regs = host->base; 786 host->regs = host->base;
748 host->spare0 = host->base + 0x800; 787 host->spare0 = host->base + 0x800;
749 host->spare_len = 16; 788 host->spare_len = 16;
750 oob_smallpage = &nandv1_hw_eccoob_smallpage; 789 oob_smallpage = &nandv1_hw_eccoob_smallpage;
751 oob_largepage = &nandv1_hw_eccoob_largepage; 790 oob_largepage = &nandv1_hw_eccoob_largepage;
752 } else
753 BUG();
754
755 /* disable interrupt and spare enable */
756 tmp = readw(host->regs + NFC_CONFIG1);
757 tmp |= NFC_INT_MSK;
758 tmp &= ~NFC_SP_EN;
759 writew(tmp, host->regs + NFC_CONFIG1);
760
761 init_waitqueue_head(&host->irq_waitq);
762
763 host->irq = platform_get_irq(pdev, 0);
764
765 err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host);
766 if (err)
767 goto eirq;
768
769 /* Reset NAND */
770 this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
771
772 /* preset operation */
773 /* Unlock the internal RAM Buffer */
774 writew(0x2, host->regs + NFC_CONFIG);
775
776 /* Blocks to be unlocked */
777 if (nfc_is_v21()) {
778 writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
779 writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
780 this->ecc.bytes = 9;
781 } else if (nfc_is_v1()) {
782 writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
783 writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
784 this->ecc.bytes = 3; 791 this->ecc.bytes = 3;
785 } else 792 } else
786 BUG(); 793 BUG();
787 794
788 /* Unlock Block Command for given address range */
789 writew(0x4, host->regs + NFC_WRPROT);
790
791 this->ecc.size = 512; 795 this->ecc.size = 512;
792 this->ecc.layout = oob_smallpage; 796 this->ecc.layout = oob_smallpage;
793 797
@@ -796,14 +800,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
796 this->ecc.hwctl = mxc_nand_enable_hwecc; 800 this->ecc.hwctl = mxc_nand_enable_hwecc;
797 this->ecc.correct = mxc_nand_correct_data; 801 this->ecc.correct = mxc_nand_correct_data;
798 this->ecc.mode = NAND_ECC_HW; 802 this->ecc.mode = NAND_ECC_HW;
799 tmp = readw(host->regs + NFC_CONFIG1);
800 tmp |= NFC_ECC_EN;
801 writew(tmp, host->regs + NFC_CONFIG1);
802 } else { 803 } else {
803 this->ecc.mode = NAND_ECC_SOFT; 804 this->ecc.mode = NAND_ECC_SOFT;
804 tmp = readw(host->regs + NFC_CONFIG1);
805 tmp &= ~NFC_ECC_EN;
806 writew(tmp, host->regs + NFC_CONFIG1);
807 } 805 }
808 806
809 /* NAND bus width determines access funtions used by upper layer */ 807 /* NAND bus width determines access funtions used by upper layer */
@@ -817,6 +815,14 @@ static int __init mxcnd_probe(struct platform_device *pdev)
817 this->options |= NAND_USE_FLASH_BBT; 815 this->options |= NAND_USE_FLASH_BBT;
818 } 816 }
819 817
818 init_waitqueue_head(&host->irq_waitq);
819
820 host->irq = platform_get_irq(pdev, 0);
821
822 err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host);
823 if (err)
824 goto eirq;
825
820 /* first scan to find the device and get the page size */ 826 /* first scan to find the device and get the page size */
821 if (nand_scan_ident(mtd, 1)) { 827 if (nand_scan_ident(mtd, 1)) {
822 err = -ENXIO; 828 err = -ENXIO;