Re: [pandaboard] device tree does not work
On Fri, Dec 21, 2012 at 10:12 PM, Menon, Nishanth wrote: > Shifting thread to linux-omap mailing list. This time I used the latest u-boot and working.. sorry.. U-Boot 2013.01-rc2-00022-g42e1321 (Dec 21 2012 - 22:09:54) CPU : OMAP4430 ES2.2 Board: OMAP4 Panda I2C: ready DRAM: 1 GiB MMC: OMAP SD/MMC: 0 Using default environment In:serial Out: serial Err: serial Net: No ethernet found. Hit any key to stop autoboot: 0 Panda # setenv bootargs 'console=ttyO2,115200n8 root=/dev/mmcblk0p3 rw rootwait rootfstype=ext4 init=/sbin/init ignore_loglevel debug printk.time=1 bootmem_debug=1 earlyprintk' Panda # setenv bootcmd 'mmc rescan; fatload mmc 0 8200 uImage-21dec; fatload mmc 0 8500 omap4-panda-es.dtb; bootm 8200 - 8500' Panda # boot reading uImage-21dec 4243816 bytes read in 251 ms (16.1 MiB/s) reading omap4-panda-es.dtb 13602 bytes read in 9 ms (1.4 MiB/s) ## Booting kernel from Legacy Image at 8200 ... Image Name: Linux-3.7.0-11091-gf01af9f-dirty Image Type: ARM Linux Kernel Image (uncompressed) Data Size:4243752 Bytes = 4 MiB Load Address: 80008000 Entry Point: 80008000 Verifying Checksum ... OK ## Flattened Device Tree blob at 8500 Booting using the fdt blob at 0x8500 Loading Kernel Image ... OK OK reserving fdt memory region: addr=9d00 size=300 Using Device Tree in place at 8500, end 85006521 Starting kernel ... Uncompressing Linux... done, booting the kernel. [0.00] Booting Linux on physical CPU 0x0 [0.00] Linux version 3.7.0-11091-gf01af9f-dirty (sghorai@bgsxgitb03) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-202) ) #15 SMP Fri Dec 21 15:50:23 IST 2012 [0.00] CPU: ARMv7 Processor [411fc092] revision 2 (ARMv7), cr=10c53c7d [0.00] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [0.00] Machine: Generic OMAP4 (Flattened Device Tree), model: TI OMAP4 PandaBoard .. > Regards, > Nishanth Menon > > From: pandabo...@googlegroups.com [pandabo...@googlegroups.com] on behalf of > Sukumar Ghorai [ghorai.suku...@gmail.com] > Sent: Friday, December 21, 2012 10:33 > To: pandabo...@googlegroups.com > Subject: [pandaboard] device tree does not work > > Hi, > Device Tree in Panda board does not boot. > > Device Tree with legacy u-boot : Appending dtb blob to kernel > menuconfig → boot options > select [*] Use appended device tree blob to zImage (EXPERIMENTAL) > Used with legacy u-boot > > U-Boot 2011.09 (Nov 19 2011 - 04:44:45) > > CPU : OMAP4430 > Board: OMAP4 Panda > I2C: ready > DRAM: 1 GiB > WARNING: Caches not enabled > MMC: OMAP SD/MMC: 0 > Using default environment > > In:serial > Out: serial > Err: serial > Net: No ethernet found. > Hit any key to stop autoboot: 0 > Panda # setenv bootargs 'console=ttyO2,115200n8 root=/dev/mmcblk0p3 rw > rootwait rootfstype=ext4 init=/sbin/init ignore_loglevel debug > printk.time=1 earlyprintk' > Panda # setenv bootcmd 'mmc rescan; fatload mmc 0 8020 > uImage-21dec; fatload mmc 0 8070 omap4-panda-es.dtb; bootm > 8020 - 8070' > Panda # boot > reading uImage-21dec > > 4243816 bytes read > reading omap4-panda-es.dtb > > 13602 bytes read > ## Booting kernel from Legacy Image at 8020 ... >Image Name: Linux-3.7.0-11091-gf01af9f-dirty >Image Type: ARM Linux Kernel Image (uncompressed) >Data Size:4243752 Bytes = 4 MiB >Load Address: 80008000 >Entry Point: 80008000 >Verifying Checksum ... OK > ## Flattened Device Tree blob at 8070 >Booting using the fdt blob at 0x8070 >Loading Kernel Image ... OK > OK >reserving fdt memory region: addr=9d00 size=300 >Loading Device Tree to bfef1000, end bfef7521 ... OK > > Starting kernel ... > > Uncompressing Linux... done, booting the kernel. > [0.00] Booting Linux on physical CPU 0x0 > [0.00] Linux version 3.7.0-11091-gf01af9f-dirty > (sghorai@bgsxgitb03) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-202) > ) #15 SMP Fri Dec 21 15:50:23 IST 2012 > [0.00] CPU: ARMv7 Processor [411fc092] revision 2 (ARMv7), cr=10c53c7d > [0.00] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing > instruction cache > [0.00] Machine: Generic OMAP4 (Flattened Device Tree), model: > TI OMAP4 PandaBoard > [0.00] debug: ignoring loglevel setting. > [0.00] bootconsole [earlycon0] enabled > [0.00] Memory policy: ECC disabled, Data cache writealloc > [0.00] On node 0 totalpages: 261888 > [0.00] free_area_init_node: node 0, pgdat c080eec0, > node_mem_map c0d6d000 > [0.00] Normal zone: 1520
[PATCH v9 5/7] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 22 ++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 382dea8..6741743 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -60,7 +60,6 @@ #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 @@ -606,15 +605,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + pr_err("gpmc: fifo threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -622,7 +625,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 9c060da..a243463 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)((val) << 8) + /* * Note that all values in this struct are in nanoseconds except sync_clk * (which is in picoseconds), while the register values are in gpmc_fck cycles. @@ -134,7 +137,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index fbe8414..f1648fd 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -244,7 +244,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -289,7 +290,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -345,8 +347,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, int ret; unsigned long tim, limit; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 byte
[PATCH v9 4/7] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for nand transfer(read, write) Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |2 + arch/arm/plat-omap/include/plat/nand.h |4 +- drivers/mtd/nand/omap2.c | 198 ++-- 3 files changed, 194 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index f6b7253..1964509 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, board_nand_data.nr_parts= nr_parts; board_nand_data.devsize = nand_type; + board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } #else diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 78c0bdb..ae5e053 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -13,7 +13,8 @@ enum nand_io { NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ NAND_OMAP_POLLED, /* polled mode, without prefetch */ - NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_DMA, /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_IRQ /* prefetch enabled irq mode */ }; struct omap_nand_platform_data { @@ -26,6 +27,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; enum nand_ioxfer_type; unsigned long phys_base; int devsize; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 60bac8e..fbe8414 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #defineDRIVER_NAME "omap2-nand" +#defineOMAP_NAND_TIMEOUT_MS5000 #define NAND_Ecc_P1e (1 << 0) #define NAND_Ecc_P2e (1 << 1) @@ -108,6 +110,13 @@ struct omap_nand_info { unsigned long phys_base; struct completion comp; int dma_ch; + int gpmc_irq; + enum { + OMAP_NAND_IO_READ = 0, /* read */ + OMAP_NAND_IO_WRITE, /* write */ + } iomode; + u_char *buf; + int buf_len; }; /** @@ -267,9 +276,10 @@ static void omap_write_buf_pref(struct mtd_info *mtd, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - uint32_t pref_count = 0, w_count = 0; + uint32_t w_count = 0; int i = 0, ret = 0; u16 *p; + unsigned long tim, limit; /* take care of subpage writes */ if (len % 2 != 0) { @@ -295,9 +305,12 @@ static void omap_write_buf_pref(struct mtd_info *mtd, iowrite16(*p++, info->nand.IO_ADDR_W); } /* wait for data to flushed-out before reset the prefetch */ - do { - pref_count = gpmc_read_status(GPMC_PREFETCH_COUNT); - } while (pref_count); + tim = 0; + limit = (loops_per_jiffy * + msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); + while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) + cpu_relax(); + /* disable and stop the PFPW engine */ gpmc_prefetch_reset(info->gpmc_cs); } @@ -326,11 +339,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - uint32_t prefetch_status = 0; enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; dma_addr_t dma_addr; int ret; + unsigned long tim, limit; /* The fifo depth is 64 bytes. We have a sync at each frame and frame * length is 64 bytes. @@ -376,7 +389,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, /* configure and start prefetch transfer */ ret = gpmc_prefetch_enable(info->gpmc_cs, 0x1, len, is_wr
[PATCH v9 3/7] omap: gpmc: enable irq mode in gpmc
add support the irq mode in GPMC. gpmc_init() function move after omap_init_irq() as it has dependecy on irq. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 45 +-- arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h |5 +++- arch/arm/plat-omap/include/plat/irqs.h |9 +- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 1b7b3e7..382dea8 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -14,6 +14,7 @@ */ #undef DEBUG +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include @@ -100,6 +102,8 @@ static void __iomem *gpmc_base; static struct clk *gpmc_l3_clk; +static irqreturn_t gpmc_handle_irq(int irq, void *dev); + static void gpmc_write_reg(int idx, u32 val) { __raw_writel(val, gpmc_base + idx); @@ -497,6 +501,10 @@ int gpmc_cs_configure(int cs, int cmd, int wval) u32 regval = 0; switch (cmd) { + case GPMC_ENABLE_IRQ: + gpmc_write_reg(GPMC_IRQENABLE, wval); + break; + case GPMC_SET_IRQ_STATUS: gpmc_write_reg(GPMC_IRQSTATUS, wval); break; @@ -678,9 +686,10 @@ static void __init gpmc_mem_init(void) } } -void __init gpmc_init(void) +static int __init gpmc_init(void) { - u32 l; + u32 l, irq; + int cs, ret = -EINVAL; char *ck = NULL; if (cpu_is_omap24xx()) { @@ -698,7 +707,7 @@ void __init gpmc_init(void) } if (WARN_ON(!ck)) - return; + return ret; gpmc_l3_clk = clk_get(NULL, ck); if (IS_ERR(gpmc_l3_clk)) { @@ -723,6 +732,36 @@ void __init gpmc_init(void) l |= (0x02 << 3) | (1 << 0); gpmc_write_reg(GPMC_SYSCONFIG, l); gpmc_mem_init(); + + /* initalize the irq_chained */ + irq = OMAP_GPMC_IRQ_BASE; + for (cs = 0; cs < GPMC_CS_NUM; cs++) { + set_irq_handler(irq, handle_simple_irq); + set_irq_flags(irq, IRQF_VALID); + irq++; + } + + ret = request_irq(INT_34XX_GPMC_IRQ, + gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base); + if (ret) + pr_err("gpmc: irq-%d could not claim: err %d\n", + INT_34XX_GPMC_IRQ, ret); + return ret; +} +postcore_initcall(gpmc_init); + +static irqreturn_t gpmc_handle_irq(int irq, void *dev) +{ + u8 cs; + + if (irq != INT_34XX_GPMC_IRQ) + return IRQ_HANDLED; + /* check cs to invoke the irq */ + cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7; + if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END) + generic_handle_irq(OMAP_GPMC_IRQ_BASE+cs); + + return IRQ_HANDLED; } #ifdef CONFIG_ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index e66687b..b60287c 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -30,7 +30,6 @@ #include #include -#include #include #include "clock2xxx.h" @@ -408,7 +407,6 @@ void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0, omap2_sdrc_init(sdrc_cs0, sdrc_cs1); _omap2_init_reprogram_sdrc(); } - gpmc_init(); omap_irq_base_init(); } diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 85ded59..9c060da 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -41,6 +41,8 @@ #define GPMC_NAND_ADDRESS 0x000b #define GPMC_NAND_DATA 0x000c +#define GPMC_ENABLE_IRQ0x000d + /* ECC commands */ #define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ #define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */ @@ -78,6 +80,8 @@ #define WR_RD_PIN_MONITORING 0x0060 #define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) #define GPMC_PREFETCH_STATUS_COUNT(val)(val & 0x3fff) +#define GPMC_IRQ_FIFOEVENTENABLE 0x01 +#define GPMC_IRQ_COUNT_EVENT 0x02 /* * Note that all values in this struct are in nanoseconds except sync_clk @@ -135,7 +139,6 @@ extern int gpmc_prefetch_enable(int cs, int dma_mode, extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); extern void omap3_gpmc_restore_context(void); -extern void gpmc_init(void); extern int gpmc_read_status(int cmd); extern int gpmc_cs_configure(int cs, int cmd, int wval); extern int gpmc_nand_read(int cs, int cmd); diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index 2910de9..1b
[PATCH v9 6/7] omap3: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |1 + arch/arm/plat-omap/include/plat/gpmc.h |6 ++ arch/arm/plat-omap/include/plat/nand.h |2 ++ drivers/mtd/nand/omap2.c | 26 +++--- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 1964509..a768198 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -148,6 +148,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, board_nand_data.nr_parts= nr_parts; board_nand_data.devsize = nand_type; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index a243463..773351b 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -86,6 +86,12 @@ #define PREFETCH_FIFOTHRESHOLD_MAX 0x40 #define PREFETCH_FIFOTHRESHOLD(val)((val) << 8) +enum omap_ecc { + /* 1-bit ecc: stored at end of spare area */ + OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ + OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ +}; + /* * Note that all values in this struct are in nanoseconds except sync_clk * (which is in picoseconds), while the register values are in gpmc_fck cycles. diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index ae5e053..d86d1ec 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include #include enum nand_io { @@ -31,6 +32,7 @@ struct omap_nand_platform_data { enum nand_ioxfer_type; unsigned long phys_base; int devsize; + enum omap_ecc ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index f1648fd..6d4a42e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -626,8 +626,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -847,8 +845,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1038,17 +1034,17 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) + info->nand.ecc.mode = NAND_ECC_SOFT; + else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 7/7] omap3: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-loader, u-boot and kernel. This enables to flash x-loader, u-boot, kernel, FS images from kernel itself and compatiable with other tools. This patch does not enables this feature by default and need to pass from board file to enable for any board. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/plat-omap/include/plat/gpmc.h |2 + drivers/mtd/nand/omap2.c | 37 +++- 2 files changed, 38 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 773351b..12b3161 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -90,6 +90,8 @@ enum omap_ecc { /* 1-bit ecc: stored at end of spare area */ OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ + /* 1-bit ecc: stored at begining of spare area as romcode */ + OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ }; /* diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 6d4a42e..4e33972 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -98,6 +98,20 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -914,6 +928,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1037,7 +1052,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) /* selsect the ecc type */ if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) info->nand.ecc.mode = NAND_ECC_SOFT; - else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { + else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { info->nand.ecc.bytes= 3; info->nand.ecc.size = 512; info->nand.ecc.calculate= omap_calculate_ecc; @@ -1057,6 +1073,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) { + + if (info->nand.options & NAND_BUSWIDTH_16) + offset = 2; + else { + offset = 1; + info->nand.badblock_pattern = &bb_descrip_flashbased; + } + omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16); + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 1/7] omap3630: nand: fix device size to work in polled mode
zoom3 and 3630-sdp having the x16 nand device. This patch configure gpmc as x16 and select the currect function in driver for polled mode (without prefetch enable) transfer. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-3430sdp.c |2 +- arch/arm/mach-omap2/board-3630sdp.c |3 ++- arch/arm/mach-omap2/board-flash.c | 10 ++ arch/arm/mach-omap2/board-flash.h |4 ++-- arch/arm/mach-omap2/board-ldp.c |2 +- arch/arm/mach-omap2/board-zoom.c|5 +++-- arch/arm/mach-omap2/gpmc-nand.c |7 +-- drivers/mtd/nand/omap2.c|2 +- 8 files changed, 21 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index d4e41ef..8fb5f43 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -813,7 +813,7 @@ static void __init omap_3430sdp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_3430); + board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); sdp3430_display_init(); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 6264564..b4ca7fc 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -209,7 +210,7 @@ static void __init omap_sdp_init(void) zoom_peripherals_init(); zoom_display_init(); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_sdp); + board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); } diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index fd38c05..f6b7253 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -139,11 +139,13 @@ static struct omap_nand_platform_data board_nand_data = { }; void -__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) +__init board_nand_init(struct mtd_partition *nand_parts, + u8 nr_parts, u8 cs, int nand_type) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.devsize = nand_type; gpmc_nand_init(&board_nand_data); } @@ -194,7 +196,7 @@ unmap: * @return - void. */ void board_flash_init(struct flash_partitions partition_info[], - char chip_sel_board[][GPMC_CS_NUM]) + char chip_sel_board[][GPMC_CS_NUM], int nand_type) { u8 cs = 0; u8 norcs = GPMC_CS_NUM + 1; @@ -250,5 +252,5 @@ void board_flash_init(struct flash_partitions partition_info[], "in GPMC\n"); else board_nand_init(partition_info[2].parts, - partition_info[2].nr_parts, nandcs); + partition_info[2].nr_parts, nandcs, nand_type); } diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h index 69befe0..c240a3f 100644 --- a/arch/arm/mach-omap2/board-flash.h +++ b/arch/arm/mach-omap2/board-flash.h @@ -25,6 +25,6 @@ struct flash_partitions { }; extern void board_flash_init(struct flash_partitions [], - char chip_sel[][GPMC_CS_NUM]); + char chip_sel[][GPMC_CS_NUM], int nand_type); extern void board_nand_init(struct mtd_partition *nand_parts, - u8 nr_parts, u8 cs); + u8 nr_parts, u8 cs, int nand_type); diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index e5dc748..d986d32 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -434,7 +434,7 @@ static void __init omap_ldp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_nand_init(ldp_nand_partitions, - ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS); + ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0); omap2_hsmmc_init(mmc); /* link regulators to MMC adapters */ diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index e26754c..0242611 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -126,8 +127,8 @@ static void __init omap_zoom_init(void)
[PATCH v9 2/7] omap3: nand: configurable transfer type per board
nand transfer type (sDMA, Polled, prefetch) can be select from board file, enabling all transfer type in driver, by default. this helps in multi-omap build and to select different transfer type for different board. Signed-off-by: Sukumar Ghorai --- arch/arm/plat-omap/include/plat/nand.h |7 +++ drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 94 3 files changed, 41 insertions(+), 77 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..78c0bdb 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -10,6 +10,12 @@ #include +enum nand_io { + NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ + NAND_OMAP_POLLED, /* polled mode, without prefetch */ + NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ +}; + struct omap_nand_platform_data { unsigned intoptions; int cs; @@ -20,6 +26,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + enum nand_ioxfer_type; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index c895922..178e200 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -106,23 +106,6 @@ config MTD_NAND_OMAP2 help Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. -config MTD_NAND_OMAP_PREFETCH - bool "GPMC prefetch support for NAND Flash device" - depends on MTD_NAND_OMAP2 - default y - help -The NAND device can be accessed for Read/Write using GPMC PREFETCH engine -to improve the performance. - -config MTD_NAND_OMAP_PREFETCH_DMA - depends on MTD_NAND_OMAP_PREFETCH - bool "DMA mode" - default n - help -The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode -or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used - config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 7c04cd6..60bac8e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -96,27 +96,6 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH -static int use_prefetch = 1; - -/* "modprobe ... use_prefetch=0" etc */ -module_param(use_prefetch, bool, 0); -MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH"); - -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA -static int use_dma = 1; - -/* "modprobe ... use_dma=0" etc */ -module_param(use_dma, bool, 0); -MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); -#else -static const int use_dma; -#endif -#else -const int use_prefetch; -static const int use_dma; -#endif - struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -324,7 +303,6 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } } -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA /* * omap_nand_dma_cb: callback on the completion of dma transfer * @lch: logical channel @@ -426,14 +404,6 @@ out_copy: : omap_write_buf8(mtd, (u_char *) addr, len); return 0; } -#else -static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) {} -static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, - unsigned int len, int is_write) -{ - return 0; -} -#endif /** * omap_read_buf_dma_pref - read data from NAND controller into buffer @@ -842,28 +812,13 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.chip_delay = 50; } - if (use_prefetch) { - + switch (pdata->xfer_type) { + case NAND_OMAP_PREFETCH_POLLED: info->nand.read_buf = omap_read_buf_pref; info->nand.write_buf = omap_write_buf_pref; - if (use_dma) { - err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", - omap_nand_dma_cb, &info->comp, &info->dma_ch); - if (err < 0) { - info->dma_ch = -1; - printk(KERN_WARNING "DMA request failed." - " Non-dma data transfer mode\n"); - } else { - omap_set_dma_dest_burst_mode(info->dma_ch, -
[PATCH v9 0/7] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on linux-2.6. The main motivations behind this patch series are - 1. support NAND I/O in irq mode. 2. support of different ECC schema. 3. also add support ecc layout as like in romcode ecc layout, but not enabled v9: gpmc_init() changed to postcore_initcall(gpmc_init); v8: free_irq() added; used timeout for while(tight loop) And resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg41614.html v7: NAND type (x16 or x8) is board specific and not omap specific; this passed form board file. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg41469.html v6: configurable transfer type from board file; #define irq number used for nand-irq http://www.mail-archive.com/linux-omap@vger.kernel.org/msg39397.html v5: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35860.html This address the input as to support the irq_chained in GPMC. And resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35848.html v4: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg34882.html and resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32689.html v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32071.html Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (7): omap3630: nand: fix device size to work in polled mode omap3: nand: configurable transfer type per board omap: gpmc: enable irq mode in gpmc omap3: nand: prefetch in irq mode support omap3: nand: configurable fifo threshold to gain the throughput omap3: nand: ecc layout select from board file omap3: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-3430sdp.c|2 +- arch/arm/mach-omap2/board-3630sdp.c|3 +- arch/arm/mach-omap2/board-flash.c | 13 +- arch/arm/mach-omap2/board-flash.h |4 +- arch/arm/mach-omap2/board-ldp.c|2 +- arch/arm/mach-omap2/board-zoom.c |5 +- arch/arm/mach-omap2/gpmc-nand.c|7 +- arch/arm/mach-omap2/gpmc.c | 56 +- arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h | 18 ++- arch/arm/plat-omap/include/plat/irqs.h |9 +- arch/arm/plat-omap/include/plat/nand.h | 11 + drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 367 14 files changed, 386 insertions(+), 130 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] omap3: nand: bch ecc support added
bch error correction (t=4 and t=8) for 512 bytes support added. Tested in omap-3630 es-1.1 silicon. Need to select the bch-ecc from board file. E.g. arch/arm/mach-omap2/board-flash.c: board_nand_init() board_nand_data.ecc_opt = OMAP_ECC_BCH4_CODE_HW This patch has dependency on - http://www.mail-archive.com/linux-omap@vger.kernel.org/msg42658.html Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 126 --- arch/arm/plat-omap/include/plat/gpmc.h |6 +- drivers/mtd/nand/Makefile |1 + drivers/mtd/nand/omap2.c | 119 -- drivers/mtd/nand/omap_bch_decoder.c| 393 5 files changed, 583 insertions(+), 62 deletions(-) create mode 100644 drivers/mtd/nand/omap_bch_decoder.c diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 29c9732..91cfdca 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -48,6 +48,7 @@ #define GPMC_ECC_CONTROL 0x1f8 #define GPMC_ECC_SIZE_CONFIG 0x1fc #define GPMC_ECC1_RESULT0x200 +#define GPMC_ECC_BCH_RESULT_0 0x240 #define GPMC_CS0_OFFSET0x60 #define GPMC_CS_SIZE 0x30 @@ -94,7 +95,6 @@ static struct resourcegpmc_mem_root; static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); static unsigned int gpmc_cs_map; /* flag for cs which are initialized */ -static int gpmc_ecc_used = -EINVAL;/* cs using ecc engine */ static void __iomem *gpmc_base; @@ -832,52 +832,77 @@ void omap3_gpmc_restore_context(void) /** * gpmc_enable_hwecc - enable hardware ecc functionality + * @ecc_type: ecc type e.g. Hamming, BCH * @cs: chip select number * @mode: read/write mode * @dev_width: device bus width(1 for x16, 0 for x8) * @ecc_size: bytes for which ECC will be generated */ -int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size) +int gpmc_enable_hwecc(int ecc_type, int cs, int mode, + int dev_width, int ecc_size) { - unsigned int val; - - /* check if ecc module is in used */ - if (gpmc_ecc_used != -EINVAL) - return -EINVAL; - - gpmc_ecc_used = cs; - - /* clear ecc and enable bits */ - val = ((0x0001<<8) | 0x0001); - gpmc_write_reg(GPMC_ECC_CONTROL, val); - - /* program ecc and result sizes */ - val = ecc_size >> 1) - 1) << 22) | (0x000F)); - gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, val); + unsigned int bch_mod = 0, bch_wrapmode = 0, eccsize1 = 0, eccsize0 = 0; + unsigned int ecc_conf_val = 0, ecc_size_conf_val = 0; switch (mode) { case GPMC_ECC_READ: - gpmc_write_reg(GPMC_ECC_CONTROL, 0x101); + if (ecc_type == OMAP_ECC_BCH4_CODE_HW) { + eccsize1 = 0xD; eccsize0 = 0x48; + bch_mod = 0; + bch_wrapmode = 0x09; + } else if (ecc_type == OMAP_ECC_BCH8_CODE_HW) { + eccsize1 = 0x1A; eccsize0 = 0x18; + bch_mod = 1; + bch_wrapmode = 0x04; + } else + eccsize1 = ((ecc_size >> 1) - 1) << 22; break; + case GPMC_ECC_READSYN: -gpmc_write_reg(GPMC_ECC_CONTROL, 0x100); break; + case GPMC_ECC_WRITE: - gpmc_write_reg(GPMC_ECC_CONTROL, 0x101); + if (ecc_type == OMAP_ECC_BCH4_CODE_HW) { + eccsize1 = 0x20; eccsize0 = 0x00; + bch_mod = 0; + bch_wrapmode = 0x06; + } else if (ecc_type == OMAP_ECC_BCH8_CODE_HW) { + eccsize1 = 0x20; eccsize0 = 0x00; + bch_mod = 1; + bch_wrapmode = 0x06; + } else + eccsize1 = ((ecc_size >> 1) - 1) << 22; break; + default: printk(KERN_INFO "Error: Unrecognized Mode[%d]!\n", mode); break; } - /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ - val = (dev_width << 7) | (cs << 1) | (0x1); - gpmc_write_reg(GPMC_ECC_CONFIG, val); + /* clear ecc and enable bits */ + if ((ecc_type == OMAP_ECC_BCH4_CODE_HW) || + (ecc_type == OMAP_ECC_BCH8_CODE_HW)) { + gpmc_write_reg(GPMC_ECC_CONTROL, 0x0001); + ecc_size_conf_val = (eccsize1 << 22) | (eccsize0 << 12); + ecc_conf_val = ((0x01 << 16) | (bch_mod << 12) + | (bch_wrapmode << 8) | (dev_width << 7) + | (0x03 << 4) | (cs << 1) | (0x1)); + } else { + gpmc_write_reg(GPMC_ECC_CONTROL, 0x0101); + ecc_s
[PATCH RESEND v8 7/7] omap3: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-loader, u-boot and kernel. This enables to flash x-loader, u-boot, kernel, FS images from kernel itself and compatiable with other tools. This patch does not enables this feature by default and need to pass from board file to enable for any board. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/plat-omap/include/plat/gpmc.h |2 + drivers/mtd/nand/omap2.c | 37 +++- 2 files changed, 38 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 4626e7a..49aea09 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -90,6 +90,8 @@ enum omap_ecc { /* 1-bit ecc: stored at end of spare area */ OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ + /* 1-bit ecc: stored at begining of spare area as romcode */ + OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ }; /* diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 6d4a42e..4e33972 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -98,6 +98,20 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -914,6 +928,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1037,7 +1052,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) /* selsect the ecc type */ if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) info->nand.ecc.mode = NAND_ECC_SOFT; - else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { + else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { info->nand.ecc.bytes= 3; info->nand.ecc.size = 512; info->nand.ecc.calculate= omap_calculate_ecc; @@ -1057,6 +1073,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) { + + if (info->nand.options & NAND_BUSWIDTH_16) + offset = 2; + else { + offset = 1; + info->nand.badblock_pattern = &bb_descrip_flashbased; + } + omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16); + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v8 6/7] omap3: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |1 + arch/arm/plat-omap/include/plat/gpmc.h |6 ++ arch/arm/plat-omap/include/plat/nand.h |2 ++ drivers/mtd/nand/omap2.c | 26 +++--- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 1964509..a768198 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -148,6 +148,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, board_nand_data.nr_parts= nr_parts; board_nand_data.devsize = nand_type; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 1b4a095..4626e7a 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -86,6 +86,12 @@ #define PREFETCH_FIFOTHRESHOLD_MAX 0x40 #define PREFETCH_FIFOTHRESHOLD(val)((val) << 8) +enum omap_ecc { + /* 1-bit ecc: stored at end of spare area */ + OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ + OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ +}; + /* * Note that all values in this struct are in nanoseconds except sync_clk * (which is in picoseconds), while the register values are in gpmc_fck cycles. diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index ae5e053..d86d1ec 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include #include enum nand_io { @@ -31,6 +32,7 @@ struct omap_nand_platform_data { enum nand_ioxfer_type; unsigned long phys_base; int devsize; + enum omap_ecc ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index f1648fd..6d4a42e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -626,8 +626,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -847,8 +845,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1038,17 +1034,17 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) + info->nand.ecc.mode = NAND_ECC_SOFT; + else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v8 4/7] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for nand transfer(read, write) Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |2 + arch/arm/plat-omap/include/plat/nand.h |4 +- drivers/mtd/nand/omap2.c | 198 ++-- 3 files changed, 194 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index f6b7253..1964509 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, board_nand_data.nr_parts= nr_parts; board_nand_data.devsize = nand_type; + board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } #else diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 78c0bdb..ae5e053 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -13,7 +13,8 @@ enum nand_io { NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ NAND_OMAP_POLLED, /* polled mode, without prefetch */ - NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_DMA, /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_IRQ /* prefetch enabled irq mode */ }; struct omap_nand_platform_data { @@ -26,6 +27,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; enum nand_ioxfer_type; unsigned long phys_base; int devsize; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 60bac8e..fbe8414 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #defineDRIVER_NAME "omap2-nand" +#defineOMAP_NAND_TIMEOUT_MS5000 #define NAND_Ecc_P1e (1 << 0) #define NAND_Ecc_P2e (1 << 1) @@ -108,6 +110,13 @@ struct omap_nand_info { unsigned long phys_base; struct completion comp; int dma_ch; + int gpmc_irq; + enum { + OMAP_NAND_IO_READ = 0, /* read */ + OMAP_NAND_IO_WRITE, /* write */ + } iomode; + u_char *buf; + int buf_len; }; /** @@ -267,9 +276,10 @@ static void omap_write_buf_pref(struct mtd_info *mtd, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - uint32_t pref_count = 0, w_count = 0; + uint32_t w_count = 0; int i = 0, ret = 0; u16 *p; + unsigned long tim, limit; /* take care of subpage writes */ if (len % 2 != 0) { @@ -295,9 +305,12 @@ static void omap_write_buf_pref(struct mtd_info *mtd, iowrite16(*p++, info->nand.IO_ADDR_W); } /* wait for data to flushed-out before reset the prefetch */ - do { - pref_count = gpmc_read_status(GPMC_PREFETCH_COUNT); - } while (pref_count); + tim = 0; + limit = (loops_per_jiffy * + msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); + while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) + cpu_relax(); + /* disable and stop the PFPW engine */ gpmc_prefetch_reset(info->gpmc_cs); } @@ -326,11 +339,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - uint32_t prefetch_status = 0; enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; dma_addr_t dma_addr; int ret; + unsigned long tim, limit; /* The fifo depth is 64 bytes. We have a sync at each frame and frame * length is 64 bytes. @@ -376,7 +389,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, /* configure and start prefetch transfer */ ret = gpmc_prefetch_enable(info->gpmc_cs, 0x1, len, is_wr
[PATCH RESEND v8 3/7] omap: gpmc: enable irq mode in gpmc
add support the irq mode in GPMC. gpmc_init() function move after omap_init_irq() as it has dependecy on irq. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|1 + arch/arm/mach-omap2/board-3630sdp.c|1 + arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|1 + arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom.c |2 + arch/arm/mach-omap2/gpmc.c | 39 ++- arch/arm/mach-omap2/io.c |3 -- arch/arm/plat-omap/include/plat/gpmc.h |4 +++ arch/arm/plat-omap/include/plat/irqs.h |9 +- 26 files changed, 79 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index e066177..527374f 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -146,6 +146,7 @@ static void __init omap_2430sdp_init_irq(void) omap2_init_common_infrastructure(); omap2_init_common_devices(NULL, NULL); omap_init_irq(); + gpmc_init(); } static struct twl4030_gpio_platform_data sdp2430_gpio_data = { diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 8fb5f43..8304d16 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -335,6 +335,7 @@ static void __init omap_3430sdp_init_irq(void) omap2_init_common_infrastructure(); omap2_init_common_devices(hyb18m512160af6_sdrc_params, NULL); omap_init_irq(); + gpmc_init(); } static int sdp3430_batt_table[] = { diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index b4ca7fc..befebde 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -78,6 +78,7 @@ static void __init omap_sdp_init_irq(void) omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params); omap_init_irq(); + gpmc_init(); } #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 07d1b20..2c125ab 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "mux.h" #include "hsmmc.h" @@ -249,6 +250,7 @@ static void __init omap_4430sdp_init_irq(void) omap2_gp_clockevent_set_gptimer(1); #endif gic_init_irq(); + gpmc_init(); } static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 10d60b7..2d87087 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "mux.h" @@ -403,6 +404,7 @@ static void __init am3517_evm_init_irq(void) omap2_init_common_infrastructure(); omap2_init_common_devices(NULL, NULL); omap_init_irq(); + gpmc_init(); } static struct omap_musb_board_data musb_board_data = { diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 9f55b68..09f6322 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -281,6 +281,7 @@ static void __init omap_apollon_init_irq(void) omap2_init_common_infrastructure(); omap2_init_common_devices(NULL, NULL); omap_init_irq(); + gpmc_init(); } static void __init apollon_led_init(void) diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index dac1416..8aca46f 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -692,6 +692,7 @@ static void __init cm_t35_init_irq(void) omap2_init_common_devices(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_
[PATCH RESEND v8 1/7] omap3630: nand: fix device size to work in polled mode
zoom3 and 3630-sdp having the x16 nand device. This patch configure gpmc as x16 and select the currect function in driver for polled mode (without prefetch enable) transfer. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-3430sdp.c |2 +- arch/arm/mach-omap2/board-3630sdp.c |3 ++- arch/arm/mach-omap2/board-flash.c | 10 ++ arch/arm/mach-omap2/board-flash.h |4 ++-- arch/arm/mach-omap2/board-ldp.c |2 +- arch/arm/mach-omap2/board-zoom.c|5 +++-- arch/arm/mach-omap2/gpmc-nand.c |7 +-- drivers/mtd/nand/omap2.c|2 +- 8 files changed, 21 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index d4e41ef..8fb5f43 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -813,7 +813,7 @@ static void __init omap_3430sdp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_3430); + board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); sdp3430_display_init(); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 6264564..b4ca7fc 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -209,7 +210,7 @@ static void __init omap_sdp_init(void) zoom_peripherals_init(); zoom_display_init(); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_sdp); + board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); } diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index fd38c05..f6b7253 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -139,11 +139,13 @@ static struct omap_nand_platform_data board_nand_data = { }; void -__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) +__init board_nand_init(struct mtd_partition *nand_parts, + u8 nr_parts, u8 cs, int nand_type) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.devsize = nand_type; gpmc_nand_init(&board_nand_data); } @@ -194,7 +196,7 @@ unmap: * @return - void. */ void board_flash_init(struct flash_partitions partition_info[], - char chip_sel_board[][GPMC_CS_NUM]) + char chip_sel_board[][GPMC_CS_NUM], int nand_type) { u8 cs = 0; u8 norcs = GPMC_CS_NUM + 1; @@ -250,5 +252,5 @@ void board_flash_init(struct flash_partitions partition_info[], "in GPMC\n"); else board_nand_init(partition_info[2].parts, - partition_info[2].nr_parts, nandcs); + partition_info[2].nr_parts, nandcs, nand_type); } diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h index 69befe0..c240a3f 100644 --- a/arch/arm/mach-omap2/board-flash.h +++ b/arch/arm/mach-omap2/board-flash.h @@ -25,6 +25,6 @@ struct flash_partitions { }; extern void board_flash_init(struct flash_partitions [], - char chip_sel[][GPMC_CS_NUM]); + char chip_sel[][GPMC_CS_NUM], int nand_type); extern void board_nand_init(struct mtd_partition *nand_parts, - u8 nr_parts, u8 cs); + u8 nr_parts, u8 cs, int nand_type); diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index e5dc748..d986d32 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -434,7 +434,7 @@ static void __init omap_ldp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_nand_init(ldp_nand_partitions, - ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS); + ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0); omap2_hsmmc_init(mmc); /* link regulators to MMC adapters */ diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index e26754c..0242611 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -126,8 +127,8 @@ static void __init omap_zoom_init(void)
[PATCH RESEND v8 2/7] omap3: nand: configurable transfer type per board
nand transfer type (sDMA, Polled, prefetch) can be select from board file, enabling all transfer type in driver, by default. this helps in multi-omap build and to select different transfer type for different board. Signed-off-by: Sukumar Ghorai --- arch/arm/plat-omap/include/plat/nand.h |7 +++ drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 94 3 files changed, 41 insertions(+), 77 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..78c0bdb 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -10,6 +10,12 @@ #include +enum nand_io { + NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ + NAND_OMAP_POLLED, /* polled mode, without prefetch */ + NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ +}; + struct omap_nand_platform_data { unsigned intoptions; int cs; @@ -20,6 +26,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + enum nand_ioxfer_type; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index c895922..178e200 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -106,23 +106,6 @@ config MTD_NAND_OMAP2 help Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. -config MTD_NAND_OMAP_PREFETCH - bool "GPMC prefetch support for NAND Flash device" - depends on MTD_NAND_OMAP2 - default y - help -The NAND device can be accessed for Read/Write using GPMC PREFETCH engine -to improve the performance. - -config MTD_NAND_OMAP_PREFETCH_DMA - depends on MTD_NAND_OMAP_PREFETCH - bool "DMA mode" - default n - help -The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode -or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used - config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 7c04cd6..60bac8e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -96,27 +96,6 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH -static int use_prefetch = 1; - -/* "modprobe ... use_prefetch=0" etc */ -module_param(use_prefetch, bool, 0); -MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH"); - -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA -static int use_dma = 1; - -/* "modprobe ... use_dma=0" etc */ -module_param(use_dma, bool, 0); -MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); -#else -static const int use_dma; -#endif -#else -const int use_prefetch; -static const int use_dma; -#endif - struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -324,7 +303,6 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } } -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA /* * omap_nand_dma_cb: callback on the completion of dma transfer * @lch: logical channel @@ -426,14 +404,6 @@ out_copy: : omap_write_buf8(mtd, (u_char *) addr, len); return 0; } -#else -static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) {} -static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, - unsigned int len, int is_write) -{ - return 0; -} -#endif /** * omap_read_buf_dma_pref - read data from NAND controller into buffer @@ -842,28 +812,13 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.chip_delay = 50; } - if (use_prefetch) { - + switch (pdata->xfer_type) { + case NAND_OMAP_PREFETCH_POLLED: info->nand.read_buf = omap_read_buf_pref; info->nand.write_buf = omap_write_buf_pref; - if (use_dma) { - err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", - omap_nand_dma_cb, &info->comp, &info->dma_ch); - if (err < 0) { - info->dma_ch = -1; - printk(KERN_WARNING "DMA request failed." - " Non-dma data transfer mode\n"); - } else { - omap_set_dma_dest_burst_mode(info->dma_ch, -
[PATCH RESEND v8 5/7] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 22 ++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index b198598..29c9732 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -59,7 +59,6 @@ #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 @@ -605,15 +604,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + pr_err("gpmc: fifo threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -621,7 +624,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index ffd2a24..1b4a095 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)((val) << 8) + /* * Note that all values in this struct are in nanoseconds except sync_clk * (which is in picoseconds), while the register values are in gpmc_fck cycles. @@ -134,7 +137,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index fbe8414..f1648fd 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -244,7 +244,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -289,7 +290,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -345,8 +347,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, int ret; unsigned long tim, limit; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 byte
[PATCH RESEND v8 0/7] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on linux-2.6. The main motivations behind this patch series are - 1. support NAND I/O in irq mode. 2. support of different ECC schema. 3. also add support ecc layout as like in romcode ecc layout, but not enabled v8: free_irq() added; usedtimeout for this while loop. Rebase and resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg41614.html v7: NAND type (x16 or x8) is board specific and not omap specific; this passed form board file. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg41469.html v6: configurable transfer type from board file; #define irq number used for nand-irq http://www.mail-archive.com/linux-omap@vger.kernel.org/msg39397.html v5: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35860.html This address the input as to support the irq_chained in GPMC. And resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35848.html v4: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg34882.html and resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32689.html v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32071.html Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (7): omap3630: nand: fix device size to work in polled mode omap3: nand: configurable transfer type per board omap: gpmc: enable irq mode in gpmc omap3: nand: prefetch in irq mode support omap3: nand: configurable fifo threshold to gain the throughput omap3: nand: ecc layout select from board file omap3: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|3 +- arch/arm/mach-omap2/board-3630sdp.c|4 +- arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-flash.c | 13 +- arch/arm/mach-omap2/board-flash.h |4 +- arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|3 +- arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom.c |7 +- arch/arm/mach-omap2/gpmc-nand.c|7 +- arch/arm/mach-omap2/gpmc.c | 50 - arch/arm/mach-omap2/io.c |3 - arch/arm/plat-omap/include/plat/gpmc.h | 17 ++- arch/arm/plat-omap/include/plat/irqs.h |9 +- arch/arm/plat-omap/include/plat/nand.h | 11 + drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 367 +--- 32 files changed, 411 insertions(+), 129 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 5/7] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 22 ++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index a2df8b1..117ab29 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -59,7 +59,6 @@ #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 @@ -595,15 +594,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + pr_err("gpmc: fifo threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -611,7 +614,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 054e704..9e4dc7a 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)((val) << 8) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -133,7 +136,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index fbe8414..f1648fd 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -244,7 +244,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -289,7 +290,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -345,8 +347,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, int ret; unsigned long tim, limit; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 bytes max. +* But configure the FIFO-t
[PATCH v8 6/7] omap3: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |1 + arch/arm/plat-omap/include/plat/gpmc.h |6 ++ arch/arm/plat-omap/include/plat/nand.h |2 ++ drivers/mtd/nand/omap2.c | 26 +++--- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 1964509..a768198 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -148,6 +148,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, board_nand_data.nr_parts= nr_parts; board_nand_data.devsize = nand_type; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 9e4dc7a..bc325c5 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -86,6 +86,12 @@ #define PREFETCH_FIFOTHRESHOLD_MAX 0x40 #define PREFETCH_FIFOTHRESHOLD(val)((val) << 8) +enum omap_ecc { + /* 1-bit ecc: stored at end of spare area */ + OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ + OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ +}; + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index ae5e053..d86d1ec 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include #include enum nand_io { @@ -31,6 +32,7 @@ struct omap_nand_platform_data { enum nand_ioxfer_type; unsigned long phys_base; int devsize; + enum omap_ecc ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index f1648fd..6d4a42e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -626,8 +626,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -847,8 +845,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1038,17 +1034,17 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) + info->nand.ecc.mode = NAND_ECC_SOFT; + else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 7/7] omap3: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-loader, u-boot and kernel. This enables to flash x-loader, u-boot, kernel, FS images from kernel itself and compatiable with other tools. This patch does not enables this feature by default and need to pass from board file to enable for any board. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/plat-omap/include/plat/gpmc.h |2 + drivers/mtd/nand/omap2.c | 37 +++- 2 files changed, 38 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index bc325c5..c07f3f2 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -90,6 +90,8 @@ enum omap_ecc { /* 1-bit ecc: stored at end of spare area */ OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ + /* 1-bit ecc: stored at begining of spare area as romcode */ + OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ }; /* diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 6d4a42e..4e33972 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -98,6 +98,20 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -914,6 +928,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1037,7 +1052,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) /* selsect the ecc type */ if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) info->nand.ecc.mode = NAND_ECC_SOFT; - else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { + else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { info->nand.ecc.bytes= 3; info->nand.ecc.size = 512; info->nand.ecc.calculate= omap_calculate_ecc; @@ -1057,6 +1073,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) { + + if (info->nand.options & NAND_BUSWIDTH_16) + offset = 2; + else { + offset = 1; + info->nand.badblock_pattern = &bb_descrip_flashbased; + } + omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16); + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 3/7] omap: gpmc: enable irq mode in gpmc
add support the irq mode in GPMC. gpmc_init() function move after omap_init_irq() as it has dependecy on irq. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|1 + arch/arm/mach-omap2/board-3630sdp.c|1 + arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|1 + arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |2 + arch/arm/mach-omap2/board-zoom3.c |2 + arch/arm/mach-omap2/gpmc.c | 39 ++- arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h |4 +++ arch/arm/plat-omap/include/plat/irqs.h |9 +- 27 files changed, 81 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index b527f8d..11c89dc 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -145,6 +145,7 @@ static void __init omap_2430sdp_init_irq(void) omap_board_config_size = ARRAY_SIZE(sdp2430_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 470872e..690fecd 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -328,6 +328,7 @@ static void __init omap_3430sdp_init_irq(void) omap3_pm_init_cpuidle(omap3_cpuidle_params_table); omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 0a74141..46c1755 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -77,6 +77,7 @@ static void __init omap_sdp_init_irq(void) omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index df5a425..8d15604 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "hsmmc.h" #include "timer-gp.h" @@ -222,6 +223,7 @@ static void __init omap_4430sdp_init_irq(void) omap2_gp_clockevent_set_gptimer(1); #endif gic_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 0739950..460e3d1 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "mux.h" #include "control.h" @@ -392,6 +393,7 @@ static void __init am3517_evm_init_irq(void) omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 2c6db1a..8264e7a 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -280,6 +280,7 @@ static void __init omap_apollon_init_irq(void) omap_board_config_size = ARRAY_SIZE(apollon_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); apollon_init_smc91x(); } diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 63f764e..7c9a834 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -686,6 +686,7 @@ static void __init cm_t35_init_irq(void) omap2_init_common_hw(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(
[PATCH v8 0/7] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on linux-2.6. The main motivations behind this patch series are - 1. support NAND I/O in irq mode. 2. support of different ECC schema. 3. also add support ecc layout as like in romcode ecc layout, but not enabled v8: free_irq() added; usedtimeout for this while loop v7: NAND type (x16 or x8) is board specific and not omap specific; this passed form board file. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg41469.html v6: configurable transfer type from board file; #define irq number used for nand-irq http://www.mail-archive.com/linux-omap@vger.kernel.org/msg39397.html v5: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35860.html This address the input as to support the irq_chained in GPMC. And resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35848.html v4: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg34882.html and resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32689.html v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32071.html Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (7): omap3630: nand: fix device size to work in polled mode omap3: nand: configurable transfer type per board omap: gpmc: enable irq mode in gpmc omap3: nand: prefetch in irq mode support omap3: nand: configurable fifo threshold to gain the throughput omap3: nand: ecc layout select from board file omap3: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|3 +- arch/arm/mach-omap2/board-3630sdp.c|4 +- arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-flash.c | 13 +- arch/arm/mach-omap2/board-flash.h |4 +- arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|3 +- arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |7 +- arch/arm/mach-omap2/board-zoom3.c |7 +- arch/arm/mach-omap2/gpmc-nand.c|7 +- arch/arm/mach-omap2/gpmc.c | 50 - arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h | 17 ++- arch/arm/plat-omap/include/plat/irqs.h |9 +- arch/arm/plat-omap/include/plat/nand.h | 11 + drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 336 +--- 33 files changed, 396 insertions(+), 119 deletions(-) Sukumar Ghorai (7): omap3630: nand: fix device size to work in polled mode omap3: nand: configurable transfer type per board omap: gpmc: enable irq mode in gpmc omap3: nand: prefetch in irq mode support omap3: nand: configurable fifo threshold to gain the throughput omap3: nand: ecc layout select from board file omap3: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|3 +- arch/arm/mach-omap2/board-3630sdp.c|4 +- arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-flash.c | 13 +- arch/arm/mach-omap2/board-flash.h |4 +- arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|3 +- arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach
[PATCH v8 1/7] omap3630: nand: fix device size to work in polled mode
zoom3 and 3630-sdp having the x16 nand device. This patch configure gpmc as x16 and select the currect function in driver for polled mode (without prefetch enable) transfer. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-3430sdp.c |2 +- arch/arm/mach-omap2/board-3630sdp.c |3 ++- arch/arm/mach-omap2/board-flash.c | 10 ++ arch/arm/mach-omap2/board-flash.h |4 ++-- arch/arm/mach-omap2/board-ldp.c |2 +- arch/arm/mach-omap2/board-zoom2.c |5 +++-- arch/arm/mach-omap2/board-zoom3.c |5 +++-- arch/arm/mach-omap2/gpmc-nand.c |7 +-- drivers/mtd/nand/omap2.c|2 +- 9 files changed, 24 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 4e3742c..470872e 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -809,7 +809,7 @@ static void __init omap_3430sdp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_3430); + board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); sdp3430_display_init(); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index bbcf580..0a74141 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -210,7 +211,7 @@ static void __init omap_sdp_init(void) omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); zoom_peripherals_init(); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_sdp); + board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); } diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index fd38c05..f6b7253 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -139,11 +139,13 @@ static struct omap_nand_platform_data board_nand_data = { }; void -__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) +__init board_nand_init(struct mtd_partition *nand_parts, + u8 nr_parts, u8 cs, int nand_type) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.devsize = nand_type; gpmc_nand_init(&board_nand_data); } @@ -194,7 +196,7 @@ unmap: * @return - void. */ void board_flash_init(struct flash_partitions partition_info[], - char chip_sel_board[][GPMC_CS_NUM]) + char chip_sel_board[][GPMC_CS_NUM], int nand_type) { u8 cs = 0; u8 norcs = GPMC_CS_NUM + 1; @@ -250,5 +252,5 @@ void board_flash_init(struct flash_partitions partition_info[], "in GPMC\n"); else board_nand_init(partition_info[2].parts, - partition_info[2].nr_parts, nandcs); + partition_info[2].nr_parts, nandcs, nand_type); } diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h index 69befe0..c240a3f 100644 --- a/arch/arm/mach-omap2/board-flash.h +++ b/arch/arm/mach-omap2/board-flash.h @@ -25,6 +25,6 @@ struct flash_partitions { }; extern void board_flash_init(struct flash_partitions [], - char chip_sel[][GPMC_CS_NUM]); + char chip_sel[][GPMC_CS_NUM], int nand_type); extern void board_nand_init(struct mtd_partition *nand_parts, - u8 nr_parts, u8 cs); + u8 nr_parts, u8 cs, int nand_type); diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 001fd97..b088b1d 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -436,7 +436,7 @@ static void __init omap_ldp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_nand_init(ldp_nand_partitions, - ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS); + ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0); omap2_hsmmc_init(mmc); /* link regulators to MMC adapters */ diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c index 2992a9f..994d286 100644 --- a/arch/arm/mach-omap2/board-zoom2.c +++ b/arch/arm/mach-omap2/board-zoom2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #inclu
[PATCH v8 4/7] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for nand transfer(read, write) Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |2 + arch/arm/plat-omap/include/plat/nand.h |4 +- drivers/mtd/nand/omap2.c | 198 ++-- 3 files changed, 194 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index f6b7253..1964509 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, board_nand_data.nr_parts= nr_parts; board_nand_data.devsize = nand_type; + board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } #else diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 78c0bdb..ae5e053 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -13,7 +13,8 @@ enum nand_io { NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ NAND_OMAP_POLLED, /* polled mode, without prefetch */ - NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_DMA, /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_IRQ /* prefetch enabled irq mode */ }; struct omap_nand_platform_data { @@ -26,6 +27,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; enum nand_ioxfer_type; unsigned long phys_base; int devsize; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 60bac8e..fbe8414 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #defineDRIVER_NAME "omap2-nand" +#defineOMAP_NAND_TIMEOUT_MS5000 #define NAND_Ecc_P1e (1 << 0) #define NAND_Ecc_P2e (1 << 1) @@ -108,6 +110,13 @@ struct omap_nand_info { unsigned long phys_base; struct completion comp; int dma_ch; + int gpmc_irq; + enum { + OMAP_NAND_IO_READ = 0, /* read */ + OMAP_NAND_IO_WRITE, /* write */ + } iomode; + u_char *buf; + int buf_len; }; /** @@ -267,9 +276,10 @@ static void omap_write_buf_pref(struct mtd_info *mtd, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - uint32_t pref_count = 0, w_count = 0; + uint32_t w_count = 0; int i = 0, ret = 0; u16 *p; + unsigned long tim, limit; /* take care of subpage writes */ if (len % 2 != 0) { @@ -295,9 +305,12 @@ static void omap_write_buf_pref(struct mtd_info *mtd, iowrite16(*p++, info->nand.IO_ADDR_W); } /* wait for data to flushed-out before reset the prefetch */ - do { - pref_count = gpmc_read_status(GPMC_PREFETCH_COUNT); - } while (pref_count); + tim = 0; + limit = (loops_per_jiffy * + msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); + while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) + cpu_relax(); + /* disable and stop the PFPW engine */ gpmc_prefetch_reset(info->gpmc_cs); } @@ -326,11 +339,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - uint32_t prefetch_status = 0; enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; dma_addr_t dma_addr; int ret; + unsigned long tim, limit; /* The fifo depth is 64 bytes. We have a sync at each frame and frame * length is 64 bytes. @@ -376,7 +389,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, /* configure and start prefetch transfer */ ret = gpmc_prefetch_enable(info->gpmc_cs, 0x1, len, is_wr
[PATCH v8 2/7] omap3: nand: configurable transfer type per board
nand transfer type (sDMA, Polled, prefetch) can be select from board file, enabling all transfer type in driver, by default. this helps in multi-omap build and to select different transfer type for different board. Signed-off-by: Sukumar Ghorai --- arch/arm/plat-omap/include/plat/nand.h |7 +++ drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 94 3 files changed, 41 insertions(+), 77 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..78c0bdb 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -10,6 +10,12 @@ #include +enum nand_io { + NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ + NAND_OMAP_POLLED, /* polled mode, without prefetch */ + NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ +}; + struct omap_nand_platform_data { unsigned intoptions; int cs; @@ -20,6 +26,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + enum nand_ioxfer_type; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 8229802..89bb297 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -105,23 +105,6 @@ config MTD_NAND_OMAP2 help Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. -config MTD_NAND_OMAP_PREFETCH - bool "GPMC prefetch support for NAND Flash device" - depends on MTD_NAND_OMAP2 - default y - help -The NAND device can be accessed for Read/Write using GPMC PREFETCH engine -to improve the performance. - -config MTD_NAND_OMAP_PREFETCH_DMA - depends on MTD_NAND_OMAP_PREFETCH - bool "DMA mode" - default n - help -The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode -or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used - config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 7c04cd6..60bac8e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -96,27 +96,6 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH -static int use_prefetch = 1; - -/* "modprobe ... use_prefetch=0" etc */ -module_param(use_prefetch, bool, 0); -MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH"); - -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA -static int use_dma = 1; - -/* "modprobe ... use_dma=0" etc */ -module_param(use_dma, bool, 0); -MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); -#else -static const int use_dma; -#endif -#else -const int use_prefetch; -static const int use_dma; -#endif - struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -324,7 +303,6 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } } -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA /* * omap_nand_dma_cb: callback on the completion of dma transfer * @lch: logical channel @@ -426,14 +404,6 @@ out_copy: : omap_write_buf8(mtd, (u_char *) addr, len); return 0; } -#else -static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) {} -static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, - unsigned int len, int is_write) -{ - return 0; -} -#endif /** * omap_read_buf_dma_pref - read data from NAND controller into buffer @@ -842,28 +812,13 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.chip_delay = 50; } - if (use_prefetch) { - + switch (pdata->xfer_type) { + case NAND_OMAP_PREFETCH_POLLED: info->nand.read_buf = omap_read_buf_pref; info->nand.write_buf = omap_write_buf_pref; - if (use_dma) { - err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", - omap_nand_dma_cb, &info->comp, &info->dma_ch); - if (err < 0) { - info->dma_ch = -1; - printk(KERN_WARNING "DMA request failed." - " Non-dma data transfer mode\n"); - } else { - omap_set_dma_dest_burst_mode(info->dma_ch, -
[PATCH v7 2/7] omap3: nand: configurable transfer type per board
nand transfer type (sDMA, Polled, prefetch) can be select from board file, enabling all transfer type in driver, by default. this helps in multi-omap build and to select different transfer type for different board. Signed-off-by: Sukumar Ghorai --- arch/arm/plat-omap/include/plat/nand.h |7 +++ drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 92 +++ 3 files changed, 40 insertions(+), 76 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..78c0bdb 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -10,6 +10,12 @@ #include +enum nand_io { + NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ + NAND_OMAP_POLLED, /* polled mode, without prefetch */ + NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ +}; + struct omap_nand_platform_data { unsigned intoptions; int cs; @@ -20,6 +26,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + enum nand_ioxfer_type; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 8229802..89bb297 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -105,23 +105,6 @@ config MTD_NAND_OMAP2 help Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. -config MTD_NAND_OMAP_PREFETCH - bool "GPMC prefetch support for NAND Flash device" - depends on MTD_NAND_OMAP2 - default y - help -The NAND device can be accessed for Read/Write using GPMC PREFETCH engine -to improve the performance. - -config MTD_NAND_OMAP_PREFETCH_DMA - depends on MTD_NAND_OMAP_PREFETCH - bool "DMA mode" - default n - help -The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode -or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used - config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 7c04cd6..66b7428 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -96,27 +96,6 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH -static int use_prefetch = 1; - -/* "modprobe ... use_prefetch=0" etc */ -module_param(use_prefetch, bool, 0); -MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH"); - -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA -static int use_dma = 1; - -/* "modprobe ... use_dma=0" etc */ -module_param(use_dma, bool, 0); -MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); -#else -static const int use_dma; -#endif -#else -const int use_prefetch; -static const int use_dma; -#endif - struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -324,7 +303,6 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } } -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA /* * omap_nand_dma_cb: callback on the completion of dma transfer * @lch: logical channel @@ -426,14 +404,6 @@ out_copy: : omap_write_buf8(mtd, (u_char *) addr, len); return 0; } -#else -static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) {} -static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, - unsigned int len, int is_write) -{ - return 0; -} -#endif /** * omap_read_buf_dma_pref - read data from NAND controller into buffer @@ -842,28 +812,13 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.chip_delay = 50; } - if (use_prefetch) { - + switch (pdata->xfer_type) { + case NAND_OMAP_PREFETCH_POLLED: info->nand.read_buf = omap_read_buf_pref; info->nand.write_buf = omap_write_buf_pref; - if (use_dma) { - err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", - omap_nand_dma_cb, &info->comp, &info->dma_ch); - if (err < 0) { - info->dma_ch = -1; - printk(KERN_WARNING "DMA request failed." - " Non-dma data transfer mode\n"); - } else { - omap_set_dma_dest_burst_mode(info->dma_ch, -
[PATCH v7 3/7] omap: gpmc: enable irq mode in gpmc
add support the irq mode in GPMC. gpmc_init() function move after omap_init_irq() as it has dependecy on irq. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|1 + arch/arm/mach-omap2/board-3630sdp.c|1 + arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|1 + arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |2 + arch/arm/mach-omap2/board-zoom3.c |2 + arch/arm/mach-omap2/gpmc.c | 39 ++- arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h |4 +++ arch/arm/plat-omap/include/plat/irqs.h |9 +- 27 files changed, 81 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index b527f8d..11c89dc 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -145,6 +145,7 @@ static void __init omap_2430sdp_init_irq(void) omap_board_config_size = ARRAY_SIZE(sdp2430_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 470872e..690fecd 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -328,6 +328,7 @@ static void __init omap_3430sdp_init_irq(void) omap3_pm_init_cpuidle(omap3_cpuidle_params_table); omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 0a74141..46c1755 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -77,6 +77,7 @@ static void __init omap_sdp_init_irq(void) omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index df5a425..8d15604 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "hsmmc.h" #include "timer-gp.h" @@ -222,6 +223,7 @@ static void __init omap_4430sdp_init_irq(void) omap2_gp_clockevent_set_gptimer(1); #endif gic_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 0739950..460e3d1 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "mux.h" #include "control.h" @@ -392,6 +393,7 @@ static void __init am3517_evm_init_irq(void) omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 2c6db1a..8264e7a 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -280,6 +280,7 @@ static void __init omap_apollon_init_irq(void) omap_board_config_size = ARRAY_SIZE(apollon_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); apollon_init_smc91x(); } diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 63f764e..7c9a834 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -686,6 +686,7 @@ static void __init cm_t35_init_irq(void) omap2_init_common_hw(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(
[PATCH v7 7/7] omap3: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-loader, u-boot and kernel. This enables to flash x-loader, u-boot, kernel, FS images from kernel itself and compatiable with other tools. This patch does not enables this feature by default and need to pass from board file to enable for any board. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/plat-omap/include/plat/gpmc.h |2 + drivers/mtd/nand/omap2.c | 37 +++- 2 files changed, 38 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 28a5607..fcc0530 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -90,6 +90,8 @@ enum omap_ecc { /* 1-bit ecc: stored at end of spare area */ OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ + /* 1-bit ecc: stored at begining of spare area as romcode */ + OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ }; /* diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index c6f3ea9..72af2d9 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -97,6 +97,20 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -906,6 +920,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1029,7 +1044,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) /* selsect the ecc type */ if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) info->nand.ecc.mode = NAND_ECC_SOFT; - else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { + else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { info->nand.ecc.bytes= 3; info->nand.ecc.size = 512; info->nand.ecc.calculate= omap_calculate_ecc; @@ -1049,6 +1065,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) { + + if (info->nand.options & NAND_BUSWIDTH_16) + offset = 2; + else { + offset = 1; + info->nand.badblock_pattern = &bb_descrip_flashbased; + } + omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16); + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 4/7] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for nand transfer(read, write) Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |2 + arch/arm/plat-omap/include/plat/nand.h |4 +- drivers/mtd/nand/omap2.c | 169 3 files changed, 174 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index f6b7253..1964509 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, board_nand_data.nr_parts= nr_parts; board_nand_data.devsize = nand_type; + board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } #else diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 78c0bdb..ae5e053 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -13,7 +13,8 @@ enum nand_io { NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ NAND_OMAP_POLLED, /* polled mode, without prefetch */ - NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_DMA, /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_IRQ /* prefetch enabled irq mode */ }; struct omap_nand_platform_data { @@ -26,6 +27,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; enum nand_ioxfer_type; unsigned long phys_base; int devsize; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 66b7428..007862e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,13 @@ struct omap_nand_info { unsigned long phys_base; struct completion comp; int dma_ch; + int gpmc_irq; + enum { + OMAP_NAND_IO_READ = 0, /* read */ + OMAP_NAND_IO_WRITE, /* write */ + } iomode; + u_char *buf; + int buf_len; }; /** @@ -436,6 +444,153 @@ static void omap_write_buf_dma_pref(struct mtd_info *mtd, omap_nand_dma_transfer(mtd, (u_char *) buf, len, 0x1); } +/* + * omap_nand_irq - GMPC irq handler + * @this_irq: gpmc irq number + * @dev: omap_nand_info structure pointer is passed here + */ +static irqreturn_t omap_nand_irq(int this_irq, void *dev) +{ + struct omap_nand_info *info = (struct omap_nand_info *) dev; + u32 bytes; + u32 irq_stat; + + irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); + bytes = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */ + if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ + if (irq_stat & 0x2) + goto done; + + if (info->buf_len & (info->buf_len < bytes)) + bytes = info->buf_len; + else if (!info->buf_len) + bytes = 0; + iowrite32_rep(info->nand.IO_ADDR_W, + (u32 *)info->buf, bytes >> 2); + info->buf = info->buf + bytes; + info->buf_len -= bytes; + + } else { + ioread32_rep(info->nand.IO_ADDR_R, + (u32 *)info->buf, bytes >> 2); + info->buf = info->buf + bytes; + + if (irq_stat & 0x2) + goto done; + } + gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); + irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); + + return IRQ_HANDLED; + +done: + complete(&info->comp); + /* disable irq */ + gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 0); + + /* clear status */ + gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); + irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); + + return IRQ_HANDLED; +} + +/* + * omap_read_buf_irq_pref - read data from NAND controller into buffer + * @mtd: MTD device structure + * @buf: buffer to store date + * @len: number of bytes to read + */ +static void omap_read_bu
[PATCH v7 6/7] omap3: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. And hw ecc layout selected for sdp and zoom boards, by default. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |1 + arch/arm/plat-omap/include/plat/gpmc.h |6 ++ arch/arm/plat-omap/include/plat/nand.h |2 ++ drivers/mtd/nand/omap2.c | 26 +++--- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 1964509..a768198 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -148,6 +148,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, board_nand_data.nr_parts= nr_parts; board_nand_data.devsize = nand_type; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index fb82335..28a5607 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -86,6 +86,12 @@ #define PREFETCH_FIFOTHRESHOLD_MAX 0x40 #define PREFETCH_FIFOTHRESHOLD(val)(val << 8) +enum omap_ecc { + /* 1-bit ecc: stored at end of spare area */ + OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ + OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ +}; + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index ae5e053..d86d1ec 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include #include enum nand_io { @@ -31,6 +32,7 @@ struct omap_nand_platform_data { enum nand_ioxfer_type; unsigned long phys_base; int devsize; + enum omap_ecc ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 384d89b..c6f3ea9 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -618,8 +618,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -839,8 +837,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1030,17 +1026,17 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) + info->nand.ecc.mode = NAND_ECC_SOFT; + else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 1/7] omap3630: nand: fix device size to work in polled mode
zoom3 and 3630-sdp having the x16 nand device. This patch configure gpmc as x16 and select the currect function in driver for polled mode (without prefetch enable) transfer. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-3430sdp.c |2 +- arch/arm/mach-omap2/board-3630sdp.c |3 ++- arch/arm/mach-omap2/board-flash.c | 10 ++ arch/arm/mach-omap2/board-flash.h |4 ++-- arch/arm/mach-omap2/board-ldp.c |2 +- arch/arm/mach-omap2/board-zoom2.c |5 +++-- arch/arm/mach-omap2/board-zoom3.c |5 +++-- arch/arm/mach-omap2/gpmc-nand.c |7 +-- drivers/mtd/nand/omap2.c|2 +- 9 files changed, 24 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 4e3742c..470872e 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -809,7 +809,7 @@ static void __init omap_3430sdp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_3430); + board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); sdp3430_display_init(); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index bbcf580..0a74141 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -210,7 +211,7 @@ static void __init omap_sdp_init(void) omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); zoom_peripherals_init(); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_sdp); + board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); } diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index fd38c05..f6b7253 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -139,11 +139,13 @@ static struct omap_nand_platform_data board_nand_data = { }; void -__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) +__init board_nand_init(struct mtd_partition *nand_parts, + u8 nr_parts, u8 cs, int nand_type) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.devsize = nand_type; gpmc_nand_init(&board_nand_data); } @@ -194,7 +196,7 @@ unmap: * @return - void. */ void board_flash_init(struct flash_partitions partition_info[], - char chip_sel_board[][GPMC_CS_NUM]) + char chip_sel_board[][GPMC_CS_NUM], int nand_type) { u8 cs = 0; u8 norcs = GPMC_CS_NUM + 1; @@ -250,5 +252,5 @@ void board_flash_init(struct flash_partitions partition_info[], "in GPMC\n"); else board_nand_init(partition_info[2].parts, - partition_info[2].nr_parts, nandcs); + partition_info[2].nr_parts, nandcs, nand_type); } diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h index 69befe0..c240a3f 100644 --- a/arch/arm/mach-omap2/board-flash.h +++ b/arch/arm/mach-omap2/board-flash.h @@ -25,6 +25,6 @@ struct flash_partitions { }; extern void board_flash_init(struct flash_partitions [], - char chip_sel[][GPMC_CS_NUM]); + char chip_sel[][GPMC_CS_NUM], int nand_type); extern void board_nand_init(struct mtd_partition *nand_parts, - u8 nr_parts, u8 cs); + u8 nr_parts, u8 cs, int nand_type); diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 001fd97..b088b1d 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -436,7 +436,7 @@ static void __init omap_ldp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_nand_init(ldp_nand_partitions, - ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS); + ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0); omap2_hsmmc_init(mmc); /* link regulators to MMC adapters */ diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c index 2992a9f..994d286 100644 --- a/arch/arm/mach-omap2/board-zoom2.c +++ b/arch/arm/mach-omap2/board-zoom2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #inclu
[PATCH v7 5/7] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 22 ++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index cfaf357..b26b1a5 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -59,7 +59,6 @@ #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 @@ -595,15 +594,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + printk(KERN_ERR "PREFETCH Fifo Threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -611,7 +614,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 054e704..fb82335 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)(val << 8) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -133,7 +136,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 007862e..384d89b 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -243,7 +243,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -287,7 +288,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -340,8 +342,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 bytes max. +* But configure the FIF
[PATCH v7 0/7] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on linux-2.6. The main motivations behind this patch series are - 1. support NAND I/O in irq mode. 2. support of different ECC schema. 3. also add support ecc layout as like in romcode ecc layout, but not enabled v7: NAND type (x16 or x8) is board specific and not omap specific; this passed form board file. v6: configurable transfer type from board file; #define irq number used for nand-irq http://www.mail-archive.com/linux-omap@vger.kernel.org/msg39397.html v5: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35860.html This address the input as to support the irq_chained in GPMC. And resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35848.html v4: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg34882.html and resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32689.html v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32071.html Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (7): omap3630: nand: fix device size to work in polled mode omap3: nand: configurable transfer type per board omap: gpmc: enable irq mode in gpmc omap3: nand: prefetch in irq mode support omap3: nand: configurable fifo threshold to gain the throughput omap3: nand: ecc layout select from board file omap3: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|3 +- arch/arm/mach-omap2/board-3630sdp.c|4 +- arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-flash.c | 13 +- arch/arm/mach-omap2/board-flash.h |4 +- arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|3 +- arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |7 +- arch/arm/mach-omap2/board-zoom3.c |7 +- arch/arm/mach-omap2/gpmc-nand.c|7 +- arch/arm/mach-omap2/gpmc.c | 50 - arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h | 17 ++- arch/arm/plat-omap/include/plat/irqs.h |9 +- arch/arm/plat-omap/include/plat/nand.h | 11 + drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 336 +--- 33 files changed, 396 insertions(+), 119 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 3/7] omap: gpmc: enable irq mode in gpmc
add support the irq mode in GPMC. gpmc_init() function move after omap_init_irq() as it has dependecy on irq. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|1 + arch/arm/mach-omap2/board-3630sdp.c|1 + arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|1 + arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |2 + arch/arm/mach-omap2/board-zoom3.c |2 + arch/arm/mach-omap2/gpmc.c | 39 ++- arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h |4 +++ arch/arm/plat-omap/include/plat/irqs.h |9 +- 27 files changed, 81 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index b527f8d..11c89dc 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -145,6 +145,7 @@ static void __init omap_2430sdp_init_irq(void) omap_board_config_size = ARRAY_SIZE(sdp2430_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 4e3742c..a040165 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -328,6 +328,7 @@ static void __init omap_3430sdp_init_irq(void) omap3_pm_init_cpuidle(omap3_cpuidle_params_table); omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index bbcf580..17983ed 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -76,6 +76,7 @@ static void __init omap_sdp_init_irq(void) omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index df5a425..8d15604 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "hsmmc.h" #include "timer-gp.h" @@ -222,6 +223,7 @@ static void __init omap_4430sdp_init_irq(void) omap2_gp_clockevent_set_gptimer(1); #endif gic_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 0739950..460e3d1 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "mux.h" #include "control.h" @@ -392,6 +393,7 @@ static void __init am3517_evm_init_irq(void) omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 2c6db1a..8264e7a 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -280,6 +280,7 @@ static void __init omap_apollon_init_irq(void) omap_board_config_size = ARRAY_SIZE(apollon_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); apollon_init_smc91x(); } diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 63f764e..7c9a834 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -686,6 +686,7 @@ static void __init cm_t35_init_irq(void) omap2_init_common_hw(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(
[PATCH v6 7/7] omap: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-loader, u-boot and kernel. This patch also enables to use romcode ecc for spd and zoom, by default. This enables to flash x-loader, u-boot, kernel, FS images from kernel itself and compatiable with other tools. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- drivers/mtd/nand/omap2.c | 34 ++ 1 files changed, 34 insertions(+), 0 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 0937001..d4c508a 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -98,6 +98,20 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -907,6 +921,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1051,6 +1066,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } + /* rom code layout */ + if (pdata->ecc_opt != OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) { + offset = (info->nand.options & NAND_BUSWIDTH_16) ? 2 : 1; + if (info->mtd.oobsize == 16) { + info->nand.badblock_pattern = &bb_descrip_flashbased; + omap_oobinfo.eccbytes = 3; + } else + omap_oobinfo.eccbytes = 3 * 4; + + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } + #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 4/7] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for nand transfer(read, write) Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |3 + arch/arm/plat-omap/include/plat/nand.h |4 +- drivers/mtd/nand/omap2.c | 169 3 files changed, 175 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 001c605..78abcd9 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -16,7 +16,9 @@ #include #include #include +#include +#include #include #include #include @@ -148,6 +150,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) if (cpu_is_omap3630()) board_nand_data.devsize = 1; + board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } #else diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 78c0bdb..ae5e053 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -13,7 +13,8 @@ enum nand_io { NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ NAND_OMAP_POLLED, /* polled mode, without prefetch */ - NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_DMA, /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_IRQ /* prefetch enabled irq mode */ }; struct omap_nand_platform_data { @@ -26,6 +27,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; enum nand_ioxfer_type; unsigned long phys_base; int devsize; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 6011e90..c4bbbd0 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,13 @@ struct omap_nand_info { unsigned long phys_base; struct completion comp; int dma_ch; + int gpmc_irq; + enum { + OMAP_NAND_IO_READ = 0, /* read */ + OMAP_NAND_IO_WRITE, /* write */ + } iomode; + u_char *buf; + int buf_len; }; /** @@ -436,6 +444,153 @@ static void omap_write_buf_dma_pref(struct mtd_info *mtd, omap_nand_dma_transfer(mtd, (u_char *) buf, len, 0x1); } +/* + * omap_nand_irq - GMPC irq handler + * @this_irq: gpmc irq number + * @dev: omap_nand_info structure pointer is passed here + */ +static irqreturn_t omap_nand_irq(int this_irq, void *dev) +{ + struct omap_nand_info *info = (struct omap_nand_info *) dev; + u32 bytes; + u32 irq_stat; + + irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); + bytes = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */ + if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ + if (irq_stat & 0x2) + goto done; + + if (info->buf_len & (info->buf_len < bytes)) + bytes = info->buf_len; + else if (!info->buf_len) + bytes = 0; + iowrite32_rep(info->nand.IO_ADDR_W, + (u32 *)info->buf, bytes >> 2); + info->buf = info->buf + bytes; + info->buf_len -= bytes; + + } else { + ioread32_rep(info->nand.IO_ADDR_R, + (u32 *)info->buf, bytes >> 2); + info->buf = info->buf + bytes; + + if (irq_stat & 0x2) + goto done; + } + gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); + irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); + + return IRQ_HANDLED; + +done: + complete(&info->comp); + /* disable irq */ + gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 0); + + /* clear status */ + gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); + irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); + + return IRQ_HANDLED; +} + +/* + * omap_read_buf_irq_pref - read data from NAND controller into buffer + * @mtd: MTD device structure + * @buf: buffer to store date + * @len: number of bytes to read + */ +sta
[PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on linux-2.6. The main motivations behind this patch series are - 1. support NAND I/O in irq mode. 2. support of different ECC schema. 3. also to make ecc layout as like in romcode ecc layout v6: configurable transfer type from board file; #define irq number used for nand-irq v5: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35860.html This address the input as to support the irq_chained in GPMC. And resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35848.html v4: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg34882.html and resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32689.html v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32071.html Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (7): omap3630: nand: fix device size to work in polled mode omap3: nand: configurable transfer type per board omap: gpmc: enable irq mode in gpmc omap3: nand: prefetch in irq mode support omap3: nand: configurable fifo threshold to gain the throughput omap: nand: ecc layout select from board file omap: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|1 + arch/arm/mach-omap2/board-3630sdp.c|1 + arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-flash.c |7 + arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|1 + arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |2 + arch/arm/mach-omap2/board-zoom3.c |2 + arch/arm/mach-omap2/gpmc.c | 50 - arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h | 16 ++- arch/arm/plat-omap/include/plat/irqs.h |9 +- arch/arm/plat-omap/include/plat/nand.h | 11 + drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 314 ++-- 31 files changed, 364 insertions(+), 94 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 6/7] omap: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. And hw ecc layout selected for sdp and zoom boards, by default. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |1 + arch/arm/plat-omap/include/plat/gpmc.h |7 +++ arch/arm/plat-omap/include/plat/nand.h |2 ++ drivers/mtd/nand/omap2.c |5 + 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 78abcd9..3340427 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -150,6 +150,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) if (cpu_is_omap3630()) board_nand_data.devsize = 1; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index fb82335..ca6e8db 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -86,6 +86,13 @@ #define PREFETCH_FIFOTHRESHOLD_MAX 0x40 #define PREFETCH_FIFOTHRESHOLD(val)(val << 8) +enum omap_ecc { + OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT = 0, + /* 1-bit s/w ecc and layout different from romcode */ + OMAP_ECC_HAMMING_CODE_HW,/* 1-bit ecc, romcode layout */ + OMAP_ECC_HAMMING_CODE_SW,/* 1-bit ecc, romcode layout */ +}; + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index ae5e053..d86d1ec 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include #include enum nand_io { @@ -31,6 +32,7 @@ struct omap_nand_platform_data { enum nand_ioxfer_type; unsigned long phys_base; int devsize; + enum omap_ecc ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index fea9f59..0937001 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#define CONFIG_MTD_NAND_OMAP_HWECC #include #include @@ -618,8 +619,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -839,8 +838,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 5/7] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 24 +++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index cfaf357..b26b1a5 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -59,7 +59,6 @@ #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 @@ -595,15 +594,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + printk(KERN_ERR "PREFETCH Fifo Threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -611,7 +614,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 054e704..fb82335 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)(val << 8) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -133,7 +136,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index c4bbbd0..fea9f59 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -243,7 +243,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -287,7 +288,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -340,10 +342,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 bytes max. +* But configure
[PATCH 1/7] omap3630: nand: fix device size to work in polled mode
zoom3 and 3630-sdp having the x16 nand device. This patch configure gpmc as x16 and select the currect function in driver for polled mode (without prefetch enable) transfer. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index fd38c05..001c605 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -145,6 +145,9 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) board_nand_data.parts = nand_parts; board_nand_data.nr_parts= nr_parts; + if (cpu_is_omap3630()) + board_nand_data.devsize = 1; + gpmc_nand_init(&board_nand_data); } #else -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] omap3: nand: configurable transfer type per board
nand transfer type (sDMA, Polled, prefetch) can be select from board file, enabling all transfer type in driver, by default. this helps in multi-omap build and to select different transfer type for different board. Signed-off-by: Sukumar Ghorai --- arch/arm/plat-omap/include/plat/nand.h |7 +++ drivers/mtd/nand/Kconfig | 17 -- drivers/mtd/nand/omap2.c | 92 +++ 3 files changed, 40 insertions(+), 76 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..78c0bdb 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -10,6 +10,12 @@ #include +enum nand_io { + NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ + NAND_OMAP_POLLED, /* polled mode, without prefetch */ + NAND_OMAP_PREFETCH_DMA /* prefetch enabled sDMA mode */ +}; + struct omap_nand_platform_data { unsigned intoptions; int cs; @@ -20,6 +26,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + enum nand_ioxfer_type; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 8229802..89bb297 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -105,23 +105,6 @@ config MTD_NAND_OMAP2 help Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. -config MTD_NAND_OMAP_PREFETCH - bool "GPMC prefetch support for NAND Flash device" - depends on MTD_NAND_OMAP2 - default y - help -The NAND device can be accessed for Read/Write using GPMC PREFETCH engine -to improve the performance. - -config MTD_NAND_OMAP_PREFETCH_DMA - depends on MTD_NAND_OMAP_PREFETCH - bool "DMA mode" - default n - help -The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode -or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used - config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 15682ec..6011e90 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -96,27 +96,6 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; #endif -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH -static int use_prefetch = 1; - -/* "modprobe ... use_prefetch=0" etc */ -module_param(use_prefetch, bool, 0); -MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH"); - -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA -static int use_dma = 1; - -/* "modprobe ... use_dma=0" etc */ -module_param(use_dma, bool, 0); -MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); -#else -static const int use_dma; -#endif -#else -const int use_prefetch; -static const int use_dma; -#endif - struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -324,7 +303,6 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } } -#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA /* * omap_nand_dma_cb: callback on the completion of dma transfer * @lch: logical channel @@ -426,14 +404,6 @@ out_copy: : omap_write_buf8(mtd, (u_char *) addr, len); return 0; } -#else -static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) {} -static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, - unsigned int len, int is_write) -{ - return 0; -} -#endif /** * omap_read_buf_dma_pref - read data from NAND controller into buffer @@ -842,28 +812,13 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.chip_delay = 50; } - if (use_prefetch) { - + switch (pdata->xfer_type) { + case NAND_OMAP_PREFETCH_POLLED: info->nand.read_buf = omap_read_buf_pref; info->nand.write_buf = omap_write_buf_pref; - if (use_dma) { - err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", - omap_nand_dma_cb, &info->comp, &info->dma_ch); - if (err < 0) { - info->dma_ch = -1; - printk(KERN_WARNING "DMA request failed." - " Non-dma data transfer mode\n"); - } else { - omap_set_dma_dest_burst_mode(info->dma_ch, -
[PATCH V2] omap: nand: remove hardware ECC as default
CONFIG_MTD_NAND_OMAP_HWECC defined wrongly in patch submitted for 2.6.36. This flag enables hw ecc by default. Boards like beagle and pandora uses sw ecc for write (e.g. binary flushed from u-boot) and read from kernel. https://patchwork.kernel.org/patch/111036/ Signed-off-by: Sukumar Ghorai --- drivers/mtd/nand/omap2.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index cd41c58..15682ec 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define CONFIG_MTD_NAND_OMAP_HWECC #include #include -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] omap: nand: remove hardware ECC as default
CONFIG_MTD_NAND_OMAP_HWECC defined wronly in patch submitted during 2.6.36 that using the hardware ECC by default Signed-off-by: Sukumar Ghorai --- drivers/mtd/nand/omap2.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index cd41c58..15682ec 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define CONFIG_MTD_NAND_OMAP_HWECC #include #include -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v5 2/5] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for NAND. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |4 +- arch/arm/plat-omap/include/plat/nand.h |1 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 196 +++- 4 files changed, 208 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index ac834aa..2355e4a 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -142,8 +143,9 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } #else diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..5e69463 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -20,6 +20,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 8b4b67c..88cea0c 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -112,6 +112,9 @@ config MTD_NAND_OMAP_PREFETCH help The NAND device can be accessed for Read/Write using GPMC PREFETCH engine to improve the performance. +GPMC PREFETCH can be configured eigther in MPU interrupt mode or in DMA +interrupt mode. If not selected any of them prefetch will be used in +polling mode. config MTD_NAND_OMAP_PREFETCH_DMA depends on MTD_NAND_OMAP_PREFETCH @@ -120,7 +123,16 @@ config MTD_NAND_OMAP_PREFETCH_DMA help The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used +Say y for DMA mode + +config MTD_NAND_OMAP_PREFETCH_IRQ + depends on MTD_NAND_OMAP_PREFETCH && !MTD_NAND_OMAP_PREFETCH_DMA + bool "IRQ mode" + default n + help +The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode +or in DMA interrupt mode. +Say y for IRQ mode config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 133d515..72994e8 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -105,17 +106,27 @@ module_param(use_prefetch, bool, 0); MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH"); #ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA +const int use_interrupt; static int use_dma = 1; /* "modprobe ... use_dma=0" etc */ module_param(use_dma, bool, 0); -MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); +MODULE_PARM_DESC(use_dma, "enable/disable use of DMA mode"); +#elif defined(CONFIG_MTD_NAND_OMAP_PREFETCH_IRQ) +const int use_dma; +static int use_interrupt = 1; + +/* "modprobe ... use_dma=0" etc */ +module_param(use_interrupt, bool, 0); +MODULE_PARM_DESC(use_interrupt, "enable/disable use of IRQ mode"); #else const int use_dma; +const int use_interrupt; #endif #else const int use_prefetch; const int use_dma; +const int use_interrupt; #endif struct omap_nand_info { @@ -130,6 +141,13 @@ struct omap_nand_info { unsigned long phys_base; struct completion comp; int dma_ch; + int gpmc_irq; + enum { + OMAP_NAND_IO_READ = 0, /* read */ + OMAP_NAND_IO_WRITE, /* write */ + } iomode; + u_char *buf; + int buf_len; }; /** @@ -467,6 +485,153 @@ static void omap_write_buf_dma_pref(struct mtd_info *mtd, omap_nand_dma_transfer(mtd, (u_char *) buf, len, 0x1); } +/* + * omap_nand_irq - GMPC irq handler + * @this_irq: gpmc irq number + * @dev: omap_nand_info structure pointer is passed here + */ +static irqreturn_t omap_nand_irq(int this_irq, void *dev) +{ + struct omap_nand_info *info = (struct omap_nand_info *) dev; + u32 byte
[PATCH RESEND v5 5/5] omap: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-loader, u-boot and kernel. This patch also enables to use romcode ecc for spd and zoom, by default. This enables to flash x-loader, u-boot, kernel, FS images from kernel itself and compatiable with other tools. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- drivers/mtd/nand/omap2.c | 34 ++ 1 files changed, 34 insertions(+), 0 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 3fd9ee0..9ccfd88 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -128,6 +128,20 @@ const int use_dma; const int use_interrupt; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -946,6 +960,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1079,6 +1094,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt != OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) { + offset = (info->nand.options & NAND_BUSWIDTH_16) ? 2 : 1; + if (info->mtd.oobsize == 16) { + info->nand.badblock_pattern = &bb_descrip_flashbased; + omap_oobinfo.eccbytes = 3; + } else + omap_oobinfo.eccbytes = 3 * 4; + + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } + #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v5 1/5] omap gpmc: enable irq mode in gpmc
add support the irq mode in GPMC. gpmc_init() function move after omap_init_irq() as it has dependecy on irq. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|1 + arch/arm/mach-omap2/board-3630sdp.c|1 + arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|1 + arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |2 + arch/arm/mach-omap2/board-zoom3.c |2 + arch/arm/mach-omap2/gpmc.c | 37 ++- arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h |4 +++ arch/arm/plat-omap/include/plat/irqs.h |9 ++- 27 files changed, 79 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 8538e41..a047a35 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -144,6 +144,7 @@ static void __init omap_2430sdp_init_irq(void) omap_board_config_size = ARRAY_SIZE(sdp2430_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 67b95b5..549cd62 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -328,6 +328,7 @@ static void __init omap_3430sdp_init_irq(void) omap3_pm_init_cpuidle(omap3_cpuidle_params_table); omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index b359c3f..19cb423 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -76,6 +76,7 @@ static void __init omap_sdp_init_irq(void) omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 9447644..5fc66eb 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "hsmmc.h" #define ETH_KS8851_IRQ 34 @@ -181,6 +182,7 @@ static void __init omap_4430sdp_init_irq(void) omap2_gp_clockevent_set_gptimer(1); #endif gic_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 4d0f585..3a12571 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "mux.h" @@ -372,6 +373,7 @@ static void __init am3517_evm_init_irq(void) omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index c6421a7..10fe693 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -280,6 +280,7 @@ static void __init omap_apollon_init_irq(void) omap_board_config_size = ARRAY_SIZE(apollon_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); apollon_init_smc91x(); } diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index e10bc10..8c32e34 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -687,6 +687,7 @@ static void __init cm_t35_init_irq(void) omap2_init_common_hw(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a
[PATCH RESEND v5 0/5] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on linux-2.6. The main motivations behind this patch series are - 1. support NAND I/O in irq mode. 2. support of different ECC schema. 3. also to make ecc layout as like in romcode ecc layout v5: This address the input as to support the irq_chained in GPMC. And resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg35848.html v4: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg34882.html and resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32689.html v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32071.html Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (5): omap gpmc: enable irq mode in gpmc omap3: nand: prefetch in irq mode support omap3: nand: configurable fifo threshold to gain the throughput omap: nand: ecc layout select from board file omap: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|1 + arch/arm/mach-omap2/board-3630sdp.c|1 + arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-flash.c |5 +- arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|1 + arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |2 + arch/arm/mach-omap2/board-zoom3.c |2 + arch/arm/mach-omap2/gpmc.c | 48 +- arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h | 16 ++- arch/arm/plat-omap/include/plat/irqs.h |9 +- arch/arm/plat-omap/include/plat/nand.h |3 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 277 +--- 31 files changed, 367 insertions(+), 39 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v5 3/5] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 24 +++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 9ecb2a7..10ce5d5 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -59,7 +59,6 @@ #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 @@ -595,15 +594,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + printk(KERN_ERR "PREFETCH Fifo Threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -611,7 +614,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 054e704..fb82335 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)(val << 8) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -133,7 +136,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 72994e8..5ac7f7c 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -275,7 +275,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -319,7 +320,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -373,10 +375,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 bytes max. +* But configure
[PATCH RESEND v5 4/5] omap: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. And hw ecc layout selected for sdp and zoom boards, by default. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |1 + arch/arm/plat-omap/include/plat/gpmc.h |7 +++ arch/arm/plat-omap/include/plat/nand.h |2 ++ drivers/mtd/nand/omap2.c | 29 + 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 2355e4a..ecd41ae 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -144,6 +144,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) board_nand_data.cs = cs; board_nand_data.parts = nand_parts; board_nand_data.nr_parts= nr_parts; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index fb82335..54902d8 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -86,6 +86,13 @@ #define PREFETCH_FIFOTHRESHOLD_MAX 0x40 #define PREFETCH_FIFOTHRESHOLD(val)(val << 8) +enum omap_ecc{ + OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT = 0, + /* 1-bit s/w ecc and layout different from romcode */ + OMAP_ECC_HAMMING_CODE_HW,/* 1-bit ecc, romcode layout */ + OMAP_ECC_HAMMING_CODE_SW,/* 1-bit ecc, romcode layout */ +}; + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 5e69463..d5b6fc6 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include #include struct omap_nand_platform_data { @@ -23,6 +24,7 @@ struct omap_nand_platform_data { int gpmc_irq; unsigned long phys_base; int devsize; + enum omap_ecc ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 5ac7f7c..3fd9ee0 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define CONFIG_MTD_NAND_OMAP_HWECC #include #include @@ -659,8 +658,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -880,8 +877,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1059,17 +1054,19 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW)) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + + } else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_SW) { + info->nand.ecc.mode = NAND_ECC_SOFT; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 5/5] omap: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-loader, u-boot and kernel. This patch also enables to use romcode ecc for spd and zoom, by default. This enables to flash x-loader, u-boot, kernel, FS images from kernel itself and compatiable with other tools. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- drivers/mtd/nand/omap2.c | 34 ++ 1 files changed, 34 insertions(+), 0 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 3fd9ee0..9ccfd88 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -128,6 +128,20 @@ const int use_dma; const int use_interrupt; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -946,6 +960,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1079,6 +1094,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt != OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) { + offset = (info->nand.options & NAND_BUSWIDTH_16) ? 2 : 1; + if (info->mtd.oobsize == 16) { + info->nand.badblock_pattern = &bb_descrip_flashbased; + omap_oobinfo.eccbytes = 3; + } else + omap_oobinfo.eccbytes = 3 * 4; + + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } + #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 2/5] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for NAND. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |4 +- arch/arm/plat-omap/include/plat/nand.h |1 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 196 +++- 4 files changed, 208 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index ac834aa..2355e4a 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -142,8 +143,9 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } #else diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..5e69463 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -20,6 +20,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 8b4b67c..88cea0c 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -112,6 +112,9 @@ config MTD_NAND_OMAP_PREFETCH help The NAND device can be accessed for Read/Write using GPMC PREFETCH engine to improve the performance. +GPMC PREFETCH can be configured eigther in MPU interrupt mode or in DMA +interrupt mode. If not selected any of them prefetch will be used in +polling mode. config MTD_NAND_OMAP_PREFETCH_DMA depends on MTD_NAND_OMAP_PREFETCH @@ -120,7 +123,16 @@ config MTD_NAND_OMAP_PREFETCH_DMA help The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used +Say y for DMA mode + +config MTD_NAND_OMAP_PREFETCH_IRQ + depends on MTD_NAND_OMAP_PREFETCH && !MTD_NAND_OMAP_PREFETCH_DMA + bool "IRQ mode" + default n + help +The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode +or in DMA interrupt mode. +Say y for IRQ mode config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 133d515..72994e8 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -105,17 +106,27 @@ module_param(use_prefetch, bool, 0); MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH"); #ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA +const int use_interrupt; static int use_dma = 1; /* "modprobe ... use_dma=0" etc */ module_param(use_dma, bool, 0); -MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); +MODULE_PARM_DESC(use_dma, "enable/disable use of DMA mode"); +#elif defined(CONFIG_MTD_NAND_OMAP_PREFETCH_IRQ) +const int use_dma; +static int use_interrupt = 1; + +/* "modprobe ... use_dma=0" etc */ +module_param(use_interrupt, bool, 0); +MODULE_PARM_DESC(use_interrupt, "enable/disable use of IRQ mode"); #else const int use_dma; +const int use_interrupt; #endif #else const int use_prefetch; const int use_dma; +const int use_interrupt; #endif struct omap_nand_info { @@ -130,6 +141,13 @@ struct omap_nand_info { unsigned long phys_base; struct completion comp; int dma_ch; + int gpmc_irq; + enum { + OMAP_NAND_IO_READ = 0, /* read */ + OMAP_NAND_IO_WRITE, /* write */ + } iomode; + u_char *buf; + int buf_len; }; /** @@ -467,6 +485,153 @@ static void omap_write_buf_dma_pref(struct mtd_info *mtd, omap_nand_dma_transfer(mtd, (u_char *) buf, len, 0x1); } +/* + * omap_nand_irq - GMPC irq handler + * @this_irq: gpmc irq number + * @dev: omap_nand_info structure pointer is passed here + */ +static irqreturn_t omap_nand_irq(int this_irq, void *dev) +{ + struct omap_nand_info *info = (struct omap_nand_info *) dev; + u32 byte
[PATCH v5 4/5] omap: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. And hw ecc layout selected for sdp and zoom boards, by default. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |1 + arch/arm/plat-omap/include/plat/gpmc.h |7 +++ arch/arm/plat-omap/include/plat/nand.h |2 ++ drivers/mtd/nand/omap2.c | 29 + 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 2355e4a..ecd41ae 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -144,6 +144,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) board_nand_data.cs = cs; board_nand_data.parts = nand_parts; board_nand_data.nr_parts= nr_parts; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index fb82335..54902d8 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -86,6 +86,13 @@ #define PREFETCH_FIFOTHRESHOLD_MAX 0x40 #define PREFETCH_FIFOTHRESHOLD(val)(val << 8) +enum omap_ecc{ + OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT = 0, + /* 1-bit s/w ecc and layout different from romcode */ + OMAP_ECC_HAMMING_CODE_HW,/* 1-bit ecc, romcode layout */ + OMAP_ECC_HAMMING_CODE_SW,/* 1-bit ecc, romcode layout */ +}; + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 5e69463..d5b6fc6 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include #include struct omap_nand_platform_data { @@ -23,6 +24,7 @@ struct omap_nand_platform_data { int gpmc_irq; unsigned long phys_base; int devsize; + enum omap_ecc ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 5ac7f7c..3fd9ee0 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define CONFIG_MTD_NAND_OMAP_HWECC #include #include @@ -659,8 +658,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -880,8 +877,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1059,17 +1054,19 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW)) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + + } else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_SW) { + info->nand.ecc.mode = NAND_ECC_SOFT; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 1/5] omap gpmc: enable irq mode in gpmc
add support the irq mode in GPMC. gpmc_init() function move after omap_init_irq() as it has dependecy on irq. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|1 + arch/arm/mach-omap2/board-3630sdp.c|1 + arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|1 + arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |2 + arch/arm/mach-omap2/board-zoom3.c |2 + arch/arm/mach-omap2/gpmc.c | 37 ++- arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h |4 +++ arch/arm/plat-omap/include/plat/irqs.h |9 ++- 27 files changed, 79 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 8538e41..a047a35 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -144,6 +144,7 @@ static void __init omap_2430sdp_init_irq(void) omap_board_config_size = ARRAY_SIZE(sdp2430_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 67b95b5..549cd62 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -328,6 +328,7 @@ static void __init omap_3430sdp_init_irq(void) omap3_pm_init_cpuidle(omap3_cpuidle_params_table); omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index b359c3f..19cb423 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -76,6 +76,7 @@ static void __init omap_sdp_init_irq(void) omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 9447644..5fc66eb 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "hsmmc.h" #define ETH_KS8851_IRQ 34 @@ -181,6 +182,7 @@ static void __init omap_4430sdp_init_irq(void) omap2_gp_clockevent_set_gptimer(1); #endif gic_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 4d0f585..3a12571 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "mux.h" @@ -372,6 +373,7 @@ static void __init am3517_evm_init_irq(void) omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index c6421a7..10fe693 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -280,6 +280,7 @@ static void __init omap_apollon_init_irq(void) omap_board_config_size = ARRAY_SIZE(apollon_config); omap2_init_common_hw(NULL, NULL); omap_init_irq(); + gpmc_init(); omap_gpio_init(); apollon_init_smc91x(); } diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index e10bc10..8c32e34 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -687,6 +687,7 @@ static void __init cm_t35_init_irq(void) omap2_init_common_hw(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); omap_init_irq(); + gpmc_init(); omap_gpio_init(); } diff -
[PATCH v5 3/5] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 24 +++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 9ecb2a7..10ce5d5 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -59,7 +59,6 @@ #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 @@ -595,15 +594,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + printk(KERN_ERR "PREFETCH Fifo Threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -611,7 +614,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 054e704..fb82335 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)(val << 8) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -133,7 +136,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 72994e8..5ac7f7c 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -275,7 +275,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -319,7 +320,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -373,10 +375,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 bytes max. +* But conf
[PATCH v5 0/5] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on linux-2.6. The main motivations behind this patch series are - 1. support NAND I/O in irq mode. 2. support of different ECC schema. 3. also to make ecc layout as like in romcode ecc layout v5: This address the input as to support the irq_chained in GPMC v4: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg34882.html and resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32689.html v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32071.html Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (5): omap gpmc: enable irq mode in gpmc omap3: nand: prefetch in irq mode support omap3: nand: configurable fifo threshold to gain the throughput omap: nand: ecc layout select from board file omap: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-2430sdp.c|1 + arch/arm/mach-omap2/board-3430sdp.c|1 + arch/arm/mach-omap2/board-3630sdp.c|1 + arch/arm/mach-omap2/board-4430sdp.c|2 + arch/arm/mach-omap2/board-am3517evm.c |2 + arch/arm/mach-omap2/board-apollon.c|1 + arch/arm/mach-omap2/board-cm-t35.c |1 + arch/arm/mach-omap2/board-devkit8000.c |1 + arch/arm/mach-omap2/board-flash.c |5 +- arch/arm/mach-omap2/board-generic.c|2 + arch/arm/mach-omap2/board-h4.c |1 + arch/arm/mach-omap2/board-igep0020.c |1 + arch/arm/mach-omap2/board-ldp.c|1 + arch/arm/mach-omap2/board-n8x0.c |2 + arch/arm/mach-omap2/board-omap3beagle.c|1 + arch/arm/mach-omap2/board-omap3evm.c |2 + arch/arm/mach-omap2/board-omap3pandora.c |2 + arch/arm/mach-omap2/board-omap3stalker.c |1 + arch/arm/mach-omap2/board-omap3touchbook.c |1 + arch/arm/mach-omap2/board-omap4panda.c |2 + arch/arm/mach-omap2/board-overo.c |1 + arch/arm/mach-omap2/board-rx51.c |1 + arch/arm/mach-omap2/board-zoom2.c |2 + arch/arm/mach-omap2/board-zoom3.c |2 + arch/arm/mach-omap2/gpmc.c | 48 +- arch/arm/mach-omap2/io.c |2 - arch/arm/plat-omap/include/plat/gpmc.h | 16 ++- arch/arm/plat-omap/include/plat/irqs.h |9 +- arch/arm/plat-omap/include/plat/nand.h |3 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 277 +--- 31 files changed, 367 insertions(+), 39 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v4 1/4] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for NAND. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |2 + arch/arm/mach-omap2/gpmc.c |4 + arch/arm/plat-omap/include/plat/gpmc.h |4 + arch/arm/plat-omap/include/plat/irqs.h |1 + arch/arm/plat-omap/include/plat/nand.h |1 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 198 +++- 7 files changed, 217 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index ac834aa..4871d71 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -133,6 +134,7 @@ static struct omap_nand_platform_data board_nand_data = { .nand_setup = NULL, .gpmc_t = &nand_timings, .dma_channel= -1, /* disable DMA in OMAP NAND driver */ + .gpmc_irq = INT_34XX_GPMC_IRQ, .dev_ready = NULL, .devsize= 0,/* '0' for 8-bit, '1' for 16-bit device */ }; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index f46933b..86a6f78 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -487,6 +487,10 @@ int gpmc_cs_configure(int cs, int cmd, int wval) u32 regval = 0; switch (cmd) { + case GPMC_ENABLE_IRQ: + gpmc_write_reg(GPMC_IRQENABLE, wval); + break; + case GPMC_SET_IRQ_STATUS: gpmc_write_reg(GPMC_IRQSTATUS, wval); break; diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 9fd99b9..054e704 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -41,6 +41,8 @@ #define GPMC_NAND_ADDRESS 0x000b #define GPMC_NAND_DATA 0x000c +#define GPMC_ENABLE_IRQ0x000d + /* ECC commands */ #define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ #define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */ @@ -78,6 +80,8 @@ #define WR_RD_PIN_MONITORING 0x0060 #define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) #define GPMC_PREFETCH_STATUS_COUNT(val)(val & 0x3fff) +#define GPMC_IRQ_FIFOEVENTENABLE 0x01 +#define GPMC_IRQ_COUNT_EVENT 0x02 /* * Note that all values in this struct are in nanoseconds, while diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index c01d9f0..fd6d677 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h @@ -318,6 +318,7 @@ #define INT_34XX_PRCM_MPU_IRQ 11 #define INT_34XX_MCBSP1_IRQ16 #define INT_34XX_MCBSP2_IRQ17 +#define INT_34XX_GPMC_IRQ 20 #define INT_34XX_MCBSP3_IRQ22 #define INT_34XX_MCBSP4_IRQ23 #define INT_34XX_CAM_IRQ 24 diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..5e69463 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -20,6 +20,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 8b4b67c..88cea0c 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -112,6 +112,9 @@ config MTD_NAND_OMAP_PREFETCH help The NAND device can be accessed for Read/Write using GPMC PREFETCH engine to improve the performance. +GPMC PREFETCH can be configured eigther in MPU interrupt mode or in DMA +interrupt mode. If not selected any of them prefetch will be used in +polling mode. config MTD_NAND_OMAP_PREFETCH_DMA depends on MTD_NAND_OMAP_PREFETCH @@ -120,7 +123,16 @@ config MTD_NAND_OMAP_PREFETCH_DMA help The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used +Say y for DMA mode + +config MTD_NAND_OMAP_PREFETCH_IRQ + depends on MTD_NAND_OMAP_PREFETCH && !MTD_NAND_OMAP_PREFETCH_DMA + bool "IRQ mode" + default n + help +The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode +or in DMA interrupt mode. +Say y for IRQ mode config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap
[PATCH RESEND v4 3/4] omap: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. And hw ecc layout selected for sdp and zoom boards, by default. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/board-flash.c |3 ++- arch/arm/plat-omap/include/plat/nand.h |6 ++ drivers/mtd/nand/omap2.c | 29 + 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 4871d71..5f74c8f 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -144,7 +144,8 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; gpmc_nand_init(&board_nand_data); } diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 5e69463..2e026e4 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -23,6 +23,12 @@ struct omap_nand_platform_data { int gpmc_irq; unsigned long phys_base; int devsize; + enum { + OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT = 0, + /* 1-bit s/w ecc and layout different from romcode */ + OMAP_ECC_HAMMING_CODE_HW,/* 1-bit ecc, romcode layout */ + OMAP_ECC_HAMMING_CODE_SW,/* 1-bit ecc, romcode layout */ + } ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index d457b9b..dbbd699 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define CONFIG_MTD_NAND_OMAP_HWECC #include #include @@ -658,8 +657,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -879,8 +876,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1059,17 +1054,19 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW)) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + + } else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_SW) { + info->nand.ecc.mode = NAND_ECC_SOFT; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v4 2/4] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 24 +++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 86a6f78..8871a91 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -58,7 +58,6 @@ #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 @@ -592,15 +591,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + printk(KERN_ERR "PREFETCH Fifo Threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -608,7 +611,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 054e704..fb82335 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)(val << 8) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -133,7 +136,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index d834740..d457b9b 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -275,7 +275,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -319,7 +320,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -373,10 +375,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 bytes max. +* But conf
[PATCH RESEND v4 4/4] omap: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-loader, u-boot and kernel. This patch also enables to use romcode ecc for spd and zoom, by default. This enables to flash x-loader, u-boot, kernel, FS images from kernel itself and compatiable with other tools. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/board-flash.c |2 +- drivers/mtd/nand/omap2.c | 34 ++ 2 files changed, 35 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 5f74c8f..d71c511 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -145,7 +145,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) board_nand_data.cs = cs; board_nand_data.parts = nand_parts; board_nand_data.nr_parts= nr_parts; - board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_HW; gpmc_nand_init(&board_nand_data); } diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index dbbd699..33c356b 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -128,6 +128,20 @@ const int use_dma; const int use_interrupt; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -945,6 +959,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1079,6 +1094,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt != OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) { + offset = (info->nand.options & NAND_BUSWIDTH_16) ? 2 : 1; + if (info->mtd.oobsize == 16) { + info->nand.badblock_pattern = &bb_descrip_flashbased; + omap_oobinfo.eccbytes = 3; + } else + omap_oobinfo.eccbytes = 3 * 4; + + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } + #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v4 0/4] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on linux-2.6. v4: resend of http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32689.html v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32071.html Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (5): Merge branches 'master' and 'master' of git://git.kernel.org/.../torvalds/linux-2.6 omap3: nand: prefetch in irq mode support omap3: nand: configurable fifo threshold to gain the throughput omap: nand: ecc layout select from board file omap: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-flash.c |5 +- arch/arm/mach-omap2/gpmc.c | 15 ++- arch/arm/plat-omap/include/plat/gpmc.h |9 +- arch/arm/plat-omap/include/plat/irqs.h |1 + arch/arm/plat-omap/include/plat/nand.h |7 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 277 --- 7 files changed, 294 insertions(+), 34 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] omap mmc: extended to pass host capabilities from board file
wires variable is renamed, extended and this single variable to be used to pass the platform capabilities, e.g DDR mode. Also removed the hardcoded value was using as bus-width. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-2430sdp.c |3 ++- arch/arm/mach-omap2/board-3430sdp.c |5 +++-- arch/arm/mach-omap2/board-4430sdp.c |4 ++-- arch/arm/mach-omap2/board-cm-t35.c |5 +++-- arch/arm/mach-omap2/board-devkit8000.c |3 ++- arch/arm/mach-omap2/board-igep0020.c |5 +++-- arch/arm/mach-omap2/board-ldp.c |3 ++- arch/arm/mach-omap2/board-n8x0.c |2 +- arch/arm/mach-omap2/board-omap3beagle.c |3 ++- arch/arm/mach-omap2/board-omap3evm.c |3 ++- arch/arm/mach-omap2/board-omap3pandora.c |7 --- arch/arm/mach-omap2/board-omap3stalker.c |3 ++- arch/arm/mach-omap2/board-omap3touchbook.c |3 ++- arch/arm/mach-omap2/board-omap4panda.c |2 +- arch/arm/mach-omap2/board-overo.c|5 +++-- arch/arm/mach-omap2/board-rx51-peripherals.c |5 +++-- arch/arm/mach-omap2/board-zoom-peripherals.c |5 +++-- arch/arm/mach-omap2/devices.c| 16 +--- arch/arm/mach-omap2/hsmmc.c | 16 ++-- arch/arm/mach-omap2/hsmmc.h |3 ++- arch/arm/plat-omap/include/plat/mmc.h|7 +++ drivers/mmc/host/omap.c |2 +- drivers/mmc/host/omap_hsmmc.c| 18 ++ 23 files changed, 67 insertions(+), 61 deletions(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 8538e41..fc178a0 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -190,7 +191,7 @@ static int __init omap2430_i2c_init(void) static struct omap2_hsmmc_info mmc[] __initdata = { { .mmc= 1, - .wires = 4, + .caps = MMC_CAP_4_BIT_DATA, .gpio_cd= -EINVAL, .gpio_wp= -EINVAL, .ext_clock = 1, diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 67b95b5..3eb9839 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -353,12 +354,12 @@ static struct omap2_hsmmc_info mmc[] = { /* 8 bits (default) requires S6.3 == ON, * so the SIM card isn't used; else 4 bits. */ - .wires = 8, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_wp= 4, }, { .mmc= 2, - .wires = 8, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_wp= 7, }, {} /* Terminator */ diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 9447644..e379bef 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -193,12 +193,12 @@ static struct omap_musb_board_data musb_board_data = { static struct omap2_hsmmc_info mmc[] = { { .mmc= 1, - .wires = 8, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_wp= -EINVAL, }, { .mmc= 2, - .wires = 8, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_cd= -EINVAL, .gpio_wp= -EINVAL, .nonremovable = true, diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index e10bc10..b72009a 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -579,14 +580,14 @@ static struct twl4030_keypad_data cm_t35_kp_data = { static struct omap2_hsmmc_info mmc[] = { { .mmc= 1, - .wires = 4, + .caps = MMC_CAP_4_BIT_DATA, .gpio_cd= -EINVAL, .gpio_wp= -EINVAL, }, { .mmc= 2, - .wires = 4, + .caps = MMC_CAP_4_BIT_DATA, .transceiver= 1, .gpio_cd= -EINVAL, .gpio_wp= -EINVAL, diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-
[PATCH v4 4/4] omap: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-loader, u-boot and kernel. This patch also enables to use romcode ecc for spd and zoom, by default. This enables to flash x-loader, u-boot, kernel, FS images from kernel itself and compatiable with other tools. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/board-flash.c |2 +- drivers/mtd/nand/omap2.c | 34 ++ 2 files changed, 35 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 5f74c8f..d71c511 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -145,7 +145,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) board_nand_data.cs = cs; board_nand_data.parts = nand_parts; board_nand_data.nr_parts= nr_parts; - board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_HW; gpmc_nand_init(&board_nand_data); } diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 63682c0..1041783 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -128,6 +128,20 @@ const int use_dma; const int use_interrupt; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -945,6 +959,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1079,6 +1094,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt != OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) { + offset = (info->nand.options & NAND_BUSWIDTH_16) ? 2 : 1; + if (info->mtd.oobsize == 16) { + info->nand.badblock_pattern = &bb_descrip_flashbased; + omap_oobinfo.eccbytes = 3; + } else + omap_oobinfo.eccbytes = 3 * 4; + + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } + #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 3/4] omap: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. And hw ecc layout selected for sdp and zoom boards, by default. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/board-flash.c |3 ++- arch/arm/plat-omap/include/plat/nand.h |6 ++ drivers/mtd/nand/omap2.c | 29 + 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 4871d71..5f74c8f 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -144,7 +144,8 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; gpmc_nand_init(&board_nand_data); } diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 5e69463..2e026e4 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -23,6 +23,12 @@ struct omap_nand_platform_data { int gpmc_irq; unsigned long phys_base; int devsize; + enum { + OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT = 0, + /* 1-bit s/w ecc and layout different from romcode */ + OMAP_ECC_HAMMING_CODE_HW,/* 1-bit ecc, romcode layout */ + OMAP_ECC_HAMMING_CODE_SW,/* 1-bit ecc, romcode layout */ + } ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 20e73bf..63682c0 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define CONFIG_MTD_NAND_OMAP_HWECC #include #include @@ -658,8 +657,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -879,8 +876,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1059,17 +1054,19 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW)) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + + } else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_SW) { + info->nand.ecc.mode = NAND_ECC_SOFT; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/4] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for NAND. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |2 + arch/arm/mach-omap2/gpmc.c |4 + arch/arm/plat-omap/include/plat/gpmc.h |4 + arch/arm/plat-omap/include/plat/irqs.h |1 + arch/arm/plat-omap/include/plat/nand.h |1 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 196 +++- 7 files changed, 216 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index ac834aa..4871d71 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -133,6 +134,7 @@ static struct omap_nand_platform_data board_nand_data = { .nand_setup = NULL, .gpmc_t = &nand_timings, .dma_channel= -1, /* disable DMA in OMAP NAND driver */ + .gpmc_irq = INT_34XX_GPMC_IRQ, .dev_ready = NULL, .devsize= 0,/* '0' for 8-bit, '1' for 16-bit device */ }; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index f46933b..86a6f78 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -487,6 +487,10 @@ int gpmc_cs_configure(int cs, int cmd, int wval) u32 regval = 0; switch (cmd) { + case GPMC_ENABLE_IRQ: + gpmc_write_reg(GPMC_IRQENABLE, wval); + break; + case GPMC_SET_IRQ_STATUS: gpmc_write_reg(GPMC_IRQSTATUS, wval); break; diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 9fd99b9..054e704 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -41,6 +41,8 @@ #define GPMC_NAND_ADDRESS 0x000b #define GPMC_NAND_DATA 0x000c +#define GPMC_ENABLE_IRQ0x000d + /* ECC commands */ #define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ #define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */ @@ -78,6 +80,8 @@ #define WR_RD_PIN_MONITORING 0x0060 #define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) #define GPMC_PREFETCH_STATUS_COUNT(val)(val & 0x3fff) +#define GPMC_IRQ_FIFOEVENTENABLE 0x01 +#define GPMC_IRQ_COUNT_EVENT 0x02 /* * Note that all values in this struct are in nanoseconds, while diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index c01d9f0..fd6d677 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h @@ -318,6 +318,7 @@ #define INT_34XX_PRCM_MPU_IRQ 11 #define INT_34XX_MCBSP1_IRQ16 #define INT_34XX_MCBSP2_IRQ17 +#define INT_34XX_GPMC_IRQ 20 #define INT_34XX_MCBSP3_IRQ22 #define INT_34XX_MCBSP4_IRQ23 #define INT_34XX_CAM_IRQ 24 diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..5e69463 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -20,6 +20,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index ffc3720..46361ef 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -112,6 +112,9 @@ config MTD_NAND_OMAP_PREFETCH help The NAND device can be accessed for Read/Write using GPMC PREFETCH engine to improve the performance. +GPMC PREFETCH can be configured eigther in MPU interrupt mode or in DMA +interrupt mode. If not selected any of them prefetch will be used in +polling mode. config MTD_NAND_OMAP_PREFETCH_DMA depends on MTD_NAND_OMAP_PREFETCH @@ -120,7 +123,16 @@ config MTD_NAND_OMAP_PREFETCH_DMA help The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used +Say y for DMA mode + +config MTD_NAND_OMAP_PREFETCH_IRQ + depends on MTD_NAND_OMAP_PREFETCH && !MTD_NAND_OMAP_PREFETCH_DMA + bool "IRQ mode" + default n + help +The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode +or in DMA interrupt mode. +Say y for IRQ mode config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap
[PATCH v4 2/4] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 24 +++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 86a6f78..8871a91 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -58,7 +58,6 @@ #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 @@ -592,15 +591,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + printk(KERN_ERR "PREFETCH Fifo Threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -608,7 +611,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 054e704..fb82335 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)(val << 8) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -133,7 +136,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 9dc5ff9..20e73bf 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -275,7 +275,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -319,7 +320,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -373,10 +375,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 bytes max. +* But conf
[PATCH v4 0/4] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on top of omap-for-linus. v4: Comments incorporated v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32071.html Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (4): omap3: nand: prefetch in irq mode support omap: nand: configurable fifo threshold to gain the throughput omap: nand: ecc layout select from board file omap: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-flash.c |5 +- arch/arm/mach-omap2/gpmc.c | 15 ++- arch/arm/plat-omap/include/plat/gpmc.h |9 +- arch/arm/plat-omap/include/plat/irqs.h |1 + arch/arm/plat-omap/include/plat/nand.h |7 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 277 --- 7 files changed, 294 insertions(+), 34 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] omap: hsmmc funtionality breaks when CONFIG_PM not define
Issue if power_saving option passed from board file and CONFIG_PM not define. This is because hosts refer to wrong operation table and that try to power save. Signed-off-by: Sukumar Ghorai Signed-off-by: Santosh Shilimkar CC: Madhusudhan Chikkature CC: Andrew Morton --- Tested on omap3, omap4430 ES2.0 drivers/mmc/host/omap_hsmmc.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index b032828..f84eed0 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2015,9 +2015,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); +#ifdef CONFIG_PM if (mmc_slot(host).power_saving) mmc->ops= &omap_hsmmc_ps_ops; else +#endif mmc->ops= &omap_hsmmc_ops; /* -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: csd version check updated to support MMC v4.41
CSD_STRUCTURE [127:126] describes the version of the CSD structure. According to the MMC specificaiton (v4.4.1), 3 is also a valid number. Signed-off-by: Sukumar Ghorai --- Tested on omap4430 ES2.0 drivers/mmc/core/mmc.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 89f7a25..525af33 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -122,7 +122,7 @@ static int mmc_decode_csd(struct mmc_card *card) * v1.2 has extra information in bits 15, 11 and 10. */ csd_struct = UNSTUFF_BITS(resp, 126, 2); - if (csd_struct != 1 && csd_struct != 2) { + if (csd_struct > 3) { printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", mmc_hostname(card->host), csd_struct); return -EINVAL; -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/4] omap: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-laod, u-boot and kernel. This patch also enables to use romcode ecc for spd and zoom, by default. This enables to flash x-load, u-boot, kernel, FS images from kernel itself and compatiable with other tools. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/board-flash.c |2 +- drivers/mtd/nand/omap2.c | 34 ++ 2 files changed, 35 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index ab31e7f..a15aab6 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -144,7 +144,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) board_nand_data.cs = cs; board_nand_data.parts = nand_parts; board_nand_data.nr_parts= nr_parts; - board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_HW; gpmc_nand_init(&board_nand_data); } diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 0464a19..09b26d7 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -128,6 +128,20 @@ const int use_dma; const int use_interrupt; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -945,6 +959,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1079,6 +1094,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt != OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) { + offset = (info->nand.options & NAND_BUSWIDTH_16) ? 2 : 1; + if (info->mtd.oobsize == 16) { + info->nand.badblock_pattern = &bb_descrip_flashbased; + omap_oobinfo.eccbytes = 3; + } else + omap_oobinfo.eccbytes = 3 * 4; + + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } + #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/4] omap: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. And hw ecc layout selected for sdp and zoom boards, by default. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/board-flash.c |3 ++- arch/arm/plat-omap/include/plat/nand.h |6 ++ drivers/mtd/nand/omap2.c | 29 + 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index c6a07dd..ab31e7f 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -143,7 +143,8 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; gpmc_nand_init(&board_nand_data); } diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 5e69463..2e026e4 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -23,6 +23,12 @@ struct omap_nand_platform_data { int gpmc_irq; unsigned long phys_base; int devsize; + enum { + OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT = 0, + /* 1-bit s/w ecc and layout different from romcode */ + OMAP_ECC_HAMMING_CODE_HW,/* 1-bit ecc, romcode layout */ + OMAP_ECC_HAMMING_CODE_SW,/* 1-bit ecc, romcode layout */ + } ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index d5fad84..0464a19 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define CONFIG_MTD_NAND_OMAP_HWECC #include #include @@ -658,8 +657,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -879,8 +876,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1059,17 +1054,19 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW)) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + + } else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_SW) { + info->nand.ecc.mode = NAND_ECC_SOFT; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/4] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for NAND. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |1 + arch/arm/mach-omap2/gpmc.c |4 + arch/arm/mach-omap2/include/mach/board-flash.h |3 + arch/arm/plat-omap/include/plat/gpmc.h |4 + arch/arm/plat-omap/include/plat/nand.h |1 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 196 +++- 7 files changed, 217 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index ac834aa..c6a07dd 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -133,6 +133,7 @@ static struct omap_nand_platform_data board_nand_data = { .nand_setup = NULL, .gpmc_t = &nand_timings, .dma_channel= -1, /* disable DMA in OMAP NAND driver */ + .gpmc_irq = GPMC_IRQ_NUMBER, .dev_ready = NULL, .devsize= 0,/* '0' for 8-bit, '1' for 16-bit device */ }; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index e301e7e..2c100e4 100755 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -487,6 +487,10 @@ int gpmc_cs_configure(int cs, int cmd, int wval) u32 regval = 0; switch (cmd) { + case GPMC_ENABLE_IRQ: + gpmc_write_reg(GPMC_IRQENABLE, wval); + break; + case GPMC_SET_IRQ_STATUS: gpmc_write_reg(GPMC_IRQSTATUS, wval); break; diff --git a/arch/arm/mach-omap2/include/mach/board-flash.h b/arch/arm/mach-omap2/include/mach/board-flash.h index b2242ae..37567a7 100644 --- a/arch/arm/mach-omap2/include/mach/board-flash.h +++ b/arch/arm/mach-omap2/include/mach/board-flash.h @@ -19,6 +19,9 @@ #define PDC_ONENAND3 #define DBG_MPDB 4 +/* Interrupt number to the MPU Subsystem for GPMC */ +#define GPMC_IRQ_NUMBER20 + struct flash_partitions { struct mtd_partition *parts; int nr_parts; diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 9fd99b9..054e704 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -41,6 +41,8 @@ #define GPMC_NAND_ADDRESS 0x000b #define GPMC_NAND_DATA 0x000c +#define GPMC_ENABLE_IRQ0x000d + /* ECC commands */ #define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ #define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */ @@ -78,6 +80,8 @@ #define WR_RD_PIN_MONITORING 0x0060 #define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) #define GPMC_PREFETCH_STATUS_COUNT(val)(val & 0x3fff) +#define GPMC_IRQ_FIFOEVENTENABLE 0x01 +#define GPMC_IRQ_COUNT_EVENT 0x02 /* * Note that all values in this struct are in nanoseconds, while diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..5e69463 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -20,6 +20,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index ffc3720..46361ef 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -112,6 +112,9 @@ config MTD_NAND_OMAP_PREFETCH help The NAND device can be accessed for Read/Write using GPMC PREFETCH engine to improve the performance. +GPMC PREFETCH can be configured eigther in MPU interrupt mode or in DMA +interrupt mode. If not selected any of them prefetch will be used in +polling mode. config MTD_NAND_OMAP_PREFETCH_DMA depends on MTD_NAND_OMAP_PREFETCH @@ -120,7 +123,16 @@ config MTD_NAND_OMAP_PREFETCH_DMA help The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used +Say y for DMA mode + +config MTD_NAND_OMAP_PREFETCH_IRQ + depends on MTD_NAND_OMAP_PREFETCH && !MTD_NAND_OMAP_PREFETCH_DMA + bool "IRQ mode" + default n + help +The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode +or in DMA interrupt mode. +Say y for IRQ mode config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 133d515..6a57743
[PATCH v3 2/4] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 24 +++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 2c100e4..d10041a 100755 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -58,7 +58,6 @@ #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 @@ -592,15 +591,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + printk(KERN_ERR "PREFETCH Fifo Threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -608,7 +611,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 054e704..fb82335 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -83,6 +83,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)(val << 8) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -133,7 +136,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 6a57743..d5fad84 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -275,7 +275,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -319,7 +320,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -373,10 +375,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 bytes max. +* But conf
[PATCH v3 0/4] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on top of for-next branch. And is dependent on the following patches 1. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30305.html v3: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31963.html v2: Rebase on latest codebase and previous patch(posted). http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31471.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (4): omap3: nand: prefetch in irq mode support omap: nand: configurable fifo threshold to gain the throughput omap: nand: ecc layout select from board file omap: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-flash.c |4 +- arch/arm/mach-omap2/gpmc.c | 15 +- arch/arm/mach-omap2/include/mach/board-flash.h |3 + arch/arm/plat-omap/include/plat/gpmc.h |9 +- arch/arm/plat-omap/include/plat/nand.h |7 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 277 +--- 7 files changed, 295 insertions(+), 34 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/5] omap3 flash: rename board-sdp-flash.c to be use by other boards
rename board-sdp-flash.c(board-flash.c) and board-sdp.h(board-flash.h) to used by other board e.g. zoom Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/Makefile |2 +- arch/arm/mach-omap2/board-3430sdp.c| 16 +++- .../{board-sdp-flash.c => board-flash.c} | 88 --- .../include/mach/{board-sdp.h => board-flash.h}|9 ++- 4 files changed, 60 insertions(+), 55 deletions(-) rename arch/arm/mach-omap2/{board-sdp-flash.c => board-flash.c} (68%) rename arch/arm/mach-omap2/include/mach/{board-sdp.h => board-flash.h} (71%) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index f5b4ff4..7820b6e 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -119,7 +119,7 @@ obj-$(CONFIG_MACH_OMAP3_PANDORA)+= board-omap3pandora.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP_3430SDP)+= board-3430sdp.o \ hsmmc.o \ - board-sdp-flash.o + board-flash.o obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ board-rx51-sdram.o \ diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index e51f8e3..61b5632 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -41,7 +41,7 @@ #include #include -#include +#include #include "mux.h" #include "sdram-qimonda-hyb18m512160af-6.h" @@ -667,6 +667,18 @@ static struct omap_board_mux board_mux[] __initdata = { #define board_mux NULL #endif +/* + * SDP3430 V2 Board CS organization + * Different from SDP3430 V1. Now 4 switches used to specify CS + * + * See also the Switch S8 settings in the comments. + */ +static char chip_sel_3430[][GPMC_CS_NUM] = { + {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8: */ + {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */ + {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */ +}; + static struct mtd_partition sdp_nor_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { @@ -797,7 +809,7 @@ static void __init omap_3430sdp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_smc91x_init(); - sdp_flash_init(sdp_flash_partitions); + board_flash_init(sdp_flash_partitions, chip_sel_3430); sdp3430_display_init(); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); diff --git a/arch/arm/mach-omap2/board-sdp-flash.c b/arch/arm/mach-omap2/board-flash.c similarity index 68% rename from arch/arm/mach-omap2/board-sdp-flash.c rename to arch/arm/mach-omap2/board-flash.c index 2638c83..ac834aa 100644 --- a/arch/arm/mach-omap2/board-sdp-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #define REG_FPGA_REV 0x10 #define REG_FPGA_DIP_SWITCH_INPUT2 0x60 @@ -29,72 +29,53 @@ #define DEBUG_BASE 0x0800 /* debug board */ -#define PDC_NOR1 -#define PDC_NAND 2 -#define PDC_ONENAND3 -#define DBG_MPDB 4 - /* various memory sizes */ #define FLASH_SIZE_SDPV1 SZ_64M /* NOR flash (64 Meg aligned) */ #define FLASH_SIZE_SDPV2 SZ_128M /* NOR flash (256 Meg aligned) */ -/* - * SDP3430 V2 Board CS organization - * Different from SDP3430 V1. Now 4 switches used to specify CS - * - * See also the Switch S8 settings in the comments. - * - * REVISIT: Add support for 2430 SDP - */ -static const unsigned char chip_sel_sdp[][GPMC_CS_NUM] = { - {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8: */ - {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */ - {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */ -}; - -static struct physmap_flash_data sdp_nor_data = { +static struct physmap_flash_data board_nor_data = { .width = 2, }; -static struct resource sdp_nor_resource = { +static struct resource board_nor_resource = { .flags = IORESOURCE_MEM, }; -static struct platform_device sdp_nor_device = { +static struct platform_device board_nor_device = { .name = "physmap-flash", .id = 0, .dev= { - .platform_data = &sdp_nor_data, + .platform_data = &board_nor_data, }, .num_resources = 1, - .resource = &sdp_nor_resource, + .resource = &board_nor_resource, }; static void -__init board_nor_init(struct flash_partitions sdp_nor_parts, u8 cs) +__init
[PATCH v4 4/5] omap-3630-sdp : Add support for Flash
add support for NAND, OneNAND, NOR on omap 3630-sdp board. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/Makefile|1 + arch/arm/mach-omap2/board-3630sdp.c | 120 +++ 2 files changed, 121 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index cbd3458..b55a5d7 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -138,6 +138,7 @@ obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom3.o \ board-zoom-debugboard.o obj-$(CONFIG_MACH_OMAP_3630SDP)+= board-3630sdp.o \ board-zoom-peripherals.o \ + board-flash.o \ hsmmc.o obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \ hsmmc.o diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 8b7c2f9..69cb52b 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -21,6 +21,7 @@ #include #include +#include #include "mux.h" #include "sdram-hynix-h8mbx00u0mer-0em.h" @@ -86,12 +87,131 @@ static struct omap_board_mux board_mux[] __initdata = { #define board_mux NULL #endif +/* + * SDP3630 CS organization + * See also the Switch S8 settings in the comments. + */ +static char chip_sel_sdp[][GPMC_CS_NUM] = { + {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8: */ + {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */ + {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */ +}; + +static struct mtd_partition sdp_nor_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "Bootloader-NOR", + .offset = 0, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "Params-NOR", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "Kernel-NOR", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* file system */ + { + .name = "Filesystem-NOR", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct mtd_partition sdp_onenand_partitions[] = { + { + .name = "X-Loader-OneNAND", + .offset = 0, + .size = 4 * (64 * 2048), + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 2 * (64 * 2048), + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot Environment-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 1 * (64 * 2048), + }, + { + .name = "Kernel-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 16 * (64 * 2048), + }, + { + .name = "File System-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition sdp_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x8 */ + .size = 10 * (64 * 2048), + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "Boot Env-NAND", + + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c */ + .size = 6 * (64 * 2048), + }, + { + .name = &quo
[PATCH v4 3/5] omap3: add support for NAND on zoom3 board
patch adds NAND support to zoom3 board. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/Makefile |1 + arch/arm/mach-omap2/board-zoom3.c | 43 + 2 files changed, 44 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 81c3b08..cbd3458 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -133,6 +133,7 @@ obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \ board-zoom-debugboard.o obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom3.o \ board-zoom-peripherals.o \ + board-flash.o \ hsmmc.o \ board-zoom-debugboard.o obj-$(CONFIG_MACH_OMAP_3630SDP)+= board-3630sdp.o \ diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c index 0c6858b..84f49da 100644 --- a/arch/arm/mach-omap2/board-zoom3.c +++ b/arch/arm/mach-omap2/board-zoom3.c @@ -28,6 +28,47 @@ static struct omap_board_config_kernel zoom_config[] __initdata = { }; +static struct mtd_partition zoom_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), /* 512KB, 0x8 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x8 */ + .size = 10 * (64 * 2048), /* 1.25MB, 0x14 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "Boot Env-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c */ + .size = 2 * (64 * 2048), /* 256KB, 0x4 */ + }, + { + .name = "Kernel-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x020*/ + .size = 240 * (64 * 2048),/* 30M, 0x1E0 */ + }, + { + .name = "system", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x200 */ + .size = 3328 * (64 * 2048), /* 416M, 0x1A00 */ + }, + { + .name = "userdata", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1C00*/ + .size = 256 * (64 * 2048),/* 32M, 0x200 */ + }, + { + .name = "cache", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1E00*/ + .size = 256 * (64 * 2048),/* 32M, 0x200 */ + }, +}; + static void __init omap_zoom_init_irq(void) { omap_board_config = zoom_config; @@ -75,6 +116,8 @@ static void __init omap_zoom_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); zoom_peripherals_init(); + board_nand_init(zoom_nand_partitions, +ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS); zoom_debugboard_init(); omap_mux_init_gpio(64, OMAP_PIN_OUTPUT); -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 5/5] omap3: add support for NAND on LDP board
patch adds NAND support to LDP board. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/Makefile|1 + arch/arm/mach-omap2/board-ldp.c | 35 +++ 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index b55a5d7..fc9133f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -110,6 +110,7 @@ obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \ obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP_LDP)+= board-ldp.o \ + board-flash.o \ hsmmc.o obj-$(CONFIG_MACH_OVERO) += board-overo.o \ hsmmc.o diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 6e3930e..9845995 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -388,6 +389,38 @@ static struct omap_musb_board_data musb_board_data = { .power = 100, }; +static struct mtd_partition ldp_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), /* 512KB, 0x8 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x8 */ + .size = 10 * (64 * 2048), /* 1.25MB, 0x14 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "Boot Env-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c */ + .size = 2 * (64 * 2048), /* 256KB, 0x4 */ + }, + { + .name = "Kernel-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x020*/ + .size = 240 * (64 * 2048),/* 30M, 0x1E0 */ + }, + { + .name = "File System - NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x200 */ + .size = MTDPART_SIZ_FULL, /* 96MB, 0x600 */ + }, + +}; + static void __init omap_ldp_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); @@ -400,6 +433,8 @@ static void __init omap_ldp_init(void) ads7846_dev_init(); omap_serial_init(); usb_musb_init(&musb_board_data); + board_nand_init(ldp_nand_partitions, + ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS); omap2_hsmmc_init(mmc); /* link regulators to MMC adapters */ -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/5] omap3: add support for NAND on zoom2 board
This patch adds NAND support to ZOOM2 board. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/Makefile |1 + arch/arm/mach-omap2/board-zoom2.c | 43 + arch/arm/mach-omap2/include/mach/board-zoom.h |6 +++ 3 files changed, 50 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 7820b6e..81c3b08 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -128,6 +128,7 @@ obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \ board-zoom-peripherals.o \ + board-flash.o \ hsmmc.o \ board-zoom-debugboard.o obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom3.o \ diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c index bbc7826..a0d88bd 100644 --- a/arch/arm/mach-omap2/board-zoom2.c +++ b/arch/arm/mach-omap2/board-zoom2.c @@ -92,10 +92,53 @@ static struct omap_board_mux board_mux[] __initdata = { #define board_mux NULL #endif +static struct mtd_partition zoom_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), /* 512KB, 0x8 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x8 */ + .size = 10 * (64 * 2048), /* 1.25MB, 0x14 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "Boot Env-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c */ + .size = 2 * (64 * 2048), /* 256KB, 0x4 */ + }, + { + .name = "Kernel-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x020*/ + .size = 240 * (64 * 2048),/* 30M, 0x1E0 */ + }, + { + .name = "system", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x200 */ + .size = 3328 * (64 * 2048), /* 416M, 0x1A00 */ + }, + { + .name = "userdata", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1C00*/ + .size = 256 * (64 * 2048),/* 32M, 0x200 */ + }, + { + .name = "cache", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1E00*/ + .size = 256 * (64 * 2048),/* 32M, 0x200 */ + }, +}; + static void __init omap_zoom2_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); zoom_peripherals_init(); + board_nand_init(zoom_nand_partitions, + ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS); zoom_debugboard_init(); } diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h b/arch/arm/mach-omap2/include/mach/board-zoom.h index c93b29e..3af69d2 100644 --- a/arch/arm/mach-omap2/include/mach/board-zoom.h +++ b/arch/arm/mach-omap2/include/mach/board-zoom.h @@ -1,5 +1,11 @@ /* * Defines for zoom boards */ +#include +#include + +#define ZOOM_NAND_CS0 + +extern void __init board_nand_init(struct mtd_partition *, u8 nr_parts, u8 cs); extern int __init zoom_debugboard_init(void); extern void __init zoom_peripherals_init(void); -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/8] nand support on omap3 boards
The following set of patches applies on top of for-next branch. And these are the patches required to enable nand (nor and onenand for sdp only) for different platform. v4: patch rebase on latest code base; depend on http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31950.html v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30735.html patch rebase on latest nand patch and depend on - http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30305.html v2: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg26479.html rework to use full nand in partition table of ZOOM2/3; ZOOM1(LDP)support added. v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg22205.html Sukumar Ghorai (5): omap3 flash: rename board-sdp-flash.c to be use by other boards omap3: add support for NAND on zoom2 board omap3: add support for NAND on zoom3 board omap-3630-sdp : Add support for Flash omap3: add support for NAND on LDP board arch/arm/mach-omap2/Makefile |6 +- arch/arm/mach-omap2/board-3430sdp.c | 16 +++- arch/arm/mach-omap2/board-3630sdp.c | 120 + arch/arm/mach-omap2/board-ldp.c | 35 +++ arch/arm/mach-omap2/board-sdp-flash.c | 88 --- arch/arm/mach-omap2/board-zoom2.c | 43 + arch/arm/mach-omap2/board-zoom3.c | 43 + arch/arm/mach-omap2/include/mach/board-sdp.h |9 ++- arch/arm/mach-omap2/include/mach/board-zoom.h |6 ++ 9 files changed, 311 insertions(+), 55 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 2/3] omap3 nand: cleanup virtual address usages
This patch removes direct reference of gpmc address from generic nand platform code. Nand platform code now uses wrapper functions which are implemented in gpmc module. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc-nand.c| 38 ++ arch/arm/mach-omap2/gpmc.c |9 -- arch/arm/plat-omap/include/plat/gpmc.h |5 - arch/arm/plat-omap/include/plat/nand.h |6 +- drivers/mtd/nand/omap2.c | 214 5 files changed, 65 insertions(+), 207 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index e57fb29..53bacb5 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -19,8 +19,6 @@ #include #include -#define WR_RD_PIN_MONITORING 0x0060 - static struct omap_nand_platform_data *gpmc_nand_data; static struct resource gpmc_nand_resource = { @@ -71,10 +69,10 @@ static int omap2_nand_gpmc_retime(void) t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->wr_cycle); /* Configure GPMC */ - gpmc_cs_write_reg(gpmc_nand_data->cs, GPMC_CS_CONFIG1, - GPMC_CONFIG1_DEVICESIZE(gpmc_nand_data->devsize) | - GPMC_CONFIG1_DEVICETYPE_NAND); - + gpmc_cs_configure(gpmc_nand_data->cs, + GPMC_CONFIG_DEV_SIZE, gpmc_nand_data->devsize); + gpmc_cs_configure(gpmc_nand_data->cs, + GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND); err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t); if (err) return err; @@ -82,27 +80,13 @@ static int omap2_nand_gpmc_retime(void) return 0; } -static int gpmc_nand_setup(void) -{ - struct device *dev = &gpmc_nand_device.dev; - - /* Set timings in GPMC */ - if (omap2_nand_gpmc_retime() < 0) { - dev_err(dev, "Unable to set gpmc timings\n"); - return -EINVAL; - } - - return 0; -} - int __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data) { - unsigned int val; int err = 0; struct device *dev = &gpmc_nand_device.dev; gpmc_nand_data = _nand_data; - gpmc_nand_data->nand_setup = gpmc_nand_setup; + gpmc_nand_data->nand_setup = omap2_nand_gpmc_retime; gpmc_nand_device.dev.platform_data = gpmc_nand_data; err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE, @@ -112,19 +96,16 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data) return err; } - err = gpmc_nand_setup(); +/* Set timings in GPMC */ + err = omap2_nand_gpmc_retime(); if (err < 0) { - dev_err(dev, "NAND platform setup failed: %d\n", err); + dev_err(dev, "Unable to set gpmc timings: %d\n", err); return err; } /* Enable RD PIN Monitoring Reg */ if (gpmc_nand_data->dev_ready) { - val = gpmc_cs_read_reg(gpmc_nand_data->cs, -GPMC_CS_CONFIG1); - val |= WR_RD_PIN_MONITORING; - gpmc_cs_write_reg(gpmc_nand_data->cs, - GPMC_CS_CONFIG1, val); + gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1); } err = platform_device_register(&gpmc_nand_device); @@ -140,3 +121,4 @@ out_free_cs: return err; } + diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index d50cf01..ff6709c 100755 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -641,15 +641,6 @@ int gpmc_prefetch_reset(int cs) } 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; diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 561c64f..9fd99b9 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -25,9 +25,6 @@ #define GPMC_CS_NAND_ADDRESS 0x20 #define GPMC_CS_NAND_DATA 0x24 -#define GPMC_CONFIG0x50 -#define GPMC_STATUS0x54 - /* Control Commands */ #define GPMC_CONFIG_RDY_BSY0x0001 #define GPMC_CONFIG_DEV_SIZE 0x0002 @@ -66,7 +63,6 @@ #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) #define GPMC_CONFIG1_DEVICETYPE(val)((val & 3) << 10) #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) -#define GPMC_CONFIG1_DEVICETYPE_NANDGPMC_CONFIG1_DEVICETYPE(2) #define GPMC_CONFIG1_MUXADDDATA (1 << 9) #define GPMC_CONFIG1_TIME_PARA_GRA
[PATCH v7 1/3] omap3 gpmc: functionality enhancement
few functions added in gpmc module and to be used by other drivers like NAND. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 276 ++-- arch/arm/plat-omap/include/plat/gpmc.h | 39 - drivers/mtd/nand/omap2.c |4 +- 3 files changed, 302 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 5bc3ca0..3fef085 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -46,8 +46,9 @@ #define GPMC_ECC_CONFIG0x1f4 #define GPMC_ECC_CONTROL 0x1f8 #define GPMC_ECC_SIZE_CONFIG 0x1fc +#define GPMC_ECC1_RESULT0x200 -#define GPMC_CS0 0x60 +#define GPMC_CS0_OFFSET0x60 #define GPMC_CS_SIZE 0x30 #define GPMC_MEM_START 0x @@ -92,7 +93,8 @@ struct omap3_gpmc_regs { static struct resource gpmc_mem_root; static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); -static unsignedgpmc_cs_map; +static unsigned int gpmc_cs_map; /* flag for cs which are initialized */ +static int gpmc_ecc_used = -EINVAL;/* cs using ecc engine */ static void __iomem *gpmc_base; @@ -108,11 +110,27 @@ static u32 gpmc_read_reg(int idx) return __raw_readl(gpmc_base + idx); } +static void gpmc_cs_write_byte(int cs, int idx, u8 val) +{ + void __iomem *reg_addr; + + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; + __raw_writeb(val, reg_addr); +} + +static u8 gpmc_cs_read_byte(int cs, int idx) +{ + void __iomem *reg_addr; + + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; + return __raw_readb(reg_addr); +} + void gpmc_cs_write_reg(int cs, int idx, u32 val) { void __iomem *reg_addr; - reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; __raw_writel(val, reg_addr); } @@ -120,7 +138,7 @@ u32 gpmc_cs_read_reg(int cs, int idx) { void __iomem *reg_addr; - reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; return __raw_readl(reg_addr); } @@ -419,8 +437,157 @@ void gpmc_cs_free(int cs) EXPORT_SYMBOL(gpmc_cs_free); /** + * gpmc_read_status - read access request to get the different gpmc status + * @cmd: command type + * @return status + */ +int gpmc_read_status(int cmd) +{ + int status = -EINVAL; + u32 regval = 0; + + switch (cmd) { + case GPMC_GET_IRQ_STATUS: + status = gpmc_read_reg(GPMC_IRQSTATUS); + break; + + case GPMC_PREFETCH_FIFO_CNT: + regval = gpmc_read_reg(GPMC_PREFETCH_STATUS); + status = GPMC_PREFETCH_STATUS_FIFO_CNT(regval); + break; + + case GPMC_PREFETCH_COUNT: + regval = gpmc_read_reg(GPMC_PREFETCH_STATUS); + status = GPMC_PREFETCH_STATUS_COUNT(regval); + break; + + case GPMC_STATUS_BUFFER: + regval = gpmc_read_reg(GPMC_STATUS); + /* 1 : buffer is available to write */ + status = regval & GPMC_STATUS_BUFF_EMPTY; + break; + + default: + printk(KERN_ERR "gpmc_read_status: Not supported\n"); + } + return status; +} +EXPORT_SYMBOL(gpmc_read_status); + +/** + * gpmc_cs_configure - write request to configure gpmc + * @cs: chip select number + * @cmd: command type + * @wval: value to write + * @return status of the operation + */ +int gpmc_cs_configure(int cs, int cmd, int wval) +{ + int err = 0; + u32 regval = 0; + + switch (cmd) { + case GPMC_SET_IRQ_STATUS: + gpmc_write_reg(GPMC_IRQSTATUS, wval); + break; + + case GPMC_CONFIG_WP: + regval = gpmc_read_reg(GPMC_CONFIG); + if (wval) + regval &= ~GPMC_CONFIG_WRITEPROTECT; /* WP is ON */ + else + regval |= GPMC_CONFIG_WRITEPROTECT; /* WP is OFF */ + gpmc_write_reg(GPMC_CONFIG, regval); + break; + + case GPMC_CONFIG_RDY_BSY: + regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + if (wval) + regval |= WR_RD_PIN_MONITORING; + else + regval &= ~WR_RD_PIN_MONITORING; + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); + break; + + case GPMC_CONFIG_DEV_SIZE: + regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + regval |= GPMC_CONFIG1_DEVICESIZE(wval); + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); + break; + + case GPMC_CONFIG_DEV_TYPE: + regval
[PATCH v7 3/3] omap3 nand: fix issue in board file to detect nand
Board file modified for not to provide gpmc phys_base address to nand driver. The gpmc_nand_init funciton is now used to detect the nand and required to adopt _prob function as in nand/omap2.c Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-cm-t35.c | 20 +--- arch/arm/mach-omap2/board-devkit8000.c | 25 + arch/arm/mach-omap2/board-omap3beagle.c| 24 +--- arch/arm/mach-omap2/board-omap3touchbook.c | 25 + arch/arm/mach-omap2/board-overo.c | 24 +--- arch/arm/mach-omap2/board-sdp-flash.c |5 - 6 files changed, 5 insertions(+), 118 deletions(-) diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 79d6b15..9aa2b89 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -61,8 +61,6 @@ #define SB_T35_SMSC911X_GPIO 65 #define NAND_BLOCK_SIZESZ_128K -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS0_BASE_ADDR (OMAP34XX_GPMC_VIRT + GPMC_CS0_BASE) #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) #include @@ -223,28 +221,12 @@ static struct omap_nand_platform_data cm_t35_nand_data = { .nr_parts = ARRAY_SIZE(cm_t35_nand_partitions), .dma_channel= -1, /* disable DMA in OMAP NAND driver */ .cs = 0, - .gpmc_cs_baseaddr = (void __iomem *)GPMC_CS0_BASE_ADDR, - .gpmc_baseaddr = (void __iomem *)OMAP34XX_GPMC_VIRT, }; -static struct resource cm_t35_nand_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device cm_t35_nand_device = { - .name = "omap2-nand", - .id = -1, - .num_resources = 1, - .resource = &cm_t35_nand_resource, - .dev= { - .platform_data = &cm_t35_nand_data, - }, -}; - static void __init cm_t35_init_nand(void) { - if (platform_device_register(&cm_t35_nand_device) < 0) + if (gpmc_nand_init(&cm_t35_nand_data) < 0) pr_err("CM-T35: Unable to register NAND device\n"); } #else diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 4b7103a..a1d8764 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -59,9 +59,6 @@ #include "mux.h" #include "hsmmc.h" -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS_SIZE 0x30 - #define NAND_BLOCK_SIZESZ_128K #define OMAP_DM9000_GPIO_IRQ 25 @@ -105,20 +102,6 @@ static struct omap_nand_platform_data devkit8000_nand_data = { .dma_channel= -1, /* disable DMA in OMAP NAND driver */ }; -static struct resource devkit8000_nand_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device devkit8000_nand_device = { - .name = "omap2-nand", - .id = -1, - .dev= { - .platform_data = &devkit8000_nand_data, - }, - .num_resources = 1, - .resource = &devkit8000_nand_resource, -}; - static struct omap2_hsmmc_info mmc[] = { { .mmc= 1, @@ -591,8 +574,6 @@ static void __init devkit8000_flash_init(void) u8 cs = 0; u8 nandcs = GPMC_CS_NUM + 1; - u32 gpmc_base_add = OMAP34XX_GPMC_VIRT; - /* find out the chip-select on which NAND exists */ while (cs < GPMC_CS_NUM) { u32 ret = 0; @@ -614,13 +595,9 @@ static void __init devkit8000_flash_init(void) if (nandcs < GPMC_CS_NUM) { devkit8000_nand_data.cs = nandcs; - devkit8000_nand_data.gpmc_cs_baseaddr = (void *) - (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE); - devkit8000_nand_data.gpmc_baseaddr = (void *) - (gpmc_base_add); printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); - if (platform_device_register(&devkit8000_nand_device) < 0) + if (gpmc_nand_init(&devkit8000_nand_data) < 0) printk(KERN_ERR "Unable to register NAND device\n"); } } diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 64aa557..66177cb 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -48,9 +48,6 @@ #include "mux.h" #include "hsmmc.h" -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS_SIZE 0x30 - #define NAND_BLOCK_SIZESZ_128K static struct mtd_partition omap3beagle_nand_partitions[] = { @@ -93,20 +90,6 @@ static struct omap_nand_platfor
[PATCH v7 0/3] omap3 nand: cleanup exiting platform related code
The following set of patches applies on top of for-next branch. http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git Patches verified on: omap3430-SDP, omap3630-sdp, zoom3 and beagle board And these are the patches required to address the following input - 1. The NAND driver needs to stop tinkering with the GPMC registers The omap General Purpose Memory Controller (GPMC) registers are omap specific, and not driver specific. Tinkering with these registers can cause issues with the other devices on the GPMC. 2. Passing hardcoded GPMC_CS0_BASE needs to go from the board files Passing hardcoded GPMC virtual addressess is sure way to mess up things. This should all become unnecessary once the NAND drivers stops messing with the GPMC registers directly. Discussion: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg27630.html No code change from previous version. Looping linux-arm-kernel mailing list with new version. Changes in this series - gpmc_hwcontrol() function in gpmc.c, break into various small function. v6: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg31936.html Unused function removed. v5: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30305.html Functions related to ecc and prefetch engine are optimized. v4: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg29458.html Few functionality was missing like - There should be some locking as only one chipselect can use the ECC or prefetch engine at a time. If you have NAND in two chipselects, bad things would happen. v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg28715.html Additionally, it was needed to implement more functions for the platform init code to use. v2: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg28467.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg28164.html Sukumar Ghorai (3): omap3 gpmc: functionality enhancement omap3 nand: cleanup virtual address usages omap3 nand: fix issue in board file to detect nand arch/arm/mach-omap2/board-cm-t35.c | 20 +-- arch/arm/mach-omap2/board-devkit8000.c | 25 +--- arch/arm/mach-omap2/board-omap3beagle.c| 24 +--- arch/arm/mach-omap2/board-omap3touchbook.c | 25 +--- arch/arm/mach-omap2/board-overo.c | 24 +--- arch/arm/mach-omap2/board-sdp-flash.c |5 - arch/arm/mach-omap2/gpmc-nand.c| 38 +--- arch/arm/mach-omap2/gpmc.c | 285 ++-- arch/arm/plat-omap/include/plat/gpmc.h | 42 - arch/arm/plat-omap/include/plat/nand.h |6 +- drivers/mtd/nand/omap2.c | 218 ++ 11 files changed, 371 insertions(+), 341 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 1/3] omap3 gpmc: functionality enhancement
few functions added in gpmc module and to be used by other drivers like NAND. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc.c | 276 ++-- arch/arm/plat-omap/include/plat/gpmc.h | 39 - drivers/mtd/nand/omap2.c |4 +- 3 files changed, 302 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 5bc3ca0..3fef085 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -46,8 +46,9 @@ #define GPMC_ECC_CONFIG0x1f4 #define GPMC_ECC_CONTROL 0x1f8 #define GPMC_ECC_SIZE_CONFIG 0x1fc +#define GPMC_ECC1_RESULT0x200 -#define GPMC_CS0 0x60 +#define GPMC_CS0_OFFSET0x60 #define GPMC_CS_SIZE 0x30 #define GPMC_MEM_START 0x @@ -92,7 +93,8 @@ struct omap3_gpmc_regs { static struct resource gpmc_mem_root; static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); -static unsignedgpmc_cs_map; +static unsigned int gpmc_cs_map; /* flag for cs which are initialized */ +static int gpmc_ecc_used = -EINVAL;/* cs using ecc engine */ static void __iomem *gpmc_base; @@ -108,11 +110,27 @@ static u32 gpmc_read_reg(int idx) return __raw_readl(gpmc_base + idx); } +static void gpmc_cs_write_byte(int cs, int idx, u8 val) +{ + void __iomem *reg_addr; + + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; + __raw_writeb(val, reg_addr); +} + +static u8 gpmc_cs_read_byte(int cs, int idx) +{ + void __iomem *reg_addr; + + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; + return __raw_readb(reg_addr); +} + void gpmc_cs_write_reg(int cs, int idx, u32 val) { void __iomem *reg_addr; - reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; __raw_writel(val, reg_addr); } @@ -120,7 +138,7 @@ u32 gpmc_cs_read_reg(int cs, int idx) { void __iomem *reg_addr; - reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; return __raw_readl(reg_addr); } @@ -419,8 +437,157 @@ void gpmc_cs_free(int cs) EXPORT_SYMBOL(gpmc_cs_free); /** + * gpmc_read_status - read access request to get the different gpmc status + * @cmd: command type + * @return status + */ +int gpmc_read_status(int cmd) +{ + int status = -EINVAL; + u32 regval = 0; + + switch (cmd) { + case GPMC_GET_IRQ_STATUS: + status = gpmc_read_reg(GPMC_IRQSTATUS); + break; + + case GPMC_PREFETCH_FIFO_CNT: + regval = gpmc_read_reg(GPMC_PREFETCH_STATUS); + status = GPMC_PREFETCH_STATUS_FIFO_CNT(regval); + break; + + case GPMC_PREFETCH_COUNT: + regval = gpmc_read_reg(GPMC_PREFETCH_STATUS); + status = GPMC_PREFETCH_STATUS_COUNT(regval); + break; + + case GPMC_STATUS_BUFFER: + regval = gpmc_read_reg(GPMC_STATUS); + /* 1 : buffer is available to write */ + status = regval & GPMC_STATUS_BUFF_EMPTY; + break; + + default: + printk(KERN_ERR "gpmc_read_status: Not supported\n"); + } + return status; +} +EXPORT_SYMBOL(gpmc_read_status); + +/** + * gpmc_cs_configure - write request to configure gpmc + * @cs: chip select number + * @cmd: command type + * @wval: value to write + * @return status of the operation + */ +int gpmc_cs_configure(int cs, int cmd, int wval) +{ + int err = 0; + u32 regval = 0; + + switch (cmd) { + case GPMC_SET_IRQ_STATUS: + gpmc_write_reg(GPMC_IRQSTATUS, wval); + break; + + case GPMC_CONFIG_WP: + regval = gpmc_read_reg(GPMC_CONFIG); + if (wval) + regval &= ~GPMC_CONFIG_WRITEPROTECT; /* WP is ON */ + else + regval |= GPMC_CONFIG_WRITEPROTECT; /* WP is OFF */ + gpmc_write_reg(GPMC_CONFIG, regval); + break; + + case GPMC_CONFIG_RDY_BSY: + regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + if (wval) + regval |= WR_RD_PIN_MONITORING; + else + regval &= ~WR_RD_PIN_MONITORING; + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); + break; + + case GPMC_CONFIG_DEV_SIZE: + regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + regval |= GPMC_CONFIG1_DEVICESIZE(wval); + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); + break; + + case GPMC_CONFIG_DEV_TYPE: + regval
[PATCH v6 2/3] omap3 nand: cleanup virtual address usages
This patch removes direct reference of gpmc address from generic nand platform code. Nand platform code now uses wrapper functions which are implemented in gpmc module. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/gpmc-nand.c| 38 ++ arch/arm/mach-omap2/gpmc.c |9 -- arch/arm/plat-omap/include/plat/gpmc.h |5 - arch/arm/plat-omap/include/plat/nand.h |6 +- drivers/mtd/nand/omap2.c | 214 5 files changed, 65 insertions(+), 207 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index e57fb29..53bacb5 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -19,8 +19,6 @@ #include #include -#define WR_RD_PIN_MONITORING 0x0060 - static struct omap_nand_platform_data *gpmc_nand_data; static struct resource gpmc_nand_resource = { @@ -71,10 +69,10 @@ static int omap2_nand_gpmc_retime(void) t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->wr_cycle); /* Configure GPMC */ - gpmc_cs_write_reg(gpmc_nand_data->cs, GPMC_CS_CONFIG1, - GPMC_CONFIG1_DEVICESIZE(gpmc_nand_data->devsize) | - GPMC_CONFIG1_DEVICETYPE_NAND); - + gpmc_cs_configure(gpmc_nand_data->cs, + GPMC_CONFIG_DEV_SIZE, gpmc_nand_data->devsize); + gpmc_cs_configure(gpmc_nand_data->cs, + GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND); err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t); if (err) return err; @@ -82,27 +80,13 @@ static int omap2_nand_gpmc_retime(void) return 0; } -static int gpmc_nand_setup(void) -{ - struct device *dev = &gpmc_nand_device.dev; - - /* Set timings in GPMC */ - if (omap2_nand_gpmc_retime() < 0) { - dev_err(dev, "Unable to set gpmc timings\n"); - return -EINVAL; - } - - return 0; -} - int __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data) { - unsigned int val; int err = 0; struct device *dev = &gpmc_nand_device.dev; gpmc_nand_data = _nand_data; - gpmc_nand_data->nand_setup = gpmc_nand_setup; + gpmc_nand_data->nand_setup = omap2_nand_gpmc_retime; gpmc_nand_device.dev.platform_data = gpmc_nand_data; err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE, @@ -112,19 +96,16 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data) return err; } - err = gpmc_nand_setup(); +/* Set timings in GPMC */ + err = omap2_nand_gpmc_retime(); if (err < 0) { - dev_err(dev, "NAND platform setup failed: %d\n", err); + dev_err(dev, "Unable to set gpmc timings: %d\n", err); return err; } /* Enable RD PIN Monitoring Reg */ if (gpmc_nand_data->dev_ready) { - val = gpmc_cs_read_reg(gpmc_nand_data->cs, -GPMC_CS_CONFIG1); - val |= WR_RD_PIN_MONITORING; - gpmc_cs_write_reg(gpmc_nand_data->cs, - GPMC_CS_CONFIG1, val); + gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1); } err = platform_device_register(&gpmc_nand_device); @@ -140,3 +121,4 @@ out_free_cs: return err; } + diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index d50cf01..ff6709c 100755 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -641,15 +641,6 @@ int gpmc_prefetch_reset(int cs) } 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; diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 561c64f..9fd99b9 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -25,9 +25,6 @@ #define GPMC_CS_NAND_ADDRESS 0x20 #define GPMC_CS_NAND_DATA 0x24 -#define GPMC_CONFIG0x50 -#define GPMC_STATUS0x54 - /* Control Commands */ #define GPMC_CONFIG_RDY_BSY0x0001 #define GPMC_CONFIG_DEV_SIZE 0x0002 @@ -66,7 +63,6 @@ #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) #define GPMC_CONFIG1_DEVICETYPE(val)((val & 3) << 10) #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) -#define GPMC_CONFIG1_DEVICETYPE_NANDGPMC_CONFIG1_DEVICETYPE(2) #define GPMC_CONFIG1_MUXADDDATA (1 << 9) #define GPMC_CONFIG1_TIME_PARA_GRA
[PATCH v6 3/3] omap3 nand: fix issue in board file to detect nand
Board file modified for not to provide gpmc phys_base address to nand driver. The gpmc_nand_init funciton is now used to detect the nand and required to adopt _prob function as in nand/omap2.c Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-cm-t35.c | 20 +--- arch/arm/mach-omap2/board-devkit8000.c | 25 + arch/arm/mach-omap2/board-omap3beagle.c| 24 +--- arch/arm/mach-omap2/board-omap3touchbook.c | 25 + arch/arm/mach-omap2/board-overo.c | 24 +--- arch/arm/mach-omap2/board-sdp-flash.c |5 - 6 files changed, 5 insertions(+), 118 deletions(-) diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 79d6b15..9aa2b89 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -61,8 +61,6 @@ #define SB_T35_SMSC911X_GPIO 65 #define NAND_BLOCK_SIZESZ_128K -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS0_BASE_ADDR (OMAP34XX_GPMC_VIRT + GPMC_CS0_BASE) #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) #include @@ -223,28 +221,12 @@ static struct omap_nand_platform_data cm_t35_nand_data = { .nr_parts = ARRAY_SIZE(cm_t35_nand_partitions), .dma_channel= -1, /* disable DMA in OMAP NAND driver */ .cs = 0, - .gpmc_cs_baseaddr = (void __iomem *)GPMC_CS0_BASE_ADDR, - .gpmc_baseaddr = (void __iomem *)OMAP34XX_GPMC_VIRT, }; -static struct resource cm_t35_nand_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device cm_t35_nand_device = { - .name = "omap2-nand", - .id = -1, - .num_resources = 1, - .resource = &cm_t35_nand_resource, - .dev= { - .platform_data = &cm_t35_nand_data, - }, -}; - static void __init cm_t35_init_nand(void) { - if (platform_device_register(&cm_t35_nand_device) < 0) + if (gpmc_nand_init(&cm_t35_nand_data) < 0) pr_err("CM-T35: Unable to register NAND device\n"); } #else diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 4b7103a..a1d8764 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -59,9 +59,6 @@ #include "mux.h" #include "hsmmc.h" -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS_SIZE 0x30 - #define NAND_BLOCK_SIZESZ_128K #define OMAP_DM9000_GPIO_IRQ 25 @@ -105,20 +102,6 @@ static struct omap_nand_platform_data devkit8000_nand_data = { .dma_channel= -1, /* disable DMA in OMAP NAND driver */ }; -static struct resource devkit8000_nand_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device devkit8000_nand_device = { - .name = "omap2-nand", - .id = -1, - .dev= { - .platform_data = &devkit8000_nand_data, - }, - .num_resources = 1, - .resource = &devkit8000_nand_resource, -}; - static struct omap2_hsmmc_info mmc[] = { { .mmc= 1, @@ -591,8 +574,6 @@ static void __init devkit8000_flash_init(void) u8 cs = 0; u8 nandcs = GPMC_CS_NUM + 1; - u32 gpmc_base_add = OMAP34XX_GPMC_VIRT; - /* find out the chip-select on which NAND exists */ while (cs < GPMC_CS_NUM) { u32 ret = 0; @@ -614,13 +595,9 @@ static void __init devkit8000_flash_init(void) if (nandcs < GPMC_CS_NUM) { devkit8000_nand_data.cs = nandcs; - devkit8000_nand_data.gpmc_cs_baseaddr = (void *) - (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE); - devkit8000_nand_data.gpmc_baseaddr = (void *) - (gpmc_base_add); printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); - if (platform_device_register(&devkit8000_nand_device) < 0) + if (gpmc_nand_init(&devkit8000_nand_data) < 0) printk(KERN_ERR "Unable to register NAND device\n"); } } diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 64aa557..66177cb 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -48,9 +48,6 @@ #include "mux.h" #include "hsmmc.h" -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS_SIZE 0x30 - #define NAND_BLOCK_SIZESZ_128K static struct mtd_partition omap3beagle_nand_partitions[] = { @@ -93,20 +90,6 @@ static struct omap_nand_platfor
[PATCH v6 0/3] omap3 nand: cleanup exiting platform related code
The following set of patches applies on top of for-next branch. http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git Patches verified on: omap3430-SDP, omap3630-sdp, zoom3 and beagle board And these are the patches required to address the following input - 1. The NAND driver needs to stop tinkering with the GPMC registers The omap General Purpose Memory Controller (GPMC) registers are omap specific, and not driver specific. Tinkering with these registers can cause issues with the other devices on the GPMC. 2. Passing hardcoded GPMC_CS0_BASE needs to go from the board files Passing hardcoded GPMC virtual addressess is sure way to mess up things. This should all become unnecessary once the NAND drivers stops messing with the GPMC registers directly. Discussion: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg27630.html Changes in this series - gpmc_hwcontrol() function in gpmc.c, break into various small function. Unused function removed. v5: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30305.html Functions related to ecc and prefetch engine are optimized. v4: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg29458.html Few functionality was missing like - There should be some locking as only one chipselect can use the ECC or prefetch engine at a time. If you have NAND in two chipselects, bad things would happen. v3: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg28715.html Additionally, it was needed to implement more functions for the platform init code to use. v2: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg28467.html v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg28164.html Sukumar Ghorai (3): omap3 gpmc: functionality enhancement omap3 nand: cleanup virtual address usages omap3 nand: fix issue in board file to detect nand arch/arm/mach-omap2/board-cm-t35.c | 20 +-- arch/arm/mach-omap2/board-devkit8000.c | 25 +--- arch/arm/mach-omap2/board-omap3beagle.c| 24 +--- arch/arm/mach-omap2/board-omap3touchbook.c | 25 +--- arch/arm/mach-omap2/board-overo.c | 24 +--- arch/arm/mach-omap2/board-sdp-flash.c |5 - arch/arm/mach-omap2/gpmc-nand.c| 38 +--- arch/arm/mach-omap2/gpmc.c | 285 ++-- arch/arm/plat-omap/include/plat/gpmc.h | 42 - arch/arm/plat-omap/include/plat/nand.h |6 +- drivers/mtd/nand/omap2.c | 218 ++ 11 files changed, 371 insertions(+), 341 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/4] omap: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit device) to support hw ecc in romcode layout. So as to have in sync with ecc layout throughout; i.e. x-laod, u-boot and kernel. This patch also enables to use romcode ecc for spd and zoom, by default. This enables to flash x-load, u-boot, kernel, FS images from kernel itself and compatiable with other tools. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/board-flash.c |2 +- drivers/mtd/nand/omap2.c | 34 ++ 2 files changed, 35 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index ab31e7f..a15aab6 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -144,7 +144,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) board_nand_data.cs = cs; board_nand_data.parts = nand_parts; board_nand_data.nr_parts= nr_parts; - board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_HW; gpmc_nand_init(&board_nand_data); } diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index d696026..4b777f0 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -128,6 +128,20 @@ const int use_dma; const int use_interrupt; #endif +/* oob info generated runtime depending on ecc algorithm and layout selected */ +static struct nand_ecclayout omap_oobinfo; +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks + */ +static uint8_t scan_ff_pattern[] = { 0xff }; +static struct nand_bbt_descr bb_descrip_flashbased = { + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + + struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -959,6 +973,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; + int i, offset; pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -1093,6 +1108,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } } + /* rom code layout */ + if (pdata->ecc_opt != OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) { + offset = (info->nand.options & NAND_BUSWIDTH_16) ? 2 : 1; + if (info->mtd.oobsize == 16) { + info->nand.badblock_pattern = &bb_descrip_flashbased; + omap_oobinfo.eccbytes = 3; + } else + omap_oobinfo.eccbytes = 3 * 4; + + for (i = 0; i < omap_oobinfo.eccbytes; i++) + omap_oobinfo.eccpos[i] = i+offset; + + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; + omap_oobinfo.oobfree->length = info->mtd.oobsize - + (offset + omap_oobinfo.eccbytes); + + info->nand.ecc.layout = &omap_oobinfo; + } + #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/4] omap3: nand: prefetch in irq mode support
This patch enable prefetch-irq mode for NAND. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/board-flash.c |1 + arch/arm/mach-omap2/gpmc.c |7 + arch/arm/mach-omap2/include/mach/board-flash.h |3 + arch/arm/plat-omap/include/plat/gpmc.h |3 + arch/arm/plat-omap/include/plat/nand.h |1 + drivers/mtd/nand/Kconfig | 14 ++- drivers/mtd/nand/omap2.c | 199 +++- 7 files changed, 222 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index ac834aa..c6a07dd 100755 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -133,6 +133,7 @@ static struct omap_nand_platform_data board_nand_data = { .nand_setup = NULL, .gpmc_t = &nand_timings, .dma_channel= -1, /* disable DMA in OMAP NAND driver */ + .gpmc_irq = GPMC_IRQ_NUMBER, .dev_ready = NULL, .devsize= 0,/* '0' for 8-bit, '1' for 16-bit device */ }; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index b8077c6..4e12a9f 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -465,6 +465,13 @@ int gpmc_hwcontrol(int cs, int cmd, int write, int wval, int *rval) *rval = gpmc_read_reg(GPMC_IRQSTATUS); break; + case GPMC_ENABLE_IRQ: + if (write) + gpmc_write_reg(GPMC_IRQENABLE, wval); + else + *rval = gpmc_read_reg(GPMC_IRQENABLE); + break; + case GPMC_PREFETCH_FIFO_CNT: regval = gpmc_read_reg(GPMC_PREFETCH_STATUS); *rval = GPMC_PREFETCH_STATUS_FIFO_CNT(regval); diff --git a/arch/arm/mach-omap2/include/mach/board-flash.h b/arch/arm/mach-omap2/include/mach/board-flash.h index b2242ae..37567a7 100644 --- a/arch/arm/mach-omap2/include/mach/board-flash.h +++ b/arch/arm/mach-omap2/include/mach/board-flash.h @@ -19,6 +19,9 @@ #define PDC_ONENAND3 #define DBG_MPDB 4 +/* Interrupt number to the MPU Subsystem for GPMC */ +#define GPMC_IRQ_NUMBER20 + struct flash_partitions { struct mtd_partition *parts; int nr_parts; diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index ccbc530..4bdd851 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -37,6 +37,7 @@ #define GPMC_PREFETCH_FIFO_CNT 0x0009 /* bytes available in FIFO for r/w */ #define GPMC_PREFETCH_COUNT0x000A /* remaining bytes to be read/write*/ #define GPMC_GET_SET_IRQ_STATUS0x000B +#define GPMC_ENABLE_IRQ0x000C /* ECC commands */ #define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ @@ -75,6 +76,8 @@ #define WR_RD_PIN_MONITORING 0x0060 #define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) #define GPMC_PREFETCH_STATUS_COUNT(val)(val & 0x3fff) +#define GPMC_IRQ_FIFOEVENTENABLE 0x01 +#define GPMC_IRQ_COUNT_EVENT 0x02 /* * Note that all values in this struct are in nanoseconds, while diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd0..5e69463 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -20,6 +20,7 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; unsigned long phys_base; int devsize; }; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 98a04b3..d0e934b 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -111,6 +111,9 @@ config MTD_NAND_OMAP_PREFETCH help The NAND device can be accessed for Read/Write using GPMC PREFETCH engine to improve the performance. +GPMC PREFETCH can be configured eigther in MPU interrupt mode or in DMA +interrupt mode. If not selected any of them prefetch will be used in +polling mode. config MTD_NAND_OMAP_PREFETCH_DMA depends on MTD_NAND_OMAP_PREFETCH @@ -119,7 +122,16 @@ config MTD_NAND_OMAP_PREFETCH_DMA help The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode or in DMA interrupt mode. -Say y for DMA mode or MPU mode will be used +Say y for DMA mode + +config MTD_NAND_OMAP_PREFETCH_IRQ + depends on MTD_NAND_OMAP_PREFETCH && !MTD_NAND_OMAP_PREFETCH_DMA + bool "IRQ mode" + default
[PATCH v2 2/4] omap3: nand: configurable fifo threshold to gain the throughput
Configure the FIFO THREASHOLD value different for read and write to keep busy both filling and to drain out of FIFO at reading and writing. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/gpmc.c | 11 +++ arch/arm/plat-omap/include/plat/gpmc.h |5 - drivers/mtd/nand/omap2.c | 24 +++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 4e12a9f..cb38cff --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -58,7 +58,6 @@ #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 @@ -538,15 +537,19 @@ EXPORT_SYMBOL(gpmc_hwcontrol); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @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, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + printk(KERN_ERR "PREFETCH Fifo Threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -554,7 +557,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 4bdd851..40ce1db --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -79,6 +79,9 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val)(val << 8) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -129,7 +132,7 @@ 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, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 2fbdd66..f136fb5 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -280,7 +280,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -325,7 +326,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); + ret = gpmc_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -381,10 +383,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; - /* The fifo depth is 64 bytes. We have a sync at each frame and frame -* length is 64 bytes. + /* The fifo depth is 64 bytes max. +* But configure the FIFO-threahold
[PATCH v2 3/4] omap: nand: ecc layout select from board file
This patch makes it possible to select sw or hw (different layout options) ecc scheme supported by omap nand driver. And hw ecc layout selected for sdp and zoom boards, by default. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/board-flash.c |3 ++- arch/arm/plat-omap/include/plat/nand.h |6 ++ drivers/mtd/nand/omap2.c | 29 + 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index c6a07dd..ab31e7f 100755 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -143,7 +143,8 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts= nr_parts; + board_nand_data.nr_parts= nr_parts; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT; gpmc_nand_init(&board_nand_data); } diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 5e69463..2e026e4 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -23,6 +23,12 @@ struct omap_nand_platform_data { int gpmc_irq; unsigned long phys_base; int devsize; + enum { + OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT = 0, + /* 1-bit s/w ecc and layout different from romcode */ + OMAP_ECC_HAMMING_CODE_HW,/* 1-bit ecc, romcode layout */ + OMAP_ECC_HAMMING_CODE_SW,/* 1-bit ecc, romcode layout */ + } ecc_opt; }; /* minimum size for IO mapping */ diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 00f88d6..d696026 100755 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define CONFIG_MTD_NAND_OMAP_HWECC #include #include @@ -670,8 +669,6 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) return 0; } -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - /** * gen_true_ecc - This function will generate true ECC value * @ecc_buf: buffer to store ecc code @@ -891,8 +888,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); } -#endif - /** * omap_wait - wait until the command is done * @mtd: MTD device structure @@ -1073,17 +1068,19 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } info->nand.verify_buf = omap_verify_buf; -#ifdef CONFIG_MTD_NAND_OMAP_HWECC - info->nand.ecc.bytes= 3; - info->nand.ecc.size = 512; - info->nand.ecc.calculate= omap_calculate_ecc; - info->nand.ecc.hwctl= omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - -#else - info->nand.ecc.mode = NAND_ECC_SOFT; -#endif + /* selsect the ecc type */ + if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DIFF_LAYOUT) || + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW)) { + info->nand.ecc.bytes= 3; + info->nand.ecc.size = 512; + info->nand.ecc.calculate= omap_calculate_ecc; + info->nand.ecc.hwctl= omap_enable_hwecc; + info->nand.ecc.correct = omap_correct_data; + info->nand.ecc.mode = NAND_ECC_HW; + + } else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_SW) { + info->nand.ecc.mode = NAND_ECC_SOFT; + } /* DIP switches on some boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/4] nand prefetch-irq support and ecc layout chanage
The following set of patches applies on top of for-next branch. And is dependent on the following patches not yet applied onto this branch. 1. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30305.html 2. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30735.html v2: Rebase on latest codebase and previous patch(posted). v1: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg2.html Sukumar Ghorai (4): omap3: nand: prefetch in irq mode support omap: nand: configurable fifo threshold to gain the throughput omap: nand: ecc layout select from board file omap: nand: making ecc layout as compatible with romcode ecc arch/arm/mach-omap2/board-flash.c |4 +- arch/arm/mach-omap2/gpmc.c | 18 ++- arch/arm/mach-omap2/include/mach/board-flash.h |3 + arch/arm/plat-omap/include/plat/gpmc.h |8 +- arch/arm/plat-omap/include/plat/nand.h |7 + drivers/mtd/nand/Kconfig | 14 +- drivers/mtd/nand/omap2.c | 280 +--- 7 files changed, 300 insertions(+), 34 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/8] omap3: add support for NAND on zoom3 board
patch adds NAND support to zoom3 board. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/Makefile |1 + arch/arm/mach-omap2/board-zoom3.c | 43 + 2 files changed, 44 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index e7159b0..00f4cfd 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -131,6 +131,7 @@ obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \ board-zoom-debugboard.o obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom3.o \ board-zoom-peripherals.o \ + board-flash.o \ hsmmc.o \ board-zoom-debugboard.o obj-$(CONFIG_MACH_OMAP_3630SDP)+= board-3630sdp.o \ diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c index 3314704..692c6c6 100644 --- a/arch/arm/mach-omap2/board-zoom3.c +++ b/arch/arm/mach-omap2/board-zoom3.c @@ -34,6 +34,47 @@ static void __init omap_zoom_map_io(void) static struct omap_board_config_kernel zoom_config[] __initdata = { }; +static struct mtd_partition zoom_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), /* 512KB, 0x8 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x8 */ + .size = 10 * (64 * 2048), /* 1.25MB, 0x14 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "Boot Env-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c */ + .size = 2 * (64 * 2048), /* 256KB, 0x4 */ + }, + { + .name = "Kernel-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x020*/ + .size = 240 * (64 * 2048),/* 30M, 0x1E0 */ + }, + { + .name = "system", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x200 */ + .size = 3328 * (64 * 2048), /* 416M, 0x1A00 */ + }, + { + .name = "userdata", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1C00*/ + .size = 256 * (64 * 2048),/* 32M, 0x200 */ + }, + { + .name = "cache", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1E00*/ + .size = 256 * (64 * 2048),/* 32M, 0x200 */ + }, +}; + static void __init omap_zoom_init_irq(void) { omap_board_config = zoom_config; @@ -66,6 +107,8 @@ static void __init omap_zoom_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); zoom_peripherals_init(); + board_nand_init(zoom_nand_partitions, +ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS); zoom_debugboard_init(); omap_mux_init_gpio(64, OMAP_PIN_OUTPUT); -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/8] omap3: add support for NAND on zoom2 board
This patch adds NAND support to ZOOM2 board. Signed-off-by: Sukumar Ghorai Signed-off-by: Vimal Singh --- arch/arm/mach-omap2/Makefile |1 + arch/arm/mach-omap2/board-zoom2.c | 43 + arch/arm/mach-omap2/include/mach/board-zoom.h |6 +++ 3 files changed, 50 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 0d854f1..e7159b0 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -126,6 +126,7 @@ obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \ board-zoom-peripherals.o \ + board-flash.o \ hsmmc.o \ board-zoom-debugboard.o obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom3.o \ diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c index 803ef14..549f274 100644 --- a/arch/arm/mach-omap2/board-zoom2.c +++ b/arch/arm/mach-omap2/board-zoom2.c @@ -77,10 +77,53 @@ static struct omap_board_mux board_mux[] __initdata = { #define board_mux NULL #endif +static struct mtd_partition zoom_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), /* 512KB, 0x8 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x8 */ + .size = 10 * (64 * 2048), /* 1.25MB, 0x14 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "Boot Env-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c */ + .size = 2 * (64 * 2048), /* 256KB, 0x4 */ + }, + { + .name = "Kernel-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x020*/ + .size = 240 * (64 * 2048),/* 30M, 0x1E0 */ + }, + { + .name = "system", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x200 */ + .size = 3328 * (64 * 2048), /* 416M, 0x1A00 */ + }, + { + .name = "userdata", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1C00*/ + .size = 256 * (64 * 2048),/* 32M, 0x200 */ + }, + { + .name = "cache", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1E00*/ + .size = 256 * (64 * 2048),/* 32M, 0x200 */ + }, +}; + static void __init omap_zoom2_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); zoom_peripherals_init(); + board_nand_init(zoom_nand_partitions, + ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS); zoom_debugboard_init(); } diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h b/arch/arm/mach-omap2/include/mach/board-zoom.h index c93b29e..3af69d2 100644 --- a/arch/arm/mach-omap2/include/mach/board-zoom.h +++ b/arch/arm/mach-omap2/include/mach/board-zoom.h @@ -1,5 +1,11 @@ /* * Defines for zoom boards */ +#include +#include + +#define ZOOM_NAND_CS0 + +extern void __init board_nand_init(struct mtd_partition *, u8 nr_parts, u8 cs); extern int __init zoom_debugboard_init(void); extern void __init zoom_peripherals_init(void); -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/8] omap-3630-sdp : Add support for Flash
add support for NAND, OneNAND, NOR on omap 3630-sdp board. Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/Makefile|1 + arch/arm/mach-omap2/board-3630sdp.c | 120 +++ 2 files changed, 121 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index a795eb6..400f9cf --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -133,6 +133,7 @@ obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom3.o \ board-zoom-debugboard.o obj-$(CONFIG_MACH_OMAP_3630SDP)+= board-3630sdp.o \ board-zoom-peripherals.o \ + board-flash.o \ hsmmc.o obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \ hsmmc.o diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 504d2bd..a3f24cb --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -22,6 +22,7 @@ #include #include +#include #include "mux.h" #include "sdram-hynix-h8mbx00u0mer-0em.h" @@ -93,12 +94,131 @@ static struct omap_board_mux board_mux[] __initdata = { #define board_mux NULL #endif +/* + * SDP3630 CS organization + * See also the Switch S8 settings in the comments. + */ +static char chip_sel_sdp[][GPMC_CS_NUM] = { + {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8: */ + {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */ + {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */ +}; + +static struct mtd_partition sdp_nor_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "Bootloader-NOR", + .offset = 0, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "Params-NOR", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "Kernel-NOR", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* file system */ + { + .name = "Filesystem-NOR", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct mtd_partition sdp_onenand_partitions[] = { + { + .name = "X-Loader-OneNAND", + .offset = 0, + .size = 4 * (64 * 2048), + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 2 * (64 * 2048), + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot Environment-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 1 * (64 * 2048), + }, + { + .name = "Kernel-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 16 * (64 * 2048), + }, + { + .name = "File System-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition sdp_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x8 */ + .size = 10 * (64 * 2048), + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "Boot Env-NAND", + + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c */ + .size = 6 * (64 * 2048), + }, + { + .name = "Kernel-NAND", + .offset
[PATCH v3 6/8] omap-3630-sdp: enable Flash device support
update config file to support for NAND, OneNAND, NOR on omap 3630-sdp board. Signed-off-by: Sukumar Ghorai --- arch/arm/configs/omap_3630sdp_defconfig | 31 ++- 1 files changed, 30 insertions(+), 1 deletions(-) diff --git a/arch/arm/configs/omap_3630sdp_defconfig b/arch/arm/configs/omap_3630sdp_defconfig index 609f348..8c75c19 --- a/arch/arm/configs/omap_3630sdp_defconfig +++ b/arch/arm/configs/omap_3630sdp_defconfig @@ -461,7 +461,29 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_SYS_HYPERVISOR is not set CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y -# CONFIG_MTD is not set +CONFIG_MTD=y +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_OMAP2=y +CONFIG_MTD_NAND_OMAP_PREFETCH=y +CONFIG_MTD_NAND_IDS=y +CONFIG_MTD_ONENAND=y +CONFIG_MTD_ONENAND_OMAP2=y # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set @@ -1310,6 +1332,13 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +CONFIG_JFFS2_CMODE_PRIORITY=y # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set -- 1.5.4.7 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 8/8] zoom3: enable NAND support
update config file to support for NAND on zoom3 board. Signed-off-by: Sukumar Ghorai --- arch/arm/configs/omap_zoom3_defconfig | 24 +++- 1 files changed, 23 insertions(+), 1 deletions(-) arch/arm/configs/omap_zoom3_defconfig diff --git a/arch/arm/configs/omap_zoom3_defconfig b/arch/arm/configs/omap_zoom3_defconfig index 5e55b55..e3e53cd --- a/arch/arm/configs/omap_zoom3_defconfig +++ b/arch/arm/configs/omap_zoom3_defconfig @@ -461,7 +461,22 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_SYS_HYPERVISOR is not set CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y -# CONFIG_MTD is not set +CONFIG_MTD=y +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_OMAP2=y +CONFIG_MTD_NAND_OMAP_PREFETCH=y +CONFIG_MTD_NAND_IDS=y # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set @@ -1311,6 +1326,13 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +CONFIG_JFFS2_CMODE_PRIORITY=y # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set -- 1.5.4.7 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 5/8] omap3: add support for NAND on LDP board
patch adds NAND support to LDP board. Signed-off-by: Vimal Singh Signed-off-by: Sukumar Ghorai --- arch/arm/mach-omap2/Makefile|1 + arch/arm/mach-omap2/board-ldp.c | 35 +++ 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 6c67126..af715fa 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -108,6 +108,7 @@ obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \ obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP_LDP)+= board-ldp.o \ + board-flash.o \ hsmmc.o obj-$(CONFIG_MACH_OVERO) += board-overo.o \ hsmmc.o diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index fefd7e6..778afab 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -388,6 +389,38 @@ static struct omap_musb_board_data musb_board_data = { .power = 100, }; +static struct mtd_partition ldp_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), /* 512KB, 0x8 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x8 */ + .size = 10 * (64 * 2048), /* 1.25MB, 0x14 */ + .mask_flags = MTD_WRITEABLE,/* force read-only */ + }, + { + .name = "Boot Env-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c */ + .size = 2 * (64 * 2048), /* 256KB, 0x4 */ + }, + { + .name = "Kernel-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x020*/ + .size = 240 * (64 * 2048),/* 30M, 0x1E0 */ + }, + { + .name = "File System - NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x200 */ + .size = MTDPART_SIZ_FULL, /* 96MB, 0x600 */ + }, + +}; + static void __init omap_ldp_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); @@ -400,6 +433,8 @@ static void __init omap_ldp_init(void) ads7846_dev_init(); omap_serial_init(); usb_musb_init(&musb_board_data); + board_nand_init(ldp_nand_partitions, + ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS); omap2_hsmmc_init(mmc); /* link regulators to MMC adapters */ -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 7/8] zoom2: enable NAND support
update config file to support for NAND in zoom2. Signed-off-by: Sukumar Ghorai --- arch/arm/configs/omap_zoom2_defconfig | 24 +++- 1 files changed, 23 insertions(+), 1 deletions(-) arch/arm/configs/omap_zoom2_defconfig diff --git a/arch/arm/configs/omap_zoom2_defconfig b/arch/arm/configs/omap_zoom2_defconfig index 881faea..ec58688 --- a/arch/arm/configs/omap_zoom2_defconfig +++ b/arch/arm/configs/omap_zoom2_defconfig @@ -440,7 +440,22 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_SYS_HYPERVISOR is not set CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y -# CONFIG_MTD is not set +CONFIG_MTD=y +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_OMAP2=y +CONFIG_MTD_NAND_OMAP_PREFETCH=y +CONFIG_MTD_NAND_IDS=y # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set @@ -1248,6 +1263,13 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +CONFIG_JFFS2_CMODE_PRIORITY=y # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set -- 1.5.4.7 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html