[TG3]: Add tagged status support.
[linux-2.6/verdex.git] / drivers / mtd / chips / jedec.c
blob62d235a9a4e21930baa3ca972e5ee82509ca52ef
2 /* JEDEC Flash Interface.
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.
5 * It is called JEDEC because the JEDEC association distributes the ID codes
6 * for the chips.
8 * See the AMD flash databook for information on how to operate the interface.
10 * This code does not support anything wider than 8 bit flash chips, I am
11 * not going to guess how to send commands to them, plus I expect they will
12 * all speak CFI..
14 * $Id: jedec.c,v 1.22 2005/01/05 18:05:11 dwmw2 Exp $
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/mtd/jedec.h>
21 #include <linux/mtd/map.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/compatmac.h>
25 static struct mtd_info *jedec_probe(struct map_info *);
26 static int jedec_probe8(struct map_info *map,unsigned long base,
27 struct jedec_private *priv);
28 static int jedec_probe16(struct map_info *map,unsigned long base,
29 struct jedec_private *priv);
30 static int jedec_probe32(struct map_info *map,unsigned long base,
31 struct jedec_private *priv);
32 static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,
33 unsigned long len);
34 static int flash_erase(struct mtd_info *mtd, struct erase_info *instr);
35 static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
36 size_t *retlen, const u_char *buf);
38 static unsigned long my_bank_size;
40 /* Listing of parts and sizes. We need this table to learn the sector
41 size of the chip and the total length */
42 static const struct JEDECTable JEDEC_table[] = {
44 .jedec = 0x013D,
45 .name = "AMD Am29F017D",
46 .size = 2*1024*1024,
47 .sectorsize = 64*1024,
48 .capabilities = MTD_CAP_NORFLASH
51 .jedec = 0x01AD,
52 .name = "AMD Am29F016",
53 .size = 2*1024*1024,
54 .sectorsize = 64*1024,
55 .capabilities = MTD_CAP_NORFLASH
58 .jedec = 0x01D5,
59 .name = "AMD Am29F080",
60 .size = 1*1024*1024,
61 .sectorsize = 64*1024,
62 .capabilities = MTD_CAP_NORFLASH
65 .jedec = 0x01A4,
66 .name = "AMD Am29F040",
67 .size = 512*1024,
68 .sectorsize = 64*1024,
69 .capabilities = MTD_CAP_NORFLASH
72 .jedec = 0x20E3,
73 .name = "AMD Am29W040B",
74 .size = 512*1024,
75 .sectorsize = 64*1024,
76 .capabilities = MTD_CAP_NORFLASH
79 .jedec = 0xC2AD,
80 .name = "Macronix MX29F016",
81 .size = 2*1024*1024,
82 .sectorsize = 64*1024,
83 .capabilities = MTD_CAP_NORFLASH
85 { .jedec = 0x0 }
88 static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
89 static void jedec_sync(struct mtd_info *mtd) {};
90 static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
91 size_t *retlen, u_char *buf);
92 static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
93 size_t *retlen, u_char *buf);
95 static struct mtd_info *jedec_probe(struct map_info *map);
99 static struct mtd_chip_driver jedec_chipdrv = {
100 .probe = jedec_probe,
101 .name = "jedec",
102 .module = THIS_MODULE
105 /* Probe entry point */
107 static struct mtd_info *jedec_probe(struct map_info *map)
109 struct mtd_info *MTD;
110 struct jedec_private *priv;
111 unsigned long Base;
112 unsigned long SectorSize;
113 unsigned count;
114 unsigned I,Uniq;
115 char Part[200];
116 memset(&priv,0,sizeof(priv));
118 MTD = kmalloc(sizeof(struct mtd_info) + sizeof(struct jedec_private), GFP_KERNEL);
119 if (!MTD)
120 return NULL;
122 memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
123 priv = (struct jedec_private *)&MTD[1];
125 my_bank_size = map->size;
127 if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
129 printk("mtd: Increase MAX_JEDEC_CHIPS, too many banks.\n");
130 kfree(MTD);
131 return NULL;
134 for (Base = 0; Base < map->size; Base += my_bank_size)
136 // Perhaps zero could designate all tests?
137 if (map->buswidth == 0)
138 map->buswidth = 1;
140 if (map->buswidth == 1){
141 if (jedec_probe8(map,Base,priv) == 0) {
142 printk("did recognize jedec chip\n");
143 kfree(MTD);
144 return NULL;
147 if (map->buswidth == 2)
148 jedec_probe16(map,Base,priv);
149 if (map->buswidth == 4)
150 jedec_probe32(map,Base,priv);
153 // Get the biggest sector size
154 SectorSize = 0;
155 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
157 // printk("priv->chips[%d].jedec is %x\n",I,priv->chips[I].jedec);
158 // printk("priv->chips[%d].sectorsize is %lx\n",I,priv->chips[I].sectorsize);
159 if (priv->chips[I].sectorsize > SectorSize)
160 SectorSize = priv->chips[I].sectorsize;
163 // Quickly ensure that the other sector sizes are factors of the largest
164 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
166 if ((SectorSize/priv->chips[I].sectorsize)*priv->chips[I].sectorsize != SectorSize)
168 printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
169 kfree(MTD);
170 return NULL;
174 /* Generate a part name that includes the number of different chips and
175 other configuration information */
176 count = 1;
177 strlcpy(Part,map->name,sizeof(Part)-10);
178 strcat(Part," ");
179 Uniq = 0;
180 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
182 const struct JEDECTable *JEDEC;
184 if (priv->chips[I+1].jedec == priv->chips[I].jedec)
186 count++;
187 continue;
190 // Locate the chip in the jedec table
191 JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
192 if (JEDEC == 0)
194 printk("mtd: Internal Error, JEDEC not set\n");
195 kfree(MTD);
196 return NULL;
199 if (Uniq != 0)
200 strcat(Part,",");
201 Uniq++;
203 if (count != 1)
204 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
205 else
206 sprintf(Part+strlen(Part),"%s",JEDEC->name);
207 if (strlen(Part) > sizeof(Part)*2/3)
208 break;
209 count = 1;
212 /* Determine if the chips are organized in a linear fashion, or if there
213 are empty banks. Note, the last bank does not count here, only the
214 first banks are important. Holes on non-bank boundaries can not exist
215 due to the way the detection algorithm works. */
216 if (priv->size < my_bank_size)
217 my_bank_size = priv->size;
218 priv->is_banked = 0;
219 //printk("priv->size is %x, my_bank_size is %x\n",priv->size,my_bank_size);
220 //printk("priv->bank_fill[0] is %x\n",priv->bank_fill[0]);
221 if (!priv->size) {
222 printk("priv->size is zero\n");
223 kfree(MTD);
224 return NULL;
226 if (priv->size/my_bank_size) {
227 if (priv->size/my_bank_size == 1) {
228 priv->size = my_bank_size;
230 else {
231 for (I = 0; I != priv->size/my_bank_size - 1; I++)
233 if (priv->bank_fill[I] != my_bank_size)
234 priv->is_banked = 1;
236 /* This even could be eliminated, but new de-optimized read/write
237 functions have to be written */
238 printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
239 if (priv->bank_fill[I] != priv->bank_fill[0])
241 printk("mtd: Failed. Cannot handle unsymmetric banking\n");
242 kfree(MTD);
243 return NULL;
248 if (priv->is_banked == 1)
249 strcat(Part,", banked");
251 // printk("Part: '%s'\n",Part);
253 memset(MTD,0,sizeof(*MTD));
254 // strlcpy(MTD->name,Part,sizeof(MTD->name));
255 MTD->name = map->name;
256 MTD->type = MTD_NORFLASH;
257 MTD->flags = MTD_CAP_NORFLASH;
258 MTD->erasesize = SectorSize*(map->buswidth);
259 // printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize);
260 MTD->size = priv->size;
261 // printk("MTD->size is %x\n",(unsigned int)MTD->size);
262 //MTD->module = THIS_MODULE; // ? Maybe this should be the low level module?
263 MTD->erase = flash_erase;
264 if (priv->is_banked == 1)
265 MTD->read = jedec_read_banked;
266 else
267 MTD->read = jedec_read;
268 MTD->write = flash_write;
269 MTD->sync = jedec_sync;
270 MTD->priv = map;
271 map->fldrv_priv = priv;
272 map->fldrv = &jedec_chipdrv;
273 __module_get(THIS_MODULE);
274 return MTD;
277 /* Helper for the JEDEC function, JEDEC numbers all have odd parity */
278 static int checkparity(u_char C)
280 u_char parity = 0;
281 while (C != 0)
283 parity ^= C & 1;
284 C >>= 1;
287 return parity == 1;
291 /* Take an array of JEDEC numbers that represent interleved flash chips
292 and process them. Check to make sure they are good JEDEC numbers, look
293 them up and then add them to the chip list */
294 static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
295 unsigned long base,struct jedec_private *priv)
297 unsigned I,J;
298 unsigned long Size;
299 unsigned long SectorSize;
300 const struct JEDECTable *JEDEC;
302 // Test #2 JEDEC numbers exhibit odd parity
303 for (I = 0; I != Count; I++)
305 if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
306 return 0;
309 // Finally, just make sure all the chip sizes are the same
310 JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
312 if (JEDEC == 0)
314 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
315 return 0;
318 Size = JEDEC->size;
319 SectorSize = JEDEC->sectorsize;
320 for (I = 0; I != Count; I++)
322 JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
323 if (JEDEC == 0)
325 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
326 return 0;
329 if (Size != JEDEC->size || SectorSize != JEDEC->sectorsize)
331 printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
332 return 0;
336 // Load the Chips
337 for (I = 0; I != MAX_JEDEC_CHIPS; I++)
339 if (priv->chips[I].jedec == 0)
340 break;
343 if (I + Count > MAX_JEDEC_CHIPS)
345 printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
346 return 0;
349 // Add them to the table
350 for (J = 0; J != Count; J++)
352 unsigned long Bank;
354 JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
355 priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
356 priv->chips[I].size = JEDEC->size;
357 priv->chips[I].sectorsize = JEDEC->sectorsize;
358 priv->chips[I].base = base + J;
359 priv->chips[I].datashift = J*8;
360 priv->chips[I].capabilities = JEDEC->capabilities;
361 priv->chips[I].offset = priv->size + J;
363 // log2 n :|
364 priv->chips[I].addrshift = 0;
365 for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
367 // Determine how filled this bank is.
368 Bank = base & (~(my_bank_size-1));
369 if (priv->bank_fill[Bank/my_bank_size] < base +
370 (JEDEC->size << priv->chips[I].addrshift) - Bank)
371 priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
372 I++;
375 priv->size += priv->chips[I-1].size*Count;
377 return priv->chips[I-1].size;
380 /* Lookup the chip information from the JEDEC ID table. */
381 static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
383 __u16 Id = (mfr << 8) | id;
384 unsigned long I = 0;
385 for (I = 0; JEDEC_table[I].jedec != 0; I++)
386 if (JEDEC_table[I].jedec == Id)
387 return JEDEC_table + I;
388 return NULL;
391 // Look for flash using an 8 bit bus interface
392 static int jedec_probe8(struct map_info *map,unsigned long base,
393 struct jedec_private *priv)
395 #define flread(x) map_read8(map,base+x)
396 #define flwrite(v,x) map_write8(map,v,base+x)
398 const unsigned long AutoSel1 = 0xAA;
399 const unsigned long AutoSel2 = 0x55;
400 const unsigned long AutoSel3 = 0x90;
401 const unsigned long Reset = 0xF0;
402 __u32 OldVal;
403 __u8 Mfg[1];
404 __u8 Id[1];
405 unsigned I;
406 unsigned long Size;
408 // Wait for any write/erase operation to settle
409 OldVal = flread(base);
410 for (I = 0; OldVal != flread(base) && I < 10000; I++)
411 OldVal = flread(base);
413 // Reset the chip
414 flwrite(Reset,0x555);
416 // Send the sequence
417 flwrite(AutoSel1,0x555);
418 flwrite(AutoSel2,0x2AA);
419 flwrite(AutoSel3,0x555);
421 // Get the JEDEC numbers
422 Mfg[0] = flread(0);
423 Id[0] = flread(1);
424 // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
426 Size = handle_jedecs(map,Mfg,Id,1,base,priv);
427 // printk("handle_jedecs Size is %x\n",(unsigned int)Size);
428 if (Size == 0)
430 flwrite(Reset,0x555);
431 return 0;
435 // Reset.
436 flwrite(Reset,0x555);
438 return 1;
440 #undef flread
441 #undef flwrite
444 // Look for flash using a 16 bit bus interface (ie 2 8-bit chips)
445 static int jedec_probe16(struct map_info *map,unsigned long base,
446 struct jedec_private *priv)
448 return 0;
451 // Look for flash using a 32 bit bus interface (ie 4 8-bit chips)
452 static int jedec_probe32(struct map_info *map,unsigned long base,
453 struct jedec_private *priv)
455 #define flread(x) map_read32(map,base+((x)<<2))
456 #define flwrite(v,x) map_write32(map,v,base+((x)<<2))
458 const unsigned long AutoSel1 = 0xAAAAAAAA;
459 const unsigned long AutoSel2 = 0x55555555;
460 const unsigned long AutoSel3 = 0x90909090;
461 const unsigned long Reset = 0xF0F0F0F0;
462 __u32 OldVal;
463 __u8 Mfg[4];
464 __u8 Id[4];
465 unsigned I;
466 unsigned long Size;
468 // Wait for any write/erase operation to settle
469 OldVal = flread(base);
470 for (I = 0; OldVal != flread(base) && I < 10000; I++)
471 OldVal = flread(base);
473 // Reset the chip
474 flwrite(Reset,0x555);
476 // Send the sequence
477 flwrite(AutoSel1,0x555);
478 flwrite(AutoSel2,0x2AA);
479 flwrite(AutoSel3,0x555);
481 // Test #1, JEDEC numbers are readable from 0x??00/0x??01
482 if (flread(0) != flread(0x100) ||
483 flread(1) != flread(0x101))
485 flwrite(Reset,0x555);
486 return 0;
489 // Split up the JEDEC numbers
490 OldVal = flread(0);
491 for (I = 0; I != 4; I++)
492 Mfg[I] = (OldVal >> (I*8));
493 OldVal = flread(1);
494 for (I = 0; I != 4; I++)
495 Id[I] = (OldVal >> (I*8));
497 Size = handle_jedecs(map,Mfg,Id,4,base,priv);
498 if (Size == 0)
500 flwrite(Reset,0x555);
501 return 0;
504 /* Check if there is address wrap around within a single bank, if this
505 returns JEDEC numbers then we assume that it is wrap around. Notice
506 we call this routine with the JEDEC return still enabled, if two or
507 more flashes have a truncated address space the probe test will still
508 work */
509 if (base + (Size<<2)+0x555 < map->size &&
510 base + (Size<<2)+0x555 < (base & (~(my_bank_size-1))) + my_bank_size)
512 if (flread(base+Size) != flread(base+Size + 0x100) ||
513 flread(base+Size + 1) != flread(base+Size + 0x101))
515 jedec_probe32(map,base+Size,priv);
519 // Reset.
520 flwrite(0xF0F0F0F0,0x555);
522 return 1;
524 #undef flread
525 #undef flwrite
528 /* Linear read. */
529 static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
530 size_t *retlen, u_char *buf)
532 struct map_info *map = mtd->priv;
534 map_copy_from(map, buf, from, len);
535 *retlen = len;
536 return 0;
539 /* Banked read. Take special care to jump past the holes in the bank
540 mapping. This version assumes symetry in the holes.. */
541 static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
542 size_t *retlen, u_char *buf)
544 struct map_info *map = mtd->priv;
545 struct jedec_private *priv = map->fldrv_priv;
547 *retlen = 0;
548 while (len > 0)
550 // Determine what bank and offset into that bank the first byte is
551 unsigned long bank = from & (~(priv->bank_fill[0]-1));
552 unsigned long offset = from & (priv->bank_fill[0]-1);
553 unsigned long get = len;
554 if (priv->bank_fill[0] - offset < len)
555 get = priv->bank_fill[0] - offset;
557 bank /= priv->bank_fill[0];
558 map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
560 len -= get;
561 *retlen += get;
562 from += get;
564 return 0;
567 /* Pass the flags value that the flash return before it re-entered read
568 mode. */
569 static void jedec_flash_failed(unsigned char code)
571 /* Bit 5 being high indicates that there was an internal device
572 failure, erasure time limits exceeded or something */
573 if ((code & (1 << 5)) != 0)
575 printk("mtd: Internal Flash failure\n");
576 return;
578 printk("mtd: Programming didn't take\n");
581 /* This uses the erasure function described in the AMD Flash Handbook,
582 it will work for flashes with a fixed sector size only. Flashes with
583 a selection of sector sizes (ie the AMD Am29F800B) will need a different
584 routine. This routine tries to parallize erasing multiple chips/sectors
585 where possible */
586 static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
588 // Does IO to the currently selected chip
589 #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift))
590 #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
592 unsigned long Time = 0;
593 unsigned long NoTime = 0;
594 unsigned long start = instr->addr, len = instr->len;
595 unsigned int I;
596 struct map_info *map = mtd->priv;
597 struct jedec_private *priv = map->fldrv_priv;
599 // Verify the arguments..
600 if (start + len > mtd->size ||
601 (start % mtd->erasesize) != 0 ||
602 (len % mtd->erasesize) != 0 ||
603 (len/mtd->erasesize) == 0)
604 return -EINVAL;
606 jedec_flash_chip_scan(priv,start,len);
608 // Start the erase sequence on each chip
609 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
611 unsigned long off;
612 struct jedec_flash_chip *chip = priv->chips + I;
614 if (chip->length == 0)
615 continue;
617 if (chip->start + chip->length > chip->size)
619 printk("DIE\n");
620 return -EIO;
623 flwrite(0xF0,chip->start + 0x555);
624 flwrite(0xAA,chip->start + 0x555);
625 flwrite(0x55,chip->start + 0x2AA);
626 flwrite(0x80,chip->start + 0x555);
627 flwrite(0xAA,chip->start + 0x555);
628 flwrite(0x55,chip->start + 0x2AA);
630 /* Once we start selecting the erase sectors the delay between each
631 command must not exceed 50us or it will immediately start erasing
632 and ignore the other sectors */
633 for (off = 0; off < len; off += chip->sectorsize)
635 // Check to make sure we didn't timeout
636 flwrite(0x30,chip->start + off);
637 if (off == 0)
638 continue;
639 if ((flread(chip->start + off) & (1 << 3)) != 0)
641 printk("mtd: Ack! We timed out the erase timer!\n");
642 return -EIO;
647 /* We could split this into a timer routine and return early, performing
648 background erasure.. Maybe later if the need warrents */
650 /* Poll the flash for erasure completion, specs say this can take as long
651 as 480 seconds to do all the sectors (for a 2 meg flash).
652 Erasure time is dependent on chip age, temp and wear.. */
654 /* This being a generic routine assumes a 32 bit bus. It does read32s
655 and bundles interleved chips into the same grouping. This will work
656 for all bus widths */
657 Time = 0;
658 NoTime = 0;
659 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
661 struct jedec_flash_chip *chip = priv->chips + I;
662 unsigned long off = 0;
663 unsigned todo[4] = {0,0,0,0};
664 unsigned todo_left = 0;
665 unsigned J;
667 if (chip->length == 0)
668 continue;
670 /* Find all chips in this data line, realistically this is all
671 or nothing up to the interleve count */
672 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
674 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
675 (chip->base & (~((1<<chip->addrshift)-1))))
677 todo_left++;
678 todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
682 /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
683 (short)todo[2],(short)todo[3]);
685 while (1)
687 __u32 Last[4];
688 unsigned long Count = 0;
690 /* During erase bit 7 is held low and bit 6 toggles, we watch this,
691 should it stop toggling or go high then the erase is completed,
692 or this is not really flash ;> */
693 switch (map->buswidth) {
694 case 1:
695 Last[0] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
696 Last[1] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
697 Last[2] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
698 break;
699 case 2:
700 Last[0] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
701 Last[1] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
702 Last[2] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
703 break;
704 case 3:
705 Last[0] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
706 Last[1] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
707 Last[2] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
708 break;
710 Count = 3;
711 while (todo_left != 0)
713 for (J = 0; J != 4; J++)
715 __u8 Byte1 = (Last[(Count-1)%4] >> (J*8)) & 0xFF;
716 __u8 Byte2 = (Last[(Count-2)%4] >> (J*8)) & 0xFF;
717 __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
718 if (todo[J] == 0)
719 continue;
721 if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
723 // printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
724 continue;
727 if (Byte1 == Byte2)
729 jedec_flash_failed(Byte3);
730 return -EIO;
733 todo[J] = 0;
734 todo_left--;
737 /* if (NoTime == 0)
738 Time += HZ/10 - schedule_timeout(HZ/10);*/
739 NoTime = 0;
741 switch (map->buswidth) {
742 case 1:
743 Last[Count % 4] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
744 break;
745 case 2:
746 Last[Count % 4] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
747 break;
748 case 4:
749 Last[Count % 4] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
750 break;
752 Count++;
754 /* // Count time, max of 15s per sector (according to AMD)
755 if (Time > 15*len/mtd->erasesize*HZ)
757 printk("mtd: Flash Erase Timed out\n");
758 return -EIO;
759 } */
762 // Skip to the next chip if we used chip erase
763 if (chip->length == chip->size)
764 off = chip->size;
765 else
766 off += chip->sectorsize;
768 if (off >= chip->length)
769 break;
770 NoTime = 1;
773 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
775 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
776 (chip->base & (~((1<<chip->addrshift)-1))))
777 priv->chips[J].length = 0;
781 //printk("done\n");
782 instr->state = MTD_ERASE_DONE;
783 mtd_erase_callback(instr);
784 return 0;
786 #undef flread
787 #undef flwrite
790 /* This is the simple flash writing function. It writes to every byte, in
791 sequence. It takes care of how to properly address the flash if
792 the flash is interleved. It can only be used if all the chips in the
793 array are identical!*/
794 static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
795 size_t *retlen, const u_char *buf)
797 /* Does IO to the currently selected chip. It takes the bank addressing
798 base (which is divisible by the chip size) adds the necessary lower bits
799 of addrshift (interleave index) and then adds the control register index. */
800 #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
801 #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
803 struct map_info *map = mtd->priv;
804 struct jedec_private *priv = map->fldrv_priv;
805 unsigned long base;
806 unsigned long off;
807 size_t save_len = len;
809 if (start + len > mtd->size)
810 return -EIO;
812 //printk("Here");
814 //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
815 while (len != 0)
817 struct jedec_flash_chip *chip = priv->chips;
818 unsigned long bank;
819 unsigned long boffset;
821 // Compute the base of the flash.
822 off = ((unsigned long)start) % (chip->size << chip->addrshift);
823 base = start - off;
825 // Perform banked addressing translation.
826 bank = base & (~(priv->bank_fill[0]-1));
827 boffset = base & (priv->bank_fill[0]-1);
828 bank = (bank/priv->bank_fill[0])*my_bank_size;
829 base = bank + boffset;
831 // printk("Flasing %X %X %X\n",base,chip->size,len);
832 // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
834 // Loop over this page
835 for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
837 unsigned char oldbyte = map_read8(map,base+off);
838 unsigned char Last[4];
839 unsigned long Count = 0;
841 if (oldbyte == *buf) {
842 // printk("oldbyte and *buf is %x,len is %x\n",oldbyte,len);
843 continue;
845 if (((~oldbyte) & *buf) != 0)
846 printk("mtd: warn: Trying to set a 0 to a 1\n");
848 // Write
849 flwrite(0xAA,0x555);
850 flwrite(0x55,0x2AA);
851 flwrite(0xA0,0x555);
852 map_write8(map,*buf,base + off);
853 Last[0] = map_read8(map,base + off);
854 Last[1] = map_read8(map,base + off);
855 Last[2] = map_read8(map,base + off);
857 /* Wait for the flash to finish the operation. We store the last 4
858 status bytes that have been retrieved so we can determine why
859 it failed. The toggle bits keep toggling when there is a
860 failure */
861 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
862 Count < 10000; Count++)
863 Last[Count % 4] = map_read8(map,base + off);
864 if (Last[(Count - 1) % 4] != *buf)
866 jedec_flash_failed(Last[(Count - 3) % 4]);
867 return -EIO;
871 *retlen = save_len;
872 return 0;
875 /* This is used to enhance the speed of the erase routine,
876 when things are being done to multiple chips it is possible to
877 parallize the operations, particularly full memory erases of multi
878 chip memories benifit */
879 static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,
880 unsigned long len)
882 unsigned int I;
884 // Zero the records
885 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
886 priv->chips[I].start = priv->chips[I].length = 0;
888 // Intersect the region with each chip
889 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
891 struct jedec_flash_chip *chip = priv->chips + I;
892 unsigned long ByteStart;
893 unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
895 // End is before this chip or the start is after it
896 if (start+len < chip->offset ||
897 ChipEndByte - (1 << chip->addrshift) < start)
898 continue;
900 if (start < chip->offset)
902 ByteStart = chip->offset;
903 chip->start = 0;
905 else
907 chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;
908 ByteStart = start;
911 if (start + len >= ChipEndByte)
912 chip->length = (ChipEndByte - ByteStart) >> chip->addrshift;
913 else
914 chip->length = (start + len - ByteStart + (1 << chip->addrshift)-1) >> chip->addrshift;
918 int __init jedec_init(void)
920 register_mtd_chip_driver(&jedec_chipdrv);
921 return 0;
924 static void __exit jedec_exit(void)
926 unregister_mtd_chip_driver(&jedec_chipdrv);
929 module_init(jedec_init);
930 module_exit(jedec_exit);
932 MODULE_LICENSE("GPL");
933 MODULE_AUTHOR("Jason Gunthorpe <jgg@deltatee.com> et al.");
934 MODULE_DESCRIPTION("Old MTD chip driver for JEDEC-compliant flash chips");