Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.27-rc2 511 lines 13 kB view raw
1 2/* Common Flash Interface structures 3 * See http://support.intel.com/design/flash/technote/index.htm 4 */ 5 6#ifndef __MTD_CFI_H__ 7#define __MTD_CFI_H__ 8 9#include <linux/delay.h> 10#include <linux/types.h> 11#include <linux/interrupt.h> 12#include <linux/mtd/flashchip.h> 13#include <linux/mtd/map.h> 14#include <linux/mtd/cfi_endian.h> 15 16#ifdef CONFIG_MTD_CFI_I1 17#define cfi_interleave(cfi) 1 18#define cfi_interleave_is_1(cfi) (cfi_interleave(cfi) == 1) 19#else 20#define cfi_interleave_is_1(cfi) (0) 21#endif 22 23#ifdef CONFIG_MTD_CFI_I2 24# ifdef cfi_interleave 25# undef cfi_interleave 26# define cfi_interleave(cfi) ((cfi)->interleave) 27# else 28# define cfi_interleave(cfi) 2 29# endif 30#define cfi_interleave_is_2(cfi) (cfi_interleave(cfi) == 2) 31#else 32#define cfi_interleave_is_2(cfi) (0) 33#endif 34 35#ifdef CONFIG_MTD_CFI_I4 36# ifdef cfi_interleave 37# undef cfi_interleave 38# define cfi_interleave(cfi) ((cfi)->interleave) 39# else 40# define cfi_interleave(cfi) 4 41# endif 42#define cfi_interleave_is_4(cfi) (cfi_interleave(cfi) == 4) 43#else 44#define cfi_interleave_is_4(cfi) (0) 45#endif 46 47#ifdef CONFIG_MTD_CFI_I8 48# ifdef cfi_interleave 49# undef cfi_interleave 50# define cfi_interleave(cfi) ((cfi)->interleave) 51# else 52# define cfi_interleave(cfi) 8 53# endif 54#define cfi_interleave_is_8(cfi) (cfi_interleave(cfi) == 8) 55#else 56#define cfi_interleave_is_8(cfi) (0) 57#endif 58 59#ifndef cfi_interleave 60#warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. 61static inline int cfi_interleave(void *cfi) 62{ 63 BUG(); 64 return 0; 65} 66#endif 67 68static inline int cfi_interleave_supported(int i) 69{ 70 switch (i) { 71#ifdef CONFIG_MTD_CFI_I1 72 case 1: 73#endif 74#ifdef CONFIG_MTD_CFI_I2 75 case 2: 76#endif 77#ifdef CONFIG_MTD_CFI_I4 78 case 4: 79#endif 80#ifdef CONFIG_MTD_CFI_I8 81 case 8: 82#endif 83 return 1; 84 85 default: 86 return 0; 87 } 88} 89 90 91/* NB: these values must represents the number of bytes needed to meet the 92 * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes. 93 * These numbers are used in calculations. 94 */ 95#define CFI_DEVICETYPE_X8 (8 / 8) 96#define CFI_DEVICETYPE_X16 (16 / 8) 97#define CFI_DEVICETYPE_X32 (32 / 8) 98#define CFI_DEVICETYPE_X64 (64 / 8) 99 100 101/* Device Interface Code Assignments from the "Common Flash Memory Interface 102 * Publication 100" dated December 1, 2001. 103 */ 104#define CFI_INTERFACE_X8_ASYNC 0x0000 105#define CFI_INTERFACE_X16_ASYNC 0x0001 106#define CFI_INTERFACE_X8_BY_X16_ASYNC 0x0002 107#define CFI_INTERFACE_X32_ASYNC 0x0003 108#define CFI_INTERFACE_X16_BY_X32_ASYNC 0x0005 109#define CFI_INTERFACE_NOT_ALLOWED 0xffff 110 111 112/* NB: We keep these structures in memory in HOST byteorder, except 113 * where individually noted. 114 */ 115 116/* Basic Query Structure */ 117struct cfi_ident { 118 uint8_t qry[3]; 119 uint16_t P_ID; 120 uint16_t P_ADR; 121 uint16_t A_ID; 122 uint16_t A_ADR; 123 uint8_t VccMin; 124 uint8_t VccMax; 125 uint8_t VppMin; 126 uint8_t VppMax; 127 uint8_t WordWriteTimeoutTyp; 128 uint8_t BufWriteTimeoutTyp; 129 uint8_t BlockEraseTimeoutTyp; 130 uint8_t ChipEraseTimeoutTyp; 131 uint8_t WordWriteTimeoutMax; 132 uint8_t BufWriteTimeoutMax; 133 uint8_t BlockEraseTimeoutMax; 134 uint8_t ChipEraseTimeoutMax; 135 uint8_t DevSize; 136 uint16_t InterfaceDesc; 137 uint16_t MaxBufWriteSize; 138 uint8_t NumEraseRegions; 139 uint32_t EraseRegionInfo[0]; /* Not host ordered */ 140} __attribute__((packed)); 141 142/* Extended Query Structure for both PRI and ALT */ 143 144struct cfi_extquery { 145 uint8_t pri[3]; 146 uint8_t MajorVersion; 147 uint8_t MinorVersion; 148} __attribute__((packed)); 149 150/* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */ 151 152struct cfi_pri_intelext { 153 uint8_t pri[3]; 154 uint8_t MajorVersion; 155 uint8_t MinorVersion; 156 uint32_t FeatureSupport; /* if bit 31 is set then an additional uint32_t feature 157 block follows - FIXME - not currently supported */ 158 uint8_t SuspendCmdSupport; 159 uint16_t BlkStatusRegMask; 160 uint8_t VccOptimal; 161 uint8_t VppOptimal; 162 uint8_t NumProtectionFields; 163 uint16_t ProtRegAddr; 164 uint8_t FactProtRegSize; 165 uint8_t UserProtRegSize; 166 uint8_t extra[0]; 167} __attribute__((packed)); 168 169struct cfi_intelext_otpinfo { 170 uint32_t ProtRegAddr; 171 uint16_t FactGroups; 172 uint8_t FactProtRegSize; 173 uint16_t UserGroups; 174 uint8_t UserProtRegSize; 175} __attribute__((packed)); 176 177struct cfi_intelext_blockinfo { 178 uint16_t NumIdentBlocks; 179 uint16_t BlockSize; 180 uint16_t MinBlockEraseCycles; 181 uint8_t BitsPerCell; 182 uint8_t BlockCap; 183} __attribute__((packed)); 184 185struct cfi_intelext_regioninfo { 186 uint16_t NumIdentPartitions; 187 uint8_t NumOpAllowed; 188 uint8_t NumOpAllowedSimProgMode; 189 uint8_t NumOpAllowedSimEraMode; 190 uint8_t NumBlockTypes; 191 struct cfi_intelext_blockinfo BlockTypes[1]; 192} __attribute__((packed)); 193 194struct cfi_intelext_programming_regioninfo { 195 uint8_t ProgRegShift; 196 uint8_t Reserved1; 197 uint8_t ControlValid; 198 uint8_t Reserved2; 199 uint8_t ControlInvalid; 200 uint8_t Reserved3; 201} __attribute__((packed)); 202 203/* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ 204 205struct cfi_pri_amdstd { 206 uint8_t pri[3]; 207 uint8_t MajorVersion; 208 uint8_t MinorVersion; 209 uint8_t SiliconRevision; /* bits 1-0: Address Sensitive Unlock */ 210 uint8_t EraseSuspend; 211 uint8_t BlkProt; 212 uint8_t TmpBlkUnprotect; 213 uint8_t BlkProtUnprot; 214 uint8_t SimultaneousOps; 215 uint8_t BurstMode; 216 uint8_t PageMode; 217 uint8_t VppMin; 218 uint8_t VppMax; 219 uint8_t TopBottom; 220} __attribute__((packed)); 221 222/* Vendor-Specific PRI for Atmel chips (command set 0x0002) */ 223 224struct cfi_pri_atmel { 225 uint8_t pri[3]; 226 uint8_t MajorVersion; 227 uint8_t MinorVersion; 228 uint8_t Features; 229 uint8_t BottomBoot; 230 uint8_t BurstMode; 231 uint8_t PageMode; 232} __attribute__((packed)); 233 234struct cfi_pri_query { 235 uint8_t NumFields; 236 uint32_t ProtField[1]; /* Not host ordered */ 237} __attribute__((packed)); 238 239struct cfi_bri_query { 240 uint8_t PageModeReadCap; 241 uint8_t NumFields; 242 uint32_t ConfField[1]; /* Not host ordered */ 243} __attribute__((packed)); 244 245#define P_ID_NONE 0x0000 246#define P_ID_INTEL_EXT 0x0001 247#define P_ID_AMD_STD 0x0002 248#define P_ID_INTEL_STD 0x0003 249#define P_ID_AMD_EXT 0x0004 250#define P_ID_WINBOND 0x0006 251#define P_ID_ST_ADV 0x0020 252#define P_ID_MITSUBISHI_STD 0x0100 253#define P_ID_MITSUBISHI_EXT 0x0101 254#define P_ID_SST_PAGE 0x0102 255#define P_ID_INTEL_PERFORMANCE 0x0200 256#define P_ID_INTEL_DATA 0x0210 257#define P_ID_RESERVED 0xffff 258 259 260#define CFI_MODE_CFI 1 261#define CFI_MODE_JEDEC 0 262 263struct cfi_private { 264 uint16_t cmdset; 265 void *cmdset_priv; 266 int interleave; 267 int device_type; 268 int cfi_mode; /* Are we a JEDEC device pretending to be CFI? */ 269 int addr_unlock1; 270 int addr_unlock2; 271 struct mtd_info *(*cmdset_setup)(struct map_info *); 272 struct cfi_ident *cfiq; /* For now only one. We insist that all devs 273 must be of the same type. */ 274 int mfr, id; 275 int numchips; 276 unsigned long chipshift; /* Because they're of the same type */ 277 const char *im_name; /* inter_module name for cmdset_setup */ 278 struct flchip chips[0]; /* per-chip data structure for each chip */ 279}; 280 281/* 282 * Returns the command address according to the given geometry. 283 */ 284static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type) 285{ 286 return (cmd_ofs * type) * interleave; 287} 288 289/* 290 * Transforms the CFI command for the given geometry (bus width & interleave). 291 * It looks too long to be inline, but in the common case it should almost all 292 * get optimised away. 293 */ 294static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi) 295{ 296 map_word val = { {0} }; 297 int wordwidth, words_per_bus, chip_mode, chips_per_word; 298 unsigned long onecmd; 299 int i; 300 301 /* We do it this way to give the compiler a fighting chance 302 of optimising away all the crap for 'bankwidth' larger than 303 an unsigned long, in the common case where that support is 304 disabled */ 305 if (map_bankwidth_is_large(map)) { 306 wordwidth = sizeof(unsigned long); 307 words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1 308 } else { 309 wordwidth = map_bankwidth(map); 310 words_per_bus = 1; 311 } 312 313 chip_mode = map_bankwidth(map) / cfi_interleave(cfi); 314 chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); 315 316 /* First, determine what the bit-pattern should be for a single 317 device, according to chip mode and endianness... */ 318 switch (chip_mode) { 319 default: BUG(); 320 case 1: 321 onecmd = cmd; 322 break; 323 case 2: 324 onecmd = cpu_to_cfi16(cmd); 325 break; 326 case 4: 327 onecmd = cpu_to_cfi32(cmd); 328 break; 329 } 330 331 /* Now replicate it across the size of an unsigned long, or 332 just to the bus width as appropriate */ 333 switch (chips_per_word) { 334 default: BUG(); 335#if BITS_PER_LONG >= 64 336 case 8: 337 onecmd |= (onecmd << (chip_mode * 32)); 338#endif 339 case 4: 340 onecmd |= (onecmd << (chip_mode * 16)); 341 case 2: 342 onecmd |= (onecmd << (chip_mode * 8)); 343 case 1: 344 ; 345 } 346 347 /* And finally, for the multi-word case, replicate it 348 in all words in the structure */ 349 for (i=0; i < words_per_bus; i++) { 350 val.x[i] = onecmd; 351 } 352 353 return val; 354} 355#define CMD(x) cfi_build_cmd((x), map, cfi) 356 357 358static inline unsigned long cfi_merge_status(map_word val, struct map_info *map, 359 struct cfi_private *cfi) 360{ 361 int wordwidth, words_per_bus, chip_mode, chips_per_word; 362 unsigned long onestat, res = 0; 363 int i; 364 365 /* We do it this way to give the compiler a fighting chance 366 of optimising away all the crap for 'bankwidth' larger than 367 an unsigned long, in the common case where that support is 368 disabled */ 369 if (map_bankwidth_is_large(map)) { 370 wordwidth = sizeof(unsigned long); 371 words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1 372 } else { 373 wordwidth = map_bankwidth(map); 374 words_per_bus = 1; 375 } 376 377 chip_mode = map_bankwidth(map) / cfi_interleave(cfi); 378 chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); 379 380 onestat = val.x[0]; 381 /* Or all status words together */ 382 for (i=1; i < words_per_bus; i++) { 383 onestat |= val.x[i]; 384 } 385 386 res = onestat; 387 switch(chips_per_word) { 388 default: BUG(); 389#if BITS_PER_LONG >= 64 390 case 8: 391 res |= (onestat >> (chip_mode * 32)); 392#endif 393 case 4: 394 res |= (onestat >> (chip_mode * 16)); 395 case 2: 396 res |= (onestat >> (chip_mode * 8)); 397 case 1: 398 ; 399 } 400 401 /* Last, determine what the bit-pattern should be for a single 402 device, according to chip mode and endianness... */ 403 switch (chip_mode) { 404 case 1: 405 break; 406 case 2: 407 res = cfi16_to_cpu(res); 408 break; 409 case 4: 410 res = cfi32_to_cpu(res); 411 break; 412 default: BUG(); 413 } 414 return res; 415} 416 417#define MERGESTATUS(x) cfi_merge_status((x), map, cfi) 418 419 420/* 421 * Sends a CFI command to a bank of flash for the given geometry. 422 * 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. 426 */ 427static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t base, 428 struct map_info *map, struct cfi_private *cfi, 429 int type, map_word *prev_val) 430{ 431 map_word val; 432 uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type); 433 434 val = cfi_build_cmd(cmd, map, cfi); 435 436 if (prev_val) 437 *prev_val = map_read(map, addr); 438 439 map_write(map, val, addr); 440 441 return addr - base; 442} 443 444static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) 445{ 446 map_word val = map_read(map, addr); 447 448 if (map_bankwidth_is_1(map)) { 449 return val.x[0]; 450 } else if (map_bankwidth_is_2(map)) { 451 return cfi16_to_cpu(val.x[0]); 452 } else { 453 /* No point in a 64-bit byteswap since that would just be 454 swapping the responses from different chips, and we are 455 only interested in one chip (a representative sample) */ 456 return cfi32_to_cpu(val.x[0]); 457 } 458} 459 460static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr) 461{ 462 map_word val = map_read(map, addr); 463 464 if (map_bankwidth_is_1(map)) { 465 return val.x[0] & 0xff; 466 } else if (map_bankwidth_is_2(map)) { 467 return cfi16_to_cpu(val.x[0]); 468 } else { 469 /* No point in a 64-bit byteswap since that would just be 470 swapping the responses from different chips, and we are 471 only interested in one chip (a representative sample) */ 472 return cfi32_to_cpu(val.x[0]); 473 } 474} 475 476static inline void cfi_udelay(int us) 477{ 478 if (us >= 1000) { 479 msleep((us+999)/1000); 480 } else { 481 udelay(us); 482 cond_resched(); 483 } 484} 485 486struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size, 487 const char* name); 488struct cfi_fixup { 489 uint16_t mfr; 490 uint16_t id; 491 void (*fixup)(struct mtd_info *mtd, void* param); 492 void* param; 493}; 494 495#define CFI_MFR_ANY 0xffff 496#define CFI_ID_ANY 0xffff 497 498#define CFI_MFR_AMD 0x0001 499#define CFI_MFR_ATMEL 0x001F 500#define CFI_MFR_ST 0x0020 /* STMicroelectronics */ 501 502void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups); 503 504typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip, 505 unsigned long adr, int len, void *thunk); 506 507int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, 508 loff_t ofs, size_t len, void *thunk); 509 510 511#endif /* __MTD_CFI_H__ */