aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/chips/jedec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/chips/jedec.c')
-rw-r--r--drivers/mtd/chips/jedec.c206
1 files changed, 103 insertions, 103 deletions
diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
index 4f6778f3ee3e..c40b48dabed3 100644
--- a/drivers/mtd/chips/jedec.c
+++ b/drivers/mtd/chips/jedec.c
@@ -1,6 +1,6 @@
1 1
2/* JEDEC Flash Interface. 2/* JEDEC Flash Interface.
3 * This is an older type of interface for self programming flash. It is 3 * This is an older type of interface for self programming flash. It is
4 * commonly use in older AMD chips and is obsolete compared with CFI. 4 * commonly use in older AMD chips and is obsolete compared with CFI.
5 * It is called JEDEC because the JEDEC association distributes the ID codes 5 * It is called JEDEC because the JEDEC association distributes the ID codes
6 * for the chips. 6 * for the chips.
@@ -88,9 +88,9 @@ static const struct JEDECTable JEDEC_table[] = {
88 88
89static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id); 89static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
90static void jedec_sync(struct mtd_info *mtd) {}; 90static void jedec_sync(struct mtd_info *mtd) {};
91static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 91static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
92 size_t *retlen, u_char *buf); 92 size_t *retlen, u_char *buf);
93static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 93static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
94 size_t *retlen, u_char *buf); 94 size_t *retlen, u_char *buf);
95 95
96static struct mtd_info *jedec_probe(struct map_info *map); 96static struct mtd_info *jedec_probe(struct map_info *map);
@@ -122,7 +122,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
122 122
123 memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private)); 123 memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
124 priv = (struct jedec_private *)&MTD[1]; 124 priv = (struct jedec_private *)&MTD[1];
125 125
126 my_bank_size = map->size; 126 my_bank_size = map->size;
127 127
128 if (map->size/my_bank_size > MAX_JEDEC_CHIPS) 128 if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
@@ -131,13 +131,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
131 kfree(MTD); 131 kfree(MTD);
132 return NULL; 132 return NULL;
133 } 133 }
134 134
135 for (Base = 0; Base < map->size; Base += my_bank_size) 135 for (Base = 0; Base < map->size; Base += my_bank_size)
136 { 136 {
137 // Perhaps zero could designate all tests? 137 // Perhaps zero could designate all tests?
138 if (map->buswidth == 0) 138 if (map->buswidth == 0)
139 map->buswidth = 1; 139 map->buswidth = 1;
140 140
141 if (map->buswidth == 1){ 141 if (map->buswidth == 1){
142 if (jedec_probe8(map,Base,priv) == 0) { 142 if (jedec_probe8(map,Base,priv) == 0) {
143 printk("did recognize jedec chip\n"); 143 printk("did recognize jedec chip\n");
@@ -150,7 +150,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
150 if (map->buswidth == 4) 150 if (map->buswidth == 4)
151 jedec_probe32(map,Base,priv); 151 jedec_probe32(map,Base,priv);
152 } 152 }
153 153
154 // Get the biggest sector size 154 // Get the biggest sector size
155 SectorSize = 0; 155 SectorSize = 0;
156 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 156 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
@@ -160,7 +160,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
160 if (priv->chips[I].sectorsize > SectorSize) 160 if (priv->chips[I].sectorsize > SectorSize)
161 SectorSize = priv->chips[I].sectorsize; 161 SectorSize = priv->chips[I].sectorsize;
162 } 162 }
163 163
164 // Quickly ensure that the other sector sizes are factors of the largest 164 // Quickly ensure that the other sector sizes are factors of the largest
165 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 165 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
166 { 166 {
@@ -169,9 +169,9 @@ static struct mtd_info *jedec_probe(struct map_info *map)
169 printk("mtd: Failed. Device has incompatible mixed sector sizes\n"); 169 printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
170 kfree(MTD); 170 kfree(MTD);
171 return NULL; 171 return NULL;
172 } 172 }
173 } 173 }
174 174
175 /* Generate a part name that includes the number of different chips and 175 /* Generate a part name that includes the number of different chips and
176 other configuration information */ 176 other configuration information */
177 count = 1; 177 count = 1;
@@ -181,13 +181,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
181 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 181 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
182 { 182 {
183 const struct JEDECTable *JEDEC; 183 const struct JEDECTable *JEDEC;
184 184
185 if (priv->chips[I+1].jedec == priv->chips[I].jedec) 185 if (priv->chips[I+1].jedec == priv->chips[I].jedec)
186 { 186 {
187 count++; 187 count++;
188 continue; 188 continue;
189 } 189 }
190 190
191 // Locate the chip in the jedec table 191 // Locate the chip in the jedec table
192 JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec); 192 JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
193 if (JEDEC == 0) 193 if (JEDEC == 0)
@@ -196,11 +196,11 @@ static struct mtd_info *jedec_probe(struct map_info *map)
196 kfree(MTD); 196 kfree(MTD);
197 return NULL; 197 return NULL;
198 } 198 }
199 199
200 if (Uniq != 0) 200 if (Uniq != 0)
201 strcat(Part,","); 201 strcat(Part,",");
202 Uniq++; 202 Uniq++;
203 203
204 if (count != 1) 204 if (count != 1)
205 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name); 205 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
206 else 206 else
@@ -208,7 +208,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
208 if (strlen(Part) > sizeof(Part)*2/3) 208 if (strlen(Part) > sizeof(Part)*2/3)
209 break; 209 break;
210 count = 1; 210 count = 1;
211 } 211 }
212 212
213 /* Determine if the chips are organized in a linear fashion, or if there 213 /* Determine if the chips are organized in a linear fashion, or if there
214 are empty banks. Note, the last bank does not count here, only the 214 are empty banks. Note, the last bank does not count here, only the
@@ -233,7 +233,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
233 { 233 {
234 if (priv->bank_fill[I] != my_bank_size) 234 if (priv->bank_fill[I] != my_bank_size)
235 priv->is_banked = 1; 235 priv->is_banked = 1;
236 236
237 /* This even could be eliminated, but new de-optimized read/write 237 /* This even could be eliminated, but new de-optimized read/write
238 functions have to be written */ 238 functions have to be written */
239 printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]); 239 printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
@@ -242,7 +242,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
242 printk("mtd: Failed. Cannot handle unsymmetric banking\n"); 242 printk("mtd: Failed. Cannot handle unsymmetric banking\n");
243 kfree(MTD); 243 kfree(MTD);
244 return NULL; 244 return NULL;
245 } 245 }
246 } 246 }
247 } 247 }
248 } 248 }
@@ -250,7 +250,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
250 strcat(Part,", banked"); 250 strcat(Part,", banked");
251 251
252 // printk("Part: '%s'\n",Part); 252 // printk("Part: '%s'\n",Part);
253 253
254 memset(MTD,0,sizeof(*MTD)); 254 memset(MTD,0,sizeof(*MTD));
255 // strlcpy(MTD->name,Part,sizeof(MTD->name)); 255 // strlcpy(MTD->name,Part,sizeof(MTD->name));
256 MTD->name = map->name; 256 MTD->name = map->name;
@@ -291,7 +291,7 @@ static int checkparity(u_char C)
291 291
292/* Take an array of JEDEC numbers that represent interleved flash chips 292/* Take an array of JEDEC numbers that represent interleved flash chips
293 and process them. Check to make sure they are good JEDEC numbers, look 293 and process them. Check to make sure they are good JEDEC numbers, look
294 them up and then add them to the chip list */ 294 them up and then add them to the chip list */
295static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, 295static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
296 unsigned long base,struct jedec_private *priv) 296 unsigned long base,struct jedec_private *priv)
297{ 297{
@@ -306,16 +306,16 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
306 if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0) 306 if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
307 return 0; 307 return 0;
308 } 308 }
309 309
310 // Finally, just make sure all the chip sizes are the same 310 // Finally, just make sure all the chip sizes are the same
311 JEDEC = jedec_idtoinf(Mfg[0],Id[0]); 311 JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
312 312
313 if (JEDEC == 0) 313 if (JEDEC == 0)
314 { 314 {
315 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]); 315 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
316 return 0; 316 return 0;
317 } 317 }
318 318
319 Size = JEDEC->size; 319 Size = JEDEC->size;
320 SectorSize = JEDEC->sectorsize; 320 SectorSize = JEDEC->sectorsize;
321 for (I = 0; I != Count; I++) 321 for (I = 0; I != Count; I++)
@@ -331,7 +331,7 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
331 { 331 {
332 printk("mtd: Failed. Interleved flash does not have matching characteristics\n"); 332 printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
333 return 0; 333 return 0;
334 } 334 }
335 } 335 }
336 336
337 // Load the Chips 337 // Load the Chips
@@ -345,13 +345,13 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
345 { 345 {
346 printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n"); 346 printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
347 return 0; 347 return 0;
348 } 348 }
349 349
350 // Add them to the table 350 // Add them to the table
351 for (J = 0; J != Count; J++) 351 for (J = 0; J != Count; J++)
352 { 352 {
353 unsigned long Bank; 353 unsigned long Bank;
354 354
355 JEDEC = jedec_idtoinf(Mfg[J],Id[J]); 355 JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
356 priv->chips[I].jedec = (Mfg[J] << 8) | Id[J]; 356 priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
357 priv->chips[I].size = JEDEC->size; 357 priv->chips[I].size = JEDEC->size;
@@ -364,17 +364,17 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
364 // log2 n :| 364 // log2 n :|
365 priv->chips[I].addrshift = 0; 365 priv->chips[I].addrshift = 0;
366 for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++); 366 for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
367 367
368 // Determine how filled this bank is. 368 // Determine how filled this bank is.
369 Bank = base & (~(my_bank_size-1)); 369 Bank = base & (~(my_bank_size-1));
370 if (priv->bank_fill[Bank/my_bank_size] < base + 370 if (priv->bank_fill[Bank/my_bank_size] < base +
371 (JEDEC->size << priv->chips[I].addrshift) - Bank) 371 (JEDEC->size << priv->chips[I].addrshift) - Bank)
372 priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank; 372 priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
373 I++; 373 I++;
374 } 374 }
375 375
376 priv->size += priv->chips[I-1].size*Count; 376 priv->size += priv->chips[I-1].size*Count;
377 377
378 return priv->chips[I-1].size; 378 return priv->chips[I-1].size;
379} 379}
380 380
@@ -392,7 +392,7 @@ static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
392// Look for flash using an 8 bit bus interface 392// Look for flash using an 8 bit bus interface
393static int jedec_probe8(struct map_info *map,unsigned long base, 393static int jedec_probe8(struct map_info *map,unsigned long base,
394 struct jedec_private *priv) 394 struct jedec_private *priv)
395{ 395{
396 #define flread(x) map_read8(map,base+x) 396 #define flread(x) map_read8(map,base+x)
397 #define flwrite(v,x) map_write8(map,v,base+x) 397 #define flwrite(v,x) map_write8(map,v,base+x)
398 398
@@ -410,20 +410,20 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
410 OldVal = flread(base); 410 OldVal = flread(base);
411 for (I = 0; OldVal != flread(base) && I < 10000; I++) 411 for (I = 0; OldVal != flread(base) && I < 10000; I++)
412 OldVal = flread(base); 412 OldVal = flread(base);
413 413
414 // Reset the chip 414 // Reset the chip
415 flwrite(Reset,0x555); 415 flwrite(Reset,0x555);
416 416
417 // Send the sequence 417 // Send the sequence
418 flwrite(AutoSel1,0x555); 418 flwrite(AutoSel1,0x555);
419 flwrite(AutoSel2,0x2AA); 419 flwrite(AutoSel2,0x2AA);
420 flwrite(AutoSel3,0x555); 420 flwrite(AutoSel3,0x555);
421 421
422 // Get the JEDEC numbers 422 // Get the JEDEC numbers
423 Mfg[0] = flread(0); 423 Mfg[0] = flread(0);
424 Id[0] = flread(1); 424 Id[0] = flread(1);
425 // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]); 425 // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
426 426
427 Size = handle_jedecs(map,Mfg,Id,1,base,priv); 427 Size = handle_jedecs(map,Mfg,Id,1,base,priv);
428 // printk("handle_jedecs Size is %x\n",(unsigned int)Size); 428 // printk("handle_jedecs Size is %x\n",(unsigned int)Size);
429 if (Size == 0) 429 if (Size == 0)
@@ -431,13 +431,13 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
431 flwrite(Reset,0x555); 431 flwrite(Reset,0x555);
432 return 0; 432 return 0;
433 } 433 }
434 434
435 435
436 // Reset. 436 // Reset.
437 flwrite(Reset,0x555); 437 flwrite(Reset,0x555);
438 438
439 return 1; 439 return 1;
440 440
441 #undef flread 441 #undef flread
442 #undef flwrite 442 #undef flwrite
443} 443}
@@ -470,17 +470,17 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
470 OldVal = flread(base); 470 OldVal = flread(base);
471 for (I = 0; OldVal != flread(base) && I < 10000; I++) 471 for (I = 0; OldVal != flread(base) && I < 10000; I++)
472 OldVal = flread(base); 472 OldVal = flread(base);
473 473
474 // Reset the chip 474 // Reset the chip
475 flwrite(Reset,0x555); 475 flwrite(Reset,0x555);
476 476
477 // Send the sequence 477 // Send the sequence
478 flwrite(AutoSel1,0x555); 478 flwrite(AutoSel1,0x555);
479 flwrite(AutoSel2,0x2AA); 479 flwrite(AutoSel2,0x2AA);
480 flwrite(AutoSel3,0x555); 480 flwrite(AutoSel3,0x555);
481 481
482 // Test #1, JEDEC numbers are readable from 0x??00/0x??01 482 // Test #1, JEDEC numbers are readable from 0x??00/0x??01
483 if (flread(0) != flread(0x100) || 483 if (flread(0) != flread(0x100) ||
484 flread(1) != flread(0x101)) 484 flread(1) != flread(0x101))
485 { 485 {
486 flwrite(Reset,0x555); 486 flwrite(Reset,0x555);
@@ -494,14 +494,14 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
494 OldVal = flread(1); 494 OldVal = flread(1);
495 for (I = 0; I != 4; I++) 495 for (I = 0; I != 4; I++)
496 Id[I] = (OldVal >> (I*8)); 496 Id[I] = (OldVal >> (I*8));
497 497
498 Size = handle_jedecs(map,Mfg,Id,4,base,priv); 498 Size = handle_jedecs(map,Mfg,Id,4,base,priv);
499 if (Size == 0) 499 if (Size == 0)
500 { 500 {
501 flwrite(Reset,0x555); 501 flwrite(Reset,0x555);
502 return 0; 502 return 0;
503 } 503 }
504 504
505 /* Check if there is address wrap around within a single bank, if this 505 /* Check if there is address wrap around within a single bank, if this
506 returns JEDEC numbers then we assume that it is wrap around. Notice 506 returns JEDEC numbers then we assume that it is wrap around. Notice
507 we call this routine with the JEDEC return still enabled, if two or 507 we call this routine with the JEDEC return still enabled, if two or
@@ -519,27 +519,27 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
519 519
520 // Reset. 520 // Reset.
521 flwrite(0xF0F0F0F0,0x555); 521 flwrite(0xF0F0F0F0,0x555);
522 522
523 return 1; 523 return 1;
524 524
525 #undef flread 525 #undef flread
526 #undef flwrite 526 #undef flwrite
527} 527}
528 528
529/* Linear read. */ 529/* Linear read. */
530static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 530static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
531 size_t *retlen, u_char *buf) 531 size_t *retlen, u_char *buf)
532{ 532{
533 struct map_info *map = mtd->priv; 533 struct map_info *map = mtd->priv;
534 534
535 map_copy_from(map, buf, from, len); 535 map_copy_from(map, buf, from, len);
536 *retlen = len; 536 *retlen = len;
537 return 0; 537 return 0;
538} 538}
539 539
540/* Banked read. Take special care to jump past the holes in the bank 540/* Banked read. Take special care to jump past the holes in the bank
541 mapping. This version assumes symetry in the holes.. */ 541 mapping. This version assumes symetry in the holes.. */
542static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 542static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
543 size_t *retlen, u_char *buf) 543 size_t *retlen, u_char *buf)
544{ 544{
545 struct map_info *map = mtd->priv; 545 struct map_info *map = mtd->priv;
@@ -555,17 +555,17 @@ static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
555 if (priv->bank_fill[0] - offset < len) 555 if (priv->bank_fill[0] - offset < len)
556 get = priv->bank_fill[0] - offset; 556 get = priv->bank_fill[0] - offset;
557 557
558 bank /= priv->bank_fill[0]; 558 bank /= priv->bank_fill[0];
559 map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); 559 map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
560 560
561 len -= get; 561 len -= get;
562 *retlen += get; 562 *retlen += get;
563 from += get; 563 from += get;
564 } 564 }
565 return 0; 565 return 0;
566} 566}
567 567
568/* Pass the flags value that the flash return before it re-entered read 568/* Pass the flags value that the flash return before it re-entered read
569 mode. */ 569 mode. */
570static void jedec_flash_failed(unsigned char code) 570static void jedec_flash_failed(unsigned char code)
571{ 571{
@@ -579,17 +579,17 @@ static void jedec_flash_failed(unsigned char code)
579 printk("mtd: Programming didn't take\n"); 579 printk("mtd: Programming didn't take\n");
580} 580}
581 581
582/* This uses the erasure function described in the AMD Flash Handbook, 582/* This uses the erasure function described in the AMD Flash Handbook,
583 it will work for flashes with a fixed sector size only. Flashes with 583 it will work for flashes with a fixed sector size only. Flashes with
584 a selection of sector sizes (ie the AMD Am29F800B) will need a different 584 a selection of sector sizes (ie the AMD Am29F800B) will need a different
585 routine. This routine tries to parallize erasing multiple chips/sectors 585 routine. This routine tries to parallize erasing multiple chips/sectors
586 where possible */ 586 where possible */
587static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) 587static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
588{ 588{
589 // Does IO to the currently selected chip 589 // Does IO to the currently selected chip
590 #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift)) 590 #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift))
591 #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift)) 591 #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
592 592
593 unsigned long Time = 0; 593 unsigned long Time = 0;
594 unsigned long NoTime = 0; 594 unsigned long NoTime = 0;
595 unsigned long start = instr->addr, len = instr->len; 595 unsigned long start = instr->addr, len = instr->len;
@@ -603,7 +603,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
603 (len % mtd->erasesize) != 0 || 603 (len % mtd->erasesize) != 0 ||
604 (len/mtd->erasesize) == 0) 604 (len/mtd->erasesize) == 0)
605 return -EINVAL; 605 return -EINVAL;
606 606
607 jedec_flash_chip_scan(priv,start,len); 607 jedec_flash_chip_scan(priv,start,len);
608 608
609 // Start the erase sequence on each chip 609 // Start the erase sequence on each chip
@@ -611,16 +611,16 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
611 { 611 {
612 unsigned long off; 612 unsigned long off;
613 struct jedec_flash_chip *chip = priv->chips + I; 613 struct jedec_flash_chip *chip = priv->chips + I;
614 614
615 if (chip->length == 0) 615 if (chip->length == 0)
616 continue; 616 continue;
617 617
618 if (chip->start + chip->length > chip->size) 618 if (chip->start + chip->length > chip->size)
619 { 619 {
620 printk("DIE\n"); 620 printk("DIE\n");
621 return -EIO; 621 return -EIO;
622 } 622 }
623 623
624 flwrite(0xF0,chip->start + 0x555); 624 flwrite(0xF0,chip->start + 0x555);
625 flwrite(0xAA,chip->start + 0x555); 625 flwrite(0xAA,chip->start + 0x555);
626 flwrite(0x55,chip->start + 0x2AA); 626 flwrite(0x55,chip->start + 0x2AA);
@@ -628,8 +628,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
628 flwrite(0xAA,chip->start + 0x555); 628 flwrite(0xAA,chip->start + 0x555);
629 flwrite(0x55,chip->start + 0x2AA); 629 flwrite(0x55,chip->start + 0x2AA);
630 630
631 /* Once we start selecting the erase sectors the delay between each 631 /* Once we start selecting the erase sectors the delay between each
632 command must not exceed 50us or it will immediately start erasing 632 command must not exceed 50us or it will immediately start erasing
633 and ignore the other sectors */ 633 and ignore the other sectors */
634 for (off = 0; off < len; off += chip->sectorsize) 634 for (off = 0; off < len; off += chip->sectorsize)
635 { 635 {
@@ -641,19 +641,19 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
641 { 641 {
642 printk("mtd: Ack! We timed out the erase timer!\n"); 642 printk("mtd: Ack! We timed out the erase timer!\n");
643 return -EIO; 643 return -EIO;
644 } 644 }
645 } 645 }
646 } 646 }
647 647
648 /* We could split this into a timer routine and return early, performing 648 /* We could split this into a timer routine and return early, performing
649 background erasure.. Maybe later if the need warrents */ 649 background erasure.. Maybe later if the need warrents */
650 650
651 /* Poll the flash for erasure completion, specs say this can take as long 651 /* Poll the flash for erasure completion, specs say this can take as long
652 as 480 seconds to do all the sectors (for a 2 meg flash). 652 as 480 seconds to do all the sectors (for a 2 meg flash).
653 Erasure time is dependent on chip age, temp and wear.. */ 653 Erasure time is dependent on chip age, temp and wear.. */
654 654
655 /* This being a generic routine assumes a 32 bit bus. It does read32s 655 /* This being a generic routine assumes a 32 bit bus. It does read32s
656 and bundles interleved chips into the same grouping. This will work 656 and bundles interleved chips into the same grouping. This will work
657 for all bus widths */ 657 for all bus widths */
658 Time = 0; 658 Time = 0;
659 NoTime = 0; 659 NoTime = 0;
@@ -664,20 +664,20 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
664 unsigned todo[4] = {0,0,0,0}; 664 unsigned todo[4] = {0,0,0,0};
665 unsigned todo_left = 0; 665 unsigned todo_left = 0;
666 unsigned J; 666 unsigned J;
667 667
668 if (chip->length == 0) 668 if (chip->length == 0)
669 continue; 669 continue;
670 670
671 /* Find all chips in this data line, realistically this is all 671 /* Find all chips in this data line, realistically this is all
672 or nothing up to the interleve count */ 672 or nothing up to the interleve count */
673 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) 673 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
674 { 674 {
675 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == 675 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
676 (chip->base & (~((1<<chip->addrshift)-1)))) 676 (chip->base & (~((1<<chip->addrshift)-1))))
677 { 677 {
678 todo_left++; 678 todo_left++;
679 todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1; 679 todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
680 } 680 }
681 } 681 }
682 682
683 /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1], 683 /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
@@ -687,7 +687,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
687 { 687 {
688 __u32 Last[4]; 688 __u32 Last[4];
689 unsigned long Count = 0; 689 unsigned long Count = 0;
690 690
691 /* During erase bit 7 is held low and bit 6 toggles, we watch this, 691 /* During erase bit 7 is held low and bit 6 toggles, we watch this,
692 should it stop toggling or go high then the erase is completed, 692 should it stop toggling or go high then the erase is completed,
693 or this is not really flash ;> */ 693 or this is not really flash ;> */
@@ -718,23 +718,23 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
718 __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF; 718 __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
719 if (todo[J] == 0) 719 if (todo[J] == 0)
720 continue; 720 continue;
721 721
722 if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2) 722 if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
723 { 723 {
724// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2); 724// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
725 continue; 725 continue;
726 } 726 }
727 727
728 if (Byte1 == Byte2) 728 if (Byte1 == Byte2)
729 { 729 {
730 jedec_flash_failed(Byte3); 730 jedec_flash_failed(Byte3);
731 return -EIO; 731 return -EIO;
732 } 732 }
733 733
734 todo[J] = 0; 734 todo[J] = 0;
735 todo_left--; 735 todo_left--;
736 } 736 }
737 737
738/* if (NoTime == 0) 738/* if (NoTime == 0)
739 Time += HZ/10 - schedule_timeout(HZ/10);*/ 739 Time += HZ/10 - schedule_timeout(HZ/10);*/
740 NoTime = 0; 740 NoTime = 0;
@@ -751,7 +751,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
751 break; 751 break;
752 } 752 }
753 Count++; 753 Count++;
754 754
755/* // Count time, max of 15s per sector (according to AMD) 755/* // Count time, max of 15s per sector (according to AMD)
756 if (Time > 15*len/mtd->erasesize*HZ) 756 if (Time > 15*len/mtd->erasesize*HZ)
757 { 757 {
@@ -759,38 +759,38 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
759 return -EIO; 759 return -EIO;
760 } */ 760 } */
761 } 761 }
762 762
763 // Skip to the next chip if we used chip erase 763 // Skip to the next chip if we used chip erase
764 if (chip->length == chip->size) 764 if (chip->length == chip->size)
765 off = chip->size; 765 off = chip->size;
766 else 766 else
767 off += chip->sectorsize; 767 off += chip->sectorsize;
768 768
769 if (off >= chip->length) 769 if (off >= chip->length)
770 break; 770 break;
771 NoTime = 1; 771 NoTime = 1;
772 } 772 }
773 773
774 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) 774 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
775 { 775 {
776 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == 776 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
777 (chip->base & (~((1<<chip->addrshift)-1)))) 777 (chip->base & (~((1<<chip->addrshift)-1))))
778 priv->chips[J].length = 0; 778 priv->chips[J].length = 0;
779 } 779 }
780 } 780 }
781 781
782 //printk("done\n"); 782 //printk("done\n");
783 instr->state = MTD_ERASE_DONE; 783 instr->state = MTD_ERASE_DONE;
784 mtd_erase_callback(instr); 784 mtd_erase_callback(instr);
785 return 0; 785 return 0;
786 786
787 #undef flread 787 #undef flread
788 #undef flwrite 788 #undef flwrite
789} 789}
790 790
791/* This is the simple flash writing function. It writes to every byte, in 791/* This is the simple flash writing function. It writes to every byte, in
792 sequence. It takes care of how to properly address the flash if 792 sequence. It takes care of how to properly address the flash if
793 the flash is interleved. It can only be used if all the chips in the 793 the flash is interleved. It can only be used if all the chips in the
794 array are identical!*/ 794 array are identical!*/
795static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, 795static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
796 size_t *retlen, const u_char *buf) 796 size_t *retlen, const u_char *buf)
@@ -800,25 +800,25 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
800 of addrshift (interleave index) and then adds the control register index. */ 800 of addrshift (interleave index) and then adds the control register index. */
801 #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) 801 #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
802 #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) 802 #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
803 803
804 struct map_info *map = mtd->priv; 804 struct map_info *map = mtd->priv;
805 struct jedec_private *priv = map->fldrv_priv; 805 struct jedec_private *priv = map->fldrv_priv;
806 unsigned long base; 806 unsigned long base;
807 unsigned long off; 807 unsigned long off;
808 size_t save_len = len; 808 size_t save_len = len;
809 809
810 if (start + len > mtd->size) 810 if (start + len > mtd->size)
811 return -EIO; 811 return -EIO;
812 812
813 //printk("Here"); 813 //printk("Here");
814 814
815 //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len); 815 //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
816 while (len != 0) 816 while (len != 0)
817 { 817 {
818 struct jedec_flash_chip *chip = priv->chips; 818 struct jedec_flash_chip *chip = priv->chips;
819 unsigned long bank; 819 unsigned long bank;
820 unsigned long boffset; 820 unsigned long boffset;
821 821
822 // Compute the base of the flash. 822 // Compute the base of the flash.
823 off = ((unsigned long)start) % (chip->size << chip->addrshift); 823 off = ((unsigned long)start) % (chip->size << chip->addrshift);
824 base = start - off; 824 base = start - off;
@@ -828,10 +828,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
828 boffset = base & (priv->bank_fill[0]-1); 828 boffset = base & (priv->bank_fill[0]-1);
829 bank = (bank/priv->bank_fill[0])*my_bank_size; 829 bank = (bank/priv->bank_fill[0])*my_bank_size;
830 base = bank + boffset; 830 base = bank + boffset;
831 831
832 // printk("Flasing %X %X %X\n",base,chip->size,len); 832 // printk("Flasing %X %X %X\n",base,chip->size,len);
833 // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift); 833 // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
834 834
835 // Loop over this page 835 // Loop over this page
836 for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++) 836 for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
837 { 837 {
@@ -845,7 +845,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
845 } 845 }
846 if (((~oldbyte) & *buf) != 0) 846 if (((~oldbyte) & *buf) != 0)
847 printk("mtd: warn: Trying to set a 0 to a 1\n"); 847 printk("mtd: warn: Trying to set a 0 to a 1\n");
848 848
849 // Write 849 // Write
850 flwrite(0xAA,0x555); 850 flwrite(0xAA,0x555);
851 flwrite(0x55,0x2AA); 851 flwrite(0x55,0x2AA);
@@ -854,10 +854,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
854 Last[0] = map_read8(map,base + off); 854 Last[0] = map_read8(map,base + off);
855 Last[1] = map_read8(map,base + off); 855 Last[1] = map_read8(map,base + off);
856 Last[2] = map_read8(map,base + off); 856 Last[2] = map_read8(map,base + off);
857 857
858 /* Wait for the flash to finish the operation. We store the last 4 858 /* Wait for the flash to finish the operation. We store the last 4
859 status bytes that have been retrieved so we can determine why 859 status bytes that have been retrieved so we can determine why
860 it failed. The toggle bits keep toggling when there is a 860 it failed. The toggle bits keep toggling when there is a
861 failure */ 861 failure */
862 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && 862 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
863 Count < 10000; Count++) 863 Count < 10000; Count++)
@@ -866,7 +866,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
866 { 866 {
867 jedec_flash_failed(Last[(Count - 3) % 4]); 867 jedec_flash_failed(Last[(Count - 3) % 4]);
868 return -EIO; 868 return -EIO;
869 } 869 }
870 } 870 }
871 } 871 }
872 *retlen = save_len; 872 *retlen = save_len;
@@ -885,24 +885,24 @@ static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start
885 // Zero the records 885 // Zero the records
886 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 886 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
887 priv->chips[I].start = priv->chips[I].length = 0; 887 priv->chips[I].start = priv->chips[I].length = 0;
888 888
889 // Intersect the region with each chip 889 // Intersect the region with each chip
890 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 890 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
891 { 891 {
892 struct jedec_flash_chip *chip = priv->chips + I; 892 struct jedec_flash_chip *chip = priv->chips + I;
893 unsigned long ByteStart; 893 unsigned long ByteStart;
894 unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift); 894 unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
895 895
896 // End is before this chip or the start is after it 896 // End is before this chip or the start is after it
897 if (start+len < chip->offset || 897 if (start+len < chip->offset ||
898 ChipEndByte - (1 << chip->addrshift) < start) 898 ChipEndByte - (1 << chip->addrshift) < start)
899 continue; 899 continue;
900 900
901 if (start < chip->offset) 901 if (start < chip->offset)
902 { 902 {
903 ByteStart = chip->offset; 903 ByteStart = chip->offset;
904 chip->start = 0; 904 chip->start = 0;
905 } 905 }
906 else 906 else
907 { 907 {
908 chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift; 908 chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;