forked from Minki/linux
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 <ivo.clarysse@gmail.com> Acked-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
parent
9d5da3a9b8
commit
d484018056
@ -542,6 +542,41 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
|
||||
}
|
||||
}
|
||||
|
||||
static void preset(struct mtd_info *mtd)
|
||||
{
|
||||
struct nand_chip *nand_chip = mtd->priv;
|
||||
struct mxc_nand_host *host = nand_chip->priv;
|
||||
uint16_t tmp;
|
||||
|
||||
/* disable interrupt, disable spare enable */
|
||||
tmp = readw(host->regs + NFC_CONFIG1);
|
||||
tmp |= NFC_INT_MSK;
|
||||
tmp &= ~NFC_SP_EN;
|
||||
if (nand_chip->ecc.mode == NAND_ECC_HW) {
|
||||
tmp |= NFC_ECC_EN;
|
||||
} else {
|
||||
tmp &= ~NFC_ECC_EN;
|
||||
}
|
||||
writew(tmp, host->regs + NFC_CONFIG1);
|
||||
/* preset operation */
|
||||
|
||||
/* Unlock the internal RAM Buffer */
|
||||
writew(0x2, host->regs + NFC_CONFIG);
|
||||
|
||||
/* Blocks to be unlocked */
|
||||
if (nfc_is_v21()) {
|
||||
writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
|
||||
writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
|
||||
} else if (nfc_is_v1()) {
|
||||
writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
|
||||
writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
|
||||
} else
|
||||
BUG();
|
||||
|
||||
/* Unlock Block Command for given address range */
|
||||
writew(0x4, host->regs + NFC_WRPROT);
|
||||
}
|
||||
|
||||
/* Used by the upper layer to write command to NAND Flash for
|
||||
* different operations to be carried out on NAND Flash */
|
||||
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,
|
||||
|
||||
/* Command pre-processing step */
|
||||
switch (command) {
|
||||
case NAND_CMD_RESET:
|
||||
send_cmd(host, command, false);
|
||||
preset(mtd);
|
||||
break;
|
||||
|
||||
case NAND_CMD_STATUS:
|
||||
host->buf_start = 0;
|
||||
@ -680,7 +719,6 @@ static int __init mxcnd_probe(struct platform_device *pdev)
|
||||
struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct mxc_nand_host *host;
|
||||
struct resource *res;
|
||||
uint16_t tmp;
|
||||
int err = 0, nr_parts = 0;
|
||||
struct nand_ecclayout *oob_smallpage, *oob_largepage;
|
||||
|
||||
@ -744,51 +782,17 @@ static int __init mxcnd_probe(struct platform_device *pdev)
|
||||
host->spare_len = 64;
|
||||
oob_smallpage = &nandv2_hw_eccoob_smallpage;
|
||||
oob_largepage = &nandv2_hw_eccoob_largepage;
|
||||
this->ecc.bytes = 9;
|
||||
} else if (nfc_is_v1()) {
|
||||
host->regs = host->base;
|
||||
host->spare0 = host->base + 0x800;
|
||||
host->spare_len = 16;
|
||||
oob_smallpage = &nandv1_hw_eccoob_smallpage;
|
||||
oob_largepage = &nandv1_hw_eccoob_largepage;
|
||||
} else
|
||||
BUG();
|
||||
|
||||
/* disable interrupt and spare enable */
|
||||
tmp = readw(host->regs + NFC_CONFIG1);
|
||||
tmp |= NFC_INT_MSK;
|
||||
tmp &= ~NFC_SP_EN;
|
||||
writew(tmp, host->regs + NFC_CONFIG1);
|
||||
|
||||
init_waitqueue_head(&host->irq_waitq);
|
||||
|
||||
host->irq = platform_get_irq(pdev, 0);
|
||||
|
||||
err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host);
|
||||
if (err)
|
||||
goto eirq;
|
||||
|
||||
/* Reset NAND */
|
||||
this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
|
||||
|
||||
/* preset operation */
|
||||
/* Unlock the internal RAM Buffer */
|
||||
writew(0x2, host->regs + NFC_CONFIG);
|
||||
|
||||
/* Blocks to be unlocked */
|
||||
if (nfc_is_v21()) {
|
||||
writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
|
||||
writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
|
||||
this->ecc.bytes = 9;
|
||||
} else if (nfc_is_v1()) {
|
||||
writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
|
||||
writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
|
||||
this->ecc.bytes = 3;
|
||||
} else
|
||||
BUG();
|
||||
|
||||
/* Unlock Block Command for given address range */
|
||||
writew(0x4, host->regs + NFC_WRPROT);
|
||||
|
||||
this->ecc.size = 512;
|
||||
this->ecc.layout = oob_smallpage;
|
||||
|
||||
@ -797,14 +801,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
|
||||
this->ecc.hwctl = mxc_nand_enable_hwecc;
|
||||
this->ecc.correct = mxc_nand_correct_data;
|
||||
this->ecc.mode = NAND_ECC_HW;
|
||||
tmp = readw(host->regs + NFC_CONFIG1);
|
||||
tmp |= NFC_ECC_EN;
|
||||
writew(tmp, host->regs + NFC_CONFIG1);
|
||||
} else {
|
||||
this->ecc.mode = NAND_ECC_SOFT;
|
||||
tmp = readw(host->regs + NFC_CONFIG1);
|
||||
tmp &= ~NFC_ECC_EN;
|
||||
writew(tmp, host->regs + NFC_CONFIG1);
|
||||
}
|
||||
|
||||
/* NAND bus width determines access funtions used by upper layer */
|
||||
@ -818,6 +816,14 @@ static int __init mxcnd_probe(struct platform_device *pdev)
|
||||
this->options |= NAND_USE_FLASH_BBT;
|
||||
}
|
||||
|
||||
init_waitqueue_head(&host->irq_waitq);
|
||||
|
||||
host->irq = platform_get_irq(pdev, 0);
|
||||
|
||||
err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host);
|
||||
if (err)
|
||||
goto eirq;
|
||||
|
||||
/* first scan to find the device and get the page size */
|
||||
if (nand_scan_ident(mtd, 1, NULL)) {
|
||||
err = -ENXIO;
|
||||
|
Loading…
Reference in New Issue
Block a user