diff options
Diffstat (limited to 'include/linux/mtd/cfi.h')
-rw-r--r-- | include/linux/mtd/cfi.h | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index e6b6a1c66bd5..23a568910341 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h | |||
@@ -1,14 +1,13 @@ | |||
1 | 1 | ||
2 | /* Common Flash Interface structures | 2 | /* Common Flash Interface structures |
3 | * See http://support.intel.com/design/flash/technote/index.htm | 3 | * See http://support.intel.com/design/flash/technote/index.htm |
4 | * $Id: cfi.h,v 1.54 2005/06/06 23:04:36 tpoynor Exp $ | 4 | * $Id: cfi.h,v 1.57 2005/11/15 23:28:17 tpoynor Exp $ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef __MTD_CFI_H__ | 7 | #ifndef __MTD_CFI_H__ |
8 | #define __MTD_CFI_H__ | 8 | #define __MTD_CFI_H__ |
9 | 9 | ||
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
11 | #include <linux/version.h> | ||
12 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
13 | #include <linux/types.h> | 12 | #include <linux/types.h> |
14 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
@@ -82,8 +81,8 @@ static inline int cfi_interleave_supported(int i) | |||
82 | } | 81 | } |
83 | 82 | ||
84 | 83 | ||
85 | /* NB: these values must represents the number of bytes needed to meet the | 84 | /* NB: these values must represents the number of bytes needed to meet the |
86 | * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes. | 85 | * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes. |
87 | * These numbers are used in calculations. | 86 | * These numbers are used in calculations. |
88 | */ | 87 | */ |
89 | #define CFI_DEVICETYPE_X8 (8 / 8) | 88 | #define CFI_DEVICETYPE_X8 (8 / 8) |
@@ -173,6 +172,15 @@ struct cfi_intelext_regioninfo { | |||
173 | struct cfi_intelext_blockinfo BlockTypes[1]; | 172 | struct cfi_intelext_blockinfo BlockTypes[1]; |
174 | } __attribute__((packed)); | 173 | } __attribute__((packed)); |
175 | 174 | ||
175 | struct cfi_intelext_programming_regioninfo { | ||
176 | uint8_t ProgRegShift; | ||
177 | uint8_t Reserved1; | ||
178 | uint8_t ControlValid; | ||
179 | uint8_t Reserved2; | ||
180 | uint8_t ControlInvalid; | ||
181 | uint8_t Reserved3; | ||
182 | } __attribute__((packed)); | ||
183 | |||
176 | /* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ | 184 | /* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ |
177 | 185 | ||
178 | struct cfi_pri_amdstd { | 186 | struct cfi_pri_amdstd { |
@@ -250,7 +258,7 @@ static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int | |||
250 | /* | 258 | /* |
251 | * Transforms the CFI command for the given geometry (bus width & interleave). | 259 | * Transforms the CFI command for the given geometry (bus width & interleave). |
252 | * It looks too long to be inline, but in the common case it should almost all | 260 | * It looks too long to be inline, but in the common case it should almost all |
253 | * get optimised away. | 261 | * get optimised away. |
254 | */ | 262 | */ |
255 | static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi) | 263 | static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi) |
256 | { | 264 | { |
@@ -259,7 +267,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf | |||
259 | unsigned long onecmd; | 267 | unsigned long onecmd; |
260 | int i; | 268 | int i; |
261 | 269 | ||
262 | /* We do it this way to give the compiler a fighting chance | 270 | /* We do it this way to give the compiler a fighting chance |
263 | of optimising away all the crap for 'bankwidth' larger than | 271 | of optimising away all the crap for 'bankwidth' larger than |
264 | an unsigned long, in the common case where that support is | 272 | an unsigned long, in the common case where that support is |
265 | disabled */ | 273 | disabled */ |
@@ -270,7 +278,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf | |||
270 | wordwidth = map_bankwidth(map); | 278 | wordwidth = map_bankwidth(map); |
271 | words_per_bus = 1; | 279 | words_per_bus = 1; |
272 | } | 280 | } |
273 | 281 | ||
274 | chip_mode = map_bankwidth(map) / cfi_interleave(cfi); | 282 | chip_mode = map_bankwidth(map) / cfi_interleave(cfi); |
275 | chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); | 283 | chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); |
276 | 284 | ||
@@ -289,7 +297,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf | |||
289 | break; | 297 | break; |
290 | } | 298 | } |
291 | 299 | ||
292 | /* Now replicate it across the size of an unsigned long, or | 300 | /* Now replicate it across the size of an unsigned long, or |
293 | just to the bus width as appropriate */ | 301 | just to the bus width as appropriate */ |
294 | switch (chips_per_word) { | 302 | switch (chips_per_word) { |
295 | default: BUG(); | 303 | default: BUG(); |
@@ -305,7 +313,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf | |||
305 | ; | 313 | ; |
306 | } | 314 | } |
307 | 315 | ||
308 | /* And finally, for the multi-word case, replicate it | 316 | /* And finally, for the multi-word case, replicate it |
309 | in all words in the structure */ | 317 | in all words in the structure */ |
310 | for (i=0; i < words_per_bus; i++) { | 318 | for (i=0; i < words_per_bus; i++) { |
311 | val.x[i] = onecmd; | 319 | val.x[i] = onecmd; |
@@ -316,14 +324,14 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf | |||
316 | #define CMD(x) cfi_build_cmd((x), map, cfi) | 324 | #define CMD(x) cfi_build_cmd((x), map, cfi) |
317 | 325 | ||
318 | 326 | ||
319 | static inline unsigned char cfi_merge_status(map_word val, struct map_info *map, | 327 | static inline unsigned long cfi_merge_status(map_word val, struct map_info *map, |
320 | struct cfi_private *cfi) | 328 | struct cfi_private *cfi) |
321 | { | 329 | { |
322 | int wordwidth, words_per_bus, chip_mode, chips_per_word; | 330 | int wordwidth, words_per_bus, chip_mode, chips_per_word; |
323 | unsigned long onestat, res = 0; | 331 | unsigned long onestat, res = 0; |
324 | int i; | 332 | int i; |
325 | 333 | ||
326 | /* We do it this way to give the compiler a fighting chance | 334 | /* We do it this way to give the compiler a fighting chance |
327 | of optimising away all the crap for 'bankwidth' larger than | 335 | of optimising away all the crap for 'bankwidth' larger than |
328 | an unsigned long, in the common case where that support is | 336 | an unsigned long, in the common case where that support is |
329 | disabled */ | 337 | disabled */ |
@@ -334,7 +342,7 @@ static inline unsigned char cfi_merge_status(map_word val, struct map_info *map, | |||
334 | wordwidth = map_bankwidth(map); | 342 | wordwidth = map_bankwidth(map); |
335 | words_per_bus = 1; | 343 | words_per_bus = 1; |
336 | } | 344 | } |
337 | 345 | ||
338 | chip_mode = map_bankwidth(map) / cfi_interleave(cfi); | 346 | chip_mode = map_bankwidth(map) / cfi_interleave(cfi); |
339 | chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); | 347 | chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); |
340 | 348 | ||
@@ -418,6 +426,22 @@ static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) | |||
418 | } | 426 | } |
419 | } | 427 | } |
420 | 428 | ||
429 | static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr) | ||
430 | { | ||
431 | map_word val = map_read(map, addr); | ||
432 | |||
433 | if (map_bankwidth_is_1(map)) { | ||
434 | return val.x[0] & 0xff; | ||
435 | } else if (map_bankwidth_is_2(map)) { | ||
436 | return cfi16_to_cpu(val.x[0]); | ||
437 | } else { | ||
438 | /* No point in a 64-bit byteswap since that would just be | ||
439 | swapping the responses from different chips, and we are | ||
440 | only interested in one chip (a representative sample) */ | ||
441 | return cfi32_to_cpu(val.x[0]); | ||
442 | } | ||
443 | } | ||
444 | |||
421 | static inline void cfi_udelay(int us) | 445 | static inline void cfi_udelay(int us) |
422 | { | 446 | { |
423 | if (us >= 1000) { | 447 | if (us >= 1000) { |