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