Skip to content

Commit d484018

Browse files
IvoClarysseDavid Woodhouse
authored andcommitted
mtd: 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 <[email protected]> Acked-by: Sascha Hauer <[email protected]> Signed-off-by: David Woodhouse <[email protected]>
1 parent 9d5da3a commit d484018

File tree

1 file changed

+48
-42
lines changed

1 file changed

+48
-42
lines changed

drivers/mtd/nand/mxc_nand.c

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,41 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
542542
}
543543
}
544544

545+
static 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+
545580
/* Used by the upper layer to write command to NAND Flash for
546581
* different operations to be carried out on NAND Flash */
547582
static 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,
559594

560595
/* Command pre-processing step */
561596
switch (command) {
597+
case NAND_CMD_RESET:
598+
send_cmd(host, command, false);
599+
preset(mtd);
600+
break;
562601

563602
case NAND_CMD_STATUS:
564603
host->buf_start = 0;
@@ -680,7 +719,6 @@ static int __init mxcnd_probe(struct platform_device *pdev)
680719
struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
681720
struct mxc_nand_host *host;
682721
struct resource *res;
683-
uint16_t tmp;
684722
int err = 0, nr_parts = 0;
685723
struct nand_ecclayout *oob_smallpage, *oob_largepage;
686724

@@ -744,51 +782,17 @@ static int __init mxcnd_probe(struct platform_device *pdev)
744782
host->spare_len = 64;
745783
oob_smallpage = &nandv2_hw_eccoob_smallpage;
746784
oob_largepage = &nandv2_hw_eccoob_largepage;
785+
this->ecc.bytes = 9;
747786
} else if (nfc_is_v1()) {
748787
host->regs = host->base;
749788
host->spare0 = host->base + 0x800;
750789
host->spare_len = 16;
751790
oob_smallpage = &nandv1_hw_eccoob_smallpage;
752791
oob_largepage = &nandv1_hw_eccoob_largepage;
753-
} else
754-
BUG();
755-
756-
/* disable interrupt and spare enable */
757-
tmp = readw(host->regs + NFC_CONFIG1);
758-
tmp |= NFC_INT_MSK;
759-
tmp &= ~NFC_SP_EN;
760-
writew(tmp, host->regs + NFC_CONFIG1);
761-
762-
init_waitqueue_head(&host->irq_waitq);
763-
764-
host->irq = platform_get_irq(pdev, 0);
765-
766-
err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host);
767-
if (err)
768-
goto eirq;
769-
770-
/* Reset NAND */
771-
this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
772-
773-
/* preset operation */
774-
/* Unlock the internal RAM Buffer */
775-
writew(0x2, host->regs + NFC_CONFIG);
776-
777-
/* Blocks to be unlocked */
778-
if (nfc_is_v21()) {
779-
writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
780-
writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
781-
this->ecc.bytes = 9;
782-
} else if (nfc_is_v1()) {
783-
writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
784-
writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
785792
this->ecc.bytes = 3;
786793
} else
787794
BUG();
788795

789-
/* Unlock Block Command for given address range */
790-
writew(0x4, host->regs + NFC_WRPROT);
791-
792796
this->ecc.size = 512;
793797
this->ecc.layout = oob_smallpage;
794798

@@ -797,14 +801,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
797801
this->ecc.hwctl = mxc_nand_enable_hwecc;
798802
this->ecc.correct = mxc_nand_correct_data;
799803
this->ecc.mode = NAND_ECC_HW;
800-
tmp = readw(host->regs + NFC_CONFIG1);
801-
tmp |= NFC_ECC_EN;
802-
writew(tmp, host->regs + NFC_CONFIG1);
803804
} else {
804805
this->ecc.mode = NAND_ECC_SOFT;
805-
tmp = readw(host->regs + NFC_CONFIG1);
806-
tmp &= ~NFC_ECC_EN;
807-
writew(tmp, host->regs + NFC_CONFIG1);
808806
}
809807

810808
/* NAND bus width determines access funtions used by upper layer */
@@ -818,6 +816,14 @@ static int __init mxcnd_probe(struct platform_device *pdev)
818816
this->options |= NAND_USE_FLASH_BBT;
819817
}
820818

819+
init_waitqueue_head(&host->irq_waitq);
820+
821+
host->irq = platform_get_irq(pdev, 0);
822+
823+
err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host);
824+
if (err)
825+
goto eirq;
826+
821827
/* first scan to find the device and get the page size */
822828
if (nand_scan_ident(mtd, 1, NULL)) {
823829
err = -ENXIO;

0 commit comments

Comments
 (0)