Commit 541d5d02 authored by Ladislav Michl's avatar Ladislav Michl Committed by Tony Lindgren

[PATCH] ARM: OMAP: NAND flash driver model

NAND flash driver model
parent 5ff4cea4
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <asm/hardware.h> #include <asm/hardware.h>
...@@ -40,7 +41,7 @@ ...@@ -40,7 +41,7 @@
extern int omap_gpio_init(void); extern int omap_gpio_init(void);
static struct mtd_partition h2_partitions[] = { static struct mtd_partition h2_nor_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */ /* bootloader (U-Boot, etc) in first sector */
{ {
.name = "bootloader", .name = "bootloader",
...@@ -71,26 +72,83 @@ static struct mtd_partition h2_partitions[] = { ...@@ -71,26 +72,83 @@ static struct mtd_partition h2_partitions[] = {
} }
}; };
static struct flash_platform_data h2_flash_data = { static struct flash_platform_data h2_nor_data = {
.map_name = "cfi_probe", .map_name = "cfi_probe",
.width = 2, .width = 2,
.parts = h2_partitions, .parts = h2_nor_partitions,
.nr_parts = ARRAY_SIZE(h2_partitions), .nr_parts = ARRAY_SIZE(h2_nor_partitions),
}; };
static struct resource h2_flash_resource = { static struct resource h2_nor_resource = {
/* This is on CS3, wherever it's mapped */ /* This is on CS3, wherever it's mapped */
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
static struct platform_device h2_flash_device = { static struct platform_device h2_nor_device = {
.name = "omapflash", .name = "omapflash",
.id = 0, .id = 0,
.dev = { .dev = {
.platform_data = &h2_flash_data, .platform_data = &h2_nor_data,
}, },
.num_resources = 1, .num_resources = 1,
.resource = &h2_flash_resource, .resource = &h2_nor_resource,
};
static struct mtd_partition h2_nand_partitions[] = {
#if 0
/* REVISIT: enable these partitions if you make NAND BOOT
* work on your H2 (rev C or newer); published versions of
* x-load only support P2 and H3.
*/
{
.name = "xloader",
.offset = 0,
.size = 64 * 1024,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "bootloader",
.offset = MTDPART_OFS_APPEND,
.size = 256 * 1024,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = 192 * 1024,
},
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 2 * SZ_1M,
},
#endif
{
.name = "filesystem",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
},
};
/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */
static struct nand_platform_data h2_nand_data = {
.options = NAND_SAMSUNG_LP_OPTIONS,
.parts = h2_nand_partitions,
.nr_parts = ARRAY_SIZE(h2_nand_partitions),
};
static struct resource h2_nand_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device h2_nand_device = {
.name = "omapnand",
.id = 0,
.dev = {
.platform_data = &h2_nand_data,
},
.num_resources = 1,
.resource = &h2_nand_resource,
}; };
static struct resource h2_smc91x_resources[] = { static struct resource h2_smc91x_resources[] = {
...@@ -114,7 +172,8 @@ static struct platform_device h2_smc91x_device = { ...@@ -114,7 +172,8 @@ static struct platform_device h2_smc91x_device = {
}; };
static struct platform_device *h2_devices[] __initdata = { static struct platform_device *h2_devices[] __initdata = {
&h2_flash_device, &h2_nor_device,
&h2_nand_device,
&h2_smc91x_device, &h2_smc91x_device,
}; };
...@@ -174,13 +233,34 @@ static struct omap_board_config_kernel h2_config[] = { ...@@ -174,13 +233,34 @@ static struct omap_board_config_kernel h2_config[] = {
{ OMAP_TAG_LCD, &h2_lcd_config }, { OMAP_TAG_LCD, &h2_lcd_config },
}; };
#define H2_NAND_RB_GPIO_PIN 62
static int h2_nand_dev_ready(struct nand_platform_data *data)
{
return omap_get_gpio_datain(H2_NAND_RB_GPIO_PIN);
}
static void __init h2_init(void) static void __init h2_init(void)
{ {
/* NOTE: revC boards support NAND-boot, which can put NOR on CS2B /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
* and NAND (either 16bit or 8bit) on CS3. * to address 0 by a dip switch), NAND on CS2B. The NAND driver will
* notice whether a NAND chip is enabled at probe time.
*
* FIXME revC boards (and H3) support NAND-boot, with a dip switch to
* put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3. Try
* detecting that in code here, to avoid probing every possible flash
* configuration...
*/ */
h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys(); h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys();
h2_flash_resource.end += SZ_32M - 1; h2_nor_resource.end += SZ_32M - 1;
h2_nand_resource.end = h2_nand_resource.start = OMAP_CS2B_PHYS;
h2_nand_resource.end += SZ_4K - 1;
if (!(omap_request_gpio(H2_NAND_RB_GPIO_PIN)))
h2_nand_data.dev_ready = h2_nand_dev_ready;
omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
/* MMC: card detect and WP */ /* MMC: card detect and WP */
// omap_cfg_reg(U19_ARMIO1); /* CD */ // omap_cfg_reg(U19_ARMIO1); /* CD */
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -41,7 +42,7 @@ ...@@ -41,7 +42,7 @@
extern int omap_gpio_init(void); extern int omap_gpio_init(void);
static struct mtd_partition h3_partitions[] = { static struct mtd_partition nor_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */ /* bootloader (U-Boot, etc) in first sector */
{ {
.name = "bootloader", .name = "bootloader",
...@@ -72,26 +73,80 @@ static struct mtd_partition h3_partitions[] = { ...@@ -72,26 +73,80 @@ static struct mtd_partition h3_partitions[] = {
} }
}; };
static struct flash_platform_data h3_flash_data = { static struct flash_platform_data nor_data = {
.map_name = "cfi_probe", .map_name = "cfi_probe",
.width = 2, .width = 2,
.parts = h3_partitions, .parts = nor_partitions,
.nr_parts = ARRAY_SIZE(h3_partitions), .nr_parts = ARRAY_SIZE(nor_partitions),
}; };
static struct resource h3_flash_resource = { static struct resource nor_resource = {
/* This is on CS3, wherever it's mapped */ /* This is on CS3, wherever it's mapped */
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
static struct platform_device flash_device = { static struct platform_device nor_device = {
.name = "omapflash", .name = "omapflash",
.id = 0, .id = 0,
.dev = { .dev = {
.platform_data = &h3_flash_data, .platform_data = &nor_data,
}, },
.num_resources = 1, .num_resources = 1,
.resource = &h3_flash_resource, .resource = &nor_resource,
};
static struct mtd_partition nand_partitions[] = {
#if 0
/* REVISIT: enable these partitions if you make NAND BOOT work */
{
.name = "xloader",
.offset = 0,
.size = 64 * 1024,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "bootloader",
.offset = MTDPART_OFS_APPEND,
.size = 256 * 1024,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = 192 * 1024,
},
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 2 * SZ_1M,
},
#endif
{
.name = "filesystem",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
},
};
/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */
static struct nand_platform_data nand_data = {
.options = NAND_SAMSUNG_LP_OPTIONS,
.parts = nand_partitions,
.nr_parts = ARRAY_SIZE(nand_partitions),
};
static struct resource nand_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device nand_device = {
.name = "omapnand",
.id = 0,
.dev = {
.platform_data = &nand_data,
},
.num_resources = 1,
.resource = &nand_resource,
}; };
static struct resource smc91x_resources[] = { static struct resource smc91x_resources[] = {
...@@ -139,7 +194,8 @@ static struct platform_device intlat_device = { ...@@ -139,7 +194,8 @@ static struct platform_device intlat_device = {
}; };
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&flash_device, &nor_device,
&nand_device,
&smc91x_device, &smc91x_device,
&intlat_device, &intlat_device,
}; };
...@@ -182,11 +238,36 @@ static struct omap_board_config_kernel h3_config[] = { ...@@ -182,11 +238,36 @@ static struct omap_board_config_kernel h3_config[] = {
{ OMAP_TAG_LCD, &h3_lcd_config }, { OMAP_TAG_LCD, &h3_lcd_config },
}; };
#define H3_NAND_RB_GPIO_PIN 10
static int nand_dev_ready(struct nand_platform_data *data)
{
return omap_get_gpio_datain(H3_NAND_RB_GPIO_PIN);
}
static void __init h3_init(void) static void __init h3_init(void)
{ {
h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys(); /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
h3_flash_resource.end += OMAP_CS3_SIZE - 1; * to address 0 by a dip switch), NAND on CS2B. The NAND driver will
(void) platform_add_devices(devices, ARRAY_SIZE(devices)); * notice whether a NAND chip is enabled at probe time.
*
* H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND
* (which on H2 may be 16bit) on CS3. Try detecting that in code here,
* to avoid probing every possible flash configuration...
*/
nor_resource.end = nor_resource.start = omap_cs3_phys();
nor_resource.end += SZ_32M - 1;
nand_resource.end = nand_resource.start = OMAP_CS2B_PHYS;
nand_resource.end += SZ_4K - 1;
if (!(omap_request_gpio(H3_NAND_RB_GPIO_PIN)))
nand_data.dev_ready = nand_dev_ready;
/* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
/* GPIO10 pullup/down register, Enable pullup on GPIO10 */
omap_cfg_reg(V2_1710_GPIO10);
platform_add_devices(devices, ARRAY_SIZE(devices));
omap_board_config = h3_config; omap_board_config = h3_config;
omap_board_config_size = ARRAY_SIZE(h3_config); omap_board_config_size = ARRAY_SIZE(h3_config);
omap_serial_init(); omap_serial_init();
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <asm/hardware.h> #include <asm/hardware.h>
...@@ -44,7 +45,7 @@ static struct resource smc91x_resources[] = { ...@@ -44,7 +45,7 @@ static struct resource smc91x_resources[] = {
}, },
}; };
static struct mtd_partition p2_partitions[] = { static struct mtd_partition nor_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */ /* bootloader (U-Boot, etc) in first sector */
{ {
.name = "bootloader", .name = "bootloader",
...@@ -75,27 +76,47 @@ static struct mtd_partition p2_partitions[] = { ...@@ -75,27 +76,47 @@ static struct mtd_partition p2_partitions[] = {
}, },
}; };
static struct flash_platform_data p2_flash_data = { static struct flash_platform_data nor_data = {
.map_name = "cfi_probe", .map_name = "cfi_probe",
.width = 2, .width = 2,
.parts = p2_partitions, .parts = nor_partitions,
.nr_parts = ARRAY_SIZE(p2_partitions), .nr_parts = ARRAY_SIZE(nor_partitions),
}; };
static struct resource p2_flash_resource = { static struct resource nor_resource = {
.start = OMAP_CS0_PHYS, .start = OMAP_CS0_PHYS,
.end = OMAP_CS0_PHYS + SZ_32M - 1, .end = OMAP_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
static struct platform_device p2_flash_device = { static struct platform_device nor_device = {
.name = "omapflash", .name = "omapflash",
.id = 0, .id = 0,
.dev = { .dev = {
.platform_data = &p2_flash_data, .platform_data = &nor_data,
}, },
.num_resources = 1, .num_resources = 1,
.resource = &p2_flash_resource, .resource = &nor_resource,
};
static struct nand_platform_data nand_data = {
.options = NAND_SAMSUNG_LP_OPTIONS,
};
static struct resource nand_resource = {
.start = OMAP_CS3_PHYS,
.end = OMAP_CS3_PHYS + SZ_4K - 1,
.flags = IORESOURCE_MEM,
};
static struct platform_device nand_device = {
.name = "omapnand",
.id = 0,
.dev = {
.platform_data = &nand_data,
},
.num_resources = 1,
.resource = &nand_resource,
}; };
static struct platform_device smc91x_device = { static struct platform_device smc91x_device = {
...@@ -106,10 +127,18 @@ static struct platform_device smc91x_device = { ...@@ -106,10 +127,18 @@ static struct platform_device smc91x_device = {
}; };
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&p2_flash_device, &nor_device,
&nand_device,
&smc91x_device, &smc91x_device,
}; };
#define P2_NAND_RB_GPIO_PIN 62
static int nand_dev_ready(struct nand_platform_data *data)
{
return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN);
}
static struct omap_uart_config perseus2_uart_config __initdata = { static struct omap_uart_config perseus2_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1)), .enabled_uarts = ((1 << 0) | (1 << 1)),
}; };
...@@ -126,7 +155,13 @@ static struct omap_board_config_kernel perseus2_config[] = { ...@@ -126,7 +155,13 @@ static struct omap_board_config_kernel perseus2_config[] = {
static void __init omap_perseus2_init(void) static void __init omap_perseus2_init(void)
{ {
(void) platform_add_devices(devices, ARRAY_SIZE(devices)); if (!(omap_request_gpio(P2_NAND_RB_GPIO_PIN)))
nand_data.dev_ready = nand_dev_ready;
omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
platform_add_devices(devices, ARRAY_SIZE(devices));
omap_board_config = perseus2_config; omap_board_config = perseus2_config;
omap_board_config_size = ARRAY_SIZE(perseus2_config); omap_board_config_size = ARRAY_SIZE(perseus2_config);
......
This diff is collapsed.
...@@ -34,9 +34,5 @@ ...@@ -34,9 +34,5 @@
/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
#define OMAP1610_ETHR_START 0x04000300 #define OMAP1610_ETHR_START 0x04000300
/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
#define OMAP_NAND_FLASH_START1 0x0A000000 /* CS2B */
#define OMAP_NAND_FLASH_START2 0x0C000000 /* CS3 */
#endif /* __ASM_ARCH_OMAP_H2_H */ #endif /* __ASM_ARCH_OMAP_H2_H */
...@@ -30,10 +30,6 @@ ...@@ -30,10 +30,6 @@
/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */ /* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
#define OMAP1710_ETHR_START 0x04000300 #define OMAP1710_ETHR_START 0x04000300
/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
#define OMAP_NAND_FLASH_START1 0x0A000000 /* CS2B */
#define OMAP_NAND_FLASH_START2 0x0C000000 /* CS3 */
#define MAXIRQNUM (IH_BOARD_BASE) #define MAXIRQNUM (IH_BOARD_BASE)
#define MAXFIQNUM MAXIRQNUM #define MAXFIQNUM MAXIRQNUM
#define MAXSWINUM MAXIRQNUM #define MAXSWINUM MAXIRQNUM
......
...@@ -42,8 +42,4 @@ ...@@ -42,8 +42,4 @@
#define NR_IRQS (MAXIRQNUM + 1) #define NR_IRQS (MAXIRQNUM + 1)
/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
#define OMAP_NAND_FLASH_START1 0x0A000000 /* CS2B */
#define OMAP_NAND_FLASH_START2 0x0C000000 /* CS3 */
#endif #endif
...@@ -36,4 +36,18 @@ struct flash_platform_data { ...@@ -36,4 +36,18 @@ struct flash_platform_data {
unsigned int nr_parts; unsigned int nr_parts;
}; };
/**
* struct nand_platform_data - platform data describing NAND flash banks
* @dev_ready: tests if the NAND flash is ready (READY signal is high)
* @options: bitmask for nand_chip.options
* @parts: optional array of mtd_partitions for static partitioning
* @nr_parts: number of mtd_partitions for static partitoning
*/
struct nand_platform_data {
int (*dev_ready)(struct nand_platform_data *data);
unsigned int options;
struct mtd_partition *parts;
unsigned int nr_parts;
};
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment