1 /* 2 Common Flash Interface probe code. 3 (C) 2000 Red Hat. GPL'd. 4 $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $ 5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) 6 for the standard this probe goes back to. 7 8 Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com 9 */ 10 11 #include <linux/config.h> 12 #include <linux/module.h> 13 #include <linux/init.h> 14 #include <linux/types.h> 15 #include <linux/kernel.h> 16 #include <asm/io.h> 17 #include <asm/byteorder.h> 18 #include <linux/errno.h> 19 #include <linux/slab.h> 20 #include <linux/interrupt.h> 21 #include <linux/init.h> 22 23 #include <linux/mtd/mtd.h> 24 #include <linux/mtd/map.h> 25 #include <linux/mtd/cfi.h> 26 #include <linux/mtd/gen_probe.h> 27 28 /* Manufacturers */ 29 #define MANUFACTURER_AMD 0x0001 30 #define MANUFACTURER_ATMEL 0x001f 31 #define MANUFACTURER_FUJITSU 0x0004 32 #define MANUFACTURER_HYUNDAI 0x00AD 33 #define MANUFACTURER_INTEL 0x0089 34 #define MANUFACTURER_MACRONIX 0x00C2 35 #define MANUFACTURER_NEC 0x0010 36 #define MANUFACTURER_PMC 0x009D 37 #define MANUFACTURER_SHARP 0x00b0 38 #define MANUFACTURER_SST 0x00BF 39 #define MANUFACTURER_ST 0x0020 40 #define MANUFACTURER_TOSHIBA 0x0098 41 #define MANUFACTURER_WINBOND 0x00da 42 43 44 /* AMD */ 45 #define AM29DL800BB 0x22C8 46 #define AM29DL800BT 0x224A 47 48 #define AM29F800BB 0x2258 49 #define AM29F800BT 0x22D6 50 #define AM29LV400BB 0x22BA 51 #define AM29LV400BT 0x22B9 52 #define AM29LV800BB 0x225B 53 #define AM29LV800BT 0x22DA 54 #define AM29LV160DT 0x22C4 55 #define AM29LV160DB 0x2249 56 #define AM29F017D 0x003D 57 #define AM29F016D 0x00AD 58 #define AM29F080 0x00D5 59 #define AM29F040 0x00A4 60 #define AM29LV040B 0x004F 61 #define AM29F032B 0x0041 62 #define AM29F002T 0x00B0 63 64 /* Atmel */ 65 #define AT49BV512 0x0003 66 #define AT29LV512 0x003d 67 #define AT49BV16X 0x00C0 68 #define AT49BV16XT 0x00C2 69 #define AT49BV32X 0x00C8 70 #define AT49BV32XT 0x00C9 71 72 /* Fujitsu */ 73 #define MBM29F040C 0x00A4 74 #define MBM29LV650UE 0x22D7 75 #define MBM29LV320TE 0x22F6 76 #define MBM29LV320BE 0x22F9 77 #define MBM29LV160TE 0x22C4 78 #define MBM29LV160BE 0x2249 79 #define MBM29LV800BA 0x225B 80 #define MBM29LV800TA 0x22DA 81 #define MBM29LV400TC 0x22B9 82 #define MBM29LV400BC 0x22BA 83 84 /* Hyundai */ 85 #define HY29F002T 0x00B0 86 87 /* Intel */ 88 #define I28F004B3T 0x00d4 89 #define I28F004B3B 0x00d5 90 #define I28F400B3T 0x8894 91 #define I28F400B3B 0x8895 92 #define I28F008S5 0x00a6 93 #define I28F016S5 0x00a0 94 #define I28F008SA 0x00a2 95 #define I28F008B3T 0x00d2 96 #define I28F008B3B 0x00d3 97 #define I28F800B3T 0x8892 98 #define I28F800B3B 0x8893 99 #define I28F016S3 0x00aa 100 #define I28F016B3T 0x00d0 101 #define I28F016B3B 0x00d1 102 #define I28F160B3T 0x8890 103 #define I28F160B3B 0x8891 104 #define I28F320B3T 0x8896 105 #define I28F320B3B 0x8897 106 #define I28F640B3T 0x8898 107 #define I28F640B3B 0x8899 108 #define I82802AB 0x00ad 109 #define I82802AC 0x00ac 110 111 /* Macronix */ 112 #define MX29LV040C 0x004F 113 #define MX29LV160T 0x22C4 114 #define MX29LV160B 0x2249 115 #define MX29F016 0x00AD 116 #define MX29F002T 0x00B0 117 #define MX29F004T 0x0045 118 #define MX29F004B 0x0046 119 120 /* NEC */ 121 #define UPD29F064115 0x221C 122 123 /* PMC */ 124 #define PM49FL002 0x006D 125 #define PM49FL004 0x006E 126 #define PM49FL008 0x006A 127 128 /* Sharp */ 129 #define LH28F640BF 0x00b0 130 131 /* ST - www.st.com */ 132 #define M29W800DT 0x00D7 133 #define M29W800DB 0x005B 134 #define M29W160DT 0x22C4 135 #define M29W160DB 0x2249 136 #define M29W040B 0x00E3 137 #define M50FW040 0x002C 138 #define M50FW080 0x002D 139 #define M50FW016 0x002E 140 #define M50LPW080 0x002F 141 142 /* SST */ 143 #define SST29EE020 0x0010 144 #define SST29LE020 0x0012 145 #define SST29EE512 0x005d 146 #define SST29LE512 0x003d 147 #define SST39LF800 0x2781 148 #define SST39LF160 0x2782 149 #define SST39VF1601 0x234b 150 #define SST39LF512 0x00D4 151 #define SST39LF010 0x00D5 152 #define SST39LF020 0x00D6 153 #define SST39LF040 0x00D7 154 #define SST39SF010A 0x00B5 155 #define SST39SF020A 0x00B6 156 #define SST49LF004B 0x0060 157 #define SST49LF008A 0x005a 158 #define SST49LF030A 0x001C 159 #define SST49LF040A 0x0051 160 #define SST49LF080A 0x005B 161 162 /* Toshiba */ 163 #define TC58FVT160 0x00C2 164 #define TC58FVB160 0x0043 165 #define TC58FVT321 0x009A 166 #define TC58FVB321 0x009C 167 #define TC58FVT641 0x0093 168 #define TC58FVB641 0x0095 169 170 /* Winbond */ 171 #define W49V002A 0x00b0 172 173 174 /* 175 * Unlock address sets for AMD command sets. 176 * Intel command sets use the MTD_UADDR_UNNECESSARY. 177 * Each identifier, except MTD_UADDR_UNNECESSARY, and 178 * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[]. 179 * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure 180 * initialization need not require initializing all of the 181 * unlock addresses for all bit widths. 182 */ 183 enum uaddr { 184 MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */ 185 MTD_UADDR_0x0555_0x02AA, 186 MTD_UADDR_0x0555_0x0AAA, 187 MTD_UADDR_0x5555_0x2AAA, 188 MTD_UADDR_0x0AAA_0x0555, 189 MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */ 190 MTD_UADDR_UNNECESSARY, /* Does not require any address */ 191 }; 192 193 194 struct unlock_addr { 195 u32 addr1; 196 u32 addr2; 197 }; 198 199 200 /* 201 * I don't like the fact that the first entry in unlock_addrs[] 202 * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore, 203 * should not be used. The problem is that structures with 204 * initializers have extra fields initialized to 0. It is _very_ 205 * desireable to have the unlock address entries for unsupported 206 * data widths automatically initialized - that means that 207 * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here 208 * must go unused. 209 */ 210 static const struct unlock_addr unlock_addrs[] = { 211 [MTD_UADDR_NOT_SUPPORTED] = { 212 .addr1 = 0xffff, 213 .addr2 = 0xffff 214 }, 215 216 [MTD_UADDR_0x0555_0x02AA] = { 217 .addr1 = 0x0555, 218 .addr2 = 0x02aa 219 }, 220 221 [MTD_UADDR_0x0555_0x0AAA] = { 222 .addr1 = 0x0555, 223 .addr2 = 0x0aaa 224 }, 225 226 [MTD_UADDR_0x5555_0x2AAA] = { 227 .addr1 = 0x5555, 228 .addr2 = 0x2aaa 229 }, 230 231 [MTD_UADDR_0x0AAA_0x0555] = { 232 .addr1 = 0x0AAA, 233 .addr2 = 0x0555 234 }, 235 236 [MTD_UADDR_DONT_CARE] = { 237 .addr1 = 0x0000, /* Doesn't matter which address */ 238 .addr2 = 0x0000 /* is used - must be last entry */ 239 }, 240 241 [MTD_UADDR_UNNECESSARY] = { 242 .addr1 = 0x0000, 243 .addr2 = 0x0000 244 } 245 }; 246 247 248 struct amd_flash_info { 249 const __u16 mfr_id; 250 const __u16 dev_id; 251 const char *name; 252 const int DevSize; 253 const int NumEraseRegions; 254 const int CmdSet; 255 const __u8 uaddr[4]; /* unlock addrs for 8, 16, 32, 64 */ 256 const ulong regions[6]; 257 }; 258 259 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1) 260 261 #define SIZE_64KiB 16 262 #define SIZE_128KiB 17 263 #define SIZE_256KiB 18 264 #define SIZE_512KiB 19 265 #define SIZE_1MiB 20 266 #define SIZE_2MiB 21 267 #define SIZE_4MiB 22 268 #define SIZE_8MiB 23 269 270 271 /* 272 * Please keep this list ordered by manufacturer! 273 * Fortunately, the list isn't searched often and so a 274 * slow, linear search isn't so bad. 275 */ 276 static const struct amd_flash_info jedec_table[] = { 277 { 278 .mfr_id = MANUFACTURER_AMD, 279 .dev_id = AM29F032B, 280 .name = "AMD AM29F032B", 281 .uaddr = { 282 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 283 }, 284 .DevSize = SIZE_4MiB, 285 .CmdSet = P_ID_AMD_STD, 286 .NumEraseRegions= 1, 287 .regions = { 288 ERASEINFO(0x10000,64) 289 } 290 }, { 291 .mfr_id = MANUFACTURER_AMD, 292 .dev_id = AM29LV160DT, 293 .name = "AMD AM29LV160DT", 294 .uaddr = { 295 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 296 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ 297 }, 298 .DevSize = SIZE_2MiB, 299 .CmdSet = P_ID_AMD_STD, 300 .NumEraseRegions= 4, 301 .regions = { 302 ERASEINFO(0x10000,31), 303 ERASEINFO(0x08000,1), 304 ERASEINFO(0x02000,2), 305 ERASEINFO(0x04000,1) 306 } 307 }, { 308 .mfr_id = MANUFACTURER_AMD, 309 .dev_id = AM29LV160DB, 310 .name = "AMD AM29LV160DB", 311 .uaddr = { 312 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 313 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ 314 }, 315 .DevSize = SIZE_2MiB, 316 .CmdSet = P_ID_AMD_STD, 317 .NumEraseRegions= 4, 318 .regions = { 319 ERASEINFO(0x04000,1), 320 ERASEINFO(0x02000,2), 321 ERASEINFO(0x08000,1), 322 ERASEINFO(0x10000,31) 323 } 324 }, { 325 .mfr_id = MANUFACTURER_AMD, 326 .dev_id = AM29LV400BB, 327 .name = "AMD AM29LV400BB", 328 .uaddr = { 329 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 330 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 331 }, 332 .DevSize = SIZE_512KiB, 333 .CmdSet = P_ID_AMD_STD, 334 .NumEraseRegions= 4, 335 .regions = { 336 ERASEINFO(0x04000,1), 337 ERASEINFO(0x02000,2), 338 ERASEINFO(0x08000,1), 339 ERASEINFO(0x10000,7) 340 } 341 }, { 342 .mfr_id = MANUFACTURER_AMD, 343 .dev_id = AM29LV400BT, 344 .name = "AMD AM29LV400BT", 345 .uaddr = { 346 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 347 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 348 }, 349 .DevSize = SIZE_512KiB, 350 .CmdSet = P_ID_AMD_STD, 351 .NumEraseRegions= 4, 352 .regions = { 353 ERASEINFO(0x10000,7), 354 ERASEINFO(0x08000,1), 355 ERASEINFO(0x02000,2), 356 ERASEINFO(0x04000,1) 357 } 358 }, { 359 .mfr_id = MANUFACTURER_AMD, 360 .dev_id = AM29LV800BB, 361 .name = "AMD AM29LV800BB", 362 .uaddr = { 363 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 364 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 365 }, 366 .DevSize = SIZE_1MiB, 367 .CmdSet = P_ID_AMD_STD, 368 .NumEraseRegions= 4, 369 .regions = { 370 ERASEINFO(0x04000,1), 371 ERASEINFO(0x02000,2), 372 ERASEINFO(0x08000,1), 373 ERASEINFO(0x10000,15), 374 } 375 }, { 376 /* add DL */ 377 .mfr_id = MANUFACTURER_AMD, 378 .dev_id = AM29DL800BB, 379 .name = "AMD AM29DL800BB", 380 .uaddr = { 381 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 382 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 383 }, 384 .DevSize = SIZE_1MiB, 385 .CmdSet = P_ID_AMD_STD, 386 .NumEraseRegions= 6, 387 .regions = { 388 ERASEINFO(0x04000,1), 389 ERASEINFO(0x08000,1), 390 ERASEINFO(0x02000,4), 391 ERASEINFO(0x08000,1), 392 ERASEINFO(0x04000,1), 393 ERASEINFO(0x10000,14) 394 } 395 }, { 396 .mfr_id = MANUFACTURER_AMD, 397 .dev_id = AM29DL800BT, 398 .name = "AMD AM29DL800BT", 399 .uaddr = { 400 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 401 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 402 }, 403 .DevSize = SIZE_1MiB, 404 .CmdSet = P_ID_AMD_STD, 405 .NumEraseRegions= 6, 406 .regions = { 407 ERASEINFO(0x10000,14), 408 ERASEINFO(0x04000,1), 409 ERASEINFO(0x08000,1), 410 ERASEINFO(0x02000,4), 411 ERASEINFO(0x08000,1), 412 ERASEINFO(0x04000,1) 413 } 414 }, { 415 .mfr_id = MANUFACTURER_AMD, 416 .dev_id = AM29F800BB, 417 .name = "AMD AM29F800BB", 418 .uaddr = { 419 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 420 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 421 }, 422 .DevSize = SIZE_1MiB, 423 .CmdSet = P_ID_AMD_STD, 424 .NumEraseRegions= 4, 425 .regions = { 426 ERASEINFO(0x04000,1), 427 ERASEINFO(0x02000,2), 428 ERASEINFO(0x08000,1), 429 ERASEINFO(0x10000,15), 430 } 431 }, { 432 .mfr_id = MANUFACTURER_AMD, 433 .dev_id = AM29LV800BT, 434 .name = "AMD AM29LV800BT", 435 .uaddr = { 436 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 437 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 438 }, 439 .DevSize = SIZE_1MiB, 440 .CmdSet = P_ID_AMD_STD, 441 .NumEraseRegions= 4, 442 .regions = { 443 ERASEINFO(0x10000,15), 444 ERASEINFO(0x08000,1), 445 ERASEINFO(0x02000,2), 446 ERASEINFO(0x04000,1) 447 } 448 }, { 449 .mfr_id = MANUFACTURER_AMD, 450 .dev_id = AM29F800BT, 451 .name = "AMD AM29F800BT", 452 .uaddr = { 453 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 454 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 455 }, 456 .DevSize = SIZE_1MiB, 457 .CmdSet = P_ID_AMD_STD, 458 .NumEraseRegions= 4, 459 .regions = { 460 ERASEINFO(0x10000,15), 461 ERASEINFO(0x08000,1), 462 ERASEINFO(0x02000,2), 463 ERASEINFO(0x04000,1) 464 } 465 }, { 466 .mfr_id = MANUFACTURER_AMD, 467 .dev_id = AM29F017D, 468 .name = "AMD AM29F017D", 469 .uaddr = { 470 [0] = MTD_UADDR_DONT_CARE /* x8 */ 471 }, 472 .DevSize = SIZE_2MiB, 473 .CmdSet = P_ID_AMD_STD, 474 .NumEraseRegions= 1, 475 .regions = { 476 ERASEINFO(0x10000,32), 477 } 478 }, { 479 .mfr_id = MANUFACTURER_AMD, 480 .dev_id = AM29F016D, 481 .name = "AMD AM29F016D", 482 .uaddr = { 483 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 484 }, 485 .DevSize = SIZE_2MiB, 486 .CmdSet = P_ID_AMD_STD, 487 .NumEraseRegions= 1, 488 .regions = { 489 ERASEINFO(0x10000,32), 490 } 491 }, { 492 .mfr_id = MANUFACTURER_AMD, 493 .dev_id = AM29F080, 494 .name = "AMD AM29F080", 495 .uaddr = { 496 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 497 }, 498 .DevSize = SIZE_1MiB, 499 .CmdSet = P_ID_AMD_STD, 500 .NumEraseRegions= 1, 501 .regions = { 502 ERASEINFO(0x10000,16), 503 } 504 }, { 505 .mfr_id = MANUFACTURER_AMD, 506 .dev_id = AM29F040, 507 .name = "AMD AM29F040", 508 .uaddr = { 509 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 510 }, 511 .DevSize = SIZE_512KiB, 512 .CmdSet = P_ID_AMD_STD, 513 .NumEraseRegions= 1, 514 .regions = { 515 ERASEINFO(0x10000,8), 516 } 517 }, { 518 .mfr_id = MANUFACTURER_AMD, 519 .dev_id = AM29LV040B, 520 .name = "AMD AM29LV040B", 521 .uaddr = { 522 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 523 }, 524 .DevSize = SIZE_512KiB, 525 .CmdSet = P_ID_AMD_STD, 526 .NumEraseRegions= 1, 527 .regions = { 528 ERASEINFO(0x10000,8), 529 } 530 }, { 531 .mfr_id = MANUFACTURER_AMD, 532 .dev_id = AM29F002T, 533 .name = "AMD AM29F002T", 534 .uaddr = { 535 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 536 }, 537 .DevSize = SIZE_256KiB, 538 .CmdSet = P_ID_AMD_STD, 539 .NumEraseRegions= 4, 540 .regions = { 541 ERASEINFO(0x10000,3), 542 ERASEINFO(0x08000,1), 543 ERASEINFO(0x02000,2), 544 ERASEINFO(0x04000,1), 545 } 546 }, { 547 .mfr_id = MANUFACTURER_ATMEL, 548 .dev_id = AT49BV512, 549 .name = "Atmel AT49BV512", 550 .uaddr = { 551 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 552 }, 553 .DevSize = SIZE_64KiB, 554 .CmdSet = P_ID_AMD_STD, 555 .NumEraseRegions= 1, 556 .regions = { 557 ERASEINFO(0x10000,1) 558 } 559 }, { 560 .mfr_id = MANUFACTURER_ATMEL, 561 .dev_id = AT29LV512, 562 .name = "Atmel AT29LV512", 563 .uaddr = { 564 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 565 }, 566 .DevSize = SIZE_64KiB, 567 .CmdSet = P_ID_AMD_STD, 568 .NumEraseRegions= 1, 569 .regions = { 570 ERASEINFO(0x80,256), 571 ERASEINFO(0x80,256) 572 } 573 }, { 574 .mfr_id = MANUFACTURER_ATMEL, 575 .dev_id = AT49BV16X, 576 .name = "Atmel AT49BV16X", 577 .uaddr = { 578 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ 579 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ 580 }, 581 .DevSize = SIZE_2MiB, 582 .CmdSet = P_ID_AMD_STD, 583 .NumEraseRegions= 2, 584 .regions = { 585 ERASEINFO(0x02000,8), 586 ERASEINFO(0x10000,31) 587 } 588 }, { 589 .mfr_id = MANUFACTURER_ATMEL, 590 .dev_id = AT49BV16XT, 591 .name = "Atmel AT49BV16XT", 592 .uaddr = { 593 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ 594 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ 595 }, 596 .DevSize = SIZE_2MiB, 597 .CmdSet = P_ID_AMD_STD, 598 .NumEraseRegions= 2, 599 .regions = { 600 ERASEINFO(0x10000,31), 601 ERASEINFO(0x02000,8) 602 } 603 }, { 604 .mfr_id = MANUFACTURER_ATMEL, 605 .dev_id = AT49BV32X, 606 .name = "Atmel AT49BV32X", 607 .uaddr = { 608 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ 609 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ 610 }, 611 .DevSize = SIZE_4MiB, 612 .CmdSet = P_ID_AMD_STD, 613 .NumEraseRegions= 2, 614 .regions = { 615 ERASEINFO(0x02000,8), 616 ERASEINFO(0x10000,63) 617 } 618 }, { 619 .mfr_id = MANUFACTURER_ATMEL, 620 .dev_id = AT49BV32XT, 621 .name = "Atmel AT49BV32XT", 622 .uaddr = { 623 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ 624 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ 625 }, 626 .DevSize = SIZE_4MiB, 627 .CmdSet = P_ID_AMD_STD, 628 .NumEraseRegions= 2, 629 .regions = { 630 ERASEINFO(0x10000,63), 631 ERASEINFO(0x02000,8) 632 } 633 }, { 634 .mfr_id = MANUFACTURER_FUJITSU, 635 .dev_id = MBM29F040C, 636 .name = "Fujitsu MBM29F040C", 637 .uaddr = { 638 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 639 }, 640 .DevSize = SIZE_512KiB, 641 .CmdSet = P_ID_AMD_STD, 642 .NumEraseRegions= 1, 643 .regions = { 644 ERASEINFO(0x10000,8) 645 } 646 }, { 647 .mfr_id = MANUFACTURER_FUJITSU, 648 .dev_id = MBM29LV650UE, 649 .name = "Fujitsu MBM29LV650UE", 650 .uaddr = { 651 [0] = MTD_UADDR_DONT_CARE /* x16 */ 652 }, 653 .DevSize = SIZE_8MiB, 654 .CmdSet = P_ID_AMD_STD, 655 .NumEraseRegions= 1, 656 .regions = { 657 ERASEINFO(0x10000,128) 658 } 659 }, { 660 .mfr_id = MANUFACTURER_FUJITSU, 661 .dev_id = MBM29LV320TE, 662 .name = "Fujitsu MBM29LV320TE", 663 .uaddr = { 664 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 665 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 666 }, 667 .DevSize = SIZE_4MiB, 668 .CmdSet = P_ID_AMD_STD, 669 .NumEraseRegions= 2, 670 .regions = { 671 ERASEINFO(0x10000,63), 672 ERASEINFO(0x02000,8) 673 } 674 }, { 675 .mfr_id = MANUFACTURER_FUJITSU, 676 .dev_id = MBM29LV320BE, 677 .name = "Fujitsu MBM29LV320BE", 678 .uaddr = { 679 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 680 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 681 }, 682 .DevSize = SIZE_4MiB, 683 .CmdSet = P_ID_AMD_STD, 684 .NumEraseRegions= 2, 685 .regions = { 686 ERASEINFO(0x02000,8), 687 ERASEINFO(0x10000,63) 688 } 689 }, { 690 .mfr_id = MANUFACTURER_FUJITSU, 691 .dev_id = MBM29LV160TE, 692 .name = "Fujitsu MBM29LV160TE", 693 .uaddr = { 694 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 695 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 696 }, 697 .DevSize = SIZE_2MiB, 698 .CmdSet = P_ID_AMD_STD, 699 .NumEraseRegions= 4, 700 .regions = { 701 ERASEINFO(0x10000,31), 702 ERASEINFO(0x08000,1), 703 ERASEINFO(0x02000,2), 704 ERASEINFO(0x04000,1) 705 } 706 }, { 707 .mfr_id = MANUFACTURER_FUJITSU, 708 .dev_id = MBM29LV160BE, 709 .name = "Fujitsu MBM29LV160BE", 710 .uaddr = { 711 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 712 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 713 }, 714 .DevSize = SIZE_2MiB, 715 .CmdSet = P_ID_AMD_STD, 716 .NumEraseRegions= 4, 717 .regions = { 718 ERASEINFO(0x04000,1), 719 ERASEINFO(0x02000,2), 720 ERASEINFO(0x08000,1), 721 ERASEINFO(0x10000,31) 722 } 723 }, { 724 .mfr_id = MANUFACTURER_FUJITSU, 725 .dev_id = MBM29LV800BA, 726 .name = "Fujitsu MBM29LV800BA", 727 .uaddr = { 728 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 729 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 730 }, 731 .DevSize = SIZE_1MiB, 732 .CmdSet = P_ID_AMD_STD, 733 .NumEraseRegions= 4, 734 .regions = { 735 ERASEINFO(0x04000,1), 736 ERASEINFO(0x02000,2), 737 ERASEINFO(0x08000,1), 738 ERASEINFO(0x10000,15) 739 } 740 }, { 741 .mfr_id = MANUFACTURER_FUJITSU, 742 .dev_id = MBM29LV800TA, 743 .name = "Fujitsu MBM29LV800TA", 744 .uaddr = { 745 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 746 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 747 }, 748 .DevSize = SIZE_1MiB, 749 .CmdSet = P_ID_AMD_STD, 750 .NumEraseRegions= 4, 751 .regions = { 752 ERASEINFO(0x10000,15), 753 ERASEINFO(0x08000,1), 754 ERASEINFO(0x02000,2), 755 ERASEINFO(0x04000,1) 756 } 757 }, { 758 .mfr_id = MANUFACTURER_FUJITSU, 759 .dev_id = MBM29LV400BC, 760 .name = "Fujitsu MBM29LV400BC", 761 .uaddr = { 762 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 763 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 764 }, 765 .DevSize = SIZE_512KiB, 766 .CmdSet = P_ID_AMD_STD, 767 .NumEraseRegions= 4, 768 .regions = { 769 ERASEINFO(0x04000,1), 770 ERASEINFO(0x02000,2), 771 ERASEINFO(0x08000,1), 772 ERASEINFO(0x10000,7) 773 } 774 }, { 775 .mfr_id = MANUFACTURER_FUJITSU, 776 .dev_id = MBM29LV400TC, 777 .name = "Fujitsu MBM29LV400TC", 778 .uaddr = { 779 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 780 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 781 }, 782 .DevSize = SIZE_512KiB, 783 .CmdSet = P_ID_AMD_STD, 784 .NumEraseRegions= 4, 785 .regions = { 786 ERASEINFO(0x10000,7), 787 ERASEINFO(0x08000,1), 788 ERASEINFO(0x02000,2), 789 ERASEINFO(0x04000,1) 790 } 791 }, { 792 .mfr_id = MANUFACTURER_HYUNDAI, 793 .dev_id = HY29F002T, 794 .name = "Hyundai HY29F002T", 795 .uaddr = { 796 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 797 }, 798 .DevSize = SIZE_256KiB, 799 .CmdSet = P_ID_AMD_STD, 800 .NumEraseRegions= 4, 801 .regions = { 802 ERASEINFO(0x10000,3), 803 ERASEINFO(0x08000,1), 804 ERASEINFO(0x02000,2), 805 ERASEINFO(0x04000,1), 806 } 807 }, { 808 .mfr_id = MANUFACTURER_INTEL, 809 .dev_id = I28F004B3B, 810 .name = "Intel 28F004B3B", 811 .uaddr = { 812 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 813 }, 814 .DevSize = SIZE_512KiB, 815 .CmdSet = P_ID_INTEL_STD, 816 .NumEraseRegions= 2, 817 .regions = { 818 ERASEINFO(0x02000, 8), 819 ERASEINFO(0x10000, 7), 820 } 821 }, { 822 .mfr_id = MANUFACTURER_INTEL, 823 .dev_id = I28F004B3T, 824 .name = "Intel 28F004B3T", 825 .uaddr = { 826 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 827 }, 828 .DevSize = SIZE_512KiB, 829 .CmdSet = P_ID_INTEL_STD, 830 .NumEraseRegions= 2, 831 .regions = { 832 ERASEINFO(0x10000, 7), 833 ERASEINFO(0x02000, 8), 834 } 835 }, { 836 .mfr_id = MANUFACTURER_INTEL, 837 .dev_id = I28F400B3B, 838 .name = "Intel 28F400B3B", 839 .uaddr = { 840 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 841 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 842 }, 843 .DevSize = SIZE_512KiB, 844 .CmdSet = P_ID_INTEL_STD, 845 .NumEraseRegions= 2, 846 .regions = { 847 ERASEINFO(0x02000, 8), 848 ERASEINFO(0x10000, 7), 849 } 850 }, { 851 .mfr_id = MANUFACTURER_INTEL, 852 .dev_id = I28F400B3T, 853 .name = "Intel 28F400B3T", 854 .uaddr = { 855 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 856 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 857 }, 858 .DevSize = SIZE_512KiB, 859 .CmdSet = P_ID_INTEL_STD, 860 .NumEraseRegions= 2, 861 .regions = { 862 ERASEINFO(0x10000, 7), 863 ERASEINFO(0x02000, 8), 864 } 865 }, { 866 .mfr_id = MANUFACTURER_INTEL, 867 .dev_id = I28F008B3B, 868 .name = "Intel 28F008B3B", 869 .uaddr = { 870 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 871 }, 872 .DevSize = SIZE_1MiB, 873 .CmdSet = P_ID_INTEL_STD, 874 .NumEraseRegions= 2, 875 .regions = { 876 ERASEINFO(0x02000, 8), 877 ERASEINFO(0x10000, 15), 878 } 879 }, { 880 .mfr_id = MANUFACTURER_INTEL, 881 .dev_id = I28F008B3T, 882 .name = "Intel 28F008B3T", 883 .uaddr = { 884 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 885 }, 886 .DevSize = SIZE_1MiB, 887 .CmdSet = P_ID_INTEL_STD, 888 .NumEraseRegions= 2, 889 .regions = { 890 ERASEINFO(0x10000, 15), 891 ERASEINFO(0x02000, 8), 892 } 893 }, { 894 .mfr_id = MANUFACTURER_INTEL, 895 .dev_id = I28F008S5, 896 .name = "Intel 28F008S5", 897 .uaddr = { 898 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 899 }, 900 .DevSize = SIZE_1MiB, 901 .CmdSet = P_ID_INTEL_EXT, 902 .NumEraseRegions= 1, 903 .regions = { 904 ERASEINFO(0x10000,16), 905 } 906 }, { 907 .mfr_id = MANUFACTURER_INTEL, 908 .dev_id = I28F016S5, 909 .name = "Intel 28F016S5", 910 .uaddr = { 911 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 912 }, 913 .DevSize = SIZE_2MiB, 914 .CmdSet = P_ID_INTEL_EXT, 915 .NumEraseRegions= 1, 916 .regions = { 917 ERASEINFO(0x10000,32), 918 } 919 }, { 920 .mfr_id = MANUFACTURER_INTEL, 921 .dev_id = I28F008SA, 922 .name = "Intel 28F008SA", 923 .uaddr = { 924 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 925 }, 926 .DevSize = SIZE_1MiB, 927 .CmdSet = P_ID_INTEL_STD, 928 .NumEraseRegions= 1, 929 .regions = { 930 ERASEINFO(0x10000, 16), 931 } 932 }, { 933 .mfr_id = MANUFACTURER_INTEL, 934 .dev_id = I28F800B3B, 935 .name = "Intel 28F800B3B", 936 .uaddr = { 937 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 938 }, 939 .DevSize = SIZE_1MiB, 940 .CmdSet = P_ID_INTEL_STD, 941 .NumEraseRegions= 2, 942 .regions = { 943 ERASEINFO(0x02000, 8), 944 ERASEINFO(0x10000, 15), 945 } 946 }, { 947 .mfr_id = MANUFACTURER_INTEL, 948 .dev_id = I28F800B3T, 949 .name = "Intel 28F800B3T", 950 .uaddr = { 951 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 952 }, 953 .DevSize = SIZE_1MiB, 954 .CmdSet = P_ID_INTEL_STD, 955 .NumEraseRegions= 2, 956 .regions = { 957 ERASEINFO(0x10000, 15), 958 ERASEINFO(0x02000, 8), 959 } 960 }, { 961 .mfr_id = MANUFACTURER_INTEL, 962 .dev_id = I28F016B3B, 963 .name = "Intel 28F016B3B", 964 .uaddr = { 965 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 966 }, 967 .DevSize = SIZE_2MiB, 968 .CmdSet = P_ID_INTEL_STD, 969 .NumEraseRegions= 2, 970 .regions = { 971 ERASEINFO(0x02000, 8), 972 ERASEINFO(0x10000, 31), 973 } 974 }, { 975 .mfr_id = MANUFACTURER_INTEL, 976 .dev_id = I28F016S3, 977 .name = "Intel I28F016S3", 978 .uaddr = { 979 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 980 }, 981 .DevSize = SIZE_2MiB, 982 .CmdSet = P_ID_INTEL_STD, 983 .NumEraseRegions= 1, 984 .regions = { 985 ERASEINFO(0x10000, 32), 986 } 987 }, { 988 .mfr_id = MANUFACTURER_INTEL, 989 .dev_id = I28F016B3T, 990 .name = "Intel 28F016B3T", 991 .uaddr = { 992 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 993 }, 994 .DevSize = SIZE_2MiB, 995 .CmdSet = P_ID_INTEL_STD, 996 .NumEraseRegions= 2, 997 .regions = { 998 ERASEINFO(0x10000, 31), 999 ERASEINFO(0x02000, 8), 1000 } 1001 }, { 1002 .mfr_id = MANUFACTURER_INTEL, 1003 .dev_id = I28F160B3B, 1004 .name = "Intel 28F160B3B", 1005 .uaddr = { 1006 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 1007 }, 1008 .DevSize = SIZE_2MiB, 1009 .CmdSet = P_ID_INTEL_STD, 1010 .NumEraseRegions= 2, 1011 .regions = { 1012 ERASEINFO(0x02000, 8), 1013 ERASEINFO(0x10000, 31), 1014 } 1015 }, { 1016 .mfr_id = MANUFACTURER_INTEL, 1017 .dev_id = I28F160B3T, 1018 .name = "Intel 28F160B3T", 1019 .uaddr = { 1020 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 1021 }, 1022 .DevSize = SIZE_2MiB, 1023 .CmdSet = P_ID_INTEL_STD, 1024 .NumEraseRegions= 2, 1025 .regions = { 1026 ERASEINFO(0x10000, 31), 1027 ERASEINFO(0x02000, 8), 1028 } 1029 }, { 1030 .mfr_id = MANUFACTURER_INTEL, 1031 .dev_id = I28F320B3B, 1032 .name = "Intel 28F320B3B", 1033 .uaddr = { 1034 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 1035 }, 1036 .DevSize = SIZE_4MiB, 1037 .CmdSet = P_ID_INTEL_STD, 1038 .NumEraseRegions= 2, 1039 .regions = { 1040 ERASEINFO(0x02000, 8), 1041 ERASEINFO(0x10000, 63), 1042 } 1043 }, { 1044 .mfr_id = MANUFACTURER_INTEL, 1045 .dev_id = I28F320B3T, 1046 .name = "Intel 28F320B3T", 1047 .uaddr = { 1048 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 1049 }, 1050 .DevSize = SIZE_4MiB, 1051 .CmdSet = P_ID_INTEL_STD, 1052 .NumEraseRegions= 2, 1053 .regions = { 1054 ERASEINFO(0x10000, 63), 1055 ERASEINFO(0x02000, 8), 1056 } 1057 }, { 1058 .mfr_id = MANUFACTURER_INTEL, 1059 .dev_id = I28F640B3B, 1060 .name = "Intel 28F640B3B", 1061 .uaddr = { 1062 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 1063 }, 1064 .DevSize = SIZE_8MiB, 1065 .CmdSet = P_ID_INTEL_STD, 1066 .NumEraseRegions= 2, 1067 .regions = { 1068 ERASEINFO(0x02000, 8), 1069 ERASEINFO(0x10000, 127), 1070 } 1071 }, { 1072 .mfr_id = MANUFACTURER_INTEL, 1073 .dev_id = I28F640B3T, 1074 .name = "Intel 28F640B3T", 1075 .uaddr = { 1076 [1] = MTD_UADDR_UNNECESSARY, /* x16 */ 1077 }, 1078 .DevSize = SIZE_8MiB, 1079 .CmdSet = P_ID_INTEL_STD, 1080 .NumEraseRegions= 2, 1081 .regions = { 1082 ERASEINFO(0x10000, 127), 1083 ERASEINFO(0x02000, 8), 1084 } 1085 }, { 1086 .mfr_id = MANUFACTURER_INTEL, 1087 .dev_id = I82802AB, 1088 .name = "Intel 82802AB", 1089 .uaddr = { 1090 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 1091 }, 1092 .DevSize = SIZE_512KiB, 1093 .CmdSet = P_ID_INTEL_EXT, 1094 .NumEraseRegions= 1, 1095 .regions = { 1096 ERASEINFO(0x10000,8), 1097 } 1098 }, { 1099 .mfr_id = MANUFACTURER_INTEL, 1100 .dev_id = I82802AC, 1101 .name = "Intel 82802AC", 1102 .uaddr = { 1103 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 1104 }, 1105 .DevSize = SIZE_1MiB, 1106 .CmdSet = P_ID_INTEL_EXT, 1107 .NumEraseRegions= 1, 1108 .regions = { 1109 ERASEINFO(0x10000,16), 1110 } 1111 }, { 1112 .mfr_id = MANUFACTURER_MACRONIX, 1113 .dev_id = MX29LV040C, 1114 .name = "Macronix MX29LV040C", 1115 .uaddr = { 1116 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ 1117 }, 1118 .DevSize = SIZE_512KiB, 1119 .CmdSet = P_ID_AMD_STD, 1120 .NumEraseRegions= 1, 1121 .regions = { 1122 ERASEINFO(0x10000,8), 1123 } 1124 }, { 1125 .mfr_id = MANUFACTURER_MACRONIX, 1126 .dev_id = MX29LV160T, 1127 .name = "MXIC MX29LV160T", 1128 .uaddr = { 1129 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 1130 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 1131 }, 1132 .DevSize = SIZE_2MiB, 1133 .CmdSet = P_ID_AMD_STD, 1134 .NumEraseRegions= 4, 1135 .regions = { 1136 ERASEINFO(0x10000,31), 1137 ERASEINFO(0x08000,1), 1138 ERASEINFO(0x02000,2), 1139 ERASEINFO(0x04000,1) 1140 } 1141 }, { 1142 .mfr_id = MANUFACTURER_NEC, 1143 .dev_id = UPD29F064115, 1144 .name = "NEC uPD29F064115", 1145 .uaddr = { 1146 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ 1147 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 1148 }, 1149 .DevSize = SIZE_8MiB, 1150 .CmdSet = P_ID_AMD_STD, 1151 .NumEraseRegions= 3, 1152 .regions = { 1153 ERASEINFO(0x2000,8), 1154 ERASEINFO(0x10000,126), 1155 ERASEINFO(0x2000,8), 1156 } 1157 }, { 1158 .mfr_id = MANUFACTURER_MACRONIX, 1159 .dev_id = MX29LV160B, 1160 .name = "MXIC MX29LV160B", 1161 .uaddr = { 1162 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 1163 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 1164 }, 1165 .DevSize = SIZE_2MiB, 1166 .CmdSet = P_ID_AMD_STD, 1167 .NumEraseRegions= 4, 1168 .regions = { 1169 ERASEINFO(0x04000,1), 1170 ERASEINFO(0x02000,2), 1171 ERASEINFO(0x08000,1), 1172 ERASEINFO(0x10000,31) 1173 } 1174 }, { 1175 .mfr_id = MANUFACTURER_MACRONIX, 1176 .dev_id = MX29F016, 1177 .name = "Macronix MX29F016", 1178 .uaddr = { 1179 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 1180 }, 1181 .DevSize = SIZE_2MiB, 1182 .CmdSet = P_ID_AMD_STD, 1183 .NumEraseRegions= 1, 1184 .regions = { 1185 ERASEINFO(0x10000,32), 1186 } 1187 }, { 1188 .mfr_id = MANUFACTURER_MACRONIX, 1189 .dev_id = MX29F004T, 1190 .name = "Macronix MX29F004T", 1191 .uaddr = { 1192 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 1193 }, 1194 .DevSize = SIZE_512KiB, 1195 .CmdSet = P_ID_AMD_STD, 1196 .NumEraseRegions= 4, 1197 .regions = { 1198 ERASEINFO(0x10000,7), 1199 ERASEINFO(0x08000,1), 1200 ERASEINFO(0x02000,2), 1201 ERASEINFO(0x04000,1), 1202 } 1203 }, { 1204 .mfr_id = MANUFACTURER_MACRONIX, 1205 .dev_id = MX29F004B, 1206 .name = "Macronix MX29F004B", 1207 .uaddr = { 1208 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 1209 }, 1210 .DevSize = SIZE_512KiB, 1211 .CmdSet = P_ID_AMD_STD, 1212 .NumEraseRegions= 4, 1213 .regions = { 1214 ERASEINFO(0x04000,1), 1215 ERASEINFO(0x02000,2), 1216 ERASEINFO(0x08000,1), 1217 ERASEINFO(0x10000,7), 1218 } 1219 }, { 1220 .mfr_id = MANUFACTURER_MACRONIX, 1221 .dev_id = MX29F002T, 1222 .name = "Macronix MX29F002T", 1223 .uaddr = { 1224 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 1225 }, 1226 .DevSize = SIZE_256KiB, 1227 .CmdSet = P_ID_AMD_STD, 1228 .NumEraseRegions= 4, 1229 .regions = { 1230 ERASEINFO(0x10000,3), 1231 ERASEINFO(0x08000,1), 1232 ERASEINFO(0x02000,2), 1233 ERASEINFO(0x04000,1), 1234 } 1235 }, { 1236 .mfr_id = MANUFACTURER_PMC, 1237 .dev_id = PM49FL002, 1238 .name = "PMC Pm49FL002", 1239 .uaddr = { 1240 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1241 }, 1242 .DevSize = SIZE_256KiB, 1243 .CmdSet = P_ID_AMD_STD, 1244 .NumEraseRegions= 1, 1245 .regions = { 1246 ERASEINFO( 0x01000, 64 ) 1247 } 1248 }, { 1249 .mfr_id = MANUFACTURER_PMC, 1250 .dev_id = PM49FL004, 1251 .name = "PMC Pm49FL004", 1252 .uaddr = { 1253 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1254 }, 1255 .DevSize = SIZE_512KiB, 1256 .CmdSet = P_ID_AMD_STD, 1257 .NumEraseRegions= 1, 1258 .regions = { 1259 ERASEINFO( 0x01000, 128 ) 1260 } 1261 }, { 1262 .mfr_id = MANUFACTURER_PMC, 1263 .dev_id = PM49FL008, 1264 .name = "PMC Pm49FL008", 1265 .uaddr = { 1266 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1267 }, 1268 .DevSize = SIZE_1MiB, 1269 .CmdSet = P_ID_AMD_STD, 1270 .NumEraseRegions= 1, 1271 .regions = { 1272 ERASEINFO( 0x01000, 256 ) 1273 } 1274 }, { 1275 .mfr_id = MANUFACTURER_SHARP, 1276 .dev_id = LH28F640BF, 1277 .name = "LH28F640BF", 1278 .uaddr = { 1279 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 1280 }, 1281 .DevSize = SIZE_4MiB, 1282 .CmdSet = P_ID_INTEL_STD, 1283 .NumEraseRegions= 1, 1284 .regions = { 1285 ERASEINFO(0x40000,16), 1286 } 1287 }, { 1288 .mfr_id = MANUFACTURER_SST, 1289 .dev_id = SST39LF512, 1290 .name = "SST 39LF512", 1291 .uaddr = { 1292 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1293 }, 1294 .DevSize = SIZE_64KiB, 1295 .CmdSet = P_ID_AMD_STD, 1296 .NumEraseRegions= 1, 1297 .regions = { 1298 ERASEINFO(0x01000,16), 1299 } 1300 }, { 1301 .mfr_id = MANUFACTURER_SST, 1302 .dev_id = SST39LF010, 1303 .name = "SST 39LF010", 1304 .uaddr = { 1305 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1306 }, 1307 .DevSize = SIZE_128KiB, 1308 .CmdSet = P_ID_AMD_STD, 1309 .NumEraseRegions= 1, 1310 .regions = { 1311 ERASEINFO(0x01000,32), 1312 } 1313 }, { 1314 .mfr_id = MANUFACTURER_SST, 1315 .dev_id = SST29EE020, 1316 .name = "SST 29EE020", 1317 .uaddr = { 1318 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1319 }, 1320 .DevSize = SIZE_256KiB, 1321 .CmdSet = P_ID_SST_PAGE, 1322 .NumEraseRegions= 1, 1323 .regions = {ERASEINFO(0x01000,64), 1324 } 1325 }, { 1326 .mfr_id = MANUFACTURER_SST, 1327 .dev_id = SST29LE020, 1328 .name = "SST 29LE020", 1329 .uaddr = { 1330 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1331 }, 1332 .DevSize = SIZE_256KiB, 1333 .CmdSet = P_ID_SST_PAGE, 1334 .NumEraseRegions= 1, 1335 .regions = {ERASEINFO(0x01000,64), 1336 } 1337 }, { 1338 .mfr_id = MANUFACTURER_SST, 1339 .dev_id = SST39LF020, 1340 .name = "SST 39LF020", 1341 .uaddr = { 1342 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1343 }, 1344 .DevSize = SIZE_256KiB, 1345 .CmdSet = P_ID_AMD_STD, 1346 .NumEraseRegions= 1, 1347 .regions = { 1348 ERASEINFO(0x01000,64), 1349 } 1350 }, { 1351 .mfr_id = MANUFACTURER_SST, 1352 .dev_id = SST39LF040, 1353 .name = "SST 39LF040", 1354 .uaddr = { 1355 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1356 }, 1357 .DevSize = SIZE_512KiB, 1358 .CmdSet = P_ID_AMD_STD, 1359 .NumEraseRegions= 1, 1360 .regions = { 1361 ERASEINFO(0x01000,128), 1362 } 1363 }, { 1364 .mfr_id = MANUFACTURER_SST, 1365 .dev_id = SST39SF010A, 1366 .name = "SST 39SF010A", 1367 .uaddr = { 1368 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1369 }, 1370 .DevSize = SIZE_128KiB, 1371 .CmdSet = P_ID_AMD_STD, 1372 .NumEraseRegions= 1, 1373 .regions = { 1374 ERASEINFO(0x01000,32), 1375 } 1376 }, { 1377 .mfr_id = MANUFACTURER_SST, 1378 .dev_id = SST39SF020A, 1379 .name = "SST 39SF020A", 1380 .uaddr = { 1381 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1382 }, 1383 .DevSize = SIZE_256KiB, 1384 .CmdSet = P_ID_AMD_STD, 1385 .NumEraseRegions= 1, 1386 .regions = { 1387 ERASEINFO(0x01000,64), 1388 } 1389 }, { 1390 .mfr_id = MANUFACTURER_SST, 1391 .dev_id = SST49LF004B, 1392 .name = "SST 49LF004B", 1393 .uaddr = { 1394 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1395 }, 1396 .DevSize = SIZE_512KiB, 1397 .CmdSet = P_ID_AMD_STD, 1398 .NumEraseRegions= 1, 1399 .regions = { 1400 ERASEINFO(0x01000,128), 1401 } 1402 }, { 1403 .mfr_id = MANUFACTURER_SST, 1404 .dev_id = SST49LF008A, 1405 .name = "SST 49LF008A", 1406 .uaddr = { 1407 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1408 }, 1409 .DevSize = SIZE_1MiB, 1410 .CmdSet = P_ID_AMD_STD, 1411 .NumEraseRegions= 1, 1412 .regions = { 1413 ERASEINFO(0x01000,256), 1414 } 1415 }, { 1416 .mfr_id = MANUFACTURER_SST, 1417 .dev_id = SST49LF030A, 1418 .name = "SST 49LF030A", 1419 .uaddr = { 1420 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1421 }, 1422 .DevSize = SIZE_512KiB, 1423 .CmdSet = P_ID_AMD_STD, 1424 .NumEraseRegions= 1, 1425 .regions = { 1426 ERASEINFO(0x01000,96), 1427 } 1428 }, { 1429 .mfr_id = MANUFACTURER_SST, 1430 .dev_id = SST49LF040A, 1431 .name = "SST 49LF040A", 1432 .uaddr = { 1433 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1434 }, 1435 .DevSize = SIZE_512KiB, 1436 .CmdSet = P_ID_AMD_STD, 1437 .NumEraseRegions= 1, 1438 .regions = { 1439 ERASEINFO(0x01000,128), 1440 } 1441 }, { 1442 .mfr_id = MANUFACTURER_SST, 1443 .dev_id = SST49LF080A, 1444 .name = "SST 49LF080A", 1445 .uaddr = { 1446 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1447 }, 1448 .DevSize = SIZE_1MiB, 1449 .CmdSet = P_ID_AMD_STD, 1450 .NumEraseRegions= 1, 1451 .regions = { 1452 ERASEINFO(0x01000,256), 1453 } 1454 }, { 1455 .mfr_id = MANUFACTURER_SST, /* should be CFI */ 1456 .dev_id = SST39LF160, 1457 .name = "SST 39LF160", 1458 .uaddr = { 1459 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */ 1460 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ 1461 }, 1462 .DevSize = SIZE_2MiB, 1463 .CmdSet = P_ID_AMD_STD, 1464 .NumEraseRegions= 2, 1465 .regions = { 1466 ERASEINFO(0x1000,256), 1467 ERASEINFO(0x1000,256) 1468 } 1469 }, { 1470 .mfr_id = MANUFACTURER_SST, /* should be CFI */ 1471 .dev_id = SST39VF1601, 1472 .name = "SST 39VF1601", 1473 .uaddr = { 1474 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */ 1475 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ 1476 }, 1477 .DevSize = SIZE_2MiB, 1478 .CmdSet = P_ID_AMD_STD, 1479 .NumEraseRegions= 2, 1480 .regions = { 1481 ERASEINFO(0x1000,256), 1482 ERASEINFO(0x1000,256) 1483 } 1484 1485 }, { 1486 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ 1487 .dev_id = M29W800DT, 1488 .name = "ST M29W800DT", 1489 .uaddr = { 1490 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */ 1491 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ 1492 }, 1493 .DevSize = SIZE_1MiB, 1494 .CmdSet = P_ID_AMD_STD, 1495 .NumEraseRegions= 4, 1496 .regions = { 1497 ERASEINFO(0x10000,15), 1498 ERASEINFO(0x08000,1), 1499 ERASEINFO(0x02000,2), 1500 ERASEINFO(0x04000,1) 1501 } 1502 }, { 1503 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ 1504 .dev_id = M29W800DB, 1505 .name = "ST M29W800DB", 1506 .uaddr = { 1507 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */ 1508 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ 1509 }, 1510 .DevSize = SIZE_1MiB, 1511 .CmdSet = P_ID_AMD_STD, 1512 .NumEraseRegions= 4, 1513 .regions = { 1514 ERASEINFO(0x04000,1), 1515 ERASEINFO(0x02000,2), 1516 ERASEINFO(0x08000,1), 1517 ERASEINFO(0x10000,15) 1518 } 1519 }, { 1520 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ 1521 .dev_id = M29W160DT, 1522 .name = "ST M29W160DT", 1523 .uaddr = { 1524 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ 1525 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 1526 }, 1527 .DevSize = SIZE_2MiB, 1528 .CmdSet = P_ID_AMD_STD, 1529 .NumEraseRegions= 4, 1530 .regions = { 1531 ERASEINFO(0x10000,31), 1532 ERASEINFO(0x08000,1), 1533 ERASEINFO(0x02000,2), 1534 ERASEINFO(0x04000,1) 1535 } 1536 }, { 1537 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ 1538 .dev_id = M29W160DB, 1539 .name = "ST M29W160DB", 1540 .uaddr = { 1541 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ 1542 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 1543 }, 1544 .DevSize = SIZE_2MiB, 1545 .CmdSet = P_ID_AMD_STD, 1546 .NumEraseRegions= 4, 1547 .regions = { 1548 ERASEINFO(0x04000,1), 1549 ERASEINFO(0x02000,2), 1550 ERASEINFO(0x08000,1), 1551 ERASEINFO(0x10000,31) 1552 } 1553 }, { 1554 .mfr_id = MANUFACTURER_ST, 1555 .dev_id = M29W040B, 1556 .name = "ST M29W040B", 1557 .uaddr = { 1558 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ 1559 }, 1560 .DevSize = SIZE_512KiB, 1561 .CmdSet = P_ID_AMD_STD, 1562 .NumEraseRegions= 1, 1563 .regions = { 1564 ERASEINFO(0x10000,8), 1565 } 1566 }, { 1567 .mfr_id = MANUFACTURER_ST, 1568 .dev_id = M50FW040, 1569 .name = "ST M50FW040", 1570 .uaddr = { 1571 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 1572 }, 1573 .DevSize = SIZE_512KiB, 1574 .CmdSet = P_ID_INTEL_EXT, 1575 .NumEraseRegions= 1, 1576 .regions = { 1577 ERASEINFO(0x10000,8), 1578 } 1579 }, { 1580 .mfr_id = MANUFACTURER_ST, 1581 .dev_id = M50FW080, 1582 .name = "ST M50FW080", 1583 .uaddr = { 1584 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 1585 }, 1586 .DevSize = SIZE_1MiB, 1587 .CmdSet = P_ID_INTEL_EXT, 1588 .NumEraseRegions= 1, 1589 .regions = { 1590 ERASEINFO(0x10000,16), 1591 } 1592 }, { 1593 .mfr_id = MANUFACTURER_ST, 1594 .dev_id = M50FW016, 1595 .name = "ST M50FW016", 1596 .uaddr = { 1597 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 1598 }, 1599 .DevSize = SIZE_2MiB, 1600 .CmdSet = P_ID_INTEL_EXT, 1601 .NumEraseRegions= 1, 1602 .regions = { 1603 ERASEINFO(0x10000,32), 1604 } 1605 }, { 1606 .mfr_id = MANUFACTURER_ST, 1607 .dev_id = M50LPW080, 1608 .name = "ST M50LPW080", 1609 .uaddr = { 1610 [0] = MTD_UADDR_UNNECESSARY, /* x8 */ 1611 }, 1612 .DevSize = SIZE_1MiB, 1613 .CmdSet = P_ID_INTEL_EXT, 1614 .NumEraseRegions= 1, 1615 .regions = { 1616 ERASEINFO(0x10000,16), 1617 } 1618 }, { 1619 .mfr_id = MANUFACTURER_TOSHIBA, 1620 .dev_id = TC58FVT160, 1621 .name = "Toshiba TC58FVT160", 1622 .uaddr = { 1623 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 1624 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ 1625 }, 1626 .DevSize = SIZE_2MiB, 1627 .CmdSet = P_ID_AMD_STD, 1628 .NumEraseRegions= 4, 1629 .regions = { 1630 ERASEINFO(0x10000,31), 1631 ERASEINFO(0x08000,1), 1632 ERASEINFO(0x02000,2), 1633 ERASEINFO(0x04000,1) 1634 } 1635 }, { 1636 .mfr_id = MANUFACTURER_TOSHIBA, 1637 .dev_id = TC58FVB160, 1638 .name = "Toshiba TC58FVB160", 1639 .uaddr = { 1640 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 1641 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ 1642 }, 1643 .DevSize = SIZE_2MiB, 1644 .CmdSet = P_ID_AMD_STD, 1645 .NumEraseRegions= 4, 1646 .regions = { 1647 ERASEINFO(0x04000,1), 1648 ERASEINFO(0x02000,2), 1649 ERASEINFO(0x08000,1), 1650 ERASEINFO(0x10000,31) 1651 } 1652 }, { 1653 .mfr_id = MANUFACTURER_TOSHIBA, 1654 .dev_id = TC58FVB321, 1655 .name = "Toshiba TC58FVB321", 1656 .uaddr = { 1657 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 1658 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ 1659 }, 1660 .DevSize = SIZE_4MiB, 1661 .CmdSet = P_ID_AMD_STD, 1662 .NumEraseRegions= 2, 1663 .regions = { 1664 ERASEINFO(0x02000,8), 1665 ERASEINFO(0x10000,63) 1666 } 1667 }, { 1668 .mfr_id = MANUFACTURER_TOSHIBA, 1669 .dev_id = TC58FVT321, 1670 .name = "Toshiba TC58FVT321", 1671 .uaddr = { 1672 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 1673 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ 1674 }, 1675 .DevSize = SIZE_4MiB, 1676 .CmdSet = P_ID_AMD_STD, 1677 .NumEraseRegions= 2, 1678 .regions = { 1679 ERASEINFO(0x10000,63), 1680 ERASEINFO(0x02000,8) 1681 } 1682 }, { 1683 .mfr_id = MANUFACTURER_TOSHIBA, 1684 .dev_id = TC58FVB641, 1685 .name = "Toshiba TC58FVB641", 1686 .uaddr = { 1687 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 1688 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 1689 }, 1690 .DevSize = SIZE_8MiB, 1691 .CmdSet = P_ID_AMD_STD, 1692 .NumEraseRegions= 2, 1693 .regions = { 1694 ERASEINFO(0x02000,8), 1695 ERASEINFO(0x10000,127) 1696 } 1697 }, { 1698 .mfr_id = MANUFACTURER_TOSHIBA, 1699 .dev_id = TC58FVT641, 1700 .name = "Toshiba TC58FVT641", 1701 .uaddr = { 1702 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ 1703 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ 1704 }, 1705 .DevSize = SIZE_8MiB, 1706 .CmdSet = P_ID_AMD_STD, 1707 .NumEraseRegions= 2, 1708 .regions = { 1709 ERASEINFO(0x10000,127), 1710 ERASEINFO(0x02000,8) 1711 } 1712 }, { 1713 .mfr_id = MANUFACTURER_WINBOND, 1714 .dev_id = W49V002A, 1715 .name = "Winbond W49V002A", 1716 .uaddr = { 1717 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ 1718 }, 1719 .DevSize = SIZE_256KiB, 1720 .CmdSet = P_ID_AMD_STD, 1721 .NumEraseRegions= 4, 1722 .regions = { 1723 ERASEINFO(0x10000, 3), 1724 ERASEINFO(0x08000, 1), 1725 ERASEINFO(0x02000, 2), 1726 ERASEINFO(0x04000, 1), 1727 } 1728 } 1729 }; 1730 1731 1732 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index); 1733 1734 static int jedec_probe_chip(struct map_info *map, __u32 base, 1735 unsigned long *chip_map, struct cfi_private *cfi); 1736 1737 static struct mtd_info *jedec_probe(struct map_info *map); 1738 1739 static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, 1740 struct cfi_private *cfi) 1741 { 1742 map_word result; 1743 unsigned long mask; 1744 u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type); 1745 mask = (1 << (cfi->device_type * 8)) -1; 1746 result = map_read(map, base + ofs); 1747 return result.x[0] & mask; 1748 } 1749 1750 static inline u32 jedec_read_id(struct map_info *map, __u32 base, 1751 struct cfi_private *cfi) 1752 { 1753 map_word result; 1754 unsigned long mask; 1755 u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type); 1756 mask = (1 << (cfi->device_type * 8)) -1; 1757 result = map_read(map, base + ofs); 1758 return result.x[0] & mask; 1759 } 1760 1761 static inline void jedec_reset(u32 base, struct map_info *map, 1762 struct cfi_private *cfi) 1763 { 1764 /* Reset */ 1765 1766 /* after checking the datasheets for SST, MACRONIX and ATMEL 1767 * (oh and incidentaly the jedec spec - 3.5.3.3) the reset 1768 * sequence is *supposed* to be 0xaa at 0x5555, 0x55 at 1769 * 0x2aaa, 0xF0 at 0x5555 this will not affect the AMD chips 1770 * as they will ignore the writes and dont care what address 1771 * the F0 is written to */ 1772 if(cfi->addr_unlock1) { 1773 DEBUG( MTD_DEBUG_LEVEL3, 1774 "reset unlock called %x %x \n", 1775 cfi->addr_unlock1,cfi->addr_unlock2); 1776 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); 1777 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL); 1778 } 1779 1780 cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); 1781 /* Some misdesigned intel chips do not respond for 0xF0 for a reset, 1782 * so ensure we're in read mode. Send both the Intel and the AMD command 1783 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so 1784 * this should be safe. 1785 */ 1786 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); 1787 /* FIXME - should have reset delay before continuing */ 1788 } 1789 1790 1791 static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type) 1792 { 1793 int uaddr_idx; 1794 __u8 uaddr = MTD_UADDR_NOT_SUPPORTED; 1795 1796 switch ( device_type ) { 1797 case CFI_DEVICETYPE_X8: uaddr_idx = 0; break; 1798 case CFI_DEVICETYPE_X16: uaddr_idx = 1; break; 1799 case CFI_DEVICETYPE_X32: uaddr_idx = 2; break; 1800 default: 1801 printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n", 1802 __func__, device_type); 1803 goto uaddr_done; 1804 } 1805 1806 uaddr = finfo->uaddr[uaddr_idx]; 1807 1808 if (uaddr != MTD_UADDR_NOT_SUPPORTED ) { 1809 /* ASSERT("The unlock addresses for non-8-bit mode 1810 are bollocks. We don't really need an array."); */ 1811 uaddr = finfo->uaddr[0]; 1812 } 1813 1814 uaddr_done: 1815 return uaddr; 1816 } 1817 1818 1819 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) 1820 { 1821 int i,num_erase_regions; 1822 __u8 uaddr; 1823 1824 printk("Found: %s\n",jedec_table[index].name); 1825 1826 num_erase_regions = jedec_table[index].NumEraseRegions; 1827 1828 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); 1829 if (!p_cfi->cfiq) { 1830 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); 1831 return 0; 1832 } 1833 1834 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); 1835 1836 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet; 1837 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions; 1838 p_cfi->cfiq->DevSize = jedec_table[index].DevSize; 1839 p_cfi->cfi_mode = CFI_MODE_JEDEC; 1840 1841 for (i=0; i<num_erase_regions; i++){ 1842 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; 1843 } 1844 p_cfi->cmdset_priv = NULL; 1845 1846 /* This may be redundant for some cases, but it doesn't hurt */ 1847 p_cfi->mfr = jedec_table[index].mfr_id; 1848 p_cfi->id = jedec_table[index].dev_id; 1849 1850 uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type); 1851 if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) { 1852 kfree( p_cfi->cfiq ); 1853 return 0; 1854 } 1855 1856 p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1; 1857 p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2; 1858 1859 return 1; /* ok */ 1860 } 1861 1862 1863 /* 1864 * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing 1865 * the mapped address, unlock addresses, and proper chip ID. This function 1866 * attempts to minimize errors. It is doubtfull that this probe will ever 1867 * be perfect - consequently there should be some module parameters that 1868 * could be manually specified to force the chip info. 1869 */ 1870 static inline int jedec_match( __u32 base, 1871 struct map_info *map, 1872 struct cfi_private *cfi, 1873 const struct amd_flash_info *finfo ) 1874 { 1875 int rc = 0; /* failure until all tests pass */ 1876 u32 mfr, id; 1877 __u8 uaddr; 1878 1879 /* 1880 * The IDs must match. For X16 and X32 devices operating in 1881 * a lower width ( X8 or X16 ), the device ID's are usually just 1882 * the lower byte(s) of the larger device ID for wider mode. If 1883 * a part is found that doesn't fit this assumption (device id for 1884 * smaller width mode is completely unrealated to full-width mode) 1885 * then the jedec_table[] will have to be augmented with the IDs 1886 * for different widths. 1887 */ 1888 switch (cfi->device_type) { 1889 case CFI_DEVICETYPE_X8: 1890 mfr = (__u8)finfo->mfr_id; 1891 id = (__u8)finfo->dev_id; 1892 1893 /* bjd: it seems that if we do this, we can end up 1894 * detecting 16bit flashes as an 8bit device, even though 1895 * there aren't. 1896 */ 1897 if (finfo->dev_id > 0xff) { 1898 DEBUG( MTD_DEBUG_LEVEL3, "%s(): ID is not 8bit\n", 1899 __func__); 1900 goto match_done; 1901 } 1902 break; 1903 case CFI_DEVICETYPE_X16: 1904 mfr = (__u16)finfo->mfr_id; 1905 id = (__u16)finfo->dev_id; 1906 break; 1907 case CFI_DEVICETYPE_X32: 1908 mfr = (__u16)finfo->mfr_id; 1909 id = (__u32)finfo->dev_id; 1910 break; 1911 default: 1912 printk(KERN_WARNING 1913 "MTD %s(): Unsupported device type %d\n", 1914 __func__, cfi->device_type); 1915 goto match_done; 1916 } 1917 if ( cfi->mfr != mfr || cfi->id != id ) { 1918 goto match_done; 1919 } 1920 1921 /* the part size must fit in the memory window */ 1922 DEBUG( MTD_DEBUG_LEVEL3, 1923 "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n", 1924 __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) ); 1925 if ( base + cfi_interleave(cfi) * ( 1 << finfo->DevSize ) > map->size ) { 1926 DEBUG( MTD_DEBUG_LEVEL3, 1927 "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n", 1928 __func__, finfo->mfr_id, finfo->dev_id, 1929 1 << finfo->DevSize ); 1930 goto match_done; 1931 } 1932 1933 uaddr = finfo_uaddr(finfo, cfi->device_type); 1934 if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) { 1935 goto match_done; 1936 } 1937 1938 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n", 1939 __func__, cfi->addr_unlock1, cfi->addr_unlock2 ); 1940 if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr 1941 && ( unlock_addrs[uaddr].addr1 != cfi->addr_unlock1 || 1942 unlock_addrs[uaddr].addr2 != cfi->addr_unlock2 ) ) { 1943 DEBUG( MTD_DEBUG_LEVEL3, 1944 "MTD %s(): 0x%.4x 0x%.4x did not match\n", 1945 __func__, 1946 unlock_addrs[uaddr].addr1, 1947 unlock_addrs[uaddr].addr2); 1948 goto match_done; 1949 } 1950 1951 /* 1952 * Make sure the ID's dissappear when the device is taken out of 1953 * ID mode. The only time this should fail when it should succeed 1954 * is when the ID's are written as data to the same 1955 * addresses. For this rare and unfortunate case the chip 1956 * cannot be probed correctly. 1957 * FIXME - write a driver that takes all of the chip info as 1958 * module parameters, doesn't probe but forces a load. 1959 */ 1960 DEBUG( MTD_DEBUG_LEVEL3, 1961 "MTD %s(): check ID's disappear when not in ID mode\n", 1962 __func__ ); 1963 jedec_reset( base, map, cfi ); 1964 mfr = jedec_read_mfr( map, base, cfi ); 1965 id = jedec_read_id( map, base, cfi ); 1966 if ( mfr == cfi->mfr && id == cfi->id ) { 1967 DEBUG( MTD_DEBUG_LEVEL3, 1968 "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n" 1969 "You might need to manually specify JEDEC parameters.\n", 1970 __func__, cfi->mfr, cfi->id ); 1971 goto match_done; 1972 } 1973 1974 /* all tests passed - mark as success */ 1975 rc = 1; 1976 1977 /* 1978 * Put the device back in ID mode - only need to do this if we 1979 * were truly frobbing a real device. 1980 */ 1981 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ ); 1982 if(cfi->addr_unlock1) { 1983 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); 1984 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL); 1985 } 1986 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); 1987 /* FIXME - should have a delay before continuing */ 1988 1989 match_done: 1990 return rc; 1991 } 1992 1993 1994 static int jedec_probe_chip(struct map_info *map, __u32 base, 1995 unsigned long *chip_map, struct cfi_private *cfi) 1996 { 1997 int i; 1998 enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED; 1999 u32 probe_offset1, probe_offset2; 2000 2001 retry: 2002 if (!cfi->numchips) { 2003 uaddr_idx++; 2004 2005 if (MTD_UADDR_UNNECESSARY == uaddr_idx) 2006 return 0; 2007 2008 cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1; 2009 cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2; 2010 } 2011 2012 /* Make certain we aren't probing past the end of map */ 2013 if (base >= map->size) { 2014 printk(KERN_NOTICE 2015 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n", 2016 base, map->size -1); 2017 return 0; 2018 2019 } 2020 /* Ensure the unlock addresses we try stay inside the map */ 2021 probe_offset1 = cfi_build_cmd_addr( 2022 cfi->addr_unlock1, 2023 cfi_interleave(cfi), 2024 cfi->device_type); 2025 probe_offset2 = cfi_build_cmd_addr( 2026 cfi->addr_unlock1, 2027 cfi_interleave(cfi), 2028 cfi->device_type); 2029 if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || 2030 ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) 2031 { 2032 goto retry; 2033 } 2034 2035 /* Reset */ 2036 jedec_reset(base, map, cfi); 2037 2038 /* Autoselect Mode */ 2039 if(cfi->addr_unlock1) { 2040 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); 2041 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL); 2042 } 2043 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); 2044 /* FIXME - should have a delay before continuing */ 2045 2046 if (!cfi->numchips) { 2047 /* This is the first time we're called. Set up the CFI 2048 stuff accordingly and return */ 2049 2050 cfi->mfr = jedec_read_mfr(map, base, cfi); 2051 cfi->id = jedec_read_id(map, base, cfi); 2052 DEBUG(MTD_DEBUG_LEVEL3, 2053 "Search for id:(%02x %02x) interleave(%d) type(%d)\n", 2054 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); 2055 for (i = 0; i < ARRAY_SIZE(jedec_table); i++) { 2056 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { 2057 DEBUG( MTD_DEBUG_LEVEL3, 2058 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", 2059 __func__, cfi->mfr, cfi->id, 2060 cfi->addr_unlock1, cfi->addr_unlock2 ); 2061 if (!cfi_jedec_setup(cfi, i)) 2062 return 0; 2063 goto ok_out; 2064 } 2065 } 2066 goto retry; 2067 } else { 2068 __u16 mfr; 2069 __u16 id; 2070 2071 /* Make sure it is a chip of the same manufacturer and id */ 2072 mfr = jedec_read_mfr(map, base, cfi); 2073 id = jedec_read_id(map, base, cfi); 2074 2075 if ((mfr != cfi->mfr) || (id != cfi->id)) { 2076 printk(KERN_DEBUG "%s: Found different chip or no chip at all (mfr 0x%x, id 0x%x) at 0x%x\n", 2077 map->name, mfr, id, base); 2078 jedec_reset(base, map, cfi); 2079 return 0; 2080 } 2081 } 2082 2083 /* Check each previous chip locations to see if it's an alias */ 2084 for (i=0; i < (base >> cfi->chipshift); i++) { 2085 unsigned long start; 2086 if(!test_bit(i, chip_map)) { 2087 continue; /* Skip location; no valid chip at this address */ 2088 } 2089 start = i << cfi->chipshift; 2090 if (jedec_read_mfr(map, start, cfi) == cfi->mfr && 2091 jedec_read_id(map, start, cfi) == cfi->id) { 2092 /* Eep. This chip also looks like it's in autoselect mode. 2093 Is it an alias for the new one? */ 2094 jedec_reset(start, map, cfi); 2095 2096 /* If the device IDs go away, it's an alias */ 2097 if (jedec_read_mfr(map, base, cfi) != cfi->mfr || 2098 jedec_read_id(map, base, cfi) != cfi->id) { 2099 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", 2100 map->name, base, start); 2101 return 0; 2102 } 2103 2104 /* Yes, it's actually got the device IDs as data. Most 2105 * unfortunate. Stick the new chip in read mode 2106 * too and if it's the same, assume it's an alias. */ 2107 /* FIXME: Use other modes to do a proper check */ 2108 jedec_reset(base, map, cfi); 2109 if (jedec_read_mfr(map, base, cfi) == cfi->mfr && 2110 jedec_read_id(map, base, cfi) == cfi->id) { 2111 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", 2112 map->name, base, start); 2113 return 0; 2114 } 2115 } 2116 } 2117 2118 /* OK, if we got to here, then none of the previous chips appear to 2119 be aliases for the current one. */ 2120 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ 2121 cfi->numchips++; 2122 2123 ok_out: 2124 /* Put it back into Read Mode */ 2125 jedec_reset(base, map, cfi); 2126 2127 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", 2128 map->name, cfi_interleave(cfi), cfi->device_type*8, base, 2129 map->bankwidth*8); 2130 2131 return 1; 2132 } 2133 2134 static struct chip_probe jedec_chip_probe = { 2135 .name = "JEDEC", 2136 .probe_chip = jedec_probe_chip 2137 }; 2138 2139 static struct mtd_info *jedec_probe(struct map_info *map) 2140 { 2141 /* 2142 * Just use the generic probe stuff to call our CFI-specific 2143 * chip_probe routine in all the possible permutations, etc. 2144 */ 2145 return mtd_do_chip_probe(map, &jedec_chip_probe); 2146 } 2147 2148 static struct mtd_chip_driver jedec_chipdrv = { 2149 .probe = jedec_probe, 2150 .name = "jedec_probe", 2151 .module = THIS_MODULE 2152 }; 2153 2154 static int __init jedec_probe_init(void) 2155 { 2156 register_mtd_chip_driver(&jedec_chipdrv); 2157 return 0; 2158 } 2159 2160 static void __exit jedec_probe_exit(void) 2161 { 2162 unregister_mtd_chip_driver(&jedec_chipdrv); 2163 } 2164 2165 module_init(jedec_probe_init); 2166 module_exit(jedec_probe_exit); 2167 2168 MODULE_LICENSE("GPL"); 2169 MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al."); 2170 MODULE_DESCRIPTION("Probe code for JEDEC-compliant flash chips"); 2171