Basic N800 support
Hi Tony,
Thank you for releasing N800 source code. It's very helpful for OMAP2 board, such as Apollon.
I checked and downloaded the source code in maemo. I'll check the OMAP2 core stuff and OneNAND in apollon board.
Thank you,
Kyungmin Park
P.S., Is it possible to change 'omap2.c' in drivers/mtd/onenand to 'n800.c' or another? It's not generic for OMAP2. :)
------- Original Message -------
Sender : Tony Lindgren<[email protected]>
Date : Jan 20, 2007 05:57
Title : [PATCH] Basic N800 support
Hi,
Here's a quick patch of N800 support against the current git tree for people to play with until we get N800 support merged in. It just contains the board support and basic NAND changes to get root mounted, so most driver changes are not included.
Regards,
Tony
Tony Lindgren
maintainerQuoted 4 lines · Kyungmin Park
Hi Tony,
Thank you for releasing N800 source code. It's very helpful for OMAP2 board, such as Apollon.
Well I just took what Nokia published at maemo.org..
Quoted 7 lines
I checked and downloaded the source code in maemo. I'll check the OMAP2 core stuff and OneNAND in apollon board.
Thank you,
Kyungmin Park
P.S., Is it possible to change 'omap2.c' indrivers/mtd/onenandto 'n800.c' or another? It's not generic for OMAP2. :)
Sure, maybe there's some code that should be shared though?
Regards,
Tony
Tony Lindgren
maintainerQuoted 11 lines · Tony Lindgren
Quoted 4 lines · Kyungmin Park
Hi Tony,
Thank you for releasing N800 source code. It's very helpful for OMAP2 board, such as Apollon.
Well I just took what Nokia published at maemo.org..
Quoted 3 lines
I checked and downloaded the source code in maemo. I'll check the OMAP2 core stuff and OneNAND in apollon board.
Quoted 6 lines
Quoted 4 lines
Thank you,
Kyungmin Park
P.S., Is it possible to change 'omap2.c' indrivers/mtd/onenandto 'n800.c' or another? It's not generic for OMAP2. :)Sure, maybe there's some code that should be shared though?
Kyungmin, can you list what else makes the N800 onenand support non-generic other than the GPMC timings that should come from board-*.c files?
I'd like to get this to linux-omap tree in some format to be able to mount root :)
Regards,
Tony
Hi Tony,
Quoted 9 lines
Quoted 1 line
Quoted 1 line
P.S., Is it possible to change 'omap2.c' in
drivers/mtd/onenandtoQuoted 3 lines
Quoted 1 line
'
n800.c' or another? It's not generic for OMAP2. :)Sure, maybe there's some code that should be shared though?
Kyungmin, can you list what else makes the N800 onenand support non-generic other than the GPMC timings that should come from board-*.c files?
Only things are GPMC and OneNAND configuration.
GPMC timings should be set in platform file such as board-n800-onenand.c or bootloader
and don't need to configure the OneNAND system configuration in omap2.c
In apollon, we configure GPMC timings and OneNAND configuration at bootloader
and don't modify in the kernel code.
In the previous time, OneNAND MTD don't probe chip when sync. mode enabled. Now it can find the chip whether sync. mode or not
In omap2.c it set OneNAND as async mode, probe it and then set sync. mode. I think it is reasons based on this history.
Finally it don't need to configure IOBE in omap2_onenand_wait
#if 0
/* Turn interrupts on */
syscfg = omap2_onenand_readw(info->onenand.base +
ONENAND_REG_SYS_CFG1);
syscfg |= ONENAND_SYS_CFG1_IOBE;
omap2_onenand_writew(syscfg, info->onenand.base +
ONENAND_REG_SYS_CFG1);
#endif
#if 0
/* Turn interrupts off */
syscfg = omap2_onenand_readw(info->onenand.base +
ONENAND_REG_SYS_CFG1);
syscfg &= ~ONENAND_SYS_CFG1_IOBE;
omap2_onenand_writew(syscfg, info->onenand.base +ONENAND_REG_SYS_CFG1);
#endif
Thank you,
Kyungmin Park
Hi,
Quoted 16 lines · Kyungmin Park
Finally it don't need to configure IOBE in
omap2_onenand_wait#if 0 /* Turn interrupts on */ syscfg = omap2_onenand_readw(info->onenand.base + ONENAND_REG_SYS_CFG1); syscfg |= ONENAND_SYS_CFG1_IOBE; omap2_onenand_writew(syscfg, info->onenand.base + ONENAND_REG_SYS_CFG1); #endif #if 0 /* Turn interrupts off */ syscfg = omap2_onenand_readw(info->onenand.base + ONENAND_REG_SYS_CFG1); syscfg &= ~ONENAND_SYS_CFG1_IOBE; omap2_onenand_writew(syscfg, info->onenand.base +
Quoted 2 lines
ONENAND_REG_SYS_CFG1);
#endif
Yes, this is not strictly necessery. But we noticed that using polling instead of interrupts for some operations give slightly better performance.
Cheers,
Timo
Quoted 3 lines · Kyungmin Park
GPMC timings should be set in platform file such as
board-n800-onenand.cor bootloader and don't need to configure the OneNAND system configuration inomap2.c
Attaches is a candidate patch which moves N800 OneNand sync mode timing setup into platform specific file.
Regards
Jarkko Lavinen
Quoted 1 line
From
312f30aceb98fabaec048bd35b640d444d6a52ebMon Sep 17 00:00:00 2001
From: Jarkko Lavinen <[email protected]>
Date: Thu, 1 Mar 2007 14:05:20 +0200
Subject: [PATCH] Move N800 specific OneNand setup to N800 platform file.
--- arch/arm/mach-omap2/board-n800-flash.c | 102 ++++++++++++++++++++++++++- drivers/mtd/onenand/omap2.c | 124 ++------------------------------ include/asm-arm/arch-omap/onenand.h | 1 + 3 files changed, 109 insertions(+), 118 deletions(-)
arch/arm/mach-omap2/board-n800-flash.c +101 -1
@@ -12,16 +12,23 @@#include <linux/kernel.h> #include <linux/platform_device.h> #include <asm/mach/flash.h> +#include <linux/mtd/onenand_regs.h> + +#include <asm/io.h> #include <asm/arch/onenand.h> #include <asm/arch/board.h> +#include <asm/arch/gpmc.h> static struct mtd_partition n800_partitions[8 ]; +static int n800_onenand_setup (void __iomem *); +static struct omap_onenand_platform_data n800_onenand_data = { .cs =0 , .gpio_irq =26 , .parts = n800_partitions, - .nr_parts =0 /* filled later */ + .nr_parts =0 ,/* filled later */ + .onenand_setup = n800_onenand_setup };static struct platform_device n800_onenand_device = {
@@ -32,6 +39,99 @@ static struct platform_device n800_onenand_device = { }, }; +static unsigned short omap2_onenand_readw (void __iomem *addr) +{ +return readw (addr); +} + +static void omap2_onenand_writew (unsigned short value,void __iomem *addr) +{ +writew (value, addr); +} + +static int omap2_onenand_set_sync_mode (int cs,void __iomem *onenand_base) +{ +const int min_gpmc_clk_period =18 ; +struct gpmc_timings t; +int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency; +u32 reg; + + tick_ns =gpmc_round_ns_to_ticks (1 ); + div =gpmc_cs_calc_divider (cs, min_gpmc_clk_period); + gpmc_clk_ns = div * tick_ns; +if (gpmc_clk_ns >=24 ) + latency =3 ; +else + latency =4 ; + +/* Configure OneNAND for sync read */ + reg =omap2_onenand_readw (onenand_base +ONENAND_REG_SYS_CFG1 ); + reg &= ~((0x7 <<ONENAND_SYS_CFG1_BRL_SHIFT ) | (0x7 <<9 )); + reg |= (latency <<ONENAND_SYS_CFG1_BRL_SHIFT ) | +ONENAND_SYS_CFG1_SYNC_READ | +ONENAND_SYS_CFG1_BL_16 ; +omap2_onenand_writew (reg, onenand_base +ONENAND_REG_SYS_CFG1 ); + +/* FIXME: Get timings from platform data */ +/* Set syncronous read timings */ +memset (&t,0 ,sizeof (t)); + t.sync_clk = min_gpmc_clk_period; + t.cs_on =0 ; + t.adv_on =gpmc_round_ns_to_ticks (7 ); + fclk_offset_ns = t.adv_on +gpmc_round_ns_to_ticks (7 ); + fclk_offset = fclk_offset_ns /gpmc_round_ns_to_ticks (1 ); + t.page_burst_access = gpmc_clk_ns; + +/* Read */ + t.adv_rd_off = fclk_offset_ns +gpmc_round_ns_to_ticks (7 ); + t.oe_on = t.adv_rd_off; + t.access = fclk_offset_ns + (latency +1 ) * gpmc_clk_ns; + t.oe_off = t.access +gpmc_round_ns_to_ticks (1 ); + t.cs_rd_off = t.oe_off; + t.rd_cycle = t.cs_rd_off +gpmc_round_ns_to_ticks (17 ); + +/* Write */ + t.adv_wr_off = t.adv_on +gpmc_round_ns_to_ticks (12 ); + t.we_on = t.adv_wr_off +gpmc_round_ns_to_ticks (1 ); + t.we_off = t.we_on +gpmc_round_ns_to_ticks (40 ); + t.cs_wr_off = t.we_off +gpmc_round_ns_to_ticks (1 ); + t.wr_cycle = t.cs_wr_off +gpmc_round_ns_to_ticks (1 ); + +/* Configure GPMC for synchronous read */ + fclk_offset %= div; +gpmc_cs_write_reg (cs,GPMC_CS_CONFIG1 , +GPMC_CONFIG1_WRAPBURST_SUPP | +GPMC_CONFIG1_READMULTIPLE_SUPP | +GPMC_CONFIG1_READTYPE_SYNC | +GPMC_CONFIG1_CLKACTIVATIONTIME (fclk_offset) | +GPMC_CONFIG1_PAGE_LEN (2 ) | +GPMC_CONFIG1_WAIT_READ_MON | +GPMC_CONFIG1_WAIT_PIN_SEL (0 ) | +GPMC_CONFIG1_DEVICESIZE_16 | +GPMC_CONFIG1_DEVICETYPE_NOR | +GPMC_CONFIG1_MUXADDDATA ); + +return gpmc_cs_set_timings (cs, &t); +} + +static int n800_onenand_setup (void __iomem *onenand_base) +{ +struct omap_onenand_platform_data *datap = &n800_onenand_data; +struct device *dev = &n800_onenand_device.dev; + +/* Force OneNAND to async mode */ +omap2_onenand_writew (ONENAND_SYS_CFG1_BRL_4 |ONENAND_SYS_CFG1_RDY | +ONENAND_SYS_CFG1_INT , + onenand_base +ONENAND_REG_SYS_CFG1 ); + +/* Set sync timings in GPMC */ +if (omap2_onenand_set_sync_mode (datap->cs, onenand_base) <0 ) { +dev_err (dev,"Unable to set synchronous mode\n" ); +return -EINVAL ; + } + +return 0 ; +}void __init n800_flash_init (void ) {
drivers/mtd/onenand/omap2.c +7 -117
142 lines not on this page · raw message
include/asm-arm/arch-omap/onenand.h +1 -0
@@ -16,4 +16,5 @@ struct omap_onenand_platform_data {int gpio_irq;struct mtd_partition *parts;int nr_parts; +int (*onenand_setup)(void __iomem *); };
Signature · 1 line
1.4.4.4
Hi Jarkko Lavinen,
Looks good.
Tony, please add drivers/mtd/onenand/omap2.c first
+
+static int n800_onenand_setup(void __iomem *onenand_base) +{
+ struct omap_onenand_platform_data *datap = &n800_onenand_data;
+ struct device *dev = &n800_onenand_device.dev;
+
+ /* Force OneNAND to async mode */
+ omap2_onenand_writew(ONENAND_SYS_CFG1_BRL_4 | ONENAND_SYS_CFG1_RDY |
+ ONENAND_SYS_CFG1_INT,
+ onenand_base + ONENAND_REG_SYS_CFG1);
If you don't need async mode settings, it also don't need it.
+
+ /* Set sync timings in GPMC */
+ if (omap2_onenand_set_sync_mode(datap->cs, onenand_base) < 0) {
+ dev_err(dev, "Unable to set synchronous mode\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
Thank you,
Kyungmin Park
Quoted 20 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Jarkko Lavinen
Sent: Thursday, March 01, 2007 10:46 PM
To: [email protected]
Cc: Kyungmin Park
Subject: Re: Basic N800 supportQuoted 3 lines · Kyungmin Park
GPMC timings should be set in platform file such as
board-n800-onenand.cor bootloader and don't need to configure the OneNAND system configuration inomap2.cAttaches is a candidate patch which moves N800 OneNand sync mode timing setup into platform specific file.
Regards
Jarkko Lavinen
Hi Kyungmin
Quoted 1 line
If you don't need async mode settings, it also don't need it.
Yes. It is obvious. Removed async part. New patch attached.
Best Regards
Jarkko Lavinen
Quoted 1 line
From
5b99cf491a1105cde1f766bb760e1f39d964dc1aMon Sep 17 00:00:00 2001
From: Jarkko Lavinen <[email protected]>
Date: Fri, 2 Mar 2007 17:02:09 +0200
Subject: [PATCH] Move N800 specific OneNand setup to N800 platform file.
--- arch/arm/mach-omap2/board-n800-flash.c | 97 ++++++++++++++++++++++++- drivers/mtd/onenand/omap2.c | 124 ++------------------------------ include/asm-arm/arch-omap/onenand.h | 1 + 3 files changed, 104 insertions(+), 118 deletions(-)
arch/arm/mach-omap2/board-n800-flash.c +96 -1
@@ -12,16 +12,23 @@#include <linux/kernel.h> #include <linux/platform_device.h> #include <asm/mach/flash.h> +#include <linux/mtd/onenand_regs.h> + +#include <asm/io.h> #include <asm/arch/onenand.h> #include <asm/arch/board.h> +#include <asm/arch/gpmc.h> static struct mtd_partition n800_partitions[8 ]; +static int n800_onenand_setup (void __iomem *); +static struct omap_onenand_platform_data n800_onenand_data = { .cs =0 , .gpio_irq =26 , .parts = n800_partitions, - .nr_parts =0 /* filled later */ + .nr_parts =0 ,/* filled later */ + .onenand_setup = n800_onenand_setup };static struct platform_device n800_onenand_device = {
@@ -32,6 +39,94 @@ static struct platform_device n800_onenand_device = { }, }; +static unsigned short omap2_onenand_readw (void __iomem *addr) +{ +return readw (addr); +} + +static void omap2_onenand_writew (unsigned short value,void __iomem *addr) +{ +writew (value, addr); +} + +static int omap2_onenand_set_sync_mode (int cs,void __iomem *onenand_base) +{ +const int min_gpmc_clk_period =18 ; +struct gpmc_timings t; +int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency; +u32 reg; + + tick_ns =gpmc_round_ns_to_ticks (1 ); + div =gpmc_cs_calc_divider (cs, min_gpmc_clk_period); + gpmc_clk_ns = div * tick_ns; +if (gpmc_clk_ns >=24 ) + latency =3 ; +else + latency =4 ; + +/* Configure OneNAND for sync read */ + reg =omap2_onenand_readw (onenand_base +ONENAND_REG_SYS_CFG1 ); + reg &= ~((0x7 <<ONENAND_SYS_CFG1_BRL_SHIFT ) | (0x7 <<9 )); + reg |= (latency <<ONENAND_SYS_CFG1_BRL_SHIFT ) | +ONENAND_SYS_CFG1_SYNC_READ | +ONENAND_SYS_CFG1_BL_16 ; +omap2_onenand_writew (reg, onenand_base +ONENAND_REG_SYS_CFG1 ); + +/* FIXME: Get timings from platform data */ +/* Set syncronous read timings */ +memset (&t,0 ,sizeof (t)); + t.sync_clk = min_gpmc_clk_period; + t.cs_on =0 ; + t.adv_on =gpmc_round_ns_to_ticks (7 ); + fclk_offset_ns = t.adv_on +gpmc_round_ns_to_ticks (7 ); + fclk_offset = fclk_offset_ns /gpmc_round_ns_to_ticks (1 ); + t.page_burst_access = gpmc_clk_ns; + +/* Read */ + t.adv_rd_off = fclk_offset_ns +gpmc_round_ns_to_ticks (7 ); + t.oe_on = t.adv_rd_off; + t.access = fclk_offset_ns + (latency +1 ) * gpmc_clk_ns; + t.oe_off = t.access +gpmc_round_ns_to_ticks (1 ); + t.cs_rd_off = t.oe_off; + t.rd_cycle = t.cs_rd_off +gpmc_round_ns_to_ticks (17 ); + +/* Write */ + t.adv_wr_off = t.adv_on +gpmc_round_ns_to_ticks (12 ); + t.we_on = t.adv_wr_off +gpmc_round_ns_to_ticks (1 ); + t.we_off = t.we_on +gpmc_round_ns_to_ticks (40 ); + t.cs_wr_off = t.we_off +gpmc_round_ns_to_ticks (1 ); + t.wr_cycle = t.cs_wr_off +gpmc_round_ns_to_ticks (1 ); + +/* Configure GPMC for synchronous read */ + fclk_offset %= div; +gpmc_cs_write_reg (cs,GPMC_CS_CONFIG1 , +GPMC_CONFIG1_WRAPBURST_SUPP | +GPMC_CONFIG1_READMULTIPLE_SUPP | +GPMC_CONFIG1_READTYPE_SYNC | +GPMC_CONFIG1_CLKACTIVATIONTIME (fclk_offset) | +GPMC_CONFIG1_PAGE_LEN (2 ) | +GPMC_CONFIG1_WAIT_READ_MON | +GPMC_CONFIG1_WAIT_PIN_SEL (0 ) | +GPMC_CONFIG1_DEVICESIZE_16 | +GPMC_CONFIG1_DEVICETYPE_NOR | +GPMC_CONFIG1_MUXADDDATA ); + +return gpmc_cs_set_timings (cs, &t); +} + +static int n800_onenand_setup (void __iomem *onenand_base) +{ +struct omap_onenand_platform_data *datap = &n800_onenand_data; +struct device *dev = &n800_onenand_device.dev; + +/* Set sync timings in GPMC */ +if (omap2_onenand_set_sync_mode (datap->cs, onenand_base) <0 ) { +dev_err (dev,"Unable to set synchronous mode\n" ); +return -EINVAL ; + } + +return 0 ; +}void __init n800_flash_init (void ) {
drivers/mtd/onenand/omap2.c +7 -117
142 lines not on this page · raw message
include/asm-arm/arch-omap/onenand.h +1 -0
@@ -16,4 +16,5 @@ struct omap_onenand_platform_data {int gpio_irq;struct mtd_partition *parts;int nr_parts; +int (*onenand_setup)(void __iomem *); };
Signature · 1 line
1.4.4.4
PATCH 1/1 Move N800 specific OneNand setup to N800 platform file, was: Basic N800 support
Quoted 3 lines · Jarkko Lavinen
Quoted 1 line
If you don't need async mode settings, it also don't need it.
Yes. It is obvious. Removed async part. New patch attached.
Are there any dependencies to apply this patch I missed? I tried to apply it on top of 01-onenand.patch posted by Tony
[1] but got rejects.
If not, sligthly modified patch that cleanly applies on top of [1] in attachment. I additionally removed duplication of omap2_onenand_readw and writew. Can you please test if it is still okay? ;)
Dirk
[1]
http://linux.omap.com/pipermail/linux-omap-open-source/2007-January/008958.html
Quoted 1 line
From
5b99cf491a1105cde1f766bb760e1f39d964dc1aMon Sep 17 00:00:00 2001
From: Jarkko Lavinen <[email protected]>
Date: Fri, 2 Mar 2007 17:02:09 +0200
Subject: [PATCH] Move N800 specific OneNand setup to N800 platform file.
--- arch/arm/mach-omap2/board-n800-flash.c | 97 ++++++++++++++++++++++++- drivers/mtd/onenand/omap2.c | 124 ++------------------------------ include/asm-arm/arch-omap/onenand.h | 1 + 3 files changed, 104 insertions(+), 118 deletions(-)
arch/arm/mach-omap2/board-n800-flash.c +98 -1
@@ -12,16 +12,100 @@#include <linux/kernel.h> #include <linux/platform_device.h> #include <asm/mach/flash.h> +#include <linux/mtd/onenand_regs.h> + +#include <asm/io.h> #include <asm/arch/onenand.h> #include <asm/arch/board.h> +#include <asm/arch/gpmc.h> static struct mtd_partition n800_partitions[8 ]; +static unsigned short n800_onenand_readw (void __iomem *addr) +{ +return readw (addr); +} + +static void n800_onenand_writew (unsigned short value,void __iomem *addr) +{ +writew (value, addr); +} + +static int n800_onenand_set_sync_mode (int cs,void __iomem *onenand_base) +{ +const int min_gpmc_clk_period =18 ; +struct gpmc_timings t; +int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency; +u32 reg; + + tick_ns =gpmc_round_ns_to_ticks (1 ); + div =gpmc_cs_calc_divider (cs, min_gpmc_clk_period); + gpmc_clk_ns = div * tick_ns; +if (gpmc_clk_ns >=24 ) + latency =3 ; +else + latency =4 ; + +/* Configure OneNAND for sync read */ + reg =n800_onenand_readw (onenand_base +ONENAND_REG_SYS_CFG1 ); + reg &= ~((0x7 <<ONENAND_SYS_CFG1_BRL_SHIFT ) | (0x7 <<9 )); + reg |= (latency <<ONENAND_SYS_CFG1_BRL_SHIFT ) | +ONENAND_SYS_CFG1_SYNC_READ | +ONENAND_SYS_CFG1_BL_16 ; +n800_onenand_writew (reg, onenand_base +ONENAND_REG_SYS_CFG1 ); + +/* FIXME: Get timings from platform data */ +/* Set syncronous read timings */ +memset (&t,0 ,sizeof (t)); + t.sync_clk = min_gpmc_clk_period; + t.cs_on =0 ; + t.adv_on =gpmc_round_ns_to_ticks (7 ); + fclk_offset_ns = t.adv_on +gpmc_round_ns_to_ticks (7 ); + fclk_offset = fclk_offset_ns /gpmc_round_ns_to_ticks (1 ); + t.page_burst_access = gpmc_clk_ns; + +/* Read */ + t.adv_rd_off = fclk_offset_ns +gpmc_round_ns_to_ticks (7 ); + t.oe_on = t.adv_rd_off; + t.access = fclk_offset_ns + (latency +1 ) * gpmc_clk_ns; + t.oe_off = t.access +gpmc_round_ns_to_ticks (1 ); + t.cs_rd_off = t.oe_off; + t.rd_cycle = t.cs_rd_off +gpmc_round_ns_to_ticks (17 ); + +/* Write */ + t.adv_wr_off = t.adv_on +gpmc_round_ns_to_ticks (12 ); + t.we_on = t.adv_wr_off +gpmc_round_ns_to_ticks (1 ); + t.we_off = t.we_on +gpmc_round_ns_to_ticks (40 ); + t.cs_wr_off = t.we_off +gpmc_round_ns_to_ticks (1 ); + t.wr_cycle = t.cs_wr_off +gpmc_round_ns_to_ticks (1 ); + +/* Configure GPMC for synchronous read */ + fclk_offset %= div; +gpmc_cs_write_reg (cs,GPMC_CS_CONFIG1 , +GPMC_CONFIG1_WRAPBURST_SUPP | +GPMC_CONFIG1_READMULTIPLE_SUPP | +GPMC_CONFIG1_READTYPE_SYNC | +GPMC_CONFIG1_CLKACTIVATIONTIME (fclk_offset) | +GPMC_CONFIG1_PAGE_LEN (2 ) | +GPMC_CONFIG1_WAIT_READ_MON | +GPMC_CONFIG1_WAIT_PIN_SEL (0 ) | +GPMC_CONFIG1_DEVICESIZE_16 | +GPMC_CONFIG1_DEVICETYPE_NOR | +GPMC_CONFIG1_MUXADDDATA ); + +return gpmc_cs_set_timings (cs, &t); +} + +static int n800_onenand_setup (void __iomem *); +static struct omap_onenand_platform_data n800_onenand_data = { .cs =0 , .gpio_irq =26 , .parts = n800_partitions, - .nr_parts =0 /* filled later */ + .nr_parts =0 ,/* filled later */ + .onenand_setup = n800_onenand_setup, + .onenand_readw = n800_onenand_readw, + .onenand_writew = n800_onenand_writew };static struct platform_device n800_onenand_device = {
@@ -32,6 +116,19 @@ static struct platform_device n800_onena }, }; +static int n800_onenand_setup (void __iomem *onenand_base) +{ +struct omap_onenand_platform_data *datap = &n800_onenand_data; +struct device *dev = &n800_onenand_device.dev; + +/* Set sync timings in GPMC */ +if (n800_onenand_set_sync_mode (datap->cs, onenand_base) <0 ) { +dev_err (dev,"Unable to set synchronous mode\n" ); +return -EINVAL ; + } + +return 0 ; +}void __init n800_flash_init (void ) {
drivers/mtd/onenand/omap2.c +13 -132
192 lines not on this page · raw message
include/asm-arm/arch-omap/onenand.h +3 -0
@@ -16,4 +16,7 @@ struct omap_onenand_platform_data {int gpio_irq;struct mtd_partition *parts;int nr_parts; +int (*onenand_setup)(void __iomem *); +unsigned short (*onenand_readw)(void __iomem *); +void (*onenand_writew)(unsigned short ,void __iomem *); };
Tony Lindgren
maintainerRe: [PATCH] Move N800 specific OneNand setup to N800 platform file, was: Basic N800 support
Quoted 5 lines · Dirk Behme
Quoted 3 lines · Jarkko Lavinen
Quoted 1 line
If you don't need async mode settings, it also don't need it.
Yes. It is obvious. Removed async part. New patch attached.
Quoted 8 lines
Are there any dependencies to apply this patch I missed? I tried to apply it on top of 01-onenand.patch posted by Tony
[1] but got rejects.If not, sligthly modified patch that cleanly applies on top of [1] in attachment. I additionally removed duplication of
omap2_onenand_readwand writew. Can you please test if it is still okay? ;)
I've pushed Jarkko's onenand patches as two parts:
omap-drivers: onenand support for omap2 that can be sent to mtd list
omap-upstream: onenand board specific support for n800
Can you all please verify that they're OK?
Kyungmin & Dirk, do you have some additional patches on top of Jarkko's patches?
Regards,
Tony
RE: [PATCH] Move N800 specific OneNand setup to N800 platform file, was: Basic N800 support
Hi
Quoted 12 lines · Dirk Behme
Quoted 10 lines
Quoted 3 lines · Jarkko Lavinen
Quoted 1 line
If you don't need async mode settings, it also don't need it.
Yes. It is obvious. Removed async part. New patch attached.
Are there any dependencies to apply this patch I missed? I tried to apply it on top of 01-onenand.patch posted by Tony [1] but got rejects.
If not, sligthly modified patch that cleanly applies on top
Quoted 8 lines
of [1] in
Quoted 1 line
attachment. I additionally removed duplication of
omap2_onenand_readwQuoted 1 line
and writew. Can you please test if it is still okay? ;)
I've pushed Jarkko's onenand patches as two parts:
omap-drivers: onenand support for omap2 that can be sent to mtd list
I will push it mtd list
Quoted 3 lines
omap-upstream: onenand board specific support for n800
Can you all please verify that they're OK?
There's one compiler bug related with interrupt handler.
Quoted 4 lines
Kyungmin & Dirk, do you have some additional patches on top of Jarkko's patches?
Please don't patch [1]. If this patch is applied, we have to add all platform files to add onenand_readw, onenand_writew.
Now apollon board can use it without modification of omap2.c
Thank you,
Kyungmin Park
1. http://linux.omap.com/pipermail/linux-omap-open-source/2007-March/009210.
html
Quoted 1 line
From
d4978e6cfbb4824391d568051bd0027622cac729Mon Sep 17 00:00:00 2001
From: Kyungmin Park <[email protected]>
Date: Thu, 8 Mar 2007 10:05:01 +0900
Subject: [PATCH] ARM: OMAP: Fix old interrupt handler function in omap2-onenand
Fix old interrupt handler function in omap2-onenand
--- drivers/mtd/onenand/omap2.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/mtd/onenand/omap2.c +1 -2
@@ -80,8 +80,7 @@ static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)complete (&info->dma_done); } -static irqreturn_t omap2_onenand_interrupt (int irq,void *dev_id, -struct pt_regs *regs) +static irqreturn_t omap2_onenand_interrupt (int irq,void *dev_id) {struct omap2_onenand *info = dev_id;
Signature · 1 line
1.4.4.2
RE: [PATCH] Move N800 specific OneNand setup to N800 platform file, was: Basic N800 support
Quoted 16 lines
Quoted 9 lines · Dirk Behme
Quoted 6 lines
Quoted 3 lines · Jarkko Lavinen
Quoted 1 line
If you don't need async mode settings, it also don't need it.
Yes. It is obvious. Removed async part. New patch attached.
Are there any dependencies to apply this patch I missed?
I tried to
Quoted 6 lines
Quoted 4 lines
apply it on top of 01-onenand.patch posted by Tony [1] but got rejects.
If not, sligthly modified patch that cleanly applies on top
of [1] in
Quoted 1 line
attachment. I additionally removed duplication of
Quoted 8 lines
Quoted 6 lines
omap2_onenand_readwQuoted 1 line
and writew. Can you please test if it is still okay? ;)
I've pushed Jarkko's onenand patches as two parts:
omap-drivers: onenand support for omap2 that can be sent to mtd list
I will push it mtd list
Umm, there's omap tree dependency.omap2_block_sleep() & omap2_allow_sleep().
It just increase and decrease sleep_block variable atomically
Just remove it or define dummy macro?
Please give your opinions.
Thank you,
Kyungmin Park
Re: [PATCH] Move N800 specific OneNand setup to N800 platform file, was: Basic N800 support
In reply to Kyungmin ParkHi Kyungmin
Thank you for your comments and irq handler fix.
Quoted 2 lines
If this patch is applied, we have to add all platform files to add
onenand_readw,onenand_writew.
We could pass the needed methods to the setup. This would also allow to add more fields if new omap2 devices with more complex setups are needed.
Quoted 3 lines
Umm, there's omap tree dependency.
omap2_block_sleep()&omap2_allow_sleep().
...
Just remove it or define dummy macro?
The log message in our internal tree says the sleep prevention was added to maximise speed when reading from bufferram.
I vote for dummy macro, which can then presumably be overdriven by a custom definion from some device specific header.
Regards
Jarkko Lavinen
Quoted 1 line
From
a6200a8f8f029193cce157a3efe90809104c353fMon Sep 17 00:00:00 2001
From: Jarkko Lavinen <[email protected]>
Date: Fri, 9 Mar 2007 20:56:39 +0200
Subject: [PATCH] Fix request_irq compile error and pass readw, and writew methods to platform setup.
--- arch/arm/mach-omap2/board-n800-flash.c | 27 +++++++++++---------------- drivers/mtd/onenand/omap2.c | 6 +++++- include/asm-arm/arch-omap/onenand.h | 8 +++++++- 3 files changed, 23 insertions(+), 18 deletions(-)
arch/arm/mach-omap2/board-n800-flash.c +11 -16
@@ -21,7 +21,7 @@static struct mtd_partition n800_partitions[8 ]; -static int n800_onenand_setup (void __iomem *); +static int n800_onenand_setup (struct omap_onenand_setup_data *sdata);static struct omap_onenand_platform_data n800_onenand_data = { .cs =0 ,
@@ -39,17 +39,7 @@ static struct platform_device n800_onenand_device = { }, }; -static unsigned short omap2_onenand_readw (void __iomem *addr) -{ -return readw (addr); -} - -static void omap2_onenand_writew (unsigned short value,void __iomem *addr) -{ -writew (value, addr); -} - -static int omap2_onenand_set_sync_mode (int cs,void __iomem *onenand_base) +static int omap2_onenand_set_sync_mode (int cs,struct omap_onenand_setup_data *sdata) {const int min_gpmc_clk_period =18 ;struct gpmc_timings t;
@@ -65,12 +55,12 @@ static int omap2_onenand_set_sync_mode(int cs, void __iomem *onenand_base) latency =4 ;/* Configure OneNAND for sync read */ - reg =omap2_onenand_readw (onenand_base +ONENAND_REG_SYS_CFG1 ); + reg = (sdata->readw)(sdata->iobase +ONENAND_REG_SYS_CFG1 ); reg &= ~((0x7 <<ONENAND_SYS_CFG1_BRL_SHIFT ) | (0x7 <<9 )); reg |= (latency <<ONENAND_SYS_CFG1_BRL_SHIFT ) |ONENAND_SYS_CFG1_SYNC_READ |ONENAND_SYS_CFG1_BL_16 ; -omap2_onenand_writew (reg, onenand_base +ONENAND_REG_SYS_CFG1 ); + (sdata->writew)(reg, sdata->iobase +ONENAND_REG_SYS_CFG1 );/* FIXME: Get timings from platform data */ /* Set syncronous read timings */
@@ -114,13 +104,18 @@ static int omap2_onenand_set_sync_mode(int cs, void __iomem *onenand_base)return gpmc_cs_set_timings (cs, &t); } -static int n800_onenand_setup (void __iomem *onenand_base) +static int n800_onenand_setup (struct omap_onenand_setup_data *sdata) {struct omap_onenand_platform_data *datap = &n800_onenand_data;struct device *dev = &n800_onenand_device.dev; +if (sdata ==NULL ) { +dev_err (dev,"setup data is a NULL pointer\n" ); +return -EINVAL ; + } +/* Set sync timings in GPMC */ -if (omap2_onenand_set_sync_mode (datap->cs, onenand_base) <0 ) { +if (omap2_onenand_set_sync_mode (datap->cs, sdata) <0 ) {dev_err (dev,"Unable to set synchronous mode\n" );return -EINVAL ; }
drivers/mtd/onenand/omap2.c +5 -1
@@ -337,7 +337,11 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) }if (pdata->onenand_setup !=NULL ) { - r = pdata->onenand_setup (info->onenand.base); +struct omap_onenand_setup_data data; + data.iobase = info->onenand.base; + data.readw = omap2_onenand_readw; + data.writew = omap2_onenand_writew; + r = pdata->onenand_setup (&data);if (r <0 ) {dev_err (&pdev->dev,"Onenand platform setup failed: %d\n" , r); goto err_iounmap;
include/asm-arm/arch-omap/onenand.h +7 -1
@@ -11,10 +11,16 @@#include <linux/mtd/partitions.h> +struct omap_onenand_setup_data { +void __iomem *iobase; +unsigned short (*readw)(void __iomem *); +void (*writew)(unsigned short ,void __iomem *); +}; +struct omap_onenand_platform_data {int cs;int gpio_irq;struct mtd_partition *parts;int nr_parts; -int (*onenand_setup)(void __iomem *); +int (*onenand_setup)(struct omap_onenand_setup_data *); };
Signature · 1 line
1.4.4.4
Tony Lindgren
maintainerRe: [PATCH] Move N800 specific OneNand setup to N800 platform file, was: Basic N800 support
In reply to Kyungmin ParkQuoted 14 lines · Kyungmin Park
ARM: OMAP: Fix old interrupt handler function in omap2-onenand
Fix old interrupt handler function in omap2-onenand
Signed-off-by Kyungmin Park <[email protected]>--- drivers/mtd/onenand/omap2.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)drivers/mtd/onenand/omap2.c +0
-0
drivers/mtd/onenand/omap2.c static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data) · line 86
Quoted 9 lines
drivers/mtd/onenand/omap2.c +1
-2@@ -80,8 +80,7 @@ static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)complete (&info->dma_done); } -static irqreturn_t omap2_onenand_interrupt (int irq,void *dev_id, -struct pt_regs *regs) +static irqreturn_t omap2_onenand_interrupt (int irq,void *dev_id) {struct omap2_onenand *info = dev_id;
Pushing this today.
Tony