diff options
Diffstat (limited to 'arch/arm/mach-ixp4xx/ixdp425-setup.c')
-rw-r--r-- | arch/arm/mach-ixp4xx/ixdp425-setup.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index ec4f07950ec..d5008d8fc9a 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -15,6 +15,10 @@ #include <linux/tty.h> #include <linux/serial_8250.h> #include <linux/slab.h> +#include <linux/io.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> #include <asm/types.h> #include <asm/setup.h> @@ -24,6 +28,7 @@ #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> +#include <asm/delay.h> static struct flash_platform_data ixdp425_flash_data = { .map_name = "cfi_probe", @@ -44,6 +49,77 @@ static struct platform_device ixdp425_flash = { .resource = &ixdp425_flash_resource, }; +#if defined(CONFIG_MTD_NAND_PLATFORM) || \ + defined(CONFIG_MTD_NAND_PLATFORM_MODULE) + +#ifdef CONFIG_MTD_PARTITIONS +const char *part_probes[] = { "cmdlinepart", NULL }; + +static struct mtd_partition ixdp425_partitions[] = { + { + .name = "ixp400 NAND FS 0", + .offset = 0, + .size = SZ_8M + }, { + .name = "ixp400 NAND FS 1", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL + }, +}; +#endif + +static void +ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + int offset = (int)this->priv; + + if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_NCE) { + gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_LOW); + udelay(5); + } else + gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_HIGH); + + offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0; + offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0; + this->priv = (void *)offset; + } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W + offset); +} + +static struct platform_nand_data ixdp425_flash_nand_data = { + .chip = { + .chip_delay = 30, + .options = NAND_NO_AUTOINCR, +#ifdef CONFIG_MTD_PARTITIONS + .part_probe_types = part_probes, + .partitions = ixdp425_partitions, + .nr_partitions = ARRAY_SIZE(ixdp425_partitions), +#endif + }, + .ctrl = { + .cmd_ctrl = ixdp425_flash_nand_cmd_ctrl + } +}; + +static struct resource ixdp425_flash_nand_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixdp425_flash_nand = { + .name = "gen_nand", + .id = -1, + .dev = { + .platform_data = &ixdp425_flash_nand_data, + }, + .num_resources = 1, + .resource = &ixdp425_flash_nand_resource, +}; +#endif /* CONFIG_MTD_NAND_PLATFORM */ + static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = { .sda_pin = IXDP425_SDA_PIN, .scl_pin = IXDP425_SCL_PIN, @@ -104,6 +180,10 @@ static struct platform_device ixdp425_uart = { static struct platform_device *ixdp425_devices[] __initdata = { &ixdp425_i2c_controller, &ixdp425_flash, +#if defined(CONFIG_MTD_NAND_PLATFORM) || \ + defined(CONFIG_MTD_NAND_PLATFORM_MODULE) + &ixdp425_flash_nand, +#endif &ixdp425_uart }; @@ -115,6 +195,22 @@ static void __init ixdp425_init(void) ixdp425_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; +#if defined(CONFIG_MTD_NAND_PLATFORM) || \ + defined(CONFIG_MTD_NAND_PLATFORM_MODULE) + ixdp425_flash_nand_resource.start = IXP4XX_EXP_BUS_BASE(3), + ixdp425_flash_nand_resource.end = IXP4XX_EXP_BUS_BASE(3) + 0x10 - 1; + + gpio_line_config(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_OUT); + + /* Configure expansion bus for NAND Flash */ + *IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN | + IXP4XX_EXP_BUS_STROBE_T(1) | /* extend by 1 clock */ + IXP4XX_EXP_BUS_CYCLES(0) | /* Intel cycles */ + IXP4XX_EXP_BUS_SIZE(0) | /* 512bytes addr space*/ + IXP4XX_EXP_BUS_WR_EN | + IXP4XX_EXP_BUS_BYTE_EN; /* 8 bit data bus */ +#endif + if (cpu_is_ixp43x()) { ixdp425_uart.num_resources = 1; ixdp425_uart_data[1].flags = 0; |