diff options
author | Marek Vasut <marek.vasut@gmail.com> | 2010-07-27 21:32:05 -0400 |
---|---|---|
committer | Eric Miao <eric.y.miao@gmail.com> | 2010-08-05 02:32:47 -0400 |
commit | e6a8ef54774fb01f0cf7c6d3679c76a0b60fab3b (patch) | |
tree | 495af67ab5461584fa0655ba45464802464ab75c | |
parent | 02a453e4a5a7ca8c8801140f412d327686112e4e (diff) |
[ARM] pxa/balloon3: Add NAND driver
The NAND support is implemented through the gen_nand driver.
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
-rw-r--r-- | arch/arm/mach-pxa/balloon3.c | 151 | ||||
-rw-r--r-- | arch/arm/mach-pxa/include/mach/balloon3.h | 28 |
2 files changed, 176 insertions, 3 deletions
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 6f594bd410dd..e2eb0b79634e 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/mtd/partitions.h> | 27 | #include <linux/mtd/partitions.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/i2c/pcf857x.h> | 29 | #include <linux/i2c/pcf857x.h> |
30 | #include <linux/mtd/nand.h> | ||
31 | #include <linux/mtd/physmap.h> | ||
30 | 32 | ||
31 | #include <asm/setup.h> | 33 | #include <asm/setup.h> |
32 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
@@ -530,6 +532,154 @@ static inline void balloon3_i2c_init(void) {} | |||
530 | #endif | 532 | #endif |
531 | 533 | ||
532 | /****************************************************************************** | 534 | /****************************************************************************** |
535 | * NAND | ||
536 | ******************************************************************************/ | ||
537 | #if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | ||
538 | static uint16_t balloon3_ctl = | ||
539 | BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 | | ||
540 | BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 | | ||
541 | BALLOON3_NAND_CONTROL_FLWP; | ||
542 | |||
543 | static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | ||
544 | { | ||
545 | struct nand_chip *this = mtd->priv; | ||
546 | |||
547 | if (ctrl & NAND_CTRL_CHANGE) { | ||
548 | if (ctrl & NAND_CLE) | ||
549 | balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCLE; | ||
550 | else | ||
551 | balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLCLE; | ||
552 | |||
553 | if (ctrl & NAND_ALE) | ||
554 | balloon3_ctl |= BALLOON3_NAND_CONTROL_FLALE; | ||
555 | else | ||
556 | balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLALE; | ||
557 | |||
558 | __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG); | ||
559 | } | ||
560 | |||
561 | if (cmd != NAND_CMD_NONE) | ||
562 | writeb(cmd, this->IO_ADDR_W); | ||
563 | } | ||
564 | |||
565 | static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip) | ||
566 | { | ||
567 | if (chip < 0 || chip > 3) | ||
568 | return; | ||
569 | |||
570 | balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCE0 | | ||
571 | BALLOON3_NAND_CONTROL_FLCE1 | | ||
572 | BALLOON3_NAND_CONTROL_FLCE2 | | ||
573 | BALLOON3_NAND_CONTROL_FLCE3; | ||
574 | |||
575 | /* Deassert correct nCE line */ | ||
576 | balloon3_ctl &= ~(BALLOON3_NAND_CONTROL_FLCE0 << chip); | ||
577 | |||
578 | __raw_writew(balloon3_ctl, BALLOON3_NAND_CONTROL_REG); | ||
579 | } | ||
580 | |||
581 | static int balloon3_nand_probe(struct platform_device *pdev) | ||
582 | { | ||
583 | void __iomem *temp_map; | ||
584 | uint16_t ver; | ||
585 | int ret; | ||
586 | |||
587 | __raw_writew(BALLOON3_NAND_CONTROL2_16BIT, BALLOON3_NAND_CONTROL2_REG); | ||
588 | |||
589 | ver = __raw_readw(BALLOON3_FPGA_VER); | ||
590 | if (ver > 0x0201) | ||
591 | pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. " | ||
592 | "NAND support might be broken in this version!", ver); | ||
593 | |||
594 | /* Power up the NAND chips */ | ||
595 | ret = gpio_request(BALLOON3_GPIO_RUN_NAND, "NAND"); | ||
596 | if (ret) | ||
597 | goto err1; | ||
598 | |||
599 | ret = gpio_direction_output(BALLOON3_GPIO_RUN_NAND, 1); | ||
600 | if (ret) | ||
601 | goto err2; | ||
602 | |||
603 | gpio_set_value(BALLOON3_GPIO_RUN_NAND, 1); | ||
604 | |||
605 | /* Deassert all nCE lines and write protect line */ | ||
606 | __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG); | ||
607 | return 0; | ||
608 | |||
609 | err2: | ||
610 | gpio_free(BALLOON3_GPIO_RUN_NAND); | ||
611 | err1: | ||
612 | return ret; | ||
613 | } | ||
614 | |||
615 | static void balloon3_nand_remove(struct platform_device *pdev) | ||
616 | { | ||
617 | /* Power down the NAND chips */ | ||
618 | gpio_set_value(BALLOON3_GPIO_RUN_NAND, 0); | ||
619 | gpio_free(BALLOON3_GPIO_RUN_NAND); | ||
620 | } | ||
621 | |||
622 | static struct mtd_partition balloon3_partition_info[] = { | ||
623 | [0] = { | ||
624 | .name = "Boot", | ||
625 | .offset = 0, | ||
626 | .size = SZ_4M, | ||
627 | }, | ||
628 | [1] = { | ||
629 | .name = "RootFS", | ||
630 | .offset = MTDPART_OFS_APPEND, | ||
631 | .size = MTDPART_SIZ_FULL | ||
632 | }, | ||
633 | }; | ||
634 | |||
635 | static const char *balloon3_part_probes[] = { "cmdlinepart", NULL }; | ||
636 | |||
637 | struct platform_nand_data balloon3_nand_pdata = { | ||
638 | .chip = { | ||
639 | .nr_chips = 4, | ||
640 | .chip_offset = 0, | ||
641 | .nr_partitions = ARRAY_SIZE(balloon3_partition_info), | ||
642 | .partitions = balloon3_partition_info, | ||
643 | .chip_delay = 50, | ||
644 | .part_probe_types = balloon3_part_probes, | ||
645 | }, | ||
646 | .ctrl = { | ||
647 | .hwcontrol = 0, | ||
648 | .dev_ready = 0, | ||
649 | .select_chip = balloon3_nand_select_chip, | ||
650 | .cmd_ctrl = balloon3_nand_cmd_ctl, | ||
651 | .probe = balloon3_nand_probe, | ||
652 | .remove = balloon3_nand_remove, | ||
653 | }, | ||
654 | }; | ||
655 | |||
656 | static struct resource balloon3_nand_resource[] = { | ||
657 | [0] = { | ||
658 | .start = BALLOON3_NAND_BASE, | ||
659 | .end = BALLOON3_NAND_BASE + 0x4, | ||
660 | .flags = IORESOURCE_MEM, | ||
661 | }, | ||
662 | }; | ||
663 | |||
664 | static struct platform_device balloon3_nand = { | ||
665 | .name = "gen_nand", | ||
666 | .num_resources = ARRAY_SIZE(balloon3_nand_resource), | ||
667 | .resource = balloon3_nand_resource, | ||
668 | .id = -1, | ||
669 | .dev = { | ||
670 | .platform_data = &balloon3_nand_pdata, | ||
671 | } | ||
672 | }; | ||
673 | |||
674 | static void __init balloon3_nand_init(void) | ||
675 | { | ||
676 | platform_device_register(&balloon3_nand); | ||
677 | } | ||
678 | #else | ||
679 | static inline void balloon3_nand_init(void) {} | ||
680 | #endif | ||
681 | |||
682 | /****************************************************************************** | ||
533 | * Machine init | 683 | * Machine init |
534 | ******************************************************************************/ | 684 | ******************************************************************************/ |
535 | static void __init balloon3_init(void) | 685 | static void __init balloon3_init(void) |
@@ -547,6 +697,7 @@ static void __init balloon3_init(void) | |||
547 | balloon3_lcd_init(); | 697 | balloon3_lcd_init(); |
548 | balloon3_leds_init(); | 698 | balloon3_leds_init(); |
549 | balloon3_mmc_init(); | 699 | balloon3_mmc_init(); |
700 | balloon3_nand_init(); | ||
550 | balloon3_nor_init(); | 701 | balloon3_nor_init(); |
551 | balloon3_ts_init(); | 702 | balloon3_ts_init(); |
552 | balloon3_udc_init(); | 703 | balloon3_udc_init(); |
diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h index 238f887ebaea..eec92e6fd7cf 100644 --- a/arch/arm/mach-pxa/include/mach/balloon3.h +++ b/arch/arm/mach-pxa/include/mach/balloon3.h | |||
@@ -31,12 +31,15 @@ enum balloon3_features { | |||
31 | #define BALLOON3_CF_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00008) | 31 | #define BALLOON3_CF_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00008) |
32 | /* FPGA / CPLD version register */ | 32 | /* FPGA / CPLD version register */ |
33 | #define BALLOON3_FPGA_VER (BALLOON3_FPGA_VIRT + 0x00e0001c) | 33 | #define BALLOON3_FPGA_VER (BALLOON3_FPGA_VIRT + 0x00e0001c) |
34 | /* FPGA / CPLD registers for NAND flash */ | ||
35 | #define BALLOON3_NAND_BASE (PXA_CS4_PHYS + 0x00e00000) | ||
36 | #define BALLOON3_NAND_IO_REG (BALLOON3_FPGA_VIRT + 0x00e00000) | ||
37 | #define BALLOON3_NAND_CONTROL2_REG (BALLOON3_FPGA_VIRT + 0x00e00010) | ||
38 | #define BALLOON3_NAND_STAT_REG (BALLOON3_FPGA_VIRT + 0x00e00010) | ||
39 | #define BALLOON3_NAND_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00014) | ||
34 | 40 | ||
35 | #define BALLOON3_NANDIO_IO_REG (BALLOON3_FPGA_VIRT + 0x00e00000) | ||
36 | /* fpga/cpld interrupt control register */ | 41 | /* fpga/cpld interrupt control register */ |
37 | #define BALLOON3_INT_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e0000C) | 42 | #define BALLOON3_INT_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e0000C) |
38 | #define BALLOON3_NANDIO_CTL2_REG (BALLOON3_FPGA_VIRT + 0x00e00010) | ||
39 | #define BALLOON3_NANDIO_CTL_REG (BALLOON3_FPGA_VIRT + 0x00e00014) | ||
40 | #define BALLOON3_VERSION_REG (BALLOON3_FPGA_VIRT + 0x00e0001c) | 43 | #define BALLOON3_VERSION_REG (BALLOON3_FPGA_VIRT + 0x00e0001c) |
41 | 44 | ||
42 | #define BALLOON3_SAMOSA_ADDR_REG (BALLOON3_FPGA_VIRT + 0x00c00000) | 45 | #define BALLOON3_SAMOSA_ADDR_REG (BALLOON3_FPGA_VIRT + 0x00c00000) |
@@ -56,6 +59,22 @@ enum balloon3_features { | |||
56 | #define BALLOON3_BP_CF_NRDY_IRQ BALLOON3_IRQ(0) | 59 | #define BALLOON3_BP_CF_NRDY_IRQ BALLOON3_IRQ(0) |
57 | #define BALLOON3_BP_NSTSCHG_IRQ BALLOON3_IRQ(1) | 60 | #define BALLOON3_BP_NSTSCHG_IRQ BALLOON3_IRQ(1) |
58 | 61 | ||
62 | /* NAND Control register */ | ||
63 | #define BALLOON3_NAND_CONTROL_FLWP (1 << 7) | ||
64 | #define BALLOON3_NAND_CONTROL_FLSE (1 << 6) | ||
65 | #define BALLOON3_NAND_CONTROL_FLCE3 (1 << 5) | ||
66 | #define BALLOON3_NAND_CONTROL_FLCE2 (1 << 4) | ||
67 | #define BALLOON3_NAND_CONTROL_FLCE1 (1 << 3) | ||
68 | #define BALLOON3_NAND_CONTROL_FLCE0 (1 << 2) | ||
69 | #define BALLOON3_NAND_CONTROL_FLALE (1 << 1) | ||
70 | #define BALLOON3_NAND_CONTROL_FLCLE (1 << 0) | ||
71 | |||
72 | /* NAND Status register */ | ||
73 | #define BALLOON3_NAND_STAT_RNB (1 << 0) | ||
74 | |||
75 | /* NAND Control2 register */ | ||
76 | #define BALLOON3_NAND_CONTROL2_16BIT (1 << 0) | ||
77 | |||
59 | /* GPIOs for irqs */ | 78 | /* GPIOs for irqs */ |
60 | #define BALLOON3_GPIO_AUX_NIRQ (94) | 79 | #define BALLOON3_GPIO_AUX_NIRQ (94) |
61 | #define BALLOON3_GPIO_CODEC_IRQ (95) | 80 | #define BALLOON3_GPIO_CODEC_IRQ (95) |
@@ -69,6 +88,9 @@ enum balloon3_features { | |||
69 | 88 | ||
70 | #define BALLOON3_GPIO_S0_CD (105) | 89 | #define BALLOON3_GPIO_S0_CD (105) |
71 | 90 | ||
91 | /* NAND */ | ||
92 | #define BALLOON3_GPIO_RUN_NAND (102) | ||
93 | |||
72 | /* PCF8574A Leds */ | 94 | /* PCF8574A Leds */ |
73 | #define BALLOON3_PCF_GPIO_BASE 160 | 95 | #define BALLOON3_PCF_GPIO_BASE 160 |
74 | #define BALLOON3_PCF_GPIO_LED0 (BALLOON3_PCF_GPIO_BASE + 0) | 96 | #define BALLOON3_PCF_GPIO_LED0 (BALLOON3_PCF_GPIO_BASE + 0) |