diff options
64 files changed, 2795 insertions, 251 deletions
diff --git a/Documentation/powerpc/dts-bindings/mtd-physmap.txt b/Documentation/powerpc/dts-bindings/mtd-physmap.txt index 667c9bde869..80152cb567d 100644 --- a/Documentation/powerpc/dts-bindings/mtd-physmap.txt +++ b/Documentation/powerpc/dts-bindings/mtd-physmap.txt @@ -1,18 +1,19 @@ -CFI or JEDEC memory-mapped NOR flash +CFI or JEDEC memory-mapped NOR flash, MTD-RAM (NVRAM...) Flash chips (Memory Technology Devices) are often used for solid state file systems on embedded devices. - - compatible : should contain the specific model of flash chip(s) - used, if known, followed by either "cfi-flash" or "jedec-flash" - - reg : Address range(s) of the flash chip(s) + - compatible : should contain the specific model of mtd chip(s) + used, if known, followed by either "cfi-flash", "jedec-flash" + or "mtd-ram". + - reg : Address range(s) of the mtd chip(s) It's possible to (optionally) define multiple "reg" tuples so that - non-identical NOR chips can be described in one flash node. - - bank-width : Width (in bytes) of the flash bank. Equal to the + non-identical chips can be described in one node. + - bank-width : Width (in bytes) of the bank. Equal to the device width times the number of interleaved chips. - - device-width : (optional) Width of a single flash chip. If + - device-width : (optional) Width of a single mtd chip. If omitted, assumed to be equal to 'bank-width'. - - #address-cells, #size-cells : Must be present if the flash has + - #address-cells, #size-cells : Must be present if the device has sub-nodes representing partitions (see below). In this case both #address-cells and #size-cells must be equal to 1. @@ -22,24 +23,24 @@ are defined: - vendor-id : Contains the flash chip's vendor id (1 byte). - device-id : Contains the flash chip's device id (1 byte). -In addition to the information on the flash bank itself, the +In addition to the information on the mtd bank itself, the device tree may optionally contain additional information -describing partitions of the flash address space. This can be +describing partitions of the address space. This can be used on platforms which have strong conventions about which -portions of the flash are used for what purposes, but which don't +portions of a flash are used for what purposes, but which don't use an on-flash partition table such as RedBoot. -Each partition is represented as a sub-node of the flash device. +Each partition is represented as a sub-node of the mtd device. Each node's name represents the name of the corresponding -partition of the flash device. +partition of the mtd device. Flash partitions - - reg : The partition's offset and size within the flash bank. - - label : (optional) The label / name for this flash partition. + - reg : The partition's offset and size within the mtd bank. + - label : (optional) The label / name for this partition. If omitted, the label is taken from the node name (excluding the unit address). - read-only : (optional) This parameter, if present, is a hint to - Linux that this flash partition should only be mounted + Linux that this partition should only be mounted read-only. This is usually used for flash partitions containing early-boot firmware images or data which should not be clobbered. @@ -78,3 +79,12 @@ Here an example with multiple "reg" tuples: reg = <0 0x04000000>; }; }; + +An example using SRAM: + + sram@2,0 { + compatible = "samsung,k6f1616u6a", "mtd-ram"; + reg = <2 0 0x00200000>; + bank-width = <2>; + }; + diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig index 9bb45b932f0..600cb270f2b 100644 --- a/arch/arm/configs/nhk8815_defconfig +++ b/arch/arm/configs/nhk8815_defconfig @@ -498,7 +498,7 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_DOC2001PLUS is not set CONFIG_MTD_NAND=y CONFIG_MTD_NAND_VERIFY_WRITE=y -# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_ECC_SMC=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set # CONFIG_MTD_NAND_GPIO is not set CONFIG_MTD_NAND_IDS=y diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 79bdea943eb..6bfd537d5af 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -16,12 +16,164 @@ #include <linux/amba/bus.h> #include <linux/interrupt.h> #include <linux/gpio.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/io.h> +#include <asm/sizes.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> +#include <asm/mach/flash.h> #include <mach/setup.h> +#include <mach/nand.h> +#include <mach/fsmc.h> #include "clock.h" +/* These adresses span 16MB, so use three individual pages */ +static struct resource nhk8815_nand_resources[] = { + { + .name = "nand_addr", + .start = NAND_IO_ADDR, + .end = NAND_IO_ADDR + 0xfff, + .flags = IORESOURCE_MEM, + }, { + .name = "nand_cmd", + .start = NAND_IO_CMD, + .end = NAND_IO_CMD + 0xfff, + .flags = IORESOURCE_MEM, + }, { + .name = "nand_data", + .start = NAND_IO_DATA, + .end = NAND_IO_DATA + 0xfff, + .flags = IORESOURCE_MEM, + } +}; + +static int nhk8815_nand_init(void) +{ + /* FSMC setup for nand chip select (8-bit nand in 8815NHK) */ + writel(0x0000000E, FSMC_PCR(0)); + writel(0x000D0A00, FSMC_PMEM(0)); + writel(0x00100A00, FSMC_PATT(0)); + + /* enable access to the chip select area */ + writel(readl(FSMC_PCR(0)) | 0x04, FSMC_PCR(0)); + + return 0; +} + +/* + * These partitions are the same as those used in the 2.6.20 release + * shipped by the vendor; the first two partitions are mandated + * by the boot ROM, and the bootloader area is somehow oversized... + */ +static struct mtd_partition nhk8815_partitions[] = { + { + .name = "X-Loader(NAND)", + .offset = 0, + .size = SZ_256K, + }, { + .name = "MemInit(NAND)", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K, + }, { + .name = "BootLoader(NAND)", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + }, { + .name = "Kernel zImage(NAND)", + .offset = MTDPART_OFS_APPEND, + .size = 3 * SZ_1M, + }, { + .name = "Root Filesystem(NAND)", + .offset = MTDPART_OFS_APPEND, + .size = 22 * SZ_1M, + }, { + .name = "User Filesystem(NAND)", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct nomadik_nand_platform_data nhk8815_nand_data = { + .parts = nhk8815_partitions, + .nparts = ARRAY_SIZE(nhk8815_partitions), + .options = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING \ + | NAND_NO_READRDY | NAND_NO_AUTOINCR, + .init = nhk8815_nand_init, +}; + +static struct platform_device nhk8815_nand_device = { + .name = "nomadik_nand", + .dev = { + .platform_data = &nhk8815_nand_data, + }, + .resource = nhk8815_nand_resources, + .num_resources = ARRAY_SIZE(nhk8815_nand_resources), +}; + +/* These are the partitions for the OneNand device, different from above */ +static struct mtd_partition nhk8815_onenand_partitions[] = { + { + .name = "X-Loader(OneNAND)", + .offset = 0, + .size = SZ_256K, + }, { + .name = "MemInit(OneNAND)", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K, + }, { + .name = "BootLoader(OneNAND)", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M-SZ_256K, + }, { + .name = "SysImage(OneNAND)", + .offset = MTDPART_OFS_APPEND, + .size = 4 * SZ_1M, + }, { + .name = "Root Filesystem(OneNAND)", + .offset = MTDPART_OFS_APPEND, + .size = 22 * SZ_1M, + }, { + .name = "User Filesystem(OneNAND)", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct flash_platform_data nhk8815_onenand_data = { + .parts = nhk8815_onenand_partitions, + .nr_parts = ARRAY_SIZE(nhk8815_onenand_partitions), +}; + +static struct resource nhk8815_onenand_resource[] = { + { + .start = 0x30000000, + .end = 0x30000000 + SZ_128K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device nhk8815_onenand_device = { + .name = "onenand", + .id = -1, + .dev = { + .platform_data = &nhk8815_onenand_data, + }, + .resource = nhk8815_onenand_resource, + .num_resources = ARRAY_SIZE(nhk8815_onenand_resource), +}; + +static void __init nhk8815_onenand_init(void) +{ +#ifdef CONFIG_ONENAND + /* Set up SMCS0 for OneNand */ + writel(0x000030db, FSMC_BCR0); + writel(0x02100551, FSMC_BTR0); +#endif +} + #define __MEM_4K_RESOURCE(x) \ .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} @@ -81,6 +233,8 @@ static int __init nhk8815_eth_init(void) device_initcall(nhk8815_eth_init); static struct platform_device *nhk8815_platform_devices[] __initdata = { + &nhk8815_nand_device, + &nhk8815_onenand_device, &nhk8815_eth_device, /* will add more devices */ }; @@ -90,6 +244,7 @@ static void __init nhk8815_platform_init(void) int i; cpu8815_platform_init(); + nhk8815_onenand_init(); platform_add_devices(nhk8815_platform_devices, ARRAY_SIZE(nhk8815_platform_devices)); diff --git a/arch/arm/mach-nomadik/include/mach/fsmc.h b/arch/arm/mach-nomadik/include/mach/fsmc.h new file mode 100644 index 00000000000..8c2c0518368 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/fsmc.h @@ -0,0 +1,29 @@ + +/* Definitions for the Nomadik FSMC "Flexible Static Memory controller" */ + +#ifndef __ASM_ARCH_FSMC_H +#define __ASM_ARCH_FSMC_H + +#include <mach/hardware.h> +/* + * Register list + */ + +/* bus control reg. and bus timing reg. for CS0..CS3 */ +#define FSMC_BCR(x) (NOMADIK_FSMC_VA + (x << 3)) +#define FSMC_BTR(x) (NOMADIK_FSMC_VA + (x << 3) + 0x04) + +/* PC-card and NAND: + * PCR = control register + * PMEM = memory timing + * PATT = attribute timing + * PIO = I/O timing + * PECCR = ECC result + */ +#define FSMC_PCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x00) +#define FSMC_PMEM(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x08) +#define FSMC_PATT(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x0c) +#define FSMC_PIO(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x10) +#define FSMC_PECCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x14) + +#endif /* __ASM_ARCH_FSMC_H */ diff --git a/arch/arm/mach-nomadik/include/mach/nand.h b/arch/arm/mach-nomadik/include/mach/nand.h new file mode 100644 index 00000000000..c3c8254c22a --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/nand.h @@ -0,0 +1,16 @@ +#ifndef __ASM_ARCH_NAND_H +#define __ASM_ARCH_NAND_H + +struct nomadik_nand_platform_data { + struct mtd_partition *parts; + int nparts; + int options; + int (*init) (void); + int (*exit) (void); +}; + +#define NAND_IO_DATA 0x40000000 +#define NAND_IO_CMD 0x40800000 +#define NAND_IO_ADDR 0x41000000 + +#endif /* __ASM_ARCH_NAND_H */ diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 7a2b54c7291..a1132288c70 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -87,7 +87,7 @@ static struct mtd_partition apollon_partitions[] = { }, }; -static struct flash_platform_data apollon_flash_data = { +static struct onenand_platform_data apollon_flash_data = { .parts = apollon_partitions, .nr_parts = ARRAY_SIZE(apollon_partitions), }; @@ -99,7 +99,7 @@ static struct resource apollon_flash_resource[] = { }; static struct platform_device apollon_onenand_device = { - .name = "onenand", + .name = "onenand-flash", .id = -1, .dev = { .platform_data = &apollon_flash_data, diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index f91934b2b09..15876828db2 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -57,6 +57,11 @@ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ #define GPMC_SECTION_SHIFT 28 /* 128 MB */ +#define PREFETCH_FIFOTHRESHOLD (0x40 << 8) +#define CS_NUM_SHIFT 24 +#define ENABLE_PREFETCH (0x1 << 7) +#define DMA_MPU_MODE 2 + static struct resource gpmc_mem_root; static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); @@ -386,6 +391,63 @@ void gpmc_cs_free(int cs) } EXPORT_SYMBOL(gpmc_cs_free); +/** + * gpmc_prefetch_enable - configures and starts prefetch transfer + * @cs: nand cs (chip select) number + * @dma_mode: dma mode enable (1) or disable (0) + * @u32_count: number of bytes to be transferred + * @is_write: prefetch read(0) or write post(1) mode + */ +int gpmc_prefetch_enable(int cs, int dma_mode, + unsigned int u32_count, int is_write) +{ + uint32_t prefetch_config1; + + if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + /* Set the amount of bytes to be prefetched */ + gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); + + /* Set dma/mpu mode, the prefetch read / post write and + * enable the engine. Set which cs is has requested for. + */ + prefetch_config1 = ((cs << CS_NUM_SHIFT) | + PREFETCH_FIFOTHRESHOLD | + ENABLE_PREFETCH | + (dma_mode << DMA_MPU_MODE) | + (0x1 & is_write)); + gpmc_write_reg(GPMC_PREFETCH_CONFIG1, prefetch_config1); + } else { + return -EBUSY; + } + /* Start the prefetch engine */ + gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x1); + + return 0; +} +EXPORT_SYMBOL(gpmc_prefetch_enable); + +/** + * gpmc_prefetch_reset - disables and stops the prefetch engine + */ +void gpmc_prefetch_reset(void) +{ + /* Stop the PFPW engine */ + gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x0); + + /* Reset/disable the PFPW engine */ + gpmc_write_reg(GPMC_PREFETCH_CONFIG1, 0x0); +} +EXPORT_SYMBOL(gpmc_prefetch_reset); + +/** + * gpmc_prefetch_status - reads prefetch status of engine + */ +int gpmc_prefetch_status(void) +{ + return gpmc_read_reg(GPMC_PREFETCH_STATUS); +} +EXPORT_SYMBOL(gpmc_prefetch_status); + static void __init gpmc_mem_init(void) { int cs; @@ -452,6 +514,5 @@ void __init gpmc_init(void) l &= 0x03 << 3; l |= (0x02 << 3) | (1 << 0); gpmc_write_reg(GPMC_SYSCONFIG, l); - gpmc_mem_init(); } diff --git a/arch/arm/plat-omap/include/mach/gpmc.h b/arch/arm/plat-omap/include/mach/gpmc.h index 921b16532ff..9c99cda77ba 100644 --- a/arch/arm/plat-omap/include/mach/gpmc.h +++ b/arch/arm/plat-omap/include/mach/gpmc.h @@ -103,6 +103,10 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); extern void gpmc_cs_free(int cs); extern int gpmc_cs_set_reserved(int cs, int reserved); extern int gpmc_cs_reserved(int cs); +extern int gpmc_prefetch_enable(int cs, int dma_mode, + unsigned int u32_count, int is_write); +extern void gpmc_prefetch_reset(void); +extern int gpmc_prefetch_status(void); extern void __init gpmc_init(void); #endif diff --git a/drivers/Makefile b/drivers/Makefile index ccfa259fa84..6ee53c7a57a 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -43,6 +43,8 @@ obj-y += macintosh/ obj-$(CONFIG_IDE) += ide/ obj-$(CONFIG_SCSI) += scsi/ obj-$(CONFIG_ATA) += ata/ +obj-$(CONFIG_MTD) += mtd/ +obj-$(CONFIG_SPI) += spi/ obj-y += net/ obj-$(CONFIG_ATM) += atm/ obj-$(CONFIG_FUSION) += message/ @@ -51,8 +53,6 @@ obj-y += ieee1394/ obj-$(CONFIG_UIO) += uio/ obj-y += cdrom/ obj-y += auxdisplay/ -obj-$(CONFIG_MTD) += mtd/ -obj-$(CONFIG_SPI) += spi/ obj-$(CONFIG_PCCARD) += pcmcia/ obj-$(CONFIG_DIO) += dio/ obj-$(CONFIG_SBUS) += sbus/ diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index b8e35a0b4d7..e4ec3659759 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -25,6 +25,14 @@ config MTD_DEBUG_VERBOSE help Determines the verbosity level of the MTD debugging messages. +config MTD_TESTS + tristate "MTD tests support" + depends on m + help + This option includes various MTD tests into compilation. The tests + should normally be compiled as kernel modules. The modules perform + various checks and verifications when loaded. + config MTD_CONCAT tristate "MTD concatenating support" help @@ -45,14 +53,6 @@ config MTD_PARTITIONS devices. Partitioning on NFTL 'devices' is a different - that's the 'normal' form of partitioning used on a block device. -config MTD_TESTS - tristate "MTD tests support" - depends on m - help - This option includes various MTD tests into compilation. The tests - should normally be compiled as kernel modules. The modules perform - various checks and verifications when loaded. - config MTD_REDBOOT_PARTS tristate "RedBoot partition table parsing" depends on MTD_PARTITIONS diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index d072ca5be68..cec7ab98b2a 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c @@ -239,7 +239,7 @@ static int parse_afs_partitions(struct mtd_info *mtd, parts[idx].offset = img_ptr; parts[idx].mask_flags = 0; - printk(" mtd%d: at 0x%08x, %5dKB, %8u, %s\n", + printk(" mtd%d: at 0x%08x, %5lluKiB, %8u, %s\n", idx, img_ptr, parts[idx].size / 1024, iis.imageNumber, str); diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 61ea833e090..94bb61e1904 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -282,16 +282,6 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param) } } -static void fixup_M29W128G_write_buffer(struct mtd_info *mtd, void *param) -{ - struct map_info *map = mtd->priv; - struct cfi_private *cfi = map->fldrv_priv; - if (cfi->cfiq->BufWriteTimeoutTyp) { - pr_warning("Don't use write buffer on ST flash M29W128G\n"); - cfi->cfiq->BufWriteTimeoutTyp = 0; - } -} - static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, #ifdef AMD_BOOTLOC_BUG @@ -308,7 +298,6 @@ static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, - { CFI_MFR_ST, 0x227E, fixup_M29W128G_write_buffer, NULL, }, #if !FORCE_WORD_WRITE { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, #endif diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 34d40e25d31..c5a84fda541 100644..100755 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c @@ -81,6 +81,10 @@ void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map, { cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); + /* M29W128G flashes require an additional reset command + when exit qry mode */ + if ((cfi->mfr == CFI_MFR_ST) && (cfi->id == 0x227E || cfi->id == 0x7E)) + cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); } EXPORT_SYMBOL_GPL(cfi_qry_mode_off); diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index ccc4cfc7e4b..736a3be265f 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe |