* [PATCH/RFC] Add Amstrad Delta NAND support.
@ 2006-04-24 16:15 Jonathan McDowell
2006-04-25 13:43 ` David Woodhouse
2006-05-14 2:45 ` David Woodhouse
0 siblings, 2 replies; 7+ messages in thread
From: Jonathan McDowell @ 2006-04-24 16:15 UTC (permalink / raw)
To: linux-mtd
The patch below adds support for the NAND device on the Amstrad Delta.
This is a 32MB 8bit Toshiba device, with the data bus connected to the
OMAP MPUIO pins and ALE, CLE, NCE, NRE, NWE and NWP all connected to the
Delta's latch2 16bit latch.
I'm submitting this purely for comments at this stage. While I have
tested it (booting fine with the NAND as / and able to read/write to it
ok) and had a report from another user that it works fine for them I
would appreciate any opinions you may have about the code.
In particular I'm using "udelay(1);" in the read/write routines to wait
for the bus to settle after setting the read/write enable lines. Really
I want "ndelay(40);", but ndelay doesn't seem to be implemented on ARM,
except in terms of udelay. Can I get away with udelay(0.04)? Should I be
doing something else entirely?
-----
diff -rupN -X linux-2.6.16-omap2/Documentation/dontdiff linux-2.6.16-e3-04/drivers/mtd/nand/ams-delta.c linux-2.6.16-e3-05/drivers/mtd/nand/ams-delta.c
--- linux-2.6.16-e3-04/drivers/mtd/nand/ams-delta.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.16-e3-05/drivers/mtd/nand/ams-delta.c 2006-04-07 22:16:07.478356500 +0100
@@ -0,0 +1,243 @@
+/*
+ * drivers/mtd/nand/ams-delta.c
+ *
+ * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
+ *
+ * Derived from drivers/mtd/toto.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Overview:
+ * This is a device driver for the NAND flash device found on the
+ * Amstrad E3 (Delta).
+ */
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/sizes.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/board-ams-delta.h>
+
+/*
+ * MTD structure for E3 (Delta)
+ */
+static struct mtd_info *ams_delta_mtd = NULL;
+
+#define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP)
+
+#define T_NAND_CTL_CLRALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, 0)
+#define T_NAND_CTL_SETALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, AMS_DELTA_LATCH2_NAND_ALE)
+#define T_NAND_CTL_CLRCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, 0)
+#define T_NAND_CTL_SETCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, AMS_DELTA_LATCH2_NAND_CLE)
+#define T_NAND_CTL_SETNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, 0)
+#define T_NAND_CTL_CLRNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, AMS_DELTA_LATCH2_NAND_NCE)
+
+/*
+ * Define partitions for flash devices
+ */
+
+static struct mtd_partition partition_info[] = {
+ { .name = "Kernel",
+ .offset = 0,
+ .size = 3 * SZ_1M + SZ_512K },
+ { .name = "u-boot",
+ .offset = 3 * SZ_1M + SZ_512K,
+ .size = SZ_256K },
+ { .name = "u-boot params",
+ .offset = 3 * SZ_1M + SZ_512K + SZ_256K,
+ .size = SZ_256K },
+ { .name = "Amstrad LDR",
+ .offset = 4 * SZ_1M,
+ .size = SZ_256K },
+ { .name = "File system",
+ .offset = 4 * SZ_1M + 1 * SZ_256K,
+ .size = 27 * SZ_1M },
+ { .name = "PBL reserved",
+ .offset = 32 * SZ_1M - 3 * SZ_256K,
+ .size = 3 * SZ_256K },
+};
+
+/*
+ * hardware specific access to control-lines
+*/
+
+static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+ switch(cmd){
+
+ case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break;
+ case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break;
+
+ case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break;
+ case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break;
+
+ case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break;
+ case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break;
+ }
+}
+
+static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte)
+{
+ struct nand_chip *this = mtd->priv;
+
+ omap_writew(0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
+ omap_writew(byte, this->IO_ADDR_W);
+ ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, 0);
+ udelay(1);
+ ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE,
+ AMS_DELTA_LATCH2_NAND_NWE);
+}
+
+static u_char ams_delta_read_byte(struct mtd_info *mtd)
+{
+ u_char res;
+ struct nand_chip *this = mtd->priv;
+
+ ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, 0);
+ udelay(1);
+ omap_writew(~0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
+ res = omap_readw(this->IO_ADDR_R);
+ ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE,
+ AMS_DELTA_LATCH2_NAND_NRE);
+
+ return res;
+}
+
+/*
+ * These 3 functions are basically identical to the ones in nand_base.c, but
+ * we have to call our read_byte/write_byte functions instead of readb/writeb
+ * directly. I submitted a patch to MTD to move this to nand_base.c, but it
+ * was deemed too intrusive.
+ */
+static void ams_delta_write_buf(struct mtd_info *mtd, const u_char *buf,
+ int len)
+{
+ int i;
+
+ for (i=0; i<len; i++)
+ ams_delta_write_byte(mtd, buf[i]);
+}
+
+static void ams_delta_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+ int i;
+
+ for (i=0; i<len; i++)
+ buf[i] = ams_delta_read_byte(mtd);
+}
+
+static int ams_delta_verify_buf(struct mtd_info *mtd, const u_char *buf,
+ int len)
+{
+ int i;
+
+ for (i=0; i<len; i++)
+ if (buf[i] != ams_delta_read_byte(mtd))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int ams_delta_nand_ready(struct mtd_info *mtd)
+{
+ return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB);
+}
+
+/*
+ * Main initialization routine
+ */
+int __init ams_delta_init (void)
+{
+ struct nand_chip *this;
+ int err = 0;
+
+ /* Allocate memory for MTD device structure and private data */
+ ams_delta_mtd = kmalloc (sizeof(struct mtd_info) +
+ sizeof (struct nand_chip), GFP_KERNEL);
+ if (!ams_delta_mtd) {
+ printk (KERN_WARNING
+ "Unable to allocate E3 NAND MTD device structure.\n");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /* Get pointer to private data */
+ this = (struct nand_chip *) (&ams_delta_mtd[1]);
+
+ /* Initialize structures */
+ memset((char *) ams_delta_mtd, 0, sizeof(struct mtd_info));
+ memset((char *) this, 0, sizeof(struct nand_chip));
+
+ /* Link the private data with the MTD structure */
+ ams_delta_mtd->priv = this;
+
+ /* Set address of NAND IO lines */
+ this->IO_ADDR_R = (OMAP_MPUIO_BASE + OMAP_MPUIO_INPUT_LATCH);
+ this->IO_ADDR_W = (OMAP_MPUIO_BASE + OMAP_MPUIO_OUTPUT);
+ this->read_byte = ams_delta_read_byte;
+ this->write_byte = ams_delta_write_byte;
+ this->write_buf = ams_delta_write_buf;
+ this->read_buf = ams_delta_read_buf;
+ this->verify_buf = ams_delta_verify_buf;
+ this->hwcontrol = ams_delta_hwcontrol;
+ if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) {
+ this->dev_ready = ams_delta_nand_ready;
+ } else {
+ this->dev_ready = NULL;
+ printk(KERN_NOTICE
+ "Couldn't request gpio for Delta NAND ready.\n");
+ }
+ /* 25 us command delay time */
+ this->chip_delay = 30;
+ this->eccmode = NAND_ECC_SOFT;
+
+ /* Set chip enabled, but */
+ ams_delta_latch2_write(NAND_MASK, AMS_DELTA_LATCH2_NAND_NRE | \
+ AMS_DELTA_LATCH2_NAND_NWE | \
+ AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP);
+
+ /* Scan to find existance of the device */
+ if (nand_scan (ams_delta_mtd, 1)) {
+ err = -ENXIO;
+ goto out_mtd;
+ }
+
+ /* Register the partitions */
+ add_mtd_partitions(ams_delta_mtd, partition_info,
+ ARRAY_SIZE(partition_info));
+
+ goto out;
+
+out_mtd:
+ kfree (ams_delta_mtd);
+out:
+ return err;
+}
+
+module_init(ams_delta_init);
+
+/*
+ * Clean up routine
+ */
+static void __exit ams_delta_cleanup (void)
+{
+ /* Release resources, unregister device */
+ nand_release (ams_delta_mtd);
+
+ /* Free the MTD device structure */
+ kfree (ams_delta_mtd);
+}
+module_exit(ams_delta_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
+MODULE_DESCRIPTION("Glue layer for NAND flash on Amstrad E3 (Delta)");
diff -rupN -X linux-2.6.16-omap2/Documentation/dontdiff linux-2.6.16-e3-04/drivers/mtd/nand/Kconfig linux-2.6.16-e3-05/drivers/mtd/nand/Kconfig
--- linux-2.6.16-e3-04/drivers/mtd/nand/Kconfig 2006-04-05 22:34:46.335154000 +0100
+++ linux-2.6.16-e3-05/drivers/mtd/nand/Kconfig 2006-04-07 17:47:38.526328000 +0100
@@ -55,6 +55,12 @@ config MTD_NAND_OMAP
help
Support for NAND flash on Texas Instruments H3/H2/P2 platforms.
+config MTD_NAND_AMS_DELTA
+ tristate "NAND Flash device on Amstrad E3"
+ depends on MACH_AMS_DELTA && MTD_NAND
+ help
+ Support for NAND flash on Amstrad E3 (Delta).
+
config MTD_NAND_TOTO
tristate "NAND Flash device on TOTO board"
depends on ARCH_OMAP && MTD_NAND
diff -rupN -X linux-2.6.16-omap2/Documentation/dontdiff linux-2.6.16-e3-04/drivers/mtd/nand/Makefile linux-2.6.16-e3-05/drivers/mtd/nand/Makefile
--- linux-2.6.16-e3-04/drivers/mtd/nand/Makefile 2006-04-05 22:34:46.339154250 +0100
+++ linux-2.6.16-e3-05/drivers/mtd/nand/Makefile 2006-04-07 17:47:38.526328000 +0100
@@ -7,6 +7,7 @@ obj-$(CONFIG_MTD_NAND) += nand.o nand_
obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
+obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o
obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
-----
J.
--
/------------------------------------\
| noodles is not pasta |
\------------------------------------/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH/RFC] Add Amstrad Delta NAND support.
2006-04-24 16:15 [PATCH/RFC] Add Amstrad Delta NAND support Jonathan McDowell
@ 2006-04-25 13:43 ` David Woodhouse
2006-04-25 13:48 ` Jörn Engel
2006-04-25 14:03 ` Jonathan McDowell
2006-05-14 2:45 ` David Woodhouse
1 sibling, 2 replies; 7+ messages in thread
From: David Woodhouse @ 2006-04-25 13:43 UTC (permalink / raw)
To: Jonathan McDowell; +Cc: linux-mtd
On Mon, 2006-04-24 at 17:15 +0100, Jonathan McDowell wrote:
> The patch below adds support for the NAND device on the Amstrad Delta.
> This is a 32MB 8bit Toshiba device, with the data bus connected to the
> OMAP MPUIO pins and ALE, CLE, NCE, NRE, NWE and NWP all connected to the
> Delta's latch2 16bit latch.
>
> I'm submitting this purely for comments at this stage. While I have
> tested it (booting fine with the NAND as / and able to read/write to it
> ok) and had a report from another user that it works fine for them I
> would appreciate any opinions you may have about the code.
Looks OK to me in general.
> In particular I'm using "udelay(1);" in the read/write routines to wait
> for the bus to settle after setting the read/write enable lines. Really
> I want "ndelay(40);", but ndelay doesn't seem to be implemented on ARM,
> except in terms of udelay. Can I get away with udelay(0.04)? Should I be
> doing something else entirely?
That's a question best directed at linux-arm-kernel list.
> +/*
> + * These 3 functions are basically identical to the ones in nand_base.c, but
> + * we have to call our read_byte/write_byte functions instead of readb/writeb
> + * directly. I submitted a patch to MTD to move this to nand_base.c, but it
> + * was deemed too intrusive.
> + */
Thomas' decision, I assume? I think he's right -- this way it can be
inlined in the loop rather than being a real function call for every
byte.
--
dwmw2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH/RFC] Add Amstrad Delta NAND support.
2006-04-25 13:43 ` David Woodhouse
@ 2006-04-25 13:48 ` Jörn Engel
2006-04-25 13:58 ` David Woodhouse
2006-04-25 14:03 ` Jonathan McDowell
1 sibling, 1 reply; 7+ messages in thread
From: Jörn Engel @ 2006-04-25 13:48 UTC (permalink / raw)
To: David Woodhouse; +Cc: Jonathan McDowell, linux-mtd
On Tue, 25 April 2006 14:43:12 +0100, David Woodhouse wrote:
>
> > +/*
> > + * These 3 functions are basically identical to the ones in nand_base.c, but
> > + * we have to call our read_byte/write_byte functions instead of readb/writeb
> > + * directly. I submitted a patch to MTD to move this to nand_base.c, but it
> > + * was deemed too intrusive.
> > + */
>
> Thomas' decision, I assume? I think he's right -- this way it can be
> inlined in the loop rather than being a real function call for every
> byte.
We could have a nand_read_byte()/nand_write_byte() pair of macros that
are defined to readb/writeb for the generic case and to
read_byte/write_byte for CONFIG_FIND_SOME_SANE_NAME.
Jörn
--
My second remark is that our intellectual powers are rather geared to
master static relations and that our powers to visualize processes
evolving in time are relatively poorly developed.
-- Edsger W. Dijkstra
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH/RFC] Add Amstrad Delta NAND support.
2006-04-25 13:48 ` Jörn Engel
@ 2006-04-25 13:58 ` David Woodhouse
2006-04-25 14:05 ` Jörn Engel
0 siblings, 1 reply; 7+ messages in thread
From: David Woodhouse @ 2006-04-25 13:58 UTC (permalink / raw)
To: Jörn Engel; +Cc: Jonathan McDowell, linux-mtd
On Tue, 2006-04-25 at 15:48 +0200, Jörn Engel wrote:
> We could have a nand_read_byte()/nand_write_byte() pair of macros that
> are defined to readb/writeb for the generic case and to
> read_byte/write_byte for CONFIG_FIND_SOME_SANE_NAME.
That makes nand.o non-generic, and prevents you from using it for
multiple 'board drivers' in the same kernel build.
--
dwmw2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH/RFC] Add Amstrad Delta NAND support.
2006-04-25 13:43 ` David Woodhouse
2006-04-25 13:48 ` Jörn Engel
@ 2006-04-25 14:03 ` Jonathan McDowell
1 sibling, 0 replies; 7+ messages in thread
From: Jonathan McDowell @ 2006-04-25 14:03 UTC (permalink / raw)
To: David Woodhouse; +Cc: linux-mtd
On Tue, Apr 25, 2006 at 02:43:12PM +0100, David Woodhouse wrote:
> On Mon, 2006-04-24 at 17:15 +0100, Jonathan McDowell wrote:
> > In particular I'm using "udelay(1);" in the read/write routines to wait
> > for the bus to settle after setting the read/write enable lines. Really
> > I want "ndelay(40);", but ndelay doesn't seem to be implemented on ARM,
> > except in terms of udelay. Can I get away with udelay(0.04)? Should I be
> > doing something else entirely?
>
> That's a question best directed at linux-arm-kernel list.
Ok, ta.
> > +/*
> > + * These 3 functions are basically identical to the ones in nand_base.c, but
> > + * we have to call our read_byte/write_byte functions instead of readb/writeb
> > + * directly. I submitted a patch to MTD to move this to nand_base.c, but it
> > + * was deemed too intrusive.
> > + */
>
> Thomas' decision, I assume? I think he's right -- this way it can be
> inlined in the loop rather than being a real function call for every
> byte.
Ben Dooks. I'd actually forgotten I'd left that comment in. I'll remove
it before I submit the patch proper; it was mainly a note to people who
might have picked up my earlier version that patches nand-core as well.
J.
--
/-\ | What's the worse that could
|@/ Debian GNU/Linux Developer | happen? Smoke. - Anonymous
\- | HWHacker
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH/RFC] Add Amstrad Delta NAND support.
2006-04-25 13:58 ` David Woodhouse
@ 2006-04-25 14:05 ` Jörn Engel
0 siblings, 0 replies; 7+ messages in thread
From: Jörn Engel @ 2006-04-25 14:05 UTC (permalink / raw)
To: David Woodhouse; +Cc: Jonathan McDowell, linux-mtd
On Tue, 25 April 2006 14:58:24 +0100, David Woodhouse wrote:
> On Tue, 2006-04-25 at 15:48 +0200, Jörn Engel wrote:
> > We could have a nand_read_byte()/nand_write_byte() pair of macros that
> > are defined to readb/writeb for the generic case and to
> > read_byte/write_byte for CONFIG_FIND_SOME_SANE_NAME.
>
> That makes nand.o non-generic, and prevents you from using it for
> multiple 'board drivers' in the same kernel build.
Valid concern. Still, I'd like some method to at least share all the
identical source code. You know the usual problems when two copies of
essentially the same get out of sync.
Jörn
--
Beware of bugs in the above code; I have only proved it correct, but
not tried it.
-- Donald Knuth
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH/RFC] Add Amstrad Delta NAND support.
2006-04-24 16:15 [PATCH/RFC] Add Amstrad Delta NAND support Jonathan McDowell
2006-04-25 13:43 ` David Woodhouse
@ 2006-05-14 2:45 ` David Woodhouse
1 sibling, 0 replies; 7+ messages in thread
From: David Woodhouse @ 2006-05-14 2:45 UTC (permalink / raw)
To: Jonathan McDowell; +Cc: linux-mtd
On Mon, 2006-04-24 at 17:15 +0100, Jonathan McDowell wrote:
> he patch below adds support for the NAND device on the Amstrad Delta.
> This is a 32MB 8bit Toshiba device, with the data bus connected to the
> OMAP MPUIO pins and ALE, CLE, NCE, NRE, NWE and NWP all connected to the
> Delta's latch2 16bit latch.
>
> I'm submitting this purely for comments at this stage. While I have
> tested it (booting fine with the NAND as / and able to read/write to it
> ok) and had a report from another user that it works fine for them I
> would appreciate any opinions you may have about the code.
Needs to set ams_delta_mtd->owner = THIS_MODULE; before calling
nand_scan().
--
dwmw2
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-05-14 2:45 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-24 16:15 [PATCH/RFC] Add Amstrad Delta NAND support Jonathan McDowell
2006-04-25 13:43 ` David Woodhouse
2006-04-25 13:48 ` Jörn Engel
2006-04-25 13:58 ` David Woodhouse
2006-04-25 14:05 ` Jörn Engel
2006-04-25 14:03 ` Jonathan McDowell
2006-05-14 2:45 ` David Woodhouse
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox