aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mtd/cfi.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/mtd/cfi.h')
-rw-r--r--include/linux/mtd/cfi.h50
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
175struct 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
178struct cfi_pri_amdstd { 186struct 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 */
255static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi) 263static 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
319static inline unsigned char cfi_merge_status(map_word val, struct map_info *map, 327static 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
429static 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
421static inline void cfi_udelay(int us) 445static inline void cfi_udelay(int us)
422{ 446{
423 if (us >= 1000) { 447 if (us >= 1000) {