diff options
-rw-r--r-- | drivers/mtd/maps/ck804xrom.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/cafe.c | 85 |
2 files changed, 35 insertions, 52 deletions
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 238d42e88ec5..68ed02ecb2ec 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c | |||
@@ -327,7 +327,7 @@ static int __init init_ck804xrom(void) | |||
327 | pdev = NULL; | 327 | pdev = NULL; |
328 | 328 | ||
329 | for(id = ck804xrom_pci_tbl; id->vendor; id++) { | 329 | for(id = ck804xrom_pci_tbl; id->vendor; id++) { |
330 | pdev = pci_find_device(id->vendor, id->device, NULL); | 330 | pdev = pci_get_device(id->vendor, id->device, NULL); |
331 | if (pdev) | 331 | if (pdev) |
332 | break; | 332 | break; |
333 | } | 333 | } |
diff --git a/drivers/mtd/nand/cafe.c b/drivers/mtd/nand/cafe.c index 65f9bd3ceebf..1e877cbe7757 100644 --- a/drivers/mtd/nand/cafe.c +++ b/drivers/mtd/nand/cafe.c | |||
@@ -78,8 +78,9 @@ module_param(regdebug, int, 0644); | |||
78 | static int checkecc = 1; | 78 | static int checkecc = 1; |
79 | module_param(checkecc, int, 0644); | 79 | module_param(checkecc, int, 0644); |
80 | 80 | ||
81 | static int slowtiming = 0; | 81 | static int numtimings; |
82 | module_param(slowtiming, int, 0644); | 82 | static int timing[3]; |
83 | module_param_array(timing, int, &numtimings, 0644); | ||
83 | 84 | ||
84 | /* Hrm. Why isn't this already conditional on something in the struct device? */ | 85 | /* Hrm. Why isn't this already conditional on something in the struct device? */ |
85 | #define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0) | 86 | #define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0) |
@@ -529,6 +530,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, | |||
529 | { | 530 | { |
530 | struct mtd_info *mtd; | 531 | struct mtd_info *mtd; |
531 | struct cafe_priv *cafe; | 532 | struct cafe_priv *cafe; |
533 | uint32_t timing1, timing2, timing3; | ||
532 | uint32_t ctrl; | 534 | uint32_t ctrl; |
533 | int err = 0; | 535 | int err = 0; |
534 | 536 | ||
@@ -580,30 +582,44 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, | |||
580 | cafe->nand.block_bad = cafe_nand_block_bad; | 582 | cafe->nand.block_bad = cafe_nand_block_bad; |
581 | } | 583 | } |
582 | 584 | ||
585 | if (numtimings && numtimings != 3) { | ||
586 | dev_warn(&cafe->pdev->dev, "%d timing register values ignored; precisely three are required\n", numtimings); | ||
587 | } | ||
588 | |||
589 | if (numtimings == 3) { | ||
590 | timing1 = timing[0]; | ||
591 | timing2 = timing[1]; | ||
592 | timing3 = timing[2]; | ||
593 | cafe_dev_dbg(&cafe->pdev->dev, "Using provided timings (%08x %08x %08x)\n", | ||
594 | timing1, timing2, timing3); | ||
595 | } else { | ||
596 | timing1 = cafe_readl(cafe, NAND_TIMING1); | ||
597 | timing2 = cafe_readl(cafe, NAND_TIMING2); | ||
598 | timing3 = cafe_readl(cafe, NAND_TIMING3); | ||
599 | |||
600 | if (timing1 | timing2 | timing3) { | ||
601 | cafe_dev_dbg(&cafe->pdev->dev, "Timing registers already set (%08x %08x %08x)\n", timing1, timing2, timing3); | ||
602 | } else { | ||
603 | dev_warn(&cafe->pdev->dev, "Timing registers unset; using most conservative defaults\n"); | ||
604 | timing1 = timing2 = timing3 = 0xffffffff; | ||
605 | } | ||
606 | } | ||
607 | |||
583 | /* Start off by resetting the NAND controller completely */ | 608 | /* Start off by resetting the NAND controller completely */ |
584 | cafe_writel(cafe, 1, NAND_RESET); | 609 | cafe_writel(cafe, 1, NAND_RESET); |
585 | cafe_writel(cafe, 0, NAND_RESET); | 610 | cafe_writel(cafe, 0, NAND_RESET); |
586 | 611 | ||
587 | cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK); | 612 | cafe_writel(cafe, timing1, NAND_TIMING1); |
613 | cafe_writel(cafe, timing2, NAND_TIMING2); | ||
614 | cafe_writel(cafe, timing3, NAND_TIMING3); | ||
588 | 615 | ||
589 | /* Timings from Marvell's test code (not verified or calculated by us) */ | ||
590 | if (!slowtiming) { | ||
591 | cafe_writel(cafe, 0x01010a0a, NAND_TIMING1); | ||
592 | cafe_writel(cafe, 0x24121212, NAND_TIMING2); | ||
593 | cafe_writel(cafe, 0x11000000, NAND_TIMING3); | ||
594 | } else { | ||
595 | cafe_writel(cafe, 0xffffffff, NAND_TIMING1); | ||
596 | cafe_writel(cafe, 0xffffffff, NAND_TIMING2); | ||
597 | cafe_writel(cafe, 0xffffffff, NAND_TIMING3); | ||
598 | } | ||
599 | cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK); | 616 | cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK); |
600 | err = request_irq(pdev->irq, &cafe_nand_interrupt, SA_SHIRQ, "CAFE NAND", mtd); | 617 | err = request_irq(pdev->irq, &cafe_nand_interrupt, SA_SHIRQ, "CAFE NAND", mtd); |
601 | if (err) { | 618 | if (err) { |
602 | dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq); | 619 | dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq); |
603 | |||
604 | goto out_free_dma; | 620 | goto out_free_dma; |
605 | } | 621 | } |
606 | #if 1 | 622 | |
607 | /* Disable master reset, enable NAND clock */ | 623 | /* Disable master reset, enable NAND clock */ |
608 | ctrl = cafe_readl(cafe, GLOBAL_CTRL); | 624 | ctrl = cafe_readl(cafe, GLOBAL_CTRL); |
609 | ctrl &= 0xffffeff0; | 625 | ctrl &= 0xffffeff0; |
@@ -630,32 +646,8 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, | |||
630 | cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK); | 646 | cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK); |
631 | cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n", | 647 | cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n", |
632 | cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK)); | 648 | cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK)); |
633 | #endif | 649 | |
634 | #if 1 | 650 | /* Scan to find existence of the device */ |
635 | mtd->writesize=2048; | ||
636 | mtd->oobsize = 0x40; | ||
637 | memset(cafe->dmabuf, 0x5a, 2112); | ||
638 | cafe->nand.cmdfunc(mtd, NAND_CMD_READID, 0, -1); | ||
639 | cafe->nand.read_byte(mtd); | ||
640 | cafe->nand.read_byte(mtd); | ||
641 | cafe->nand.read_byte(mtd); | ||
642 | cafe->nand.read_byte(mtd); | ||
643 | cafe->nand.read_byte(mtd); | ||
644 | #endif | ||
645 | #if 0 | ||
646 | cafe->nand.cmdfunc(mtd, NAND_CMD_READ0, 0, 0); | ||
647 | // nand_wait_ready(mtd); | ||
648 | cafe->nand.read_byte(mtd); | ||
649 | cafe->nand.read_byte(mtd); | ||
650 | cafe->nand.read_byte(mtd); | ||
651 | cafe->nand.read_byte(mtd); | ||
652 | #endif | ||
653 | #if 0 | ||
654 | writel(0x84600070, cafe->mmio); | ||
655 | udelay(10); | ||
656 | cafe_dev_dbg(&cafe->pdev->dev, "Status %x\n", cafe_readl(cafe, NAND_NONMEM)); | ||
657 | #endif | ||
658 | /* Scan to find existance of the device */ | ||
659 | if (nand_scan_ident(mtd, 1)) { | 651 | if (nand_scan_ident(mtd, 1)) { |
660 | err = -ENXIO; | 652 | err = -ENXIO; |
661 | goto out_irq; | 653 | goto out_irq; |
@@ -759,13 +751,4 @@ module_exit(cafe_nand_exit); | |||
759 | 751 | ||
760 | MODULE_LICENSE("GPL"); | 752 | MODULE_LICENSE("GPL"); |
761 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); | 753 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); |
762 | MODULE_DESCRIPTION("NAND flash driver for OLPC CAFE chip"); | 754 | MODULE_DESCRIPTION("NAND flash driver for OLPC CAFÉ chip"); |
763 | |||
764 | /* Correct ECC for 2048 bytes of 0xff: | ||
765 | 41 a0 71 65 54 27 f3 93 ec a9 be ed 0b a1 */ | ||
766 | |||
767 | /* dwmw2's B-test board, in case of completely screwing it: | ||
768 | Bad eraseblock 2394 at 0x12b40000 | ||
769 | Bad eraseblock 2627 at 0x14860000 | ||
770 | Bad eraseblock 3349 at 0x1a2a0000 | ||
771 | */ | ||