at v2.6.12 1415 lines 35 kB view raw
1/* 2 * MTD map driver for AMD compatible flash chips (non-CFI) 3 * 4 * Author: Jonas Holmberg <jonas.holmberg@axis.com> 5 * 6 * $Id: amd_flash.c,v 1.26 2004/11/20 12:49:04 dwmw2 Exp $ 7 * 8 * Copyright (c) 2001 Axis Communications AB 9 * 10 * This file is under GPL. 11 * 12 */ 13 14#include <linux/module.h> 15#include <linux/types.h> 16#include <linux/kernel.h> 17#include <linux/sched.h> 18#include <linux/errno.h> 19#include <linux/slab.h> 20#include <linux/delay.h> 21#include <linux/interrupt.h> 22#include <linux/init.h> 23#include <linux/mtd/map.h> 24#include <linux/mtd/mtd.h> 25#include <linux/mtd/flashchip.h> 26 27/* There's no limit. It exists only to avoid realloc. */ 28#define MAX_AMD_CHIPS 8 29 30#define DEVICE_TYPE_X8 (8 / 8) 31#define DEVICE_TYPE_X16 (16 / 8) 32#define DEVICE_TYPE_X32 (32 / 8) 33 34/* Addresses */ 35#define ADDR_MANUFACTURER 0x0000 36#define ADDR_DEVICE_ID 0x0001 37#define ADDR_SECTOR_LOCK 0x0002 38#define ADDR_HANDSHAKE 0x0003 39#define ADDR_UNLOCK_1 0x0555 40#define ADDR_UNLOCK_2 0x02AA 41 42/* Commands */ 43#define CMD_UNLOCK_DATA_1 0x00AA 44#define CMD_UNLOCK_DATA_2 0x0055 45#define CMD_MANUFACTURER_UNLOCK_DATA 0x0090 46#define CMD_UNLOCK_BYPASS_MODE 0x0020 47#define CMD_PROGRAM_UNLOCK_DATA 0x00A0 48#define CMD_RESET_DATA 0x00F0 49#define CMD_SECTOR_ERASE_UNLOCK_DATA 0x0080 50#define CMD_SECTOR_ERASE_UNLOCK_DATA_2 0x0030 51 52#define CMD_UNLOCK_SECTOR 0x0060 53 54/* Manufacturers */ 55#define MANUFACTURER_AMD 0x0001 56#define MANUFACTURER_ATMEL 0x001F 57#define MANUFACTURER_FUJITSU 0x0004 58#define MANUFACTURER_ST 0x0020 59#define MANUFACTURER_SST 0x00BF 60#define MANUFACTURER_TOSHIBA 0x0098 61 62/* AMD */ 63#define AM29F800BB 0x2258 64#define AM29F800BT 0x22D6 65#define AM29LV800BB 0x225B 66#define AM29LV800BT 0x22DA 67#define AM29LV160DT 0x22C4 68#define AM29LV160DB 0x2249 69#define AM29BDS323D 0x22D1 70#define AM29BDS643D 0x227E 71 72/* Atmel */ 73#define AT49xV16x 0x00C0 74#define AT49xV16xT 0x00C2 75 76/* Fujitsu */ 77#define MBM29LV160TE 0x22C4 78#define MBM29LV160BE 0x2249 79#define MBM29LV800BB 0x225B 80 81/* ST - www.st.com */ 82#define M29W800T 0x00D7 83#define M29W160DT 0x22C4 84#define M29W160DB 0x2249 85 86/* SST */ 87#define SST39LF800 0x2781 88#define SST39LF160 0x2782 89 90/* Toshiba */ 91#define TC58FVT160 0x00C2 92#define TC58FVB160 0x0043 93 94#define D6_MASK 0x40 95 96struct amd_flash_private { 97 int device_type; 98 int interleave; 99 int numchips; 100 unsigned long chipshift; 101// const char *im_name; 102 struct flchip chips[0]; 103}; 104 105struct amd_flash_info { 106 const __u16 mfr_id; 107 const __u16 dev_id; 108 const char *name; 109 const u_long size; 110 const int numeraseregions; 111 const struct mtd_erase_region_info regions[4]; 112}; 113 114 115 116static int amd_flash_read(struct mtd_info *, loff_t, size_t, size_t *, 117 u_char *); 118static int amd_flash_write(struct mtd_info *, loff_t, size_t, size_t *, 119 const u_char *); 120static int amd_flash_erase(struct mtd_info *, struct erase_info *); 121static void amd_flash_sync(struct mtd_info *); 122static int amd_flash_suspend(struct mtd_info *); 123static void amd_flash_resume(struct mtd_info *); 124static void amd_flash_destroy(struct mtd_info *); 125static struct mtd_info *amd_flash_probe(struct map_info *map); 126 127 128static struct mtd_chip_driver amd_flash_chipdrv = { 129 .probe = amd_flash_probe, 130 .destroy = amd_flash_destroy, 131 .name = "amd_flash", 132 .module = THIS_MODULE 133}; 134 135 136 137static const char im_name[] = "amd_flash"; 138 139 140 141static inline __u32 wide_read(struct map_info *map, __u32 addr) 142{ 143 if (map->buswidth == 1) { 144 return map_read8(map, addr); 145 } else if (map->buswidth == 2) { 146 return map_read16(map, addr); 147 } else if (map->buswidth == 4) { 148 return map_read32(map, addr); 149 } 150 151 return 0; 152} 153 154static inline void wide_write(struct map_info *map, __u32 val, __u32 addr) 155{ 156 if (map->buswidth == 1) { 157 map_write8(map, val, addr); 158 } else if (map->buswidth == 2) { 159 map_write16(map, val, addr); 160 } else if (map->buswidth == 4) { 161 map_write32(map, val, addr); 162 } 163} 164 165static inline __u32 make_cmd(struct map_info *map, __u32 cmd) 166{ 167 const struct amd_flash_private *private = map->fldrv_priv; 168 if ((private->interleave == 2) && 169 (private->device_type == DEVICE_TYPE_X16)) { 170 cmd |= (cmd << 16); 171 } 172 173 return cmd; 174} 175 176static inline void send_unlock(struct map_info *map, unsigned long base) 177{ 178 wide_write(map, (CMD_UNLOCK_DATA_1 << 16) | CMD_UNLOCK_DATA_1, 179 base + (map->buswidth * ADDR_UNLOCK_1)); 180 wide_write(map, (CMD_UNLOCK_DATA_2 << 16) | CMD_UNLOCK_DATA_2, 181 base + (map->buswidth * ADDR_UNLOCK_2)); 182} 183 184static inline void send_cmd(struct map_info *map, unsigned long base, __u32 cmd) 185{ 186 send_unlock(map, base); 187 wide_write(map, make_cmd(map, cmd), 188 base + (map->buswidth * ADDR_UNLOCK_1)); 189} 190 191static inline void send_cmd_to_addr(struct map_info *map, unsigned long base, 192 __u32 cmd, unsigned long addr) 193{ 194 send_unlock(map, base); 195 wide_write(map, make_cmd(map, cmd), addr); 196} 197 198static inline int flash_is_busy(struct map_info *map, unsigned long addr, 199 int interleave) 200{ 201 202 if ((interleave == 2) && (map->buswidth == 4)) { 203 __u32 read1, read2; 204 205 read1 = wide_read(map, addr); 206 read2 = wide_read(map, addr); 207 208 return (((read1 >> 16) & D6_MASK) != 209 ((read2 >> 16) & D6_MASK)) || 210 (((read1 & 0xffff) & D6_MASK) != 211 ((read2 & 0xffff) & D6_MASK)); 212 } 213 214 return ((wide_read(map, addr) & D6_MASK) != 215 (wide_read(map, addr) & D6_MASK)); 216} 217 218static inline void unlock_sector(struct map_info *map, unsigned long sect_addr, 219 int unlock) 220{ 221 /* Sector lock address. A6 = 1 for unlock, A6 = 0 for lock */ 222 int SLA = unlock ? 223 (sect_addr | (0x40 * map->buswidth)) : 224 (sect_addr & ~(0x40 * map->buswidth)) ; 225 226 __u32 cmd = make_cmd(map, CMD_UNLOCK_SECTOR); 227 228 wide_write(map, make_cmd(map, CMD_RESET_DATA), 0); 229 wide_write(map, cmd, SLA); /* 1st cycle: write cmd to any address */ 230 wide_write(map, cmd, SLA); /* 2nd cycle: write cmd to any address */ 231 wide_write(map, cmd, SLA); /* 3rd cycle: write cmd to SLA */ 232} 233 234static inline int is_sector_locked(struct map_info *map, 235 unsigned long sect_addr) 236{ 237 int status; 238 239 wide_write(map, CMD_RESET_DATA, 0); 240 send_cmd(map, sect_addr, CMD_MANUFACTURER_UNLOCK_DATA); 241 242 /* status is 0x0000 for unlocked and 0x0001 for locked */ 243 status = wide_read(map, sect_addr + (map->buswidth * ADDR_SECTOR_LOCK)); 244 wide_write(map, CMD_RESET_DATA, 0); 245 return status; 246} 247 248static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len, 249 int is_unlock) 250{ 251 struct map_info *map; 252 struct mtd_erase_region_info *merip; 253 int eraseoffset, erasesize, eraseblocks; 254 int i; 255 int retval = 0; 256 int lock_status; 257 258 map = mtd->priv; 259 260 /* Pass the whole chip through sector by sector and check for each 261 sector if the sector and the given interval overlap */ 262 for(i = 0; i < mtd->numeraseregions; i++) { 263 merip = &mtd->eraseregions[i]; 264 265 eraseoffset = merip->offset; 266 erasesize = merip->erasesize; 267 eraseblocks = merip->numblocks; 268 269 if (ofs > eraseoffset + erasesize) 270 continue; 271 272 while (eraseblocks > 0) { 273 if (ofs < eraseoffset + erasesize && ofs + len > eraseoffset) { 274 unlock_sector(map, eraseoffset, is_unlock); 275 276 lock_status = is_sector_locked(map, eraseoffset); 277 278 if (is_unlock && lock_status) { 279 printk("Cannot unlock sector at address %x length %xx\n", 280 eraseoffset, merip->erasesize); 281 retval = -1; 282 } else if (!is_unlock && !lock_status) { 283 printk("Cannot lock sector at address %x length %x\n", 284 eraseoffset, merip->erasesize); 285 retval = -1; 286 } 287 } 288 eraseoffset += erasesize; 289 eraseblocks --; 290 } 291 } 292 return retval; 293} 294 295static int amd_flash_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) 296{ 297 return amd_flash_do_unlock(mtd, ofs, len, 1); 298} 299 300static int amd_flash_lock(struct mtd_info *mtd, loff_t ofs, size_t len) 301{ 302 return amd_flash_do_unlock(mtd, ofs, len, 0); 303} 304 305 306/* 307 * Reads JEDEC manufacturer ID and device ID and returns the index of the first 308 * matching table entry (-1 if not found or alias for already found chip). 309 */ 310static int probe_new_chip(struct mtd_info *mtd, __u32 base, 311 struct flchip *chips, 312 struct amd_flash_private *private, 313 const struct amd_flash_info *table, int table_size) 314{ 315 __u32 mfr_id; 316 __u32 dev_id; 317 struct map_info *map = mtd->priv; 318 struct amd_flash_private temp; 319 int i; 320 321 temp.device_type = DEVICE_TYPE_X16; // Assume X16 (FIXME) 322 temp.interleave = 2; 323 map->fldrv_priv = &temp; 324 325 /* Enter autoselect mode. */ 326 send_cmd(map, base, CMD_RESET_DATA); 327 send_cmd(map, base, CMD_MANUFACTURER_UNLOCK_DATA); 328 329 mfr_id = wide_read(map, base + (map->buswidth * ADDR_MANUFACTURER)); 330 dev_id = wide_read(map, base + (map->buswidth * ADDR_DEVICE_ID)); 331 332 if ((map->buswidth == 4) && ((mfr_id >> 16) == (mfr_id & 0xffff)) && 333 ((dev_id >> 16) == (dev_id & 0xffff))) { 334 mfr_id &= 0xffff; 335 dev_id &= 0xffff; 336 } else { 337 temp.interleave = 1; 338 } 339 340 for (i = 0; i < table_size; i++) { 341 if ((mfr_id == table[i].mfr_id) && 342 (dev_id == table[i].dev_id)) { 343 if (chips) { 344 int j; 345 346 /* Is this an alias for an already found chip? 347 * In that case that chip should be in 348 * autoselect mode now. 349 */ 350 for (j = 0; j < private->numchips; j++) { 351 __u32 mfr_id_other; 352 __u32 dev_id_other; 353 354 mfr_id_other = 355 wide_read(map, chips[j].start + 356 (map->buswidth * 357 ADDR_MANUFACTURER 358 )); 359 dev_id_other = 360 wide_read(map, chips[j].start + 361 (map->buswidth * 362 ADDR_DEVICE_ID)); 363 if (temp.interleave == 2) { 364 mfr_id_other &= 0xffff; 365 dev_id_other &= 0xffff; 366 } 367 if ((mfr_id_other == mfr_id) && 368 (dev_id_other == dev_id)) { 369 370 /* Exit autoselect mode. */ 371 send_cmd(map, base, 372 CMD_RESET_DATA); 373 374 return -1; 375 } 376 } 377 378 if (private->numchips == MAX_AMD_CHIPS) { 379 printk(KERN_WARNING 380 "%s: Too many flash chips " 381 "detected. Increase " 382 "MAX_AMD_CHIPS from %d.\n", 383 map->name, MAX_AMD_CHIPS); 384 385 return -1; 386 } 387 388 chips[private->numchips].start = base; 389 chips[private->numchips].state = FL_READY; 390 chips[private->numchips].mutex = 391 &chips[private->numchips]._spinlock; 392 private->numchips++; 393 } 394 395 printk("%s: Found %d x %ldMiB %s at 0x%x\n", map->name, 396 temp.interleave, (table[i].size)/(1024*1024), 397 table[i].name, base); 398 399 mtd->size += table[i].size * temp.interleave; 400 mtd->numeraseregions += table[i].numeraseregions; 401 402 break; 403 } 404 } 405 406 /* Exit autoselect mode. */ 407 send_cmd(map, base, CMD_RESET_DATA); 408 409 if (i == table_size) { 410 printk(KERN_DEBUG "%s: unknown flash device at 0x%x, " 411 "mfr id 0x%x, dev id 0x%x\n", map->name, 412 base, mfr_id, dev_id); 413 map->fldrv_priv = NULL; 414 415 return -1; 416 } 417 418 private->device_type = temp.device_type; 419 private->interleave = temp.interleave; 420 421 return i; 422} 423 424 425 426static struct mtd_info *amd_flash_probe(struct map_info *map) 427{ 428 static const struct amd_flash_info table[] = { 429 { 430 .mfr_id = MANUFACTURER_AMD, 431 .dev_id = AM29LV160DT, 432 .name = "AMD AM29LV160DT", 433 .size = 0x00200000, 434 .numeraseregions = 4, 435 .regions = { 436 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, 437 { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, 438 { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, 439 { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } 440 } 441 }, { 442 .mfr_id = MANUFACTURER_AMD, 443 .dev_id = AM29LV160DB, 444 .name = "AMD AM29LV160DB", 445 .size = 0x00200000, 446 .numeraseregions = 4, 447 .regions = { 448 { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, 449 { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, 450 { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, 451 { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } 452 } 453 }, { 454 .mfr_id = MANUFACTURER_TOSHIBA, 455 .dev_id = TC58FVT160, 456 .name = "Toshiba TC58FVT160", 457 .size = 0x00200000, 458 .numeraseregions = 4, 459 .regions = { 460 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, 461 { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, 462 { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, 463 { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } 464 } 465 }, { 466 .mfr_id = MANUFACTURER_FUJITSU, 467 .dev_id = MBM29LV160TE, 468 .name = "Fujitsu MBM29LV160TE", 469 .size = 0x00200000, 470 .numeraseregions = 4, 471 .regions = { 472 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, 473 { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, 474 { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, 475 { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } 476 } 477 }, { 478 .mfr_id = MANUFACTURER_TOSHIBA, 479 .dev_id = TC58FVB160, 480 .name = "Toshiba TC58FVB160", 481 .size = 0x00200000, 482 .numeraseregions = 4, 483 .regions = { 484 { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, 485 { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, 486 { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, 487 { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } 488 } 489 }, { 490 .mfr_id = MANUFACTURER_FUJITSU, 491 .dev_id = MBM29LV160BE, 492 .name = "Fujitsu MBM29LV160BE", 493 .size = 0x00200000, 494 .numeraseregions = 4, 495 .regions = { 496 { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, 497 { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, 498 { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, 499 { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } 500 } 501 }, { 502 .mfr_id = MANUFACTURER_AMD, 503 .dev_id = AM29LV800BB, 504 .name = "AMD AM29LV800BB", 505 .size = 0x00100000, 506 .numeraseregions = 4, 507 .regions = { 508 { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, 509 { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, 510 { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, 511 { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 } 512 } 513 }, { 514 .mfr_id = MANUFACTURER_AMD, 515 .dev_id = AM29F800BB, 516 .name = "AMD AM29F800BB", 517 .size = 0x00100000, 518 .numeraseregions = 4, 519 .regions = { 520 { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, 521 { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, 522 { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, 523 { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 } 524 } 525 }, { 526 .mfr_id = MANUFACTURER_AMD, 527 .dev_id = AM29LV800BT, 528 .name = "AMD AM29LV800BT", 529 .size = 0x00100000, 530 .numeraseregions = 4, 531 .regions = { 532 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, 533 { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, 534 { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, 535 { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } 536 } 537 }, { 538 .mfr_id = MANUFACTURER_AMD, 539 .dev_id = AM29F800BT, 540 .name = "AMD AM29F800BT", 541 .size = 0x00100000, 542 .numeraseregions = 4, 543 .regions = { 544 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, 545 { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, 546 { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, 547 { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } 548 } 549 }, { 550 .mfr_id = MANUFACTURER_AMD, 551 .dev_id = AM29LV800BB, 552 .name = "AMD AM29LV800BB", 553 .size = 0x00100000, 554 .numeraseregions = 4, 555 .regions = { 556 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, 557 { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, 558 { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, 559 { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } 560 } 561 }, { 562 .mfr_id = MANUFACTURER_FUJITSU, 563 .dev_id = MBM29LV800BB, 564 .name = "Fujitsu MBM29LV800BB", 565 .size = 0x00100000, 566 .numeraseregions = 4, 567 .regions = { 568 { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, 569 { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, 570 { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, 571 { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 } 572 } 573 }, { 574 .mfr_id = MANUFACTURER_ST, 575 .dev_id = M29W800T, 576 .name = "ST M29W800T", 577 .size = 0x00100000, 578 .numeraseregions = 4, 579 .regions = { 580 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, 581 { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, 582 { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, 583 { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } 584 } 585 }, { 586 .mfr_id = MANUFACTURER_ST, 587 .dev_id = M29W160DT, 588 .name = "ST M29W160DT", 589 .size = 0x00200000, 590 .numeraseregions = 4, 591 .regions = { 592 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, 593 { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, 594 { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, 595 { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } 596 } 597 }, { 598 .mfr_id = MANUFACTURER_ST, 599 .dev_id = M29W160DB, 600 .name = "ST M29W160DB", 601 .size = 0x00200000, 602 .numeraseregions = 4, 603 .regions = { 604 { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, 605 { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, 606 { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, 607 { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } 608 } 609 }, { 610 .mfr_id = MANUFACTURER_AMD, 611 .dev_id = AM29BDS323D, 612 .name = "AMD AM29BDS323D", 613 .size = 0x00400000, 614 .numeraseregions = 3, 615 .regions = { 616 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 48 }, 617 { .offset = 0x300000, .erasesize = 0x10000, .numblocks = 15 }, 618 { .offset = 0x3f0000, .erasesize = 0x02000, .numblocks = 8 }, 619 } 620 }, { 621 .mfr_id = MANUFACTURER_AMD, 622 .dev_id = AM29BDS643D, 623 .name = "AMD AM29BDS643D", 624 .size = 0x00800000, 625 .numeraseregions = 3, 626 .regions = { 627 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 96 }, 628 { .offset = 0x600000, .erasesize = 0x10000, .numblocks = 31 }, 629 { .offset = 0x7f0000, .erasesize = 0x02000, .numblocks = 8 }, 630 } 631 }, { 632 .mfr_id = MANUFACTURER_ATMEL, 633 .dev_id = AT49xV16x, 634 .name = "Atmel AT49xV16x", 635 .size = 0x00200000, 636 .numeraseregions = 2, 637 .regions = { 638 { .offset = 0x000000, .erasesize = 0x02000, .numblocks = 8 }, 639 { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } 640 } 641 }, { 642 .mfr_id = MANUFACTURER_ATMEL, 643 .dev_id = AT49xV16xT, 644 .name = "Atmel AT49xV16xT", 645 .size = 0x00200000, 646 .numeraseregions = 2, 647 .regions = { 648 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, 649 { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 } 650 } 651 } 652 }; 653 654 struct mtd_info *mtd; 655 struct flchip chips[MAX_AMD_CHIPS]; 656 int table_pos[MAX_AMD_CHIPS]; 657 struct amd_flash_private temp; 658 struct amd_flash_private *private; 659 u_long size; 660 unsigned long base; 661 int i; 662 int reg_idx; 663 int offset; 664 665 mtd = (struct mtd_info*)kmalloc(sizeof(*mtd), GFP_KERNEL); 666 if (!mtd) { 667 printk(KERN_WARNING 668 "%s: kmalloc failed for info structure\n", map->name); 669 return NULL; 670 } 671 memset(mtd, 0, sizeof(*mtd)); 672 mtd->priv = map; 673 674 memset(&temp, 0, sizeof(temp)); 675 676 printk("%s: Probing for AMD compatible flash...\n", map->name); 677 678 if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table, 679 sizeof(table)/sizeof(table[0]))) 680 == -1) { 681 printk(KERN_WARNING 682 "%s: Found no AMD compatible device at location zero\n", 683 map->name); 684 kfree(mtd); 685 686 return NULL; 687 } 688 689 chips[0].start = 0; 690 chips[0].state = FL_READY; 691 chips[0].mutex = &chips[0]._spinlock; 692 temp.numchips = 1; 693 for (size = mtd->size; size > 1; size >>= 1) { 694 temp.chipshift++; 695 } 696 switch (temp.interleave) { 697 case 2: 698 temp.chipshift += 1; 699 break; 700 case 4: 701 temp.chipshift += 2; 702 break; 703 } 704 705 /* Find out if there are any more chips in the map. */ 706 for (base = (1 << temp.chipshift); 707 base < map->size; 708 base += (1 << temp.chipshift)) { 709 int numchips = temp.numchips; 710 table_pos[numchips] = probe_new_chip(mtd, base, chips, 711 &temp, table, sizeof(table)/sizeof(table[0])); 712 } 713 714 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * 715 mtd->numeraseregions, GFP_KERNEL); 716 if (!mtd->eraseregions) { 717 printk(KERN_WARNING "%s: Failed to allocate " 718 "memory for MTD erase region info\n", map->name); 719 kfree(mtd); 720 map->fldrv_priv = NULL; 721 return NULL; 722 } 723 724 reg_idx = 0; 725 offset = 0; 726 for (i = 0; i < temp.numchips; i++) { 727 int dev_size; 728 int j; 729 730 dev_size = 0; 731 for (j = 0; j < table[table_pos[i]].numeraseregions; j++) { 732 mtd->eraseregions[reg_idx].offset = offset + 733 (table[table_pos[i]].regions[j].offset * 734 temp.interleave); 735 mtd->eraseregions[reg_idx].erasesize = 736 table[table_pos[i]].regions[j].erasesize * 737 temp.interleave; 738 mtd->eraseregions[reg_idx].numblocks = 739 table[table_pos[i]].regions[j].numblocks; 740 if (mtd->erasesize < 741 mtd->eraseregions[reg_idx].erasesize) { 742 mtd->erasesize = 743 mtd->eraseregions[reg_idx].erasesize; 744 } 745 dev_size += mtd->eraseregions[reg_idx].erasesize * 746 mtd->eraseregions[reg_idx].numblocks; 747 reg_idx++; 748 } 749 offset += dev_size; 750 } 751 mtd->type = MTD_NORFLASH; 752 mtd->flags = MTD_CAP_NORFLASH; 753 mtd->name = map->name; 754 mtd->erase = amd_flash_erase; 755 mtd->read = amd_flash_read; 756 mtd->write = amd_flash_write; 757 mtd->sync = amd_flash_sync; 758 mtd->suspend = amd_flash_suspend; 759 mtd->resume = amd_flash_resume; 760 mtd->lock = amd_flash_lock; 761 mtd->unlock = amd_flash_unlock; 762 763 private = kmalloc(sizeof(*private) + (sizeof(struct flchip) * 764 temp.numchips), GFP_KERNEL); 765 if (!private) { 766 printk(KERN_WARNING 767 "%s: kmalloc failed for private structure\n", map->name); 768 kfree(mtd); 769 map->fldrv_priv = NULL; 770 return NULL; 771 } 772 memcpy(private, &temp, sizeof(temp)); 773 memcpy(private->chips, chips, 774 sizeof(struct flchip) * private->numchips); 775 for (i = 0; i < private->numchips; i++) { 776 init_waitqueue_head(&private->chips[i].wq); 777 spin_lock_init(&private->chips[i]._spinlock); 778 } 779 780 map->fldrv_priv = private; 781 782 map->fldrv = &amd_flash_chipdrv; 783 784 __module_get(THIS_MODULE); 785 return mtd; 786} 787 788 789 790static inline int read_one_chip(struct map_info *map, struct flchip *chip, 791 loff_t adr, size_t len, u_char *buf) 792{ 793 DECLARE_WAITQUEUE(wait, current); 794 unsigned long timeo = jiffies + HZ; 795 796retry: 797 spin_lock_bh(chip->mutex); 798 799 if (chip->state != FL_READY){ 800 printk(KERN_INFO "%s: waiting for chip to read, state = %d\n", 801 map->name, chip->state); 802 set_current_state(TASK_UNINTERRUPTIBLE); 803 add_wait_queue(&chip->wq, &wait); 804 805 spin_unlock_bh(chip->mutex); 806 807 schedule(); 808 remove_wait_queue(&chip->wq, &wait); 809 810 if(signal_pending(current)) { 811 return -EINTR; 812 } 813 814 timeo = jiffies + HZ; 815 816 goto retry; 817 } 818 819 adr += chip->start; 820 821 chip->state = FL_READY; 822 823 map_copy_from(map, buf, adr, len); 824 825 wake_up(&chip->wq); 826 spin_unlock_bh(chip->mutex); 827 828 return 0; 829} 830 831 832 833static int amd_flash_read(struct mtd_info *mtd, loff_t from, size_t len, 834 size_t *retlen, u_char *buf) 835{ 836 struct map_info *map = mtd->priv; 837 struct amd_flash_private *private = map->fldrv_priv; 838 unsigned long ofs; 839 int chipnum; 840 int ret = 0; 841 842 if ((from + len) > mtd->size) { 843 printk(KERN_WARNING "%s: read request past end of device " 844 "(0x%lx)\n", map->name, (unsigned long)from + len); 845 846 return -EINVAL; 847 } 848 849 /* Offset within the first chip that the first read should start. */ 850 chipnum = (from >> private->chipshift); 851 ofs = from - (chipnum << private->chipshift); 852 853 *retlen = 0; 854 855 while (len) { 856 unsigned long this_len; 857 858 if (chipnum >= private->numchips) { 859 break; 860 } 861 862 if ((len + ofs - 1) >> private->chipshift) { 863 this_len = (1 << private->chipshift) - ofs; 864 } else { 865 this_len = len; 866 } 867 868 ret = read_one_chip(map, &private->chips[chipnum], ofs, 869 this_len, buf); 870 if (ret) { 871 break; 872 } 873 874 *retlen += this_len; 875 len -= this_len; 876 buf += this_len; 877 878 ofs = 0; 879 chipnum++; 880 } 881 882 return ret; 883} 884 885 886 887static int write_one_word(struct map_info *map, struct flchip *chip, 888 unsigned long adr, __u32 datum) 889{ 890 unsigned long timeo = jiffies + HZ; 891 struct amd_flash_private *private = map->fldrv_priv; 892 DECLARE_WAITQUEUE(wait, current); 893 int ret = 0; 894 int times_left; 895 896retry: 897 spin_lock_bh(chip->mutex); 898 899 if (chip->state != FL_READY){ 900 printk("%s: waiting for chip to write, state = %d\n", 901 map->name, chip->state); 902 set_current_state(TASK_UNINTERRUPTIBLE); 903 add_wait_queue(&chip->wq, &wait); 904 905 spin_unlock_bh(chip->mutex); 906 907 schedule(); 908 remove_wait_queue(&chip->wq, &wait); 909 printk(KERN_INFO "%s: woke up to write\n", map->name); 910 if(signal_pending(current)) 911 return -EINTR; 912 913 timeo = jiffies + HZ; 914 915 goto retry; 916 } 917 918 chip->state = FL_WRITING; 919 920 adr += chip->start; 921 ENABLE_VPP(map); 922 send_cmd(map, chip->start, CMD_PROGRAM_UNLOCK_DATA); 923 wide_write(map, datum, adr); 924 925 times_left = 500000; 926 while (times_left-- && flash_is_busy(map, adr, private->interleave)) { 927 if (need_resched()) { 928 spin_unlock_bh(chip->mutex); 929 schedule(); 930 spin_lock_bh(chip->mutex); 931 } 932 } 933 934 if (!times_left) { 935 printk(KERN_WARNING "%s: write to 0x%lx timed out!\n", 936 map->name, adr); 937 ret = -EIO; 938 } else { 939 __u32 verify; 940 if ((verify = wide_read(map, adr)) != datum) { 941 printk(KERN_WARNING "%s: write to 0x%lx failed. " 942 "datum = %x, verify = %x\n", 943 map->name, adr, datum, verify); 944 ret = -EIO; 945 } 946 } 947 948 DISABLE_VPP(map); 949 chip->state = FL_READY; 950 wake_up(&chip->wq); 951 spin_unlock_bh(chip->mutex); 952 953 return ret; 954} 955 956 957 958static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len, 959 size_t *retlen, const u_char *buf) 960{ 961 struct map_info *map = mtd->priv; 962 struct amd_flash_private *private = map->fldrv_priv; 963 int ret = 0; 964 int chipnum; 965 unsigned long ofs; 966 unsigned long chipstart; 967 968 *retlen = 0; 969 if (!len) { 970 return 0; 971 } 972 973 chipnum = to >> private->chipshift; 974 ofs = to - (chipnum << private->chipshift); 975 chipstart = private->chips[chipnum].start; 976 977 /* If it's not bus-aligned, do the first byte write. */ 978 if (ofs & (map->buswidth - 1)) { 979 unsigned long bus_ofs = ofs & ~(map->buswidth - 1); 980 int i = ofs - bus_ofs; 981 int n = 0; 982 u_char tmp_buf[4]; 983 __u32 datum; 984 985 map_copy_from(map, tmp_buf, 986 bus_ofs + private->chips[chipnum].start, 987 map->buswidth); 988 while (len && i < map->buswidth) 989 tmp_buf[i++] = buf[n++], len--; 990 991 if (map->buswidth == 2) { 992 datum = *(__u16*)tmp_buf; 993 } else if (map->buswidth == 4) { 994 datum = *(__u32*)tmp_buf; 995 } else { 996 return -EINVAL; /* should never happen, but be safe */ 997 } 998 999 ret = write_one_word(map, &private->chips[chipnum], bus_ofs, 1000 datum); 1001 if (ret) { 1002 return ret; 1003 } 1004 1005 ofs += n; 1006 buf += n; 1007 (*retlen) += n; 1008 1009 if (ofs >> private->chipshift) { 1010 chipnum++; 1011 ofs = 0; 1012 if (chipnum == private->numchips) { 1013 return 0; 1014 } 1015 } 1016 } 1017 1018 /* We are now aligned, write as much as possible. */ 1019 while(len >= map->buswidth) { 1020 __u32 datum; 1021 1022 if (map->buswidth == 1) { 1023 datum = *(__u8*)buf; 1024 } else if (map->buswidth == 2) { 1025 datum = *(__u16*)buf; 1026 } else if (map->buswidth == 4) { 1027 datum = *(__u32*)buf; 1028 } else { 1029 return -EINVAL; 1030 } 1031 1032 ret = write_one_word(map, &private->chips[chipnum], ofs, datum); 1033 1034 if (ret) { 1035 return ret; 1036 } 1037 1038 ofs += map->buswidth; 1039 buf += map->buswidth; 1040 (*retlen) += map->buswidth; 1041 len -= map->buswidth; 1042 1043 if (ofs >> private->chipshift) { 1044 chipnum++; 1045 ofs = 0; 1046 if (chipnum == private->numchips) { 1047 return 0; 1048 } 1049 chipstart = private->chips[chipnum].start; 1050 } 1051 } 1052 1053 if (len & (map->buswidth - 1)) { 1054 int i = 0, n = 0; 1055 u_char tmp_buf[2]; 1056 __u32 datum; 1057 1058 map_copy_from(map, tmp_buf, 1059 ofs + private->chips[chipnum].start, 1060 map->buswidth); 1061 while (len--) { 1062 tmp_buf[i++] = buf[n++]; 1063 } 1064 1065 if (map->buswidth == 2) { 1066 datum = *(__u16*)tmp_buf; 1067 } else if (map->buswidth == 4) { 1068 datum = *(__u32*)tmp_buf; 1069 } else { 1070 return -EINVAL; /* should never happen, but be safe */ 1071 } 1072 1073 ret = write_one_word(map, &private->chips[chipnum], ofs, datum); 1074 1075 if (ret) { 1076 return ret; 1077 } 1078 1079 (*retlen) += n; 1080 } 1081 1082 return 0; 1083} 1084 1085 1086 1087static inline int erase_one_block(struct map_info *map, struct flchip *chip, 1088 unsigned long adr, u_long size) 1089{ 1090 unsigned long timeo = jiffies + HZ; 1091 struct amd_flash_private *private = map->fldrv_priv; 1092 DECLARE_WAITQUEUE(wait, current); 1093 1094retry: 1095 spin_lock_bh(chip->mutex); 1096 1097 if (chip->state != FL_READY){ 1098 set_current_state(TASK_UNINTERRUPTIBLE); 1099 add_wait_queue(&chip->wq, &wait); 1100 1101 spin_unlock_bh(chip->mutex); 1102 1103 schedule(); 1104 remove_wait_queue(&chip->wq, &wait); 1105 1106 if (signal_pending(current)) { 1107 return -EINTR; 1108 } 1109 1110 timeo = jiffies + HZ; 1111 1112 goto retry; 1113 } 1114 1115 chip->state = FL_ERASING; 1116 1117 adr += chip->start; 1118 ENABLE_VPP(map); 1119 send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA); 1120 send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr); 1121 1122 timeo = jiffies + (HZ * 20); 1123 1124 spin_unlock_bh(chip->mutex); 1125 msleep(1000); 1126 spin_lock_bh(chip->mutex); 1127 1128 while (flash_is_busy(map, adr, private->interleave)) { 1129 1130 if (chip->state != FL_ERASING) { 1131 /* Someone's suspended the erase. Sleep */ 1132 set_current_state(TASK_UNINTERRUPTIBLE); 1133 add_wait_queue(&chip->wq, &wait); 1134 1135 spin_unlock_bh(chip->mutex); 1136 printk(KERN_INFO "%s: erase suspended. Sleeping\n", 1137 map->name); 1138 schedule(); 1139 remove_wait_queue(&chip->wq, &wait); 1140 1141 if (signal_pending(current)) { 1142 return -EINTR; 1143 } 1144 1145 timeo = jiffies + (HZ*2); /* FIXME */ 1146 spin_lock_bh(chip->mutex); 1147 continue; 1148 } 1149 1150 /* OK Still waiting */ 1151 if (time_after(jiffies, timeo)) { 1152 chip->state = FL_READY; 1153 spin_unlock_bh(chip->mutex); 1154 printk(KERN_WARNING "%s: waiting for erase to complete " 1155 "timed out.\n", map->name); 1156 DISABLE_VPP(map); 1157 1158 return -EIO; 1159 } 1160 1161 /* Latency issues. Drop the lock, wait a while and retry */ 1162 spin_unlock_bh(chip->mutex); 1163 1164 if (need_resched()) 1165 schedule(); 1166 else 1167 udelay(1); 1168 1169 spin_lock_bh(chip->mutex); 1170 } 1171 1172 /* Verify every single word */ 1173 { 1174 int address; 1175 int error = 0; 1176 __u8 verify; 1177 1178 for (address = adr; address < (adr + size); address++) { 1179 if ((verify = map_read8(map, address)) != 0xFF) { 1180 error = 1; 1181 break; 1182 } 1183 } 1184 if (error) { 1185 chip->state = FL_READY; 1186 spin_unlock_bh(chip->mutex); 1187 printk(KERN_WARNING 1188 "%s: verify error at 0x%x, size %ld.\n", 1189 map->name, address, size); 1190 DISABLE_VPP(map); 1191 1192 return -EIO; 1193 } 1194 } 1195 1196 DISABLE_VPP(map); 1197 chip->state = FL_READY; 1198 wake_up(&chip->wq); 1199 spin_unlock_bh(chip->mutex); 1200 1201 return 0; 1202} 1203 1204 1205 1206static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr) 1207{ 1208 struct map_info *map = mtd->priv; 1209 struct amd_flash_private *private = map->fldrv_priv; 1210 unsigned long adr, len; 1211 int chipnum; 1212 int ret = 0; 1213 int i; 1214 int first; 1215 struct mtd_erase_region_info *regions = mtd->eraseregions; 1216 1217 if (instr->addr > mtd->size) { 1218 return -EINVAL; 1219 } 1220 1221 if ((instr->len + instr->addr) > mtd->size) { 1222 return -EINVAL; 1223 } 1224 1225 /* Check that both start and end of the requested erase are 1226 * aligned with the erasesize at the appropriate addresses. 1227 */ 1228 1229 i = 0; 1230 1231 /* Skip all erase regions which are ended before the start of 1232 the requested erase. Actually, to save on the calculations, 1233 we skip to the first erase region which starts after the 1234 start of the requested erase, and then go back one. 1235 */ 1236 1237 while ((i < mtd->numeraseregions) && 1238 (instr->addr >= regions[i].offset)) { 1239 i++; 1240 } 1241 i--; 1242 1243 /* OK, now i is pointing at the erase region in which this 1244 * erase request starts. Check the start of the requested 1245 * erase range is aligned with the erase size which is in 1246 * effect here. 1247 */ 1248 1249 if (instr->addr & (regions[i].erasesize-1)) { 1250 return -EINVAL; 1251 } 1252 1253 /* Remember the erase region we start on. */ 1254 1255 first = i; 1256 1257 /* Next, check that the end of the requested erase is aligned 1258 * with the erase region at that address. 1259 */ 1260 1261 while ((i < mtd->numeraseregions) && 1262 ((instr->addr + instr->len) >= regions[i].offset)) { 1263 i++; 1264 } 1265 1266 /* As before, drop back one to point at the region in which 1267 * the address actually falls. 1268 */ 1269 1270 i--; 1271 1272 if ((instr->addr + instr->len) & (regions[i].erasesize-1)) { 1273 return -EINVAL; 1274 } 1275 1276 chipnum = instr->addr >> private->chipshift; 1277 adr = instr->addr - (chipnum << private->chipshift); 1278 len = instr->len; 1279 1280 i = first; 1281 1282 while (len) { 1283 ret = erase_one_block(map, &private->chips[chipnum], adr, 1284 regions[i].erasesize); 1285 1286 if (ret) { 1287 return ret; 1288 } 1289 1290 adr += regions[i].erasesize; 1291 len -= regions[i].erasesize; 1292 1293 if ((adr % (1 << private->chipshift)) == 1294 ((regions[i].offset + (regions[i].erasesize * 1295 regions[i].numblocks)) 1296 % (1 << private->chipshift))) { 1297 i++; 1298 } 1299 1300 if (adr >> private->chipshift) { 1301 adr = 0; 1302 chipnum++; 1303 if (chipnum >= private->numchips) { 1304 break; 1305 } 1306 } 1307 } 1308 1309 instr->state = MTD_ERASE_DONE; 1310 mtd_erase_callback(instr); 1311 1312 return 0; 1313} 1314 1315 1316 1317static void amd_flash_sync(struct mtd_info *mtd) 1318{ 1319 struct map_info *map = mtd->priv; 1320 struct amd_flash_private *private = map->fldrv_priv; 1321 int i; 1322 struct flchip *chip; 1323 int ret = 0; 1324 DECLARE_WAITQUEUE(wait, current); 1325 1326 for (i = 0; !ret && (i < private->numchips); i++) { 1327 chip = &private->chips[i]; 1328 1329 retry: 1330 spin_lock_bh(chip->mutex); 1331 1332 switch(chip->state) { 1333 case FL_READY: 1334 case FL_STATUS: 1335 case FL_CFI_QUERY: 1336 case FL_JEDEC_QUERY: 1337 chip->oldstate = chip->state; 1338 chip->state = FL_SYNCING; 1339 /* No need to wake_up() on this state change - 1340 * as the whole point is that nobody can do anything 1341 * with the chip now anyway. 1342 */ 1343 case FL_SYNCING: 1344 spin_unlock_bh(chip->mutex); 1345 break; 1346 1347 default: 1348 /* Not an idle state */ 1349 add_wait_queue(&chip->wq, &wait); 1350 1351 spin_unlock_bh(chip->mutex); 1352 1353 schedule(); 1354 1355 remove_wait_queue(&chip->wq, &wait); 1356 1357 goto retry; 1358 } 1359 } 1360 1361 /* Unlock the chips again */ 1362 for (i--; i >= 0; i--) { 1363 chip = &private->chips[i]; 1364 1365 spin_lock_bh(chip->mutex); 1366 1367 if (chip->state == FL_SYNCING) { 1368 chip->state = chip->oldstate; 1369 wake_up(&chip->wq); 1370 } 1371 spin_unlock_bh(chip->mutex); 1372 } 1373} 1374 1375 1376 1377static int amd_flash_suspend(struct mtd_info *mtd) 1378{ 1379printk("amd_flash_suspend(): not implemented!\n"); 1380 return -EINVAL; 1381} 1382 1383 1384 1385static void amd_flash_resume(struct mtd_info *mtd) 1386{ 1387printk("amd_flash_resume(): not implemented!\n"); 1388} 1389 1390 1391 1392static void amd_flash_destroy(struct mtd_info *mtd) 1393{ 1394 struct map_info *map = mtd->priv; 1395 struct amd_flash_private *private = map->fldrv_priv; 1396 kfree(private); 1397} 1398 1399int __init amd_flash_init(void) 1400{ 1401 register_mtd_chip_driver(&amd_flash_chipdrv); 1402 return 0; 1403} 1404 1405void __exit amd_flash_exit(void) 1406{ 1407 unregister_mtd_chip_driver(&amd_flash_chipdrv); 1408} 1409 1410module_init(amd_flash_init); 1411module_exit(amd_flash_exit); 1412 1413MODULE_LICENSE("GPL"); 1414MODULE_AUTHOR("Jonas Holmberg <jonas.holmberg@axis.com>"); 1415MODULE_DESCRIPTION("Old MTD chip driver for AMD flash chips");