* [PATCH 0/3] Handle GPMC-NAND registers by NAND driver @ 2012-05-11 15:26 ` Afzal Mohammed 0 siblings, 0 replies; 12+ messages in thread From: Afzal Mohammed @ 2012-05-11 15:26 UTC (permalink / raw) To: tony, dedekind1, linux-omap, linux-mtd; +Cc: Afzal Mohammed Hi, This series provides the ability for OMAP NAND driver to configure GPMC_NAND registers by NAND driver itself instead of using GPMC exported symbols. Regards Afzal Afzal Mohammed (3): ARM: OMAP2+: gpmc: update nand register helper ARM: OMAP2+: gpmc-nand: update gpmc-nand regs mtd: nand: omap2: handle nand on gpmc arch/arm/mach-omap2/gpmc-nand.c | 2 + arch/arm/mach-omap2/gpmc.c | 21 ++++ arch/arm/plat-omap/include/plat/gpmc.h | 18 +++ arch/arm/plat-omap/include/plat/nand.h | 1 + drivers/mtd/nand/omap2.c | 207 +++++++++++++++++++++++++------- 5 files changed, 205 insertions(+), 44 deletions(-) -- 1.7.10 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 0/3] Handle GPMC-NAND registers by NAND driver @ 2012-05-11 15:26 ` Afzal Mohammed 0 siblings, 0 replies; 12+ messages in thread From: Afzal Mohammed @ 2012-05-11 15:26 UTC (permalink / raw) To: tony, dedekind1, linux-omap, linux-mtd; +Cc: Afzal Mohammed Hi, This series provides the ability for OMAP NAND driver to configure GPMC_NAND registers by NAND driver itself instead of using GPMC exported symbols. Regards Afzal Afzal Mohammed (3): ARM: OMAP2+: gpmc: update nand register helper ARM: OMAP2+: gpmc-nand: update gpmc-nand regs mtd: nand: omap2: handle nand on gpmc arch/arm/mach-omap2/gpmc-nand.c | 2 + arch/arm/mach-omap2/gpmc.c | 21 ++++ arch/arm/plat-omap/include/plat/gpmc.h | 18 +++ arch/arm/plat-omap/include/plat/nand.h | 1 + drivers/mtd/nand/omap2.c | 207 +++++++++++++++++++++++++------- 5 files changed, 205 insertions(+), 44 deletions(-) -- 1.7.10 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/3] ARM: OMAP2+: gpmc: update nand register helper 2012-05-11 15:26 ` Afzal Mohammed @ 2012-05-11 15:28 ` Afzal Mohammed -1 siblings, 0 replies; 12+ messages in thread From: Afzal Mohammed @ 2012-05-11 15:28 UTC (permalink / raw) To: tony, dedekind1, ivan.djelic, linux-omap, linux-mtd; +Cc: Afzal Mohammed Provide helper function for updating NAND register details for the necessary chip select. NAND drivers platform data can be updated with this information so that NAND driver can handle GPMC NAND operations by itself. Signed-off-by: Afzal Mohammed <afzal@ti.com> --- arch/arm/mach-omap2/gpmc.c | 21 +++++++++++++++++++++ arch/arm/plat-omap/include/plat/gpmc.h | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 46b09da..a409a3e 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -49,6 +49,7 @@ #define GPMC_ECC_CONTROL 0x1f8 #define GPMC_ECC_SIZE_CONFIG 0x1fc #define GPMC_ECC1_RESULT 0x200 +#define GPMC_ECC_BCH_RESULT_0 0x240 /* GPMC ECC control settings */ #define GPMC_ECC_CTRL_ECCCLEAR 0x100 @@ -681,6 +682,26 @@ int gpmc_prefetch_reset(int cs) } EXPORT_SYMBOL(gpmc_prefetch_reset); +void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) +{ + reg->gpmc_status = gpmc_base + GPMC_STATUS; + reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + + GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; + reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET + + GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs; + reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET + + GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs; + reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1; + reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2; + reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL; + reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS; + reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG; + reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; + reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; + reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; + reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0; +} + 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 1527929..6a8078e 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -131,6 +131,24 @@ struct gpmc_timings { u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ }; +struct gpmc_nand_regs { + void __iomem *gpmc_status; + void __iomem *gpmc_nand_command; + void __iomem *gpmc_nand_address; + void __iomem *gpmc_nand_data; + void __iomem *gpmc_prefetch_config1; + void __iomem *gpmc_prefetch_config2; + void __iomem *gpmc_prefetch_control; + void __iomem *gpmc_prefetch_status; + void __iomem *gpmc_ecc_config; + void __iomem *gpmc_ecc_control; + void __iomem *gpmc_ecc_size_config; + void __iomem *gpmc_ecc1_result; + void __iomem *gpmc_bch_result0; +}; + +extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); + extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps); extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); -- 1.7.10 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 1/3] ARM: OMAP2+: gpmc: update nand register helper @ 2012-05-11 15:28 ` Afzal Mohammed 0 siblings, 0 replies; 12+ messages in thread From: Afzal Mohammed @ 2012-05-11 15:28 UTC (permalink / raw) To: tony, dedekind1, ivan.djelic, linux-omap, linux-mtd; +Cc: Afzal Mohammed Provide helper function for updating NAND register details for the necessary chip select. NAND drivers platform data can be updated with this information so that NAND driver can handle GPMC NAND operations by itself. Signed-off-by: Afzal Mohammed <afzal@ti.com> --- arch/arm/mach-omap2/gpmc.c | 21 +++++++++++++++++++++ arch/arm/plat-omap/include/plat/gpmc.h | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 46b09da..a409a3e 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -49,6 +49,7 @@ #define GPMC_ECC_CONTROL 0x1f8 #define GPMC_ECC_SIZE_CONFIG 0x1fc #define GPMC_ECC1_RESULT 0x200 +#define GPMC_ECC_BCH_RESULT_0 0x240 /* GPMC ECC control settings */ #define GPMC_ECC_CTRL_ECCCLEAR 0x100 @@ -681,6 +682,26 @@ int gpmc_prefetch_reset(int cs) } EXPORT_SYMBOL(gpmc_prefetch_reset); +void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) +{ + reg->gpmc_status = gpmc_base + GPMC_STATUS; + reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + + GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; + reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET + + GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs; + reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET + + GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs; + reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1; + reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2; + reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL; + reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS; + reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG; + reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; + reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; + reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; + reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0; +} + 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 1527929..6a8078e 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -131,6 +131,24 @@ struct gpmc_timings { u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ }; +struct gpmc_nand_regs { + void __iomem *gpmc_status; + void __iomem *gpmc_nand_command; + void __iomem *gpmc_nand_address; + void __iomem *gpmc_nand_data; + void __iomem *gpmc_prefetch_config1; + void __iomem *gpmc_prefetch_config2; + void __iomem *gpmc_prefetch_control; + void __iomem *gpmc_prefetch_status; + void __iomem *gpmc_ecc_config; + void __iomem *gpmc_ecc_control; + void __iomem *gpmc_ecc_size_config; + void __iomem *gpmc_ecc1_result; + void __iomem *gpmc_bch_result0; +}; + +extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); + extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps); extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); -- 1.7.10 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] ARM: OMAP2+: gpmc: update nand register helper 2012-05-11 15:28 ` Afzal Mohammed @ 2012-05-11 20:02 ` Tony Lindgren -1 siblings, 0 replies; 12+ messages in thread From: Tony Lindgren @ 2012-05-11 20:02 UTC (permalink / raw) To: Afzal Mohammed; +Cc: dedekind1, ivan.djelic, linux-omap, linux-mtd * Afzal Mohammed <afzal@ti.com> [120511 08:48]: > Provide helper function for updating NAND register details for > the necessary chip select. NAND drivers platform data can be > updated with this information so that NAND driver can handle > GPMC NAND operations by itself. Hmm this seems that it might be a more future proof path. Tony > Signed-off-by: Afzal Mohammed <afzal@ti.com> > --- > arch/arm/mach-omap2/gpmc.c | 21 +++++++++++++++++++++ > arch/arm/plat-omap/include/plat/gpmc.h | 18 ++++++++++++++++++ > 2 files changed, 39 insertions(+) > > diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c > index 46b09da..a409a3e 100644 > --- a/arch/arm/mach-omap2/gpmc.c > +++ b/arch/arm/mach-omap2/gpmc.c > @@ -49,6 +49,7 @@ > #define GPMC_ECC_CONTROL 0x1f8 > #define GPMC_ECC_SIZE_CONFIG 0x1fc > #define GPMC_ECC1_RESULT 0x200 > +#define GPMC_ECC_BCH_RESULT_0 0x240 > > /* GPMC ECC control settings */ > #define GPMC_ECC_CTRL_ECCCLEAR 0x100 > @@ -681,6 +682,26 @@ int gpmc_prefetch_reset(int cs) > } > EXPORT_SYMBOL(gpmc_prefetch_reset); > > +void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) > +{ > + reg->gpmc_status = gpmc_base + GPMC_STATUS; > + reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + > + GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; > + reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET + > + GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs; > + reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET + > + GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs; > + reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1; > + reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2; > + reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL; > + reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS; > + reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG; > + reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; > + reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; > + reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; > + reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0; > +} > + > 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 1527929..6a8078e 100644 > --- a/arch/arm/plat-omap/include/plat/gpmc.h > +++ b/arch/arm/plat-omap/include/plat/gpmc.h > @@ -131,6 +131,24 @@ struct gpmc_timings { > u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ > }; > > +struct gpmc_nand_regs { > + void __iomem *gpmc_status; > + void __iomem *gpmc_nand_command; > + void __iomem *gpmc_nand_address; > + void __iomem *gpmc_nand_data; > + void __iomem *gpmc_prefetch_config1; > + void __iomem *gpmc_prefetch_config2; > + void __iomem *gpmc_prefetch_control; > + void __iomem *gpmc_prefetch_status; > + void __iomem *gpmc_ecc_config; > + void __iomem *gpmc_ecc_control; > + void __iomem *gpmc_ecc_size_config; > + void __iomem *gpmc_ecc1_result; > + void __iomem *gpmc_bch_result0; > +}; > + > +extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); > + > extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); > extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps); > extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); > -- > 1.7.10 > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] ARM: OMAP2+: gpmc: update nand register helper @ 2012-05-11 20:02 ` Tony Lindgren 0 siblings, 0 replies; 12+ messages in thread From: Tony Lindgren @ 2012-05-11 20:02 UTC (permalink / raw) To: Afzal Mohammed; +Cc: ivan.djelic, linux-omap, linux-mtd, dedekind1 * Afzal Mohammed <afzal@ti.com> [120511 08:48]: > Provide helper function for updating NAND register details for > the necessary chip select. NAND drivers platform data can be > updated with this information so that NAND driver can handle > GPMC NAND operations by itself. Hmm this seems that it might be a more future proof path. Tony > Signed-off-by: Afzal Mohammed <afzal@ti.com> > --- > arch/arm/mach-omap2/gpmc.c | 21 +++++++++++++++++++++ > arch/arm/plat-omap/include/plat/gpmc.h | 18 ++++++++++++++++++ > 2 files changed, 39 insertions(+) > > diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c > index 46b09da..a409a3e 100644 > --- a/arch/arm/mach-omap2/gpmc.c > +++ b/arch/arm/mach-omap2/gpmc.c > @@ -49,6 +49,7 @@ > #define GPMC_ECC_CONTROL 0x1f8 > #define GPMC_ECC_SIZE_CONFIG 0x1fc > #define GPMC_ECC1_RESULT 0x200 > +#define GPMC_ECC_BCH_RESULT_0 0x240 > > /* GPMC ECC control settings */ > #define GPMC_ECC_CTRL_ECCCLEAR 0x100 > @@ -681,6 +682,26 @@ int gpmc_prefetch_reset(int cs) > } > EXPORT_SYMBOL(gpmc_prefetch_reset); > > +void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) > +{ > + reg->gpmc_status = gpmc_base + GPMC_STATUS; > + reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + > + GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; > + reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET + > + GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs; > + reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET + > + GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs; > + reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1; > + reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2; > + reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL; > + reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS; > + reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG; > + reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; > + reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; > + reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; > + reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0; > +} > + > 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 1527929..6a8078e 100644 > --- a/arch/arm/plat-omap/include/plat/gpmc.h > +++ b/arch/arm/plat-omap/include/plat/gpmc.h > @@ -131,6 +131,24 @@ struct gpmc_timings { > u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ > }; > > +struct gpmc_nand_regs { > + void __iomem *gpmc_status; > + void __iomem *gpmc_nand_command; > + void __iomem *gpmc_nand_address; > + void __iomem *gpmc_nand_data; > + void __iomem *gpmc_prefetch_config1; > + void __iomem *gpmc_prefetch_config2; > + void __iomem *gpmc_prefetch_control; > + void __iomem *gpmc_prefetch_status; > + void __iomem *gpmc_ecc_config; > + void __iomem *gpmc_ecc_control; > + void __iomem *gpmc_ecc_size_config; > + void __iomem *gpmc_ecc1_result; > + void __iomem *gpmc_bch_result0; > +}; > + > +extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); > + > extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); > extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps); > extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); > -- > 1.7.10 > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] ARM: OMAP2+: gpmc: update nand register helper 2012-05-11 20:02 ` Tony Lindgren @ 2012-05-15 7:22 ` Ivan Djelic -1 siblings, 0 replies; 12+ messages in thread From: Ivan Djelic @ 2012-05-15 7:22 UTC (permalink / raw) To: Tony Lindgren; +Cc: Afzal Mohammed, dedekind1, linux-omap, linux-mtd On Fri, May 11, 2012 at 09:02:14PM +0100, Tony Lindgren wrote: > * Afzal Mohammed <afzal@ti.com> [120511 08:48]: > > Provide helper function for updating NAND register details for > > the necessary chip select. NAND drivers platform data can be > > updated with this information so that NAND driver can handle > > GPMC NAND operations by itself. > > Hmm this seems that it might be a more future proof path. OK, I'll try to rewrite my patch on top of these. Best Regards, -- Ivan > > Tony > > > > Signed-off-by: Afzal Mohammed <afzal@ti.com> > > --- > > arch/arm/mach-omap2/gpmc.c | 21 +++++++++++++++++++++ > > arch/arm/plat-omap/include/plat/gpmc.h | 18 ++++++++++++++++++ > > 2 files changed, 39 insertions(+) > > > > diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c > > index 46b09da..a409a3e 100644 > > --- a/arch/arm/mach-omap2/gpmc.c > > +++ b/arch/arm/mach-omap2/gpmc.c > > @@ -49,6 +49,7 @@ > > #define GPMC_ECC_CONTROL 0x1f8 > > #define GPMC_ECC_SIZE_CONFIG 0x1fc > > #define GPMC_ECC1_RESULT 0x200 > > +#define GPMC_ECC_BCH_RESULT_0 0x240 > > > > /* GPMC ECC control settings */ > > #define GPMC_ECC_CTRL_ECCCLEAR 0x100 > > @@ -681,6 +682,26 @@ int gpmc_prefetch_reset(int cs) > > } > > EXPORT_SYMBOL(gpmc_prefetch_reset); > > > > +void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) > > +{ > > + reg->gpmc_status = gpmc_base + GPMC_STATUS; > > + reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + > > + GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; > > + reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET + > > + GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs; > > + reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET + > > + GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs; > > + reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1; > > + reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2; > > + reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL; > > + reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS; > > + reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG; > > + reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; > > + reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; > > + reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; > > + reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0; > > +} > > + > > 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 1527929..6a8078e 100644 > > --- a/arch/arm/plat-omap/include/plat/gpmc.h > > +++ b/arch/arm/plat-omap/include/plat/gpmc.h > > @@ -131,6 +131,24 @@ struct gpmc_timings { > > u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ > > }; > > > > +struct gpmc_nand_regs { > > + void __iomem *gpmc_status; > > + void __iomem *gpmc_nand_command; > > + void __iomem *gpmc_nand_address; > > + void __iomem *gpmc_nand_data; > > + void __iomem *gpmc_prefetch_config1; > > + void __iomem *gpmc_prefetch_config2; > > + void __iomem *gpmc_prefetch_control; > > + void __iomem *gpmc_prefetch_status; > > + void __iomem *gpmc_ecc_config; > > + void __iomem *gpmc_ecc_control; > > + void __iomem *gpmc_ecc_size_config; > > + void __iomem *gpmc_ecc1_result; > > + void __iomem *gpmc_bch_result0; > > +}; > > + > > +extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); > > + > > extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); > > extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps); > > extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); > > -- > > 1.7.10 > > -- Ivan Djelic Operating System Team Manager tel + 33 01 48 03 70 16 ----------------------------------------- Parrot 174, Quai de Jemmapes 75010 Paris, France tel + 33 01 48 03 60 60 fax + 33 01 48 03 70 08 ----------------------------------------- http://www.parrot.com ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] ARM: OMAP2+: gpmc: update nand register helper @ 2012-05-15 7:22 ` Ivan Djelic 0 siblings, 0 replies; 12+ messages in thread From: Ivan Djelic @ 2012-05-15 7:22 UTC (permalink / raw) To: Tony Lindgren; +Cc: Afzal Mohammed, linux-omap, linux-mtd, dedekind1 On Fri, May 11, 2012 at 09:02:14PM +0100, Tony Lindgren wrote: > * Afzal Mohammed <afzal@ti.com> [120511 08:48]: > > Provide helper function for updating NAND register details for > > the necessary chip select. NAND drivers platform data can be > > updated with this information so that NAND driver can handle > > GPMC NAND operations by itself. > > Hmm this seems that it might be a more future proof path. OK, I'll try to rewrite my patch on top of these. Best Regards, -- Ivan > > Tony > > > > Signed-off-by: Afzal Mohammed <afzal@ti.com> > > --- > > arch/arm/mach-omap2/gpmc.c | 21 +++++++++++++++++++++ > > arch/arm/plat-omap/include/plat/gpmc.h | 18 ++++++++++++++++++ > > 2 files changed, 39 insertions(+) > > > > diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c > > index 46b09da..a409a3e 100644 > > --- a/arch/arm/mach-omap2/gpmc.c > > +++ b/arch/arm/mach-omap2/gpmc.c > > @@ -49,6 +49,7 @@ > > #define GPMC_ECC_CONTROL 0x1f8 > > #define GPMC_ECC_SIZE_CONFIG 0x1fc > > #define GPMC_ECC1_RESULT 0x200 > > +#define GPMC_ECC_BCH_RESULT_0 0x240 > > > > /* GPMC ECC control settings */ > > #define GPMC_ECC_CTRL_ECCCLEAR 0x100 > > @@ -681,6 +682,26 @@ int gpmc_prefetch_reset(int cs) > > } > > EXPORT_SYMBOL(gpmc_prefetch_reset); > > > > +void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) > > +{ > > + reg->gpmc_status = gpmc_base + GPMC_STATUS; > > + reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + > > + GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; > > + reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET + > > + GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs; > > + reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET + > > + GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs; > > + reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1; > > + reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2; > > + reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL; > > + reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS; > > + reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG; > > + reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; > > + reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; > > + reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; > > + reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0; > > +} > > + > > 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 1527929..6a8078e 100644 > > --- a/arch/arm/plat-omap/include/plat/gpmc.h > > +++ b/arch/arm/plat-omap/include/plat/gpmc.h > > @@ -131,6 +131,24 @@ struct gpmc_timings { > > u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ > > }; > > > > +struct gpmc_nand_regs { > > + void __iomem *gpmc_status; > > + void __iomem *gpmc_nand_command; > > + void __iomem *gpmc_nand_address; > > + void __iomem *gpmc_nand_data; > > + void __iomem *gpmc_prefetch_config1; > > + void __iomem *gpmc_prefetch_config2; > > + void __iomem *gpmc_prefetch_control; > > + void __iomem *gpmc_prefetch_status; > > + void __iomem *gpmc_ecc_config; > > + void __iomem *gpmc_ecc_control; > > + void __iomem *gpmc_ecc_size_config; > > + void __iomem *gpmc_ecc1_result; > > + void __iomem *gpmc_bch_result0; > > +}; > > + > > +extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); > > + > > extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); > > extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps); > > extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); > > -- > > 1.7.10 > > -- Ivan Djelic Operating System Team Manager tel + 33 01 48 03 70 16 ----------------------------------------- Parrot 174, Quai de Jemmapes 75010 Paris, France tel + 33 01 48 03 60 60 fax + 33 01 48 03 70 08 ----------------------------------------- http://www.parrot.com ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/3] ARM: OMAP2+: gpmc-nand: update gpmc-nand regs 2012-05-11 15:26 ` Afzal Mohammed @ 2012-05-11 15:28 ` Afzal Mohammed -1 siblings, 0 replies; 12+ messages in thread From: Afzal Mohammed @ 2012-05-11 15:28 UTC (permalink / raw) To: tony, dedekind1, ivan.djelic, linux-omap, linux-mtd; +Cc: Afzal Mohammed GPMC has NAND registers, update nand platform data with those details so that NAND driver can configure those by itself instead of using exported symbols. Signed-off-by: Afzal Mohammed <afzal@ti.com> --- arch/arm/mach-omap2/gpmc-nand.c | 2 ++ arch/arm/plat-omap/include/plat/nand.h | 1 + 2 files changed, 3 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index 386dec8..d4e803c 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -108,6 +108,8 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data) gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1); } + gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs); + err = platform_device_register(&gpmc_nand_device); if (err < 0) { dev_err(dev, "Unable to register NAND device\n"); diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 67fc506..86e4d9c 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -29,6 +29,7 @@ struct omap_nand_platform_data { unsigned long phys_base; int devsize; enum omap_ecc ecc_opt; + struct gpmc_nand_regs reg; }; /* minimum size for IO mapping */ -- 1.7.10 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/3] ARM: OMAP2+: gpmc-nand: update gpmc-nand regs @ 2012-05-11 15:28 ` Afzal Mohammed 0 siblings, 0 replies; 12+ messages in thread From: Afzal Mohammed @ 2012-05-11 15:28 UTC (permalink / raw) To: tony, dedekind1, ivan.djelic, linux-omap, linux-mtd; +Cc: Afzal Mohammed GPMC has NAND registers, update nand platform data with those details so that NAND driver can configure those by itself instead of using exported symbols. Signed-off-by: Afzal Mohammed <afzal@ti.com> --- arch/arm/mach-omap2/gpmc-nand.c | 2 ++ arch/arm/plat-omap/include/plat/nand.h | 1 + 2 files changed, 3 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index 386dec8..d4e803c 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -108,6 +108,8 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data) gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1); } + gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs); + err = platform_device_register(&gpmc_nand_device); if (err < 0) { dev_err(dev, "Unable to register NAND device\n"); diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 67fc506..86e4d9c 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -29,6 +29,7 @@ struct omap_nand_platform_data { unsigned long phys_base; int devsize; enum omap_ecc ecc_opt; + struct gpmc_nand_regs reg; }; /* minimum size for IO mapping */ -- 1.7.10 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/3] mtd: nand: omap2: handle nand on gpmc 2012-05-11 15:26 ` Afzal Mohammed @ 2012-05-11 15:28 ` Afzal Mohammed -1 siblings, 0 replies; 12+ messages in thread From: Afzal Mohammed @ 2012-05-11 15:28 UTC (permalink / raw) To: tony, dedekind1, ivan.djelic, linux-omap, linux-mtd; +Cc: Afzal Mohammed GPMC driver has been modified to fill NAND platform data with GPMC NAND register details. As these registers are accessible in NAND driver itself, configure NAND in GPMC by itself. Modified prefetch and ecc functions are logically same as the corresponding exported symbols from GPMC code. Note: Verfying that other CS have not yet enabled for prefetch & ecc has to be incorporated. Currently this causes no issues as there are no boards that use NAND on multiple CS. With ongoing GPMC driver migration, perhaps it would be better to consider NAND connected on multiple CS as a single peripheral using multiple CS. This would make handling multiple CS issues easier. Signed-off-by: Afzal Mohammed <afzal@ti.com> --- drivers/mtd/nand/omap2.c | 207 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 163 insertions(+), 44 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index c2b0bba..25f930c 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -95,6 +95,16 @@ #define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0) #define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1) +#define PREFETCH_CONFIG1_CS_SHIFT 24 +#define ECC_CONFIG_CS_SHIFT 1 +#define CS_MASK 0x7 +#define ENABLE_PREFETCH (0x1 << 7) +#define DMA_MPU_MODE_SHIFT 2 +#define ECCSIZE1_SHIFT 22 +#define ECC1RESULTSIZE 0x1 +#define ECCCLEAR 0x100 +#define ECC1 0x1 + /* 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 @@ -127,9 +137,70 @@ struct omap_nand_info { } iomode; u_char *buf; int buf_len; + struct gpmc_nand_regs reg; }; /** + * omap_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 + */ +static int omap_prefetch_enable(int cs, int fifo_th, int dma_mode, + unsigned int u32_count, int is_write, struct omap_nand_info *info) +{ + u32 val; + + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + pr_err("gpmc: fifo threshold is not supported\n"); + return -1; + } else if (!(readl(info->reg.gpmc_prefetch_control))) { + /* Set the amount of bytes to be prefetched */ + writel(u32_count, info->reg.gpmc_prefetch_config2); + + /* Set dma/mpu mode, the prefetch read / post write and + * enable the engine. Set which cs is has requested for. + */ + val = ((cs << PREFETCH_CONFIG1_CS_SHIFT) | + PREFETCH_FIFOTHRESHOLD(fifo_th) | + ENABLE_PREFETCH | + (dma_mode << DMA_MPU_MODE_SHIFT) | + (0x1 & is_write)); + writel(val, info->reg.gpmc_prefetch_config1); + + /* Start the prefetch engine */ + writel(0x1, info->reg.gpmc_prefetch_control); + } else { + return -EBUSY; + } + + return 0; +} + +/** + * omap_prefetch_reset - disables and stops the prefetch engine + */ +static int omap_prefetch_reset(int cs, struct omap_nand_info *info) +{ + u32 config1; + + /* check if the same module/cs is trying to reset */ + config1 = readl(info->reg.gpmc_prefetch_config1); + if (((config1 >> PREFETCH_CONFIG1_CS_SHIFT) & CS_MASK) != cs) + return -EINVAL; + + /* Stop the PFPW engine */ + writel(0x0, info->reg.gpmc_prefetch_control); + + /* Reset/disable the PFPW engine */ + writel(0x0, info->reg.gpmc_prefetch_config1); + + return 0; +} + +/** * omap_hwcontrol - hardware specific access to control-lines * @mtd: MTD device structure * @cmd: command to device @@ -147,13 +218,13 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) if (cmd != NAND_CMD_NONE) { if (ctrl & NAND_CLE) - gpmc_nand_write(info->gpmc_cs, GPMC_NAND_COMMAND, cmd); + writeb(cmd, info->reg.gpmc_nand_command); else if (ctrl & NAND_ALE) - gpmc_nand_write(info->gpmc_cs, GPMC_NAND_ADDRESS, cmd); + writeb(cmd, info->reg.gpmc_nand_address); else /* NAND_NCE */ - gpmc_nand_write(info->gpmc_cs, GPMC_NAND_DATA, cmd); + writeb(cmd, info->reg.gpmc_nand_data); } } @@ -187,7 +258,8 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len) iowrite8(*p++, info->nand.IO_ADDR_W); /* wait until buffer is available for write */ do { - status = gpmc_read_status(GPMC_STATUS_BUFFER); + status = readl(info->reg.gpmc_status) & + GPMC_STATUS_BUFF_EMPTY; } while (!status); } } @@ -224,7 +296,8 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len) iowrite16(*p++, info->nand.IO_ADDR_W); /* wait until buffer is available for write */ do { - status = gpmc_read_status(GPMC_STATUS_BUFFER); + status = readl(info->reg.gpmc_status) & + GPMC_STATUS_BUFF_EMPTY; } while (!status); } } @@ -254,8 +327,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, - PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); + ret = omap_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0, info); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -264,14 +337,15 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) omap_read_buf8(mtd, (u_char *)p, len); } else { do { - r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + r_count = readl(info->reg.gpmc_prefetch_status); + r_count = GPMC_PREFETCH_STATUS_FIFO_CNT(r_count); r_count = r_count >> 2; ioread32_rep(info->nand.IO_ADDR_R, p, r_count); p += r_count; len -= r_count << 2; } while (len); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); } } @@ -290,6 +364,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd, int i = 0, ret = 0; u16 *p = (u16 *)buf; unsigned long tim, limit; + u32 val; /* take care of subpage writes */ if (len % 2 != 0) { @@ -299,8 +374,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, - PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); + ret = omap_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1, info); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -309,7 +384,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, omap_write_buf8(mtd, (u_char *)p, len); } else { while (len) { - w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + w_count = readl(info->reg.gpmc_prefetch_status); + w_count = GPMC_PREFETCH_STATUS_FIFO_CNT(w_count); w_count = w_count >> 1; for (i = 0; (i < w_count) && len; i++, len -= 2) iowrite16(*p++, info->nand.IO_ADDR_W); @@ -318,11 +394,14 @@ static void omap_write_buf_pref(struct mtd_info *mtd, tim = 0; limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); - while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) + do { cpu_relax(); + val = readl(info->reg.gpmc_prefetch_status); + val = GPMC_PREFETCH_STATUS_COUNT(val); + } while (val && (tim++ < limit)); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); } } @@ -354,6 +433,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; unsigned long tim, limit; + u32 val; /* The fifo depth is 64 bytes max. * But configure the FIFO-threahold to 32 to get a sync at each frame @@ -398,8 +478,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, - PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); + ret = omap_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write, info); if (ret) /* PFPW engine is busy, use cpu copy method */ goto out_copy; @@ -412,11 +492,15 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, wait_for_completion(&info->comp); tim = 0; limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); - while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) + + do { cpu_relax(); + val = readl(info->reg.gpmc_prefetch_status); + val = GPMC_PREFETCH_STATUS_COUNT(val); + } while (val && (tim++ < limit)); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); return 0; @@ -474,7 +558,8 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev) u32 irq_stat; irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); - bytes = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + bytes = readl(info->reg.gpmc_prefetch_status); + bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes); bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */ if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ if (irq_stat & 0x2) @@ -534,8 +619,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, - PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0); + ret = omap_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0, info); if (ret) /* PFPW engine is busy, use cpu copy method */ goto out_copy; @@ -549,7 +634,7 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) wait_for_completion(&info->comp); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); return; out_copy: @@ -572,6 +657,7 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, struct omap_nand_info, mtd); int ret = 0; unsigned long tim, limit; + u32 val; if (len <= mtd->oobsize) { omap_write_buf_pref(mtd, buf, len); @@ -583,8 +669,8 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, init_completion(&info->comp); /* configure and start prefetch transfer : size=24 */ - ret = gpmc_prefetch_enable(info->gpmc_cs, - (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1); + ret = omap_prefetch_enable(info->gpmc_cs, + (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1, info); if (ret) /* PFPW engine is busy, use cpu copy method */ goto out_copy; @@ -599,11 +685,14 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, /* wait for data to flushed-out before reset the prefetch */ tim = 0; limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); - while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) + do { + val = readl(info->reg.gpmc_prefetch_status); + val = GPMC_PREFETCH_STATUS_COUNT(val); cpu_relax(); + } while (val && (tim++ < limit)); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); return; out_copy: @@ -843,7 +932,20 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - return gpmc_calculate_ecc(info->gpmc_cs, dat, ecc_code); + u32 val; + + val = readl(info->reg.gpmc_ecc_config); + if (((val >> ECC_CONFIG_CS_SHIFT) & ~CS_MASK) != info->gpmc_cs) + return -EINVAL; + + /* read ecc result */ + val = readl(info->reg.gpmc_ecc1_result); + *ecc_code++ = val; /* P128e, ..., P1e */ + *ecc_code++ = val >> 16; /* P128o, ..., P1o */ + /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */ + *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0); + + return 0; } /** @@ -857,8 +959,34 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) mtd); struct nand_chip *chip = mtd->priv; unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; + u32 val; + + /* clear ecc and enable bits */ + val = ECCCLEAR | ECC1; + writel(val, info->reg.gpmc_ecc_control); + + /* program ecc and result sizes */ + val = ((((info->nand.ecc.size >> 1) - 1) << ECCSIZE1_SHIFT) | + ECC1RESULTSIZE); + writel(val, info->reg.gpmc_ecc_size_config); + + switch (mode) { + case NAND_ECC_READ: + case NAND_ECC_WRITE: + writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); + break; + case NAND_ECC_READSYN: + writel(ECCCLEAR, info->reg.gpmc_ecc_control); + break; + default: + dev_info(&info->pdev->dev, + "error: unrecognized Mode[%d]!\n", mode); + break; + } - gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); + /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ + val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1); + writel(val, info->reg.gpmc_ecc_config); } /** @@ -886,10 +1014,9 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) else timeo += (HZ * 20) / 1000; - gpmc_nand_write(info->gpmc_cs, - GPMC_NAND_COMMAND, (NAND_CMD_STATUS & 0xFF)); + writeb(NAND_CMD_STATUS & 0xFF, info->reg.gpmc_nand_command); while (time_before(jiffies, timeo)) { - status = gpmc_nand_read(info->gpmc_cs, GPMC_NAND_DATA); + status = readb(info->reg.gpmc_nand_data); if (status & NAND_STATUS_READY) break; cond_resched(); @@ -907,22 +1034,13 @@ static int omap_dev_ready(struct mtd_info *mtd) struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - val = gpmc_read_status(GPMC_GET_IRQ_STATUS); + val = readl(info->reg.gpmc_status); + if ((val & 0x100) == 0x100) { - /* Clear IRQ Interrupt */ - val |= 0x100; - val &= ~(0x0); - gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, val); + return 1; } else { - unsigned int cnt = 0; - while (cnt++ < 0x1FF) { - if ((val & 0x100) == 0x100) - return 0; - val = gpmc_read_status(GPMC_GET_IRQ_STATUS); - } + return 0; } - - return 1; } static int __devinit omap_nand_probe(struct platform_device *pdev) @@ -951,6 +1069,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->gpmc_cs = pdata->cs; info->phys_base = pdata->phys_base; + info->reg = pdata->reg; info->mtd.priv = &info->nand; info->mtd.name = dev_name(&pdev->dev); -- 1.7.10 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/3] mtd: nand: omap2: handle nand on gpmc @ 2012-05-11 15:28 ` Afzal Mohammed 0 siblings, 0 replies; 12+ messages in thread From: Afzal Mohammed @ 2012-05-11 15:28 UTC (permalink / raw) To: tony, dedekind1, ivan.djelic, linux-omap, linux-mtd; +Cc: Afzal Mohammed GPMC driver has been modified to fill NAND platform data with GPMC NAND register details. As these registers are accessible in NAND driver itself, configure NAND in GPMC by itself. Modified prefetch and ecc functions are logically same as the corresponding exported symbols from GPMC code. Note: Verfying that other CS have not yet enabled for prefetch & ecc has to be incorporated. Currently this causes no issues as there are no boards that use NAND on multiple CS. With ongoing GPMC driver migration, perhaps it would be better to consider NAND connected on multiple CS as a single peripheral using multiple CS. This would make handling multiple CS issues easier. Signed-off-by: Afzal Mohammed <afzal@ti.com> --- drivers/mtd/nand/omap2.c | 207 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 163 insertions(+), 44 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index c2b0bba..25f930c 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -95,6 +95,16 @@ #define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0) #define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1) +#define PREFETCH_CONFIG1_CS_SHIFT 24 +#define ECC_CONFIG_CS_SHIFT 1 +#define CS_MASK 0x7 +#define ENABLE_PREFETCH (0x1 << 7) +#define DMA_MPU_MODE_SHIFT 2 +#define ECCSIZE1_SHIFT 22 +#define ECC1RESULTSIZE 0x1 +#define ECCCLEAR 0x100 +#define ECC1 0x1 + /* 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 @@ -127,9 +137,70 @@ struct omap_nand_info { } iomode; u_char *buf; int buf_len; + struct gpmc_nand_regs reg; }; /** + * omap_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 + */ +static int omap_prefetch_enable(int cs, int fifo_th, int dma_mode, + unsigned int u32_count, int is_write, struct omap_nand_info *info) +{ + u32 val; + + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + pr_err("gpmc: fifo threshold is not supported\n"); + return -1; + } else if (!(readl(info->reg.gpmc_prefetch_control))) { + /* Set the amount of bytes to be prefetched */ + writel(u32_count, info->reg.gpmc_prefetch_config2); + + /* Set dma/mpu mode, the prefetch read / post write and + * enable the engine. Set which cs is has requested for. + */ + val = ((cs << PREFETCH_CONFIG1_CS_SHIFT) | + PREFETCH_FIFOTHRESHOLD(fifo_th) | + ENABLE_PREFETCH | + (dma_mode << DMA_MPU_MODE_SHIFT) | + (0x1 & is_write)); + writel(val, info->reg.gpmc_prefetch_config1); + + /* Start the prefetch engine */ + writel(0x1, info->reg.gpmc_prefetch_control); + } else { + return -EBUSY; + } + + return 0; +} + +/** + * omap_prefetch_reset - disables and stops the prefetch engine + */ +static int omap_prefetch_reset(int cs, struct omap_nand_info *info) +{ + u32 config1; + + /* check if the same module/cs is trying to reset */ + config1 = readl(info->reg.gpmc_prefetch_config1); + if (((config1 >> PREFETCH_CONFIG1_CS_SHIFT) & CS_MASK) != cs) + return -EINVAL; + + /* Stop the PFPW engine */ + writel(0x0, info->reg.gpmc_prefetch_control); + + /* Reset/disable the PFPW engine */ + writel(0x0, info->reg.gpmc_prefetch_config1); + + return 0; +} + +/** * omap_hwcontrol - hardware specific access to control-lines * @mtd: MTD device structure * @cmd: command to device @@ -147,13 +218,13 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) if (cmd != NAND_CMD_NONE) { if (ctrl & NAND_CLE) - gpmc_nand_write(info->gpmc_cs, GPMC_NAND_COMMAND, cmd); + writeb(cmd, info->reg.gpmc_nand_command); else if (ctrl & NAND_ALE) - gpmc_nand_write(info->gpmc_cs, GPMC_NAND_ADDRESS, cmd); + writeb(cmd, info->reg.gpmc_nand_address); else /* NAND_NCE */ - gpmc_nand_write(info->gpmc_cs, GPMC_NAND_DATA, cmd); + writeb(cmd, info->reg.gpmc_nand_data); } } @@ -187,7 +258,8 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len) iowrite8(*p++, info->nand.IO_ADDR_W); /* wait until buffer is available for write */ do { - status = gpmc_read_status(GPMC_STATUS_BUFFER); + status = readl(info->reg.gpmc_status) & + GPMC_STATUS_BUFF_EMPTY; } while (!status); } } @@ -224,7 +296,8 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len) iowrite16(*p++, info->nand.IO_ADDR_W); /* wait until buffer is available for write */ do { - status = gpmc_read_status(GPMC_STATUS_BUFFER); + status = readl(info->reg.gpmc_status) & + GPMC_STATUS_BUFF_EMPTY; } while (!status); } } @@ -254,8 +327,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, - PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); + ret = omap_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0, info); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -264,14 +337,15 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) omap_read_buf8(mtd, (u_char *)p, len); } else { do { - r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + r_count = readl(info->reg.gpmc_prefetch_status); + r_count = GPMC_PREFETCH_STATUS_FIFO_CNT(r_count); r_count = r_count >> 2; ioread32_rep(info->nand.IO_ADDR_R, p, r_count); p += r_count; len -= r_count << 2; } while (len); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); } } @@ -290,6 +364,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd, int i = 0, ret = 0; u16 *p = (u16 *)buf; unsigned long tim, limit; + u32 val; /* take care of subpage writes */ if (len % 2 != 0) { @@ -299,8 +374,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* configure and start prefetch transfer */ - ret = gpmc_prefetch_enable(info->gpmc_cs, - PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); + ret = omap_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1, info); if (ret) { /* PFPW engine is busy, use cpu copy method */ if (info->nand.options & NAND_BUSWIDTH_16) @@ -309,7 +384,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, omap_write_buf8(mtd, (u_char *)p, len); } else { while (len) { - w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + w_count = readl(info->reg.gpmc_prefetch_status); + w_count = GPMC_PREFETCH_STATUS_FIFO_CNT(w_count); w_count = w_count >> 1; for (i = 0; (i < w_count) && len; i++, len -= 2) iowrite16(*p++, info->nand.IO_ADDR_W); @@ -318,11 +394,14 @@ static void omap_write_buf_pref(struct mtd_info *mtd, tim = 0; limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); - while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) + do { cpu_relax(); + val = readl(info->reg.gpmc_prefetch_status); + val = GPMC_PREFETCH_STATUS_COUNT(val); + } while (val && (tim++ < limit)); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); } } @@ -354,6 +433,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, dma_addr_t dma_addr; int ret; unsigned long tim, limit; + u32 val; /* The fifo depth is 64 bytes max. * But configure the FIFO-threahold to 32 to get a sync at each frame @@ -398,8 +478,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, - PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); + ret = omap_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write, info); if (ret) /* PFPW engine is busy, use cpu copy method */ goto out_copy; @@ -412,11 +492,15 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, wait_for_completion(&info->comp); tim = 0; limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); - while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) + + do { cpu_relax(); + val = readl(info->reg.gpmc_prefetch_status); + val = GPMC_PREFETCH_STATUS_COUNT(val); + } while (val && (tim++ < limit)); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); return 0; @@ -474,7 +558,8 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev) u32 irq_stat; irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); - bytes = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + bytes = readl(info->reg.gpmc_prefetch_status); + bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes); bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */ if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ if (irq_stat & 0x2) @@ -534,8 +619,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, - PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0); + ret = omap_prefetch_enable(info->gpmc_cs, + PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0, info); if (ret) /* PFPW engine is busy, use cpu copy method */ goto out_copy; @@ -549,7 +634,7 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) wait_for_completion(&info->comp); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); return; out_copy: @@ -572,6 +657,7 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, struct omap_nand_info, mtd); int ret = 0; unsigned long tim, limit; + u32 val; if (len <= mtd->oobsize) { omap_write_buf_pref(mtd, buf, len); @@ -583,8 +669,8 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, init_completion(&info->comp); /* configure and start prefetch transfer : size=24 */ - ret = gpmc_prefetch_enable(info->gpmc_cs, - (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1); + ret = omap_prefetch_enable(info->gpmc_cs, + (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1, info); if (ret) /* PFPW engine is busy, use cpu copy method */ goto out_copy; @@ -599,11 +685,14 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, /* wait for data to flushed-out before reset the prefetch */ tim = 0; limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); - while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) + do { + val = readl(info->reg.gpmc_prefetch_status); + val = GPMC_PREFETCH_STATUS_COUNT(val); cpu_relax(); + } while (val && (tim++ < limit)); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); + omap_prefetch_reset(info->gpmc_cs, info); return; out_copy: @@ -843,7 +932,20 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - return gpmc_calculate_ecc(info->gpmc_cs, dat, ecc_code); + u32 val; + + val = readl(info->reg.gpmc_ecc_config); + if (((val >> ECC_CONFIG_CS_SHIFT) & ~CS_MASK) != info->gpmc_cs) + return -EINVAL; + + /* read ecc result */ + val = readl(info->reg.gpmc_ecc1_result); + *ecc_code++ = val; /* P128e, ..., P1e */ + *ecc_code++ = val >> 16; /* P128o, ..., P1o */ + /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */ + *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0); + + return 0; } /** @@ -857,8 +959,34 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) mtd); struct nand_chip *chip = mtd->priv; unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; + u32 val; + + /* clear ecc and enable bits */ + val = ECCCLEAR | ECC1; + writel(val, info->reg.gpmc_ecc_control); + + /* program ecc and result sizes */ + val = ((((info->nand.ecc.size >> 1) - 1) << ECCSIZE1_SHIFT) | + ECC1RESULTSIZE); + writel(val, info->reg.gpmc_ecc_size_config); + + switch (mode) { + case NAND_ECC_READ: + case NAND_ECC_WRITE: + writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); + break; + case NAND_ECC_READSYN: + writel(ECCCLEAR, info->reg.gpmc_ecc_control); + break; + default: + dev_info(&info->pdev->dev, + "error: unrecognized Mode[%d]!\n", mode); + break; + } - gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); + /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ + val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1); + writel(val, info->reg.gpmc_ecc_config); } /** @@ -886,10 +1014,9 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) else timeo += (HZ * 20) / 1000; - gpmc_nand_write(info->gpmc_cs, - GPMC_NAND_COMMAND, (NAND_CMD_STATUS & 0xFF)); + writeb(NAND_CMD_STATUS & 0xFF, info->reg.gpmc_nand_command); while (time_before(jiffies, timeo)) { - status = gpmc_nand_read(info->gpmc_cs, GPMC_NAND_DATA); + status = readb(info->reg.gpmc_nand_data); if (status & NAND_STATUS_READY) break; cond_resched(); @@ -907,22 +1034,13 @@ static int omap_dev_ready(struct mtd_info *mtd) struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); - val = gpmc_read_status(GPMC_GET_IRQ_STATUS); + val = readl(info->reg.gpmc_status); + if ((val & 0x100) == 0x100) { - /* Clear IRQ Interrupt */ - val |= 0x100; - val &= ~(0x0); - gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, val); + return 1; } else { - unsigned int cnt = 0; - while (cnt++ < 0x1FF) { - if ((val & 0x100) == 0x100) - return 0; - val = gpmc_read_status(GPMC_GET_IRQ_STATUS); - } + return 0; } - - return 1; } static int __devinit omap_nand_probe(struct platform_device *pdev) @@ -951,6 +1069,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->gpmc_cs = pdata->cs; info->phys_base = pdata->phys_base; + info->reg = pdata->reg; info->mtd.priv = &info->nand; info->mtd.name = dev_name(&pdev->dev); -- 1.7.10 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2012-05-15 7:22 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-05-11 15:26 [PATCH 0/3] Handle GPMC-NAND registers by NAND driver Afzal Mohammed 2012-05-11 15:26 ` Afzal Mohammed 2012-05-11 15:28 ` [PATCH 1/3] ARM: OMAP2+: gpmc: update nand register helper Afzal Mohammed 2012-05-11 15:28 ` Afzal Mohammed 2012-05-11 20:02 ` Tony Lindgren 2012-05-11 20:02 ` Tony Lindgren 2012-05-15 7:22 ` Ivan Djelic 2012-05-15 7:22 ` Ivan Djelic 2012-05-11 15:28 ` [PATCH 2/3] ARM: OMAP2+: gpmc-nand: update gpmc-nand regs Afzal Mohammed 2012-05-11 15:28 ` Afzal Mohammed 2012-05-11 15:28 ` [PATCH 3/3] mtd: nand: omap2: handle nand on gpmc Afzal Mohammed 2012-05-11 15:28 ` Afzal Mohammed
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.