From: Adam Wozniak <adam.wozniak@comdev.cc>
To: David Woodhouse <dwmw2@infradead.org>
Cc: linux-mtd@lists.infradead.org
Subject: Re: patch for 64 bit wide flash
Date: Thu, 27 Dec 2001 15:31:30 -0800 [thread overview]
Message-ID: <3C2BAF52.F0535E2E@comdev.cc> (raw)
In-Reply-To: 3698.1008926053@redhat.com
[-- Attachment #1: Type: text/plain, Size: 1552 bytes --]
David Woodhouse wrote:
>
> adam.wozniak@comdev.cc said:
> > I've got a 64 bit wide flash consisting of eight 8bit wide chips.
> > Here's a patch against the 2.4.16 kernel
>
> I'm a little concerned about the following bit - gcc is fairly crap at
> dealing with 64-bit datatypes. I'd prefer to do that only if it's
> necessary. Can we define a cfi_busword type which is only as big as we need
> - so it's only a __u64 if CONFIG_MTD_CFI_B8 is set?
Here's a new patch.
cfi.h has the following in it (paraphrased and indented for readablity):
#ifndef CONFIG_MTD_CFI_GEOMETRY
/* we don't know what we'll get, so we pick the largest possible here */
typedef __u64 cfi_word;
#else
/* pick the largest necessary */
#ifdef CONFIG_MTD_CFI_B8
typedef __u64 cfi_word;
#else /* CONFIG_MTD_CFI_B8 */
#ifdef CONFIG_MTD_CFI_B4
typedef __u32 cfi_word;
#else /* CONFIG_MTD_CFI_B4 */
#ifdef CONFIG_MTD_CFI_B2
typedef __u16 cfi_word;
#else /* CONFIG_MTD_CFI_B2 */
#ifdef CONFIG_MTD_CFI_B1
typedef __u8 cfi_word;
#else /* CONFIG_MTD_CFI_B1 */
#error You must specify a bus width
#endif /* CONFIG_MTD_CFI_B1 */
#endif /* CONFIG_MTD_CFI_B2 */
#endif /* CONFIG_MTD_CFI_B4 */
#endif /* CONFIG_MTD_CFI_B8 */
#endif
--
Adam Wozniak (KG6GZR) COM DEV Wireless - Digital and Software Systems
awozniak@comdev.cc 3450 Broad St. 107, San Luis Obispo, CA 93401
http://www.comdev.cc
Voice: (805) 544-1089 Fax: (805) 544-2055
[-- Attachment #2: mtd_delta --]
[-- Type: text/plain, Size: 8460 bytes --]
diff -urbBN --exclude=autoconf.h --exclude=compile.h --exclude=version.h --exclude=config --exclude=asm --exclude=asm-ppc --exclude=.*depend --exclude=*.flags --exclude=*.o linux-original/include/linux/mtd/cfi.h linux/include/linux/mtd/cfi.h
--- linux-original/include/linux/mtd/cfi.h Thu Oct 4 15:13:18 2001
+++ linux/include/linux/mtd/cfi.h Thu Dec 27 15:21:09 2001
@@ -28,10 +28,15 @@
#define CFIDEV_INTERLEAVE_1 (1)
#define CFIDEV_INTERLEAVE_2 (2)
#define CFIDEV_INTERLEAVE_4 (4)
+#define CFIDEV_INTERLEAVE_8 (8)
#define CFIDEV_BUSWIDTH_1 (1)
#define CFIDEV_BUSWIDTH_2 (2)
#define CFIDEV_BUSWIDTH_4 (4)
+#define CFIDEV_BUSWIDTH_8 (8)
+
+/* we don't know what we'll get, so we pick the largest possible here */
+typedef __u64 cfi_word;
#else
@@ -44,6 +49,9 @@
#ifdef CONFIG_MTD_CFI_I4
#define CFIDEV_INTERLEAVE_4 (4)
#endif
+#ifdef CONFIG_MTD_CFI_I8
+#define CFIDEV_INTERLEAVE_8 (8)
+#endif
#ifdef CONFIG_MTD_CFI_B1
#define CFIDEV_BUSWIDTH_1 (1)
@@ -54,6 +62,28 @@
#ifdef CONFIG_MTD_CFI_B4
#define CFIDEV_BUSWIDTH_4 (4)
#endif
+#ifdef CONFIG_MTD_CFI_B8
+#define CFIDEV_BUSWIDTH_8 (8)
+#endif
+
+/* pick the largest necessary */
+#ifdef CONFIG_MTD_CFI_B8
+typedef __u64 cfi_word;
+#else /* CONFIG_MTD_CFI_B8 */
+#ifdef CONFIG_MTD_CFI_B4
+typedef __u32 cfi_word;
+#else /* CONFIG_MTD_CFI_B4 */
+#ifdef CONFIG_MTD_CFI_B2
+typedef __u16 cfi_word;
+#else /* CONFIG_MTD_CFI_B2 */
+#ifdef CONFIG_MTD_CFI_B1
+typedef __u8 cfi_word;
+#else /* CONFIG_MTD_CFI_B1 */
+#error You must specify a bus width
+#endif /* CONFIG_MTD_CFI_B1 */
+#endif /* CONFIG_MTD_CFI_B2 */
+#endif /* CONFIG_MTD_CFI_B4 */
+#endif /* CONFIG_MTD_CFI_B8 */
#endif
@@ -61,7 +91,7 @@
* The following macros are used to select the code to execute:
* cfi_buswidth_is_*()
* cfi_interleave_is_*()
- * [where * is either 1, 2 or 4]
+ * [where * is either 1, 2, 4, or 8]
* Those macros should be used with 'if' statements. If only one of few
* geometry arrangements are selected, they expand to constants thus allowing
* the compiler (most of them being 0) to optimize away all the unneeded code,
@@ -105,6 +135,18 @@
# define cfi_interleave_is_4() (0)
#endif
+#ifdef CFIDEV_INTERLEAVE_8
+# ifdef CFIDEV_INTERLEAVE
+# undef CFIDEV_INTERLEAVE
+# define CFIDEV_INTERLEAVE (cfi->interleave)
+# else
+# define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_8
+# endif
+# define cfi_interleave_is_8() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_8)
+#else
+# define cfi_interleave_is_8() (0)
+#endif
+
#ifndef CFIDEV_INTERLEAVE
#error You must define at least one interleave to support!
#endif
@@ -145,6 +187,18 @@
# define cfi_buswidth_is_4() (0)
#endif
+#ifdef CFIDEV_BUSWIDTH_8
+# ifdef CFIDEV_BUSWIDTH
+# undef CFIDEV_BUSWIDTH
+# define CFIDEV_BUSWIDTH (map->buswidth)
+# else
+# define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_8
+# endif
+# define cfi_buswidth_is_8() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_8)
+#else
+# define cfi_buswidth_is_8() (0)
+#endif
+
#ifndef CFIDEV_BUSWIDTH
#error You must define at least one bus width to support!
#endif
@@ -156,6 +210,7 @@
#define CFI_DEVICETYPE_X8 (8 / 8)
#define CFI_DEVICETYPE_X16 (16 / 8)
#define CFI_DEVICETYPE_X32 (32 / 8)
+#define CFI_DEVICETYPE_X64 (64 / 8)
/* NB: We keep these structures in memory in HOST byteorder, except
* where individually noted.
@@ -264,9 +319,9 @@
/*
* Transforms the CFI command for the given geometry (bus width & interleave.
*/
-static inline __u32 cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi)
+static inline cfi_word cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi)
{
- __u32 val = 0;
+ cfi_word val = 0;
if (cfi_buswidth_is_1()) {
/* 1 x8 device */
@@ -291,6 +346,25 @@
val = (cmd << 16) | cmd;
val = cpu_to_cfi32((val << 8) | val);
}
+ } else if (cfi_buswidth_is_8()) {
+ if (cfi_interleave_is_1()) {
+ /* 1 x64 device in x64 mode */
+ val = cpu_to_cfi64(cmd);
+ } else if (cfi_interleave_is_2()) {
+ /* 2 x32 device in x32 mode */
+ val = cmd;
+ val = cpu_to_cfi64((val << 32) | val);
+ } else if (cfi_interleave_is_4()) {
+ /* 4 (x16, x32 or x64) devices in x16 mode */
+ val = (cmd << 16) | cmd;
+ val = cpu_to_cfi64((val << 32) | val);
+ } else if (cfi_interleave_is_8()) {
+ /* 8 (x8, x16 or x32) devices in x8 mode */
+ val = (cmd << 8) | cmd;
+ val = (val << 16) | val;
+ val = (val << 32) | val;
+ val = cpu_to_cfi64(val);
+ }
}
return val;
}
@@ -300,7 +374,7 @@
* Read a value according to the bus width.
*/
-static inline __u32 cfi_read(struct map_info *map, __u32 addr)
+static inline cfi_word cfi_read(struct map_info *map, __u32 addr)
{
if (cfi_buswidth_is_1()) {
return map->read8(map, addr);
@@ -308,6 +382,8 @@
return map->read16(map, addr);
} else if (cfi_buswidth_is_4()) {
return map->read32(map, addr);
+ } else if (cfi_buswidth_is_8()) {
+ return map->read64(map, addr);
} else {
return 0;
}
@@ -317,7 +393,7 @@
* Write a value according to the bus width.
*/
-static inline void cfi_write(struct map_info *map, __u32 val, __u32 addr)
+static inline void cfi_write(struct map_info *map, cfi_word val, __u32 addr)
{
if (cfi_buswidth_is_1()) {
map->write8(map, val, addr);
@@ -325,6 +401,8 @@
map->write16(map, val, addr);
} else if (cfi_buswidth_is_4()) {
map->write32(map, val, addr);
+ } else if (cfi_buswidth_is_8()) {
+ map->write64(map, val, addr);
}
}
@@ -337,9 +415,9 @@
*/
static inline __u32 cfi_send_gen_cmd(u_char cmd, __u32 cmd_addr, __u32 base,
struct map_info *map, struct cfi_private *cfi,
- int type, __u32 *prev_val)
+ int type, cfi_word *prev_val)
{
- __u32 val;
+ cfi_word val;
__u32 addr = base + cfi_build_cmd_addr(cmd_addr, CFIDEV_INTERLEAVE, type);
val = cfi_build_cmd(cmd, map, cfi);
@@ -360,6 +438,8 @@
return cfi16_to_cpu(map->read16(map, addr));
} else if (cfi_buswidth_is_4()) {
return cfi32_to_cpu(map->read32(map, addr));
+ } else if (cfi_buswidth_is_8()) {
+ return cfi64_to_cpu(map->read64(map, addr));
} else {
return 0;
}
diff -urbBN --exclude=autoconf.h --exclude=compile.h --exclude=version.h --exclude=config --exclude=asm --exclude=asm-ppc --exclude=.*depend --exclude=*.flags --exclude=*.o linux-original/include/linux/mtd/cfi_endian.h linux/include/linux/mtd/cfi_endian.h
--- linux-original/include/linux/mtd/cfi_endian.h Thu Oct 4 15:13:18 2001
+++ linux/include/linux/mtd/cfi_endian.h Wed Dec 19 11:52:03 2001
@@ -30,22 +30,28 @@
#define cfi8_to_cpu(x) (x)
#define cpu_to_cfi16(x) cpu_to_le16(x)
#define cpu_to_cfi32(x) cpu_to_le32(x)
+#define cpu_to_cfi64(x) cpu_to_le64(x)
#define cfi16_to_cpu(x) le16_to_cpu(x)
#define cfi32_to_cpu(x) le32_to_cpu(x)
+#define cfi64_to_cpu(x) le64_to_cpu(x)
#elif defined (CFI_BIG_ENDIAN)
#define cpu_to_cfi8(x) (x)
#define cfi8_to_cpu(x) (x)
#define cpu_to_cfi16(x) cpu_to_be16(x)
#define cpu_to_cfi32(x) cpu_to_be32(x)
+#define cpu_to_cfi64(x) cpu_to_be64(x)
#define cfi16_to_cpu(x) be16_to_cpu(x)
#define cfi32_to_cpu(x) be32_to_cpu(x)
+#define cfi64_to_cpu(x) be64_to_cpu(x)
#elif defined (CFI_HOST_ENDIAN)
#define cpu_to_cfi8(x) (x)
#define cfi8_to_cpu(x) (x)
#define cpu_to_cfi16(x) (x)
#define cpu_to_cfi32(x) (x)
+#define cpu_to_cfi64(x) (x)
#define cfi16_to_cpu(x) (x)
#define cfi32_to_cpu(x) (x)
+#define cfi64_to_cpu(x) (x)
#else
#error No CFI endianness defined
#endif
diff -urbBN --exclude=autoconf.h --exclude=compile.h --exclude=version.h --exclude=config --exclude=asm --exclude=asm-ppc --exclude=.*depend --exclude=*.flags --exclude=*.o linux-original/include/linux/mtd/map.h linux/include/linux/mtd/map.h
--- linux-original/include/linux/mtd/map.h Thu Oct 4 15:13:18 2001
+++ linux/include/linux/mtd/map.h Wed Dec 19 11:52:03 2001
@@ -33,6 +33,7 @@
__u8 (*read8)(struct map_info *, unsigned long);
__u16 (*read16)(struct map_info *, unsigned long);
__u32 (*read32)(struct map_info *, unsigned long);
+ __u64 (*read64)(struct map_info *, unsigned long);
/* If it returned a 'long' I'd call it readl.
* It doesn't.
* I won't.
@@ -42,6 +43,7 @@
void (*write8)(struct map_info *, __u8, unsigned long);
void (*write16)(struct map_info *, __u16, unsigned long);
void (*write32)(struct map_info *, __u32, unsigned long);
+ void (*write64)(struct map_info *, __u64, unsigned long);
void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
void (*set_vpp)(struct map_info *, int);
next prev parent reply other threads:[~2001-12-27 23:25 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-12-18 23:27 patch for 64 bit wide flash Adam Wozniak
2001-12-21 9:14 ` David Woodhouse
2001-12-21 16:30 ` Adam Wozniak
2001-12-27 23:31 ` Adam Wozniak [this message]
2002-02-14 12:32 ` Jörn Engel
2002-02-14 12:38 ` David Woodhouse
2002-02-14 12:58 ` Jörn Engel
2002-02-14 14:16 ` Allen Curtis
2002-02-14 16:16 ` Adam Wozniak
2002-02-14 16:48 ` Jörn Engel
-- strict thread matches above, loose matches on Subject: below --
2001-12-29 0:47 Allen Curtis
2001-12-31 16:01 ` adam.wozniak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3C2BAF52.F0535E2E@comdev.cc \
--to=adam.wozniak@comdev.cc \
--cc=dwmw2@infradead.org \
--cc=linux-mtd@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.