aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/davinci_nand.c
diff options
context:
space:
mode:
authorKevin Hilman <khilman@deeprootsystems.com>2010-10-21 14:21:55 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2010-10-21 14:21:55 -0400
commit7940a34b2e1e0485211a17d8c3ab4da1ea3e1330 (patch)
treefe08ba701cbf23ae44a16d3b7afa521fce943a8a /drivers/mtd/nand/davinci_nand.c
parent6451d7783ba5ff24eb1a544eaa6665b890f30466 (diff)
parent8939b3504dc35224cb9c88e5af925b22ea9eee71 (diff)
Merge branch 'davinci-next' into davinci-for-linus
Conflicts: arch/arm/mach-davinci/board-da830-evm.c arch/arm/mach-davinci/board-da850-evm.c
Diffstat (limited to 'drivers/mtd/nand/davinci_nand.c')
-rw-r--r--drivers/mtd/nand/davinci_nand.c61
1 files changed, 23 insertions, 38 deletions
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 2ac7367afe77..8beb0d0233b5 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -35,6 +35,7 @@
35#include <linux/slab.h> 35#include <linux/slab.h>
36 36
37#include <mach/nand.h> 37#include <mach/nand.h>
38#include <mach/aemif.h>
38 39
39#include <asm/mach-types.h> 40#include <asm/mach-types.h>
40 41
@@ -74,6 +75,8 @@ struct davinci_nand_info {
74 uint32_t mask_cle; 75 uint32_t mask_cle;
75 76
76 uint32_t core_chipsel; 77 uint32_t core_chipsel;
78
79 struct davinci_aemif_timing *timing;
77}; 80};
78 81
79static DEFINE_SPINLOCK(davinci_nand_lock); 82static DEFINE_SPINLOCK(davinci_nand_lock);
@@ -478,36 +481,6 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd)
478 return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0); 481 return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
479} 482}
480 483
481static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info)
482{
483 uint32_t regval, a1cr;
484
485 /*
486 * NAND FLASH timings @ PLL1 == 459 MHz
487 * - AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz
488 * - AEMIF.CLK period = 1/76.5 MHz = 13.1 ns
489 */
490 regval = 0
491 | (0 << 31) /* selectStrobe */
492 | (0 << 30) /* extWait (never with NAND) */
493 | (1 << 26) /* writeSetup 10 ns */
494 | (3 << 20) /* writeStrobe 40 ns */
495 | (1 << 17) /* writeHold 10 ns */
496 | (0 << 13) /* readSetup 10 ns */
497 | (3 << 7) /* readStrobe 60 ns */
498 | (0 << 4) /* readHold 10 ns */
499 | (3 << 2) /* turnAround ?? ns */
500 | (0 << 0) /* asyncSize 8-bit bus */
501 ;
502 a1cr = davinci_nand_readl(info, A1CR_OFFSET);
503 if (a1cr != regval) {
504 dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \
505 "reg to 0x%08x, was 0x%08x, should be done by " \
506 "bootloader.\n", regval, a1cr);
507 davinci_nand_writel(info, A1CR_OFFSET, regval);
508 }
509}
510
511/*----------------------------------------------------------------------*/ 484/*----------------------------------------------------------------------*/
512 485
513/* An ECC layout for using 4-bit ECC with small-page flash, storing 486/* An ECC layout for using 4-bit ECC with small-page flash, storing
@@ -611,6 +584,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
611 info->chip.options = pdata->options; 584 info->chip.options = pdata->options;
612 info->chip.bbt_td = pdata->bbt_td; 585 info->chip.bbt_td = pdata->bbt_td;
613 info->chip.bbt_md = pdata->bbt_md; 586 info->chip.bbt_md = pdata->bbt_md;
587 info->timing = pdata->timing;
614 588
615 info->ioaddr = (uint32_t __force) vaddr; 589 info->ioaddr = (uint32_t __force) vaddr;
616 590
@@ -688,15 +662,25 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
688 goto err_clk_enable; 662 goto err_clk_enable;
689 } 663 }
690 664
691 /* EMIF timings should normally be set by the boot loader, 665 /*
692 * especially after boot-from-NAND. The *only* reason to 666 * Setup Async configuration register in case we did not boot from
693 * have this special casing for the DM6446 EVM is to work 667 * NAND and so bootloader did not bother to set it up.
694 * with boot-from-NOR ... with CS0 manually re-jumpered
695 * (after startup) so it addresses the NAND flash, not NOR.
696 * Even for dev boards, that's unusually rude...
697 */ 668 */
698 if (machine_is_davinci_evm()) 669 val = davinci_nand_readl(info, A1CR_OFFSET + info->core_chipsel * 4);
699 nand_dm6446evm_flash_init(info); 670
671 /* Extended Wait is not valid and Select Strobe mode is not used */
672 val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK);
673 if (info->chip.options & NAND_BUSWIDTH_16)
674 val |= 0x1;
675
676 davinci_nand_writel(info, A1CR_OFFSET + info->core_chipsel * 4, val);
677
678 ret = davinci_aemif_setup_timing(info->timing, info->base,
679 info->core_chipsel);
680 if (ret < 0) {
681 dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
682 goto err_timing;
683 }
700 684
701 spin_lock_irq(&davinci_nand_lock); 685 spin_lock_irq(&davinci_nand_lock);
702 686
@@ -809,6 +793,7 @@ syndrome_done:
809 return 0; 793 return 0;
810 794
811err_scan: 795err_scan:
796err_timing:
812 clk_disable(info->clk); 797 clk_disable(info->clk);
813 798
814err_clk_enable: 799err_clk_enable: