* [PATCH 1/7] omap3630: nand: fix device size to work in polled mode
2010-11-26 15:34 [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Sukumar Ghorai
@ 2010-11-26 15:34 ` Sukumar Ghorai
2010-12-18 0:03 ` Tony Lindgren
2010-11-26 15:34 ` [PATCH 2/7] omap3: nand: configurable transfer type per board Sukumar Ghorai
` (6 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Sukumar Ghorai @ 2010-11-26 15:34 UTC (permalink / raw)
To: linux-arm-kernel
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 <s-ghorai@ti.com>
---
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
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 1/7] omap3630: nand: fix device size to work in polled mode
2010-11-26 15:34 ` [PATCH 1/7] omap3630: nand: fix device size to work in polled mode Sukumar Ghorai
@ 2010-12-18 0:03 ` Tony Lindgren
2010-12-22 9:24 ` Ghorai, Sukumar
0 siblings, 1 reply; 16+ messages in thread
From: Tony Lindgren @ 2010-12-18 0:03 UTC (permalink / raw)
To: linux-arm-kernel
* Sukumar Ghorai <s-ghorai@ti.com> [101126 07:25]:
> 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 <s-ghorai@ti.com>
> ---
> 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
I guess this is board specific for the size, not omap specific?
Regards,
Tony
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/7] omap3630: nand: fix device size to work in polled mode
2010-12-18 0:03 ` Tony Lindgren
@ 2010-12-22 9:24 ` Ghorai, Sukumar
0 siblings, 0 replies; 16+ messages in thread
From: Ghorai, Sukumar @ 2010-12-22 9:24 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Tony Lindgren [mailto:tony at atomide.com]
> Sent: Saturday, December 18, 2010 5:34 AM
> To: Ghorai, Sukumar
> Cc: linux-omap at vger.kernel.org; linux-mtd at lists.infradead.org; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH 1/7] omap3630: nand: fix device size to work in polled
> mode
>
> * Sukumar Ghorai <s-ghorai@ti.com> [101126 07:25]:
> > 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 <s-ghorai@ti.com>
> > ---
> > 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
>
> I guess this is board specific for the size, not omap specific?
[Ghorai] Agree, the NAND type (i.e. x8 NAND or x16 NAND) is a board specific,
So I will change the definition of board_nand_init() to pass the devsize form board file.
And I will submit the patch-series again.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/7] omap3: nand: configurable transfer type per board
2010-11-26 15:34 [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Sukumar Ghorai
2010-11-26 15:34 ` [PATCH 1/7] omap3630: nand: fix device size to work in polled mode Sukumar Ghorai
@ 2010-11-26 15:34 ` Sukumar Ghorai
2010-12-18 0:08 ` Tony Lindgren
2010-11-26 15:34 ` [PATCH v6 3/7] omap: gpmc: enable irq mode in gpmc Sukumar Ghorai
` (5 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Sukumar Ghorai @ 2010-11-26 15:34 UTC (permalink / raw)
To: linux-arm-kernel
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 <s-ghorai@ti.com>
---
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 <linux/mtd/partitions.h>
+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 int options;
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_io xfer_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,
- OMAP_DMA_DATA_BURST_16);
- omap_set_dma_src_burst_mode(info->dma_ch,
- OMAP_DMA_DATA_BURST_16);
-
- info->nand.read_buf = omap_read_buf_dma_pref;
- info->nand.write_buf = omap_write_buf_dma_pref;
- }
- }
- } else {
+ break;
+
+ case NAND_OMAP_POLLED:
if (info->nand.options & NAND_BUSWIDTH_16) {
info->nand.read_buf = omap_read_buf16;
info->nand.write_buf = omap_write_buf16;
@@ -871,7 +826,33 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
info->nand.read_buf = omap_read_buf8;
info->nand.write_buf = omap_write_buf8;
}
+ break;
+
+ case NAND_OMAP_PREFETCH_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;
+ dev_err(&pdev->dev, "DMA request failed!\n");
+ goto out_release_mem_region;
+ } else {
+ omap_set_dma_dest_burst_mode(info->dma_ch,
+ OMAP_DMA_DATA_BURST_16);
+ omap_set_dma_src_burst_mode(info->dma_ch,
+ OMAP_DMA_DATA_BURST_16);
+
+ info->nand.read_buf = omap_read_buf_dma_pref;
+ info->nand.write_buf = omap_write_buf_dma_pref;
+ }
+ break;
+
+ default:
+ dev_err(&pdev->dev,
+ "xfer_type(%d) not supported!\n", pdata->xfer_type);
+ err = -EINVAL;
+ goto out_release_mem_region;
}
+
info->nand.verify_buf = omap_verify_buf;
#ifdef CONFIG_MTD_NAND_OMAP_HWECC
@@ -897,6 +878,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
}
}
+
#ifdef CONFIG_MTD_PARTITIONS
err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
if (err > 0)
@@ -926,7 +908,7 @@ static int omap_nand_remove(struct platform_device *pdev)
mtd);
platform_set_drvdata(pdev, NULL);
- if (use_dma)
+ if (info->dma_ch != -1)
omap_free_dma(info->dma_ch);
/* Release NAND device, its internal structures and partitions */
@@ -949,14 +931,6 @@ static int __init omap_nand_init(void)
{
printk(KERN_INFO "%s driver initializing\n", DRIVER_NAME);
- /* This check is required if driver is being
- * loaded run time as a module
- */
- if ((1 == use_dma) && (0 == use_prefetch)) {
- printk(KERN_INFO"Wrong parameters: 'use_dma' can not be 1 "
- "without use_prefetch'. Prefetch will not be"
- " used in either mode (mpu or dma)\n");
- }
return platform_driver_register(&omap_nand_driver);
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 2/7] omap3: nand: configurable transfer type per board
2010-11-26 15:34 ` [PATCH 2/7] omap3: nand: configurable transfer type per board Sukumar Ghorai
@ 2010-12-18 0:08 ` Tony Lindgren
2010-12-22 7:52 ` Ghorai, Sukumar
0 siblings, 1 reply; 16+ messages in thread
From: Tony Lindgren @ 2010-12-18 0:08 UTC (permalink / raw)
To: linux-arm-kernel
* Sukumar Ghorai <s-ghorai@ti.com> [101126 07:25]:
> 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 <s-ghorai@ti.com>
> ---
> 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 <linux/mtd/partitions.h>
>
> +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 int options;
> 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_io xfer_type;
> unsigned long phys_base;
> int devsize;
> };
So maybe the devsize in patch 1/7 should be handled with this too?
Regards,
Tony
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH 2/7] omap3: nand: configurable transfer type per board
2010-12-18 0:08 ` Tony Lindgren
@ 2010-12-22 7:52 ` Ghorai, Sukumar
0 siblings, 0 replies; 16+ messages in thread
From: Ghorai, Sukumar @ 2010-12-22 7:52 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Tony Lindgren [mailto:tony at atomide.com]
> Sent: Saturday, December 18, 2010 5:39 AM
> To: Ghorai, Sukumar
> Cc: linux-omap at vger.kernel.org; linux-mtd at lists.infradead.org; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH 2/7] omap3: nand: configurable transfer type per board
>
> * Sukumar Ghorai <s-ghorai@ti.com> [101126 07:25]:
> > 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 <s-ghorai@ti.com>
> > ---
> > 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 <linux/mtd/partitions.h>
> >
> > +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 int options;
> > 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_io xfer_type;
> > unsigned long phys_base;
> > int devsize;
> > };
>
> So maybe the devsize in patch 1/7 should be handled with this too?
[Ghorai] patch 1/7 [1] is to select the NAND type i.e. x8 or x16 NAND;
So I am keeping as separate patch. And let me know if I am missing anything.
[1] https://patchwork.kernel.org/patch/359092/
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 3/7] omap: gpmc: enable irq mode in gpmc
2010-11-26 15:34 [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Sukumar Ghorai
2010-11-26 15:34 ` [PATCH 1/7] omap3630: nand: fix device size to work in polled mode Sukumar Ghorai
2010-11-26 15:34 ` [PATCH 2/7] omap3: nand: configurable transfer type per board Sukumar Ghorai
@ 2010-11-26 15:34 ` Sukumar Ghorai
2010-12-18 0:09 ` Tony Lindgren
2010-11-26 15:34 ` [PATCH v6 4/7] omap3: nand: prefetch in irq mode support Sukumar Ghorai
` (4 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Sukumar Ghorai @ 2010-11-26 15:34 UTC (permalink / raw)
To: linux-arm-kernel
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 <s-ghorai@ti.com>
---
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 <plat/common.h>
#include <plat/usb.h>
#include <plat/mmc.h>
+#include <plat/gpmc.h>
#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 <plat/common.h>
#include <plat/usb.h>
#include <plat/display.h>
+#include <plat/gpmc.h>
#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();
}
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 53ac762..f82d3b7 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -447,6 +447,7 @@ static void __init devkit8000_init_irq(void)
omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_init_irq();
+ gpmc_init();
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(12);
#endif
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index b1c2c9a..0b0d2cb 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -29,6 +29,7 @@
#include <plat/usb.h>
#include <plat/board.h>
#include <plat/common.h>
+#include <plat/gpmc.h>
static struct omap_board_config_kernel generic_config[] = {
};
@@ -39,6 +40,7 @@ static void __init omap_generic_init_irq(void)
omap_board_config_size = ARRAY_SIZE(generic_config);
omap2_init_common_hw(NULL, NULL);
omap_init_irq();
+ gpmc_init();
}
static void __init omap_generic_init(void)
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 929993b..41b04c4 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -293,6 +293,7 @@ static void __init omap_h4_init_irq(void)
omap_board_config_size = ARRAY_SIZE(h4_config);
omap2_init_common_hw(NULL, NULL);
omap_init_irq();
+ gpmc_init();
omap_gpio_init();
h4_init_flash();
}
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 5e035a5..c4de273 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -497,6 +497,7 @@ static void __init igep2_init_irq(void)
omap_board_config_size = ARRAY_SIZE(igep2_config);
omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params);
omap_init_irq();
+ gpmc_init();
omap_gpio_init();
}
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 001fd97..0f66645 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -294,6 +294,7 @@ static void __init omap_ldp_init_irq(void)
omap_board_config_size = ARRAY_SIZE(ldp_config);
omap2_init_common_hw(NULL, NULL);
omap_init_irq();
+ gpmc_init();
omap_gpio_init();
ldp_init_smsc911x();
}
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index e823c70..4f7c714 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -33,6 +33,7 @@
#include <plat/onenand.h>
#include <plat/mmc.h>
#include <plat/serial.h>
+#include <plat/gpmc.h>
#include "mux.h"
@@ -641,6 +642,7 @@ static void __init n8x0_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-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 14f4224..a83c3f3 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -487,6 +487,7 @@ static void __init omap3_beagle_init_irq(void)
omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_init_irq();
+ gpmc_init();
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(12);
#endif
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index b04365c..21cc9e5 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -43,6 +43,7 @@
#include <plat/common.h>
#include <plat/mcspi.h>
#include <plat/display.h>
+#include <plat/gpmc.h>
#include "mux.h"
#include "sdram-micron-mt46h32m32lf-6.h"
@@ -625,6 +626,7 @@ static void __init omap3_evm_init_irq(void)
omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
omap_init_irq();
+ gpmc_init();
omap_gpio_init();
}
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 89ed1be..e095f1d 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -47,6 +47,7 @@
#include <plat/mcspi.h>
#include <plat/usb.h>
#include <plat/display.h>
+#include <plat/gpmc.h>
#include <plat/nand.h>
#include "mux.h"
@@ -639,6 +640,7 @@ static void __init omap3pandora_init_irq(void)
omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_init_irq();
+ gpmc_init();
omap_gpio_init();
}
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index f252721..c07ba77 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -586,6 +586,7 @@ static void __init omap3_stalker_init_irq(void)
omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
omap_init_irq();
+ gpmc_init();
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(12);
#endif
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 41104bb..d549763 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -425,6 +425,7 @@ static void __init omap3_touchbook_init_irq(void)
omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_init_irq();
+ gpmc_init();
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(12);
#endif
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 1ecd0a6..a03a021 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -36,6 +36,7 @@
#include <plat/common.h>
#include <plat/usb.h>
#include <plat/mmc.h>
+#include <plat/gpmc.h>
#include "timer-gp.h"
#include "hsmmc.h"
@@ -78,6 +79,7 @@ static void __init omap4_panda_init_irq(void)
{
omap2_init_common_hw(NULL, NULL);
gic_init_irq();
+ gpmc_init();
omap_gpio_init();
}
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 7053bc0..c5fe2b0 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -416,6 +416,7 @@ static void __init overo_init_irq(void)
omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_init_irq();
+ gpmc_init();
omap_gpio_init();
}
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 36f2cf4..3be8729 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -107,6 +107,7 @@ static void __init rx51_init_irq(void)
omap3_pm_init_cpuidle(rx51_cpuidle_params);
sdrc_params = rx51_get_sdram_timings();
omap2_init_common_hw(sdrc_params, sdrc_params);
+ gpmc_init();
omap_init_irq();
omap_gpio_init();
}
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 2992a9f..ab0a05d 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -21,6 +21,7 @@
#include <plat/common.h>
#include <plat/board.h>
+#include <plat/gpmc.h>
#include <mach/board-zoom.h>
@@ -33,6 +34,7 @@ static void __init omap_zoom2_init_irq(void)
omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_init_irq();
+ gpmc_init();
omap_gpio_init();
}
diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
index 5adde12..d637d98 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -21,6 +21,7 @@
#include <plat/common.h>
#include <plat/board.h>
#include <plat/usb.h>
+#include <plat/gpmc.h>
#include "board-flash.h"
#include "mux.h"
@@ -77,6 +78,7 @@ static void __init omap_zoom_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/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index f46933b..cfaf357 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -14,6 +14,7 @@
*/
#undef DEBUG
+#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
@@ -22,12 +23,12 @@
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <plat/gpmc.h>
#include <plat/sdrc.h>
-
/* GPMC register offsets */
#define GPMC_REVISION 0x00
#define GPMC_SYSCONFIG 0x10
@@ -100,6 +101,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);
@@ -487,6 +490,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;
@@ -670,7 +677,8 @@ static void __init gpmc_mem_init(void)
void __init gpmc_init(void)
{
- u32 l;
+ u32 l, irq;
+ int cs;
char *ck = NULL;
if (cpu_is_omap24xx()) {
@@ -713,6 +721,33 @@ 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++;
+ }
+
+ if (request_irq(INT_34XX_GPMC_IRQ,
+ gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base))
+ printk(KERN_ERR "gpmc: irq-%d could not claim: err %d\n",
+ INT_34XX_GPMC_IRQ, irq);
+}
+
+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 40562dd..4d11621 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -30,7 +30,6 @@
#include <plat/sram.h>
#include <plat/sdrc.h>
-#include <plat/gpmc.h>
#include <plat/serial.h>
#include "clock2xxx.h"
@@ -351,5 +350,4 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
_omap2_init_reprogram_sdrc();
}
- gpmc_init();
}
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 0x0000000b
#define GPMC_NAND_DATA 0x0000000c
+#define GPMC_ENABLE_IRQ 0x0000000d
+
/* 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 0x00600000
#define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F)
#define GPMC_PREFETCH_STATUS_COUNT(val) (val & 0x00003fff)
+#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 65e20a6..b90b9ef 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_IRQ 16
#define INT_34XX_MCBSP2_IRQ 17
+#define INT_34XX_GPMC_IRQ 20
#define INT_34XX_MCBSP3_IRQ 22
#define INT_34XX_MCBSP4_IRQ 23
#define INT_34XX_CAM_IRQ 24
@@ -411,7 +412,13 @@
#define TWL_IRQ_END TWL6030_IRQ_END
#endif
-#define NR_IRQS TWL_IRQ_END
+/* GPMC related */
+#define OMAP_GPMC_IRQ_BASE (TWL_IRQ_END)
+#define OMAP_GPMC_NR_IRQS 7
+#define OMAP_GPMC_IRQ_END (OMAP_GPMC_IRQ_BASE + OMAP_GPMC_NR_IRQS)
+
+
+#define NR_IRQS OMAP_GPMC_IRQ_END
#define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32))
--
1.7.0.4
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v6 3/7] omap: gpmc: enable irq mode in gpmc
2010-11-26 15:34 ` [PATCH v6 3/7] omap: gpmc: enable irq mode in gpmc Sukumar Ghorai
@ 2010-12-18 0:09 ` Tony Lindgren
2010-12-22 8:00 ` Ghorai, Sukumar
0 siblings, 1 reply; 16+ messages in thread
From: Tony Lindgren @ 2010-12-18 0:09 UTC (permalink / raw)
To: linux-arm-kernel
* Sukumar Ghorai <s-ghorai@ti.com> [101126 07:25]:
> 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 <s-ghorai@ti.com>
> ---
> 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();
> }
...
The gpmc init should be done with subsys_initcall instead.
Tony
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 3/7] omap: gpmc: enable irq mode in gpmc
2010-12-18 0:09 ` Tony Lindgren
@ 2010-12-22 8:00 ` Ghorai, Sukumar
0 siblings, 0 replies; 16+ messages in thread
From: Ghorai, Sukumar @ 2010-12-22 8:00 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Tony Lindgren [mailto:tony at atomide.com]
> Sent: Saturday, December 18, 2010 5:40 AM
> To: Ghorai, Sukumar
> Cc: linux-omap at vger.kernel.org; linux-mtd at lists.infradead.org; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v6 3/7] omap: gpmc: enable irq mode in gpmc
>
> * Sukumar Ghorai <s-ghorai@ti.com> [101126 07:25]:
> > 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 <s-ghorai@ti.com>
> > ---
> > 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();
> > }
> ...
>
> The gpmc init should be done with subsys_initcall instead.
[Ghorai] You suggested the same in previous v5; and I mentioned
the issues [1] that - nand_init()called before subsys_initcall(gpmc_init);
Let me know if I am missing anything again.
[1] https://patchwork.kernel.org/patch/212452/
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 4/7] omap3: nand: prefetch in irq mode support
2010-11-26 15:34 [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Sukumar Ghorai
` (2 preceding siblings ...)
2010-11-26 15:34 ` [PATCH v6 3/7] omap: gpmc: enable irq mode in gpmc Sukumar Ghorai
@ 2010-11-26 15:34 ` Sukumar Ghorai
2010-11-26 15:34 ` [PATCH v6 5/7] omap3: nand: configurable fifo threshold to gain the throughput Sukumar Ghorai
` (3 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Sukumar Ghorai @ 2010-11-26 15:34 UTC (permalink / raw)
To: linux-arm-kernel
This patch enable prefetch-irq mode for nand transfer(read, write)
Signed-off-by: Vimal Singh <vimalsingh@ti.com>
Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com>
---
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 <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/io.h>
+#include <plat/irqs.h>
+#include <plat/irqs.h>
#include <plat/gpmc.h>
#include <plat/nand.h>
#include <plat/onenand.h>
@@ -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_io xfer_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 <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
+#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/sched.h>
#include <linux/mtd/mtd.h>
@@ -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_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
+{
+ struct omap_nand_info *info = container_of(mtd,
+ struct omap_nand_info, mtd);
+ int ret = 0;
+
+ if (len <= mtd->oobsize) {
+ omap_read_buf_pref(mtd, buf, len);
+ return;
+ }
+
+ info->iomode = OMAP_NAND_IO_READ;
+ info->buf = buf;
+ init_completion(&info->comp);
+
+ /* configure and start prefetch transfer */
+ ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);
+ if (ret)
+ /* PFPW engine is busy, use cpu copy methode */
+ goto out_copy;
+
+ info->buf_len = len;
+ /* enable irq */
+ gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ,
+ (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+ /* waiting for read to complete */
+ wait_for_completion(&info->comp);
+
+ /* disable and stop the PFPW engine */
+ gpmc_prefetch_reset(info->gpmc_cs);
+ return;
+
+out_copy:
+ if (info->nand.options & NAND_BUSWIDTH_16)
+ omap_read_buf16(mtd, buf, len);
+ else
+ omap_read_buf8(mtd, buf, len);
+}
+
+/*
+ * omap_write_buf_irq_pref - write buffer to NAND controller
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ */
+static void omap_write_buf_irq_pref(struct mtd_info *mtd,
+ const u_char *buf, int len)
+{
+ struct omap_nand_info *info = container_of(mtd,
+ struct omap_nand_info, mtd);
+ int ret = 0;
+ if (len <= mtd->oobsize) {
+ omap_write_buf_pref(mtd, buf, len);
+ return;
+ }
+
+ info->iomode = OMAP_NAND_IO_WRITE;
+ info->buf = (u_char *) buf;
+ init_completion(&info->comp);
+
+ /* configure and start prefetch transfer */
+ ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1);
+ if (ret)
+ /* PFPW engine is busy, use cpu copy methode */
+ goto out_copy;
+
+ info->buf_len = len;
+ /* enable irq */
+ gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ,
+ (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+ /* waiting for write to complete */
+ wait_for_completion(&info->comp);
+ /* wait for data to flushed-out before reset the prefetch */
+ do {
+ ret = gpmc_read_status(GPMC_PREFETCH_COUNT);
+ } while (ret);
+ /* disable and stop the PFPW engine */
+ gpmc_prefetch_reset(info->gpmc_cs);
+ return;
+
+out_copy:
+ if (info->nand.options & NAND_BUSWIDTH_16)
+ omap_write_buf16(mtd, buf, len);
+ else
+ omap_write_buf8(mtd, buf, len);
+}
+
/**
* omap_verify_buf - Verify chip data against buffer
* @mtd: MTD device structure
@@ -769,6 +924,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
info->gpmc_cs = pdata->cs;
info->phys_base = pdata->phys_base;
+ info->gpmc_irq = pdata->gpmc_irq;
info->mtd.priv = &info->nand;
info->mtd.name = dev_name(&pdev->dev);
@@ -846,6 +1002,19 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
}
break;
+ case NAND_OMAP_PREFETCH_IRQ:
+ err = request_irq(info->gpmc_irq,
+ omap_nand_irq, IRQF_SHARED, "gpmc-nand", info);
+ if (err) {
+ dev_err(&pdev->dev, "requesting irq(%d) error:%d",
+ info->gpmc_irq, err);
+ goto out_release_mem_region;
+ } else {
+ info->nand.read_buf = omap_read_buf_irq_pref;
+ info->nand.write_buf = omap_write_buf_irq_pref;
+ }
+ break;
+
default:
dev_err(&pdev->dev,
"xfer_type(%d) not supported!\n", pdata->xfer_type);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v6 5/7] omap3: nand: configurable fifo threshold to gain the throughput
2010-11-26 15:34 [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Sukumar Ghorai
` (3 preceding siblings ...)
2010-11-26 15:34 ` [PATCH v6 4/7] omap3: nand: prefetch in irq mode support Sukumar Ghorai
@ 2010-11-26 15:34 ` Sukumar Ghorai
2010-11-26 15:34 ` [PATCH v6 6/7] omap: nand: ecc layout select from board file Sukumar Ghorai
` (2 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Sukumar Ghorai @ 2010-11-26 15:34 UTC (permalink / raw)
To: linux-arm-kernel
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 <vimalsingh@ti.com>
Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com>
---
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 the FIFO-threahold to 32 to get a sync at each frame
+ * and frame length is 32 bytes.
*/
- int buf_len = len >> 6;
+ int buf_len = len >> 5;
if (addr >= high_memory) {
struct page *p1;
@@ -382,7 +385,8 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC);
}
/* configure and start prefetch transfer */
- ret = gpmc_prefetch_enable(info->gpmc_cs, 0x1, len, is_write);
+ ret = gpmc_prefetch_enable(info->gpmc_cs,
+ PREFETCH_FIFOTHRESHOLD_MAX/2, 0x1, len, is_write);
if (ret)
/* PFPW engine is busy, use cpu copy methode */
goto out_copy;
@@ -518,7 +522,8 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
init_completion(&info->comp);
/* 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/2, 0x0, len, 0x0);
if (ret)
/* PFPW engine is busy, use cpu copy methode */
goto out_copy;
@@ -563,8 +568,9 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
info->buf = (u_char *) buf;
init_completion(&info->comp);
- /* configure and start prefetch transfer */
- ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1);
+ /* configure and start prefetch transfer : size=24 */
+ ret = gpmc_prefetch_enable(info->gpmc_cs,
+ (PREFETCH_FIFOTHRESHOLD_MAX*3)/8, 0x0, len, 0x1);
if (ret)
/* PFPW engine is busy, use cpu copy methode */
goto out_copy;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v6 6/7] omap: nand: ecc layout select from board file
2010-11-26 15:34 [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Sukumar Ghorai
` (4 preceding siblings ...)
2010-11-26 15:34 ` [PATCH v6 5/7] omap3: nand: configurable fifo threshold to gain the throughput Sukumar Ghorai
@ 2010-11-26 15:34 ` Sukumar Ghorai
2010-11-26 15:34 ` [PATCH v6 7/7] omap: nand: making ecc layout as compatible with romcode ecc Sukumar Ghorai
2010-12-19 21:45 ` [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Charles Manning
7 siblings, 0 replies; 16+ messages in thread
From: Sukumar Ghorai @ 2010-11-26 15:34 UTC (permalink / raw)
To: linux-arm-kernel
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 <vimalsingh@ti.com>
Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com>
---
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 <plat/gpmc.h>
#include <linux/mtd/partitions.h>
enum nand_io {
@@ -31,6 +32,7 @@ struct omap_nand_platform_data {
enum nand_io xfer_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 <linux/platform_device.h>
#include <linux/dma-mapping.h>
@@ -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
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v6 7/7] omap: nand: making ecc layout as compatible with romcode ecc
2010-11-26 15:34 [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Sukumar Ghorai
` (5 preceding siblings ...)
2010-11-26 15:34 ` [PATCH v6 6/7] omap: nand: ecc layout select from board file Sukumar Ghorai
@ 2010-11-26 15:34 ` Sukumar Ghorai
2010-12-19 21:45 ` [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Charles Manning
7 siblings, 0 replies; 16+ messages in thread
From: Sukumar Ghorai @ 2010-11-26 15:34 UTC (permalink / raw)
To: linux-arm-kernel
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 <vimalsingh@ti.com>
Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com>
---
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
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage
2010-11-26 15:34 [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Sukumar Ghorai
` (6 preceding siblings ...)
2010-11-26 15:34 ` [PATCH v6 7/7] omap: nand: making ecc layout as compatible with romcode ecc Sukumar Ghorai
@ 2010-12-19 21:45 ` Charles Manning
2010-12-22 7:43 ` Ghorai, Sukumar
7 siblings, 1 reply; 16+ messages in thread
From: Charles Manning @ 2010-12-19 21:45 UTC (permalink / raw)
To: linux-arm-kernel
On Saturday 27 November 2010 04:34:30 Sukumar Ghorai wrote:
> 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
Why change the ECC layout?
Be very careful when you change ECC layouts. This can break production
systems.
For example if people are running something earlier and then want to deliver a
new kernel with 2.6.37 then their existing NAND file systems will no longer
be readable.
Changes to ECC should only be done for very good reasons and should be
controlled with a Kconfig with the default being the existing ECC layout.
-- Charles
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage
2010-12-19 21:45 ` [PATCH v6 0/7] nand prefetch-irq support and ecc layout chanage Charles Manning
@ 2010-12-22 7:43 ` Ghorai, Sukumar
0 siblings, 0 replies; 16+ messages in thread
From: Ghorai, Sukumar @ 2010-12-22 7:43 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Charles Manning [mailto:manningc2 at actrix.gen.nz]
> Sent: Monday, December 20, 2010 3:16 AM
> To: linux-mtd at lists.infradead.org
> Cc: Ghorai, Sukumar; linux-omap at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v6 0/7] nand prefetch-irq support and ecc layout
> chanage
>
> On Saturday 27 November 2010 04:34:30 Sukumar Ghorai wrote:
> > 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
>
> Why change the ECC layout?
>
> Be very careful when you change ECC layouts. This can break production
> systems.
>
> For example if people are running something earlier and then want to
> deliver a
> new kernel with 2.6.37 then their existing NAND file systems will no
> longer
> be readable.
>
> Changes to ECC should only be done for very good reasons and should be
> controlled with a Kconfig with the default being the existing ECC layout.
>
[Ghorai] we are just adding few ecc-layout(s) and based on the request from different customer. The default ecc-layout is the old one for backward compatibility and selection of ecc-layput is exposed form board file.
^ permalink raw reply [flat|nested] 16+ messages in thread