From: David Brownell <[email protected]> Start splitting out the board-specific NAND support better, by having board-specific flash init functions. DM355 EVM has a newer and faster chip.
It's still in the wrong place, but at least it's better factored now ... which will help later when it's moved to the board-*.c files. (NOTE: sffsdr support is missing; it might not actually need to set the EMIF A1CR register.) Also update the header comment slightly, listing key assumptions made by this driver ... and delete a broken comment in the dm6446 setup code, that's not the value it was writing. Signed-off-by: David Brownell <[email protected]> --- drivers/mtd/nand/davinci_nand.c | 79 +++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 9 deletions(-) --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -29,7 +29,15 @@ * * Overview: * This is a device driver for the NAND flash device found on the - * DaVinci board which utilizes the Samsung k9k2g08 part. + * DaVinci DM6446 EVM board which utilizes the Samsung k9k2g08 part. + * (small page NAND). It should work for some other DaVinci NAND + * configurations, but it ignores the dm355 4-bit ECC hardware. + * + * Currently makes assumptions about how the NAND device(s) are wired: + * - connected on the first chipselect, controlled by A1CR + * - single NAND chip + * - ALE and CLE wired to support boot-from-NAND + * - EM_WAIT is connected to the NAND device, not another device * * Modifications: * ver. 1.0: Feb 2005, Vinod/Sudhakar @@ -461,7 +469,53 @@ static void __init nand_davinci_set_eccb } } -static void __init nand_davinci_flash_init(struct davinci_nand_info *info) +static void __init nand_dm355evm_flash_init(struct davinci_nand_info *info) +{ + u32 val, tmp; + + /* + * For AEMIFCLK at 108.0 MHz (9.26 nsec/tick) these timings: + * - have small (a few nsec) margins for pcb+socket delays + * - assume standard mode operations (not cache mode) + * - are WAY OFF for turnaround not gated by ARM instructions + * + * Write setup (tCS, tDS) min 15 nsec + * Write strobes (tWP) could be subsumed in setup + * + * Read setup (tCEA - tREA) min 5 nsec + * Read strobes (tRP) min 12 nsec + * + * Hold times (tALH, tCLH, tCH, tDH) min 5 nsec + * Read and write cycle times (tRC, tWC) min 25 nsec + * Turnaround (tWHR, tRHW) min 100 nsec + */ + val = 0 + | (0 << 31) /* selectStrobe normal mode */ + | (0 << 30) /* extWait mbz for NAND */ + + /* WRITE: */ + | (1 << 26) /* Setup 2 ticks (18 ns) */ + | (0 << 20) /* Strobe 1 tick (9 ns) */ + | (0 << 17) /* Hold 1 tick (9 ns) */ + + /* READ: */ + | (0 << 13) /* Setup 1 tick (9 ns) */ + | (1 << 7) /* Strobe 2 ticks (18 ns) */ + | (0 << 4) /* Hold 1 tick (9 ns) */ + + | (3 << 2) /* turnAround 3 ticks (TOO LOW) */ + | (0 << 0) /* asyncSize eight-bit bus */ + ; + + tmp = davinci_nand_readl(info, A1CR_OFFSET); + if (tmp != val) { + dev_dbg(info->dev, "NAND config: Set A1CR " + "to 0x%08x, was 0x%08x\n", val, tmp); + davinci_nand_writel(info, A1CR_OFFSET, val); + } +} + +static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info) { u32 regval, tmp; @@ -526,10 +580,8 @@ static void __init nand_davinci_flash_in dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \ "reg to 0x%08x, was 0x%08x, should be done by " \ "bootloader.\n", regval, tmp); - davinci_nand_writel(info, A1CR_OFFSET, regval); /* 0x0434018C */ + davinci_nand_writel(info, A1CR_OFFSET, regval); } - - davinci_nand_writel(info, NANDFCR_OFFSET, 0x00000101); } static int __init nand_davinci_probe(struct platform_device *pdev) @@ -541,7 +593,7 @@ static int __init nand_davinci_probe(str void __iomem *vaddr; void __iomem *base; int ret; - u32 rev; + u32 val; if (!pdata) { dev_err(&pdev->dev, "platform_data missing\n"); @@ -640,7 +692,16 @@ static int __init nand_davinci_probe(str nand_davinci_set_eccsize(&info->chip); nand_davinci_set_eccbytes(&info->chip); - nand_davinci_flash_init(info); + /* FIXME these don't belong here ... */ + if (machine_is_davinci_dm355_evm()) + nand_dm355evm_flash_init(info); + if (machine_is_davinci_evm()) + nand_dm6446evm_flash_init(info); + + /* put "CS2NAND" (CS0) into NAND mode */ + val = davinci_nand_readl(info, NANDFCR_OFFSET); + val |= BIT(0); + davinci_nand_writel(info, NANDFCR_OFFSET, val); /* Scan to find existence of the device */ if (nand_scan(&info->mtd, 1)) { @@ -703,9 +764,9 @@ static int __init nand_davinci_probe(str if (ret < 0) goto err_scan; - rev = davinci_nand_readl(info, NRCSR_OFFSET); + val = davinci_nand_readl(info, NRCSR_OFFSET); dev_info(&pdev->dev, "controller rev. %d.%d\n", - (rev >> 8) & 0xff, rev & 0xff); + (val >> 8) & 0xff, val & 0xff); return 0; _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
