2 /* Common Flash Interface structures
3 * See http://support.intel.com/design/flash/technote/index.htm
4 * $Id: cfi.h,v 1.35 2003/05/28 15:37:32 dwmw2 Exp $
10 #include <linux/config.h>
11 #include <linux/version.h>
12 #include <linux/delay.h>
13 #include <linux/types.h>
14 #include <linux/interrupt.h>
15 #include <linux/mtd/flashchip.h>
16 #include <linux/mtd/cfi_endian.h>
19 * You can optimize the code size and performance by defining only
20 * the geometry(ies) available on your hardware.
21 * CFIDEV_INTERLEAVE_n, where represents the interleave (number of chips to fill the bus width)
22 * CFIDEV_BUSWIDTH_n, where n is the bus width in bytes (1, 2, 4 or 8 bytes)
24 * By default, all (known) geometries are supported.
27 #ifndef CONFIG_MTD_CFI_GEOMETRY
29 /* The default case - support all but 64-bit, which has
30 a performance penalty */
32 #define CFIDEV_INTERLEAVE_1 (1)
33 #define CFIDEV_INTERLEAVE_2 (2)
34 #define CFIDEV_INTERLEAVE_4 (4)
36 #define CFIDEV_BUSWIDTH_1 (1)
37 #define CFIDEV_BUSWIDTH_2 (2)
38 #define CFIDEV_BUSWIDTH_4 (4)
40 typedef __u32 cfi_word;
44 /* Explicitly configured buswidth/interleave support */
46 #ifdef CONFIG_MTD_CFI_I1
47 #define CFIDEV_INTERLEAVE_1 (1)
49 #ifdef CONFIG_MTD_CFI_I2
50 #define CFIDEV_INTERLEAVE_2 (2)
52 #ifdef CONFIG_MTD_CFI_I4
53 #define CFIDEV_INTERLEAVE_4 (4)
55 #ifdef CONFIG_MTD_CFI_I8
56 #define CFIDEV_INTERLEAVE_8 (8)
59 #ifdef CONFIG_MTD_CFI_B1
60 #define CFIDEV_BUSWIDTH_1 (1)
62 #ifdef CONFIG_MTD_CFI_B2
63 #define CFIDEV_BUSWIDTH_2 (2)
65 #ifdef CONFIG_MTD_CFI_B4
66 #define CFIDEV_BUSWIDTH_4 (4)
68 #ifdef CONFIG_MTD_CFI_B8
69 #define CFIDEV_BUSWIDTH_8 (8)
72 /* pick the largest necessary */
73 #ifdef CONFIG_MTD_CFI_B8
74 typedef __u64 cfi_word;
76 /* This only works if asm/io.h is included first */
78 #define __raw_readll(addr) (*(volatile __u64 *)(addr))
81 #define __raw_writell(v, addr) (*(volatile __u64 *)(addr) = (v))
84 #else /* CONFIG_MTD_CFI_B8 */
85 /* All others can use 32-bits. It's probably more efficient than
86 the smaller types anyway */
87 typedef __u32 cfi_word;
88 #endif /* CONFIG_MTD_CFI_B8 */
93 * The following macros are used to select the code to execute:
95 * cfi_interleave_is_*()
96 * [where * is either 1, 2, 4, or 8]
97 * Those macros should be used with 'if' statements. If only one of few
98 * geometry arrangements are selected, they expand to constants thus allowing
99 * the compiler (most of them being 0) to optimize away all the unneeded code,
100 * while still validating the syntax (which is not possible with embedded
101 * #if ... #endif constructs).
102 * The exception to this is the 64-bit versions, which need an extension
103 * to the cfi_word type, and cause compiler warnings about shifts being
107 #ifdef CFIDEV_INTERLEAVE_1
108 # ifdef CFIDEV_INTERLEAVE
109 # undef CFIDEV_INTERLEAVE
110 # define CFIDEV_INTERLEAVE (cfi->interleave)
112 # define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_1
114 # define cfi_interleave_is_1() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_1)
116 # define cfi_interleave_is_1() (0)
119 #ifdef CFIDEV_INTERLEAVE_2
120 # ifdef CFIDEV_INTERLEAVE
121 # undef CFIDEV_INTERLEAVE
122 # define CFIDEV_INTERLEAVE (cfi->interleave)
124 # define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_2
126 # define cfi_interleave_is_2() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_2)
128 # define cfi_interleave_is_2() (0)
131 #ifdef CFIDEV_INTERLEAVE_4
132 # ifdef CFIDEV_INTERLEAVE
133 # undef CFIDEV_INTERLEAVE
134 # define CFIDEV_INTERLEAVE (cfi->interleave)
136 # define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_4
138 # define cfi_interleave_is_4() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_4)
140 # define cfi_interleave_is_4() (0)
143 #ifdef CFIDEV_INTERLEAVE_8
144 # ifdef CFIDEV_INTERLEAVE
145 # undef CFIDEV_INTERLEAVE
146 # define CFIDEV_INTERLEAVE (cfi->interleave)
148 # define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_8
150 # define cfi_interleave_is_8() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_8)
152 # define cfi_interleave_is_8() (0)
155 #ifndef CFIDEV_INTERLEAVE
156 #error You must define at least one interleave to support!
159 #ifdef CFIDEV_BUSWIDTH_1
160 # ifdef CFIDEV_BUSWIDTH
161 # undef CFIDEV_BUSWIDTH
162 # define CFIDEV_BUSWIDTH (map->buswidth)
164 # define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_1
166 # define cfi_buswidth_is_1() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_1)
168 # define cfi_buswidth_is_1() (0)
171 #ifdef CFIDEV_BUSWIDTH_2
172 # ifdef CFIDEV_BUSWIDTH
173 # undef CFIDEV_BUSWIDTH
174 # define CFIDEV_BUSWIDTH (map->buswidth)
176 # define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_2
178 # define cfi_buswidth_is_2() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_2)
180 # define cfi_buswidth_is_2() (0)
183 #ifdef CFIDEV_BUSWIDTH_4
184 # ifdef CFIDEV_BUSWIDTH
185 # undef CFIDEV_BUSWIDTH
186 # define CFIDEV_BUSWIDTH (map->buswidth)
188 # define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_4
190 # define cfi_buswidth_is_4() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_4)
192 # define cfi_buswidth_is_4() (0)
195 #ifdef CFIDEV_BUSWIDTH_8
196 # ifdef CFIDEV_BUSWIDTH
197 # undef CFIDEV_BUSWIDTH
198 # define CFIDEV_BUSWIDTH (map->buswidth)
200 # define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_8
202 # define cfi_buswidth_is_8() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_8)
204 # define cfi_buswidth_is_8() (0)
207 #ifndef CFIDEV_BUSWIDTH
208 #error You must define at least one bus width to support!
211 /* NB: these values must represents the number of bytes needed to meet the
212 * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes.
213 * These numbers are used in calculations.
215 #define CFI_DEVICETYPE_X8 (8 / 8)
216 #define CFI_DEVICETYPE_X16 (16 / 8)
217 #define CFI_DEVICETYPE_X32 (32 / 8)
218 #define CFI_DEVICETYPE_X64 (64 / 8)
220 /* NB: We keep these structures in memory in HOST byteorder, except
221 * where individually noted.
224 /* Basic Query Structure */
235 __u8 WordWriteTimeoutTyp;
236 __u8 BufWriteTimeoutTyp;
237 __u8 BlockEraseTimeoutTyp;
238 __u8 ChipEraseTimeoutTyp;
239 __u8 WordWriteTimeoutMax;
240 __u8 BufWriteTimeoutMax;
241 __u8 BlockEraseTimeoutMax;
242 __u8 ChipEraseTimeoutMax;
245 __u16 MaxBufWriteSize;
246 __u8 NumEraseRegions;
247 __u32 EraseRegionInfo[0]; /* Not host ordered */
248 } __attribute__((packed));
250 /* Extended Query Structure for both PRI and ALT */
252 struct cfi_extquery {
256 } __attribute__((packed));
258 /* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */
260 struct cfi_pri_intelext {
264 __u32 FeatureSupport;
265 __u8 SuspendCmdSupport;
266 __u16 BlkStatusRegMask;
269 __u8 NumProtectionFields;
271 __u8 FactProtRegSize;
272 __u8 UserProtRegSize;
273 } __attribute__((packed));
275 struct cfi_pri_query {
277 __u32 ProtField[1]; /* Not host ordered */
278 } __attribute__((packed));
280 struct cfi_bri_query {
281 __u8 PageModeReadCap;
283 __u32 ConfField[1]; /* Not host ordered */
284 } __attribute__((packed));
287 #define P_ID_INTEL_EXT 1
288 #define P_ID_AMD_STD 2
289 #define P_ID_INTEL_STD 3
290 #define P_ID_AMD_EXT 4
291 #define P_ID_MITSUBISHI_STD 256
292 #define P_ID_MITSUBISHI_EXT 257
293 #define P_ID_RESERVED 65535
296 #define CFI_MODE_CFI 1
297 #define CFI_MODE_JEDEC 0
304 int cfi_mode; /* Are we a JEDEC device pretending to be CFI? */
308 struct mtd_info *(*cmdset_setup)(struct map_info *);
309 struct cfi_ident *cfiq; /* For now only one. We insist that all devs
310 must be of the same type. */
313 unsigned long chipshift; /* Because they're of the same type */
314 const char *im_name; /* inter_module name for cmdset_setup */
315 struct flchip chips[0]; /* per-chip data structure for each chip */
318 #define MAX_CFI_CHIPS 8 /* Entirely arbitrary to avoid realloc() */
321 * Returns the command address according to the given geometry.
323 static inline __u32 cfi_build_cmd_addr(__u32 cmd_ofs, int interleave, int type)
325 return (cmd_ofs * type) * interleave;
329 * Transforms the CFI command for the given geometry (bus width & interleave.
331 static inline cfi_word cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi)
335 if (cfi_buswidth_is_1()) {
338 } else if (cfi_buswidth_is_2()) {
339 if (cfi_interleave_is_1()) {
340 /* 1 x16 device in x16 mode */
341 val = cpu_to_cfi16(cmd);
342 } else if (cfi_interleave_is_2()) {
343 /* 2 (x8, x16 or x32) devices in x8 mode */
344 val = cpu_to_cfi16((cmd << 8) | cmd);
346 } else if (cfi_buswidth_is_4()) {
347 if (cfi_interleave_is_1()) {
348 /* 1 x32 device in x32 mode */
349 val = cpu_to_cfi32(cmd);
350 } else if (cfi_interleave_is_2()) {
351 /* 2 x16 device in x16 mode */
352 val = cpu_to_cfi32((cmd << 16) | cmd);
353 } else if (cfi_interleave_is_4()) {
354 /* 4 (x8, x16 or x32) devices in x8 mode */
355 val = (cmd << 16) | cmd;
356 val = cpu_to_cfi32((val << 8) | val);
359 } else if (cfi_buswidth_is_8()) {
360 if (cfi_interleave_is_1()) {
361 /* 1 x64 device in x64 mode */
362 val = cpu_to_cfi64(cmd);
363 } else if (cfi_interleave_is_2()) {
364 /* 2 x32 device in x32 mode */
366 val = cpu_to_cfi64((val << 32) | val);
367 } else if (cfi_interleave_is_4()) {
368 /* 4 (x16, x32 or x64) devices in x16 mode */
369 val = (cmd << 16) | cmd;
370 val = cpu_to_cfi64((val << 32) | val);
371 } else if (cfi_interleave_is_8()) {
372 /* 8 (x8, x16 or x32) devices in x8 mode */
373 val = (cmd << 8) | cmd;
374 val = (val << 16) | val;
375 val = (val << 32) | val;
376 val = cpu_to_cfi64(val);
378 #endif /* CFI_WORD_64 */
382 #define CMD(x) cfi_build_cmd((x), map, cfi)
385 * Read a value according to the bus width.
388 static inline cfi_word cfi_read(struct map_info *map, __u32 addr)
390 if (cfi_buswidth_is_1()) {
391 return map_read8(map, addr);
392 } else if (cfi_buswidth_is_2()) {
393 return map_read16(map, addr);
394 } else if (cfi_buswidth_is_4()) {
395 return map_read32(map, addr);
396 } else if (cfi_buswidth_is_8()) {
397 return map_read64(map, addr);
404 * Write a value according to the bus width.
407 static inline void cfi_write(struct map_info *map, cfi_word val, __u32 addr)
409 if (cfi_buswidth_is_1()) {
410 map_write8(map, val, addr);
411 } else if (cfi_buswidth_is_2()) {
412 map_write16(map, val, addr);
413 } else if (cfi_buswidth_is_4()) {
414 map_write32(map, val, addr);
415 } else if (cfi_buswidth_is_8()) {
416 map_write64(map, val, addr);
421 * Sends a CFI command to a bank of flash for the given geometry.
423 * Returns the offset in flash where the command was written.
424 * If prev_val is non-null, it will be set to the value at the command address,
425 * before the command was written.
427 static inline __u32 cfi_send_gen_cmd(u_char cmd, __u32 cmd_addr, __u32 base,
428 struct map_info *map, struct cfi_private *cfi,
429 int type, cfi_word *prev_val)
432 __u32 addr = base + cfi_build_cmd_addr(cmd_addr, CFIDEV_INTERLEAVE, type);
434 val = cfi_build_cmd(cmd, map, cfi);
437 *prev_val = cfi_read(map, addr);
439 cfi_write(map, val, addr);
444 static inline __u8 cfi_read_query(struct map_info *map, __u32 addr)
446 if (cfi_buswidth_is_1()) {
447 return map_read8(map, addr);
448 } else if (cfi_buswidth_is_2()) {
449 return cfi16_to_cpu(map_read16(map, addr));
450 } else if (cfi_buswidth_is_4()) {
451 return cfi32_to_cpu(map_read32(map, addr));
452 } else if (cfi_buswidth_is_8()) {
453 return cfi64_to_cpu(map_read64(map, addr));
459 static inline void cfi_udelay(int us)
461 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
462 unsigned long t = us * HZ / 1000000;
464 set_current_state(TASK_UNINTERRUPTIBLE);
473 static inline void cfi_spin_lock(spinlock_t *mutex)
478 static inline void cfi_spin_unlock(spinlock_t *mutex)
480 spin_unlock_bh(mutex);
483 #endif /* __MTD_CFI_H__ */