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) |
