diff options
author | Kevin Hilman <khilman@deeprootsystems.com> | 2010-10-21 14:21:55 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-10-21 14:21:55 -0400 |
commit | 7940a34b2e1e0485211a17d8c3ab4da1ea3e1330 (patch) | |
tree | fe08ba701cbf23ae44a16d3b7afa521fce943a8a /drivers/mtd/nand/davinci_nand.c | |
parent | 6451d7783ba5ff24eb1a544eaa6665b890f30466 (diff) | |
parent | 8939b3504dc35224cb9c88e5af925b22ea9eee71 (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.c | 61 |
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 | ||
79 | static DEFINE_SPINLOCK(davinci_nand_lock); | 82 | static 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 | ||
481 | static 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 | ||
811 | err_scan: | 795 | err_scan: |
796 | err_timing: | ||
812 | clk_disable(info->clk); | 797 | clk_disable(info->clk); |
813 | 798 | ||
814 | err_clk_enable: | 799 | err_clk_enable: |