diff options
Diffstat (limited to 'drivers/mtd/nand/davinci_nand.c')
-rw-r--r-- | drivers/mtd/nand/davinci_nand.c | 60 |
1 files changed, 22 insertions, 38 deletions
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 8e2d56c36811..8beb0d0233b5 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -75,6 +75,8 @@ struct davinci_nand_info { | |||
75 | uint32_t mask_cle; | 75 | uint32_t mask_cle; |
76 | 76 | ||
77 | uint32_t core_chipsel; | 77 | uint32_t core_chipsel; |
78 | |||
79 | struct davinci_aemif_timing *timing; | ||
78 | }; | 80 | }; |
79 | 81 | ||
80 | static DEFINE_SPINLOCK(davinci_nand_lock); | 82 | static DEFINE_SPINLOCK(davinci_nand_lock); |
@@ -479,36 +481,6 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd) | |||
479 | return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0); | 481 | return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0); |
480 | } | 482 | } |
481 | 483 | ||
482 | static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info) | ||
483 | { | ||
484 | uint32_t regval, a1cr; | ||
485 | |||
486 | /* | ||
487 | * NAND FLASH timings @ PLL1 == 459 MHz | ||
488 | * - AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz | ||
489 | * - AEMIF.CLK period = 1/76.5 MHz = 13.1 ns | ||
490 | */ | ||
491 | regval = 0 | ||
492 | | (0 << 31) /* selectStrobe */ | ||
493 | | (0 << 30) /* extWait (never with NAND) */ | ||
494 | | (1 << 26) /* writeSetup 10 ns */ | ||
495 | | (3 << 20) /* writeStrobe 40 ns */ | ||
496 | | (1 << 17) /* writeHold 10 ns */ | ||
497 | | (0 << 13) /* readSetup 10 ns */ | ||
498 | | (3 << 7) /* readStrobe 60 ns */ | ||
499 | | (0 << 4) /* readHold 10 ns */ | ||
500 | | (3 << 2) /* turnAround ?? ns */ | ||
501 | | (0 << 0) /* asyncSize 8-bit bus */ | ||
502 | ; | ||
503 | a1cr = davinci_nand_readl(info, A1CR_OFFSET); | ||
504 | if (a1cr != regval) { | ||
505 | dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \ | ||
506 | "reg to 0x%08x, was 0x%08x, should be done by " \ | ||
507 | "bootloader.\n", regval, a1cr); | ||
508 | davinci_nand_writel(info, A1CR_OFFSET, regval); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | /*----------------------------------------------------------------------*/ | 484 | /*----------------------------------------------------------------------*/ |
513 | 485 | ||
514 | /* 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 |
@@ -612,6 +584,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
612 | info->chip.options = pdata->options; | 584 | info->chip.options = pdata->options; |
613 | info->chip.bbt_td = pdata->bbt_td; | 585 | info->chip.bbt_td = pdata->bbt_td; |
614 | info->chip.bbt_md = pdata->bbt_md; | 586 | info->chip.bbt_md = pdata->bbt_md; |
587 | info->timing = pdata->timing; | ||
615 | 588 | ||
616 | info->ioaddr = (uint32_t __force) vaddr; | 589 | info->ioaddr = (uint32_t __force) vaddr; |
617 | 590 | ||
@@ -689,15 +662,25 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
689 | goto err_clk_enable; | 662 | goto err_clk_enable; |
690 | } | 663 | } |
691 | 664 | ||
692 | /* EMIF timings should normally be set by the boot loader, | 665 | /* |
693 | * especially after boot-from-NAND. The *only* reason to | 666 | * Setup Async configuration register in case we did not boot from |
694 | * have this special casing for the DM6446 EVM is to work | 667 | * NAND and so bootloader did not bother to set it up. |
695 | * with boot-from-NOR ... with CS0 manually re-jumpered | ||
696 | * (after startup) so it addresses the NAND flash, not NOR. | ||
697 | * Even for dev boards, that's unusually rude... | ||
698 | */ | 668 | */ |
699 | if (machine_is_davinci_evm()) | 669 | val = davinci_nand_readl(info, A1CR_OFFSET + info->core_chipsel * 4); |
700 | 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 | } | ||
701 | 684 | ||
702 | spin_lock_irq(&davinci_nand_lock); | 685 | spin_lock_irq(&davinci_nand_lock); |
703 | 686 | ||
@@ -810,6 +793,7 @@ syndrome_done: | |||
810 | return 0; | 793 | return 0; |
811 | 794 | ||
812 | err_scan: | 795 | err_scan: |
796 | err_timing: | ||
813 | clk_disable(info->clk); | 797 | clk_disable(info->clk); |
814 | 798 | ||
815 | err_clk_enable: | 799 | err_clk_enable: |