OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [mtd/] [chips/] [jedec.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
 
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.
7
 *
8
 * See the AMD flash databook for information on how to operate the interface.
9
 *
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..
13
 *
14
 * $Id: jedec.c,v 1.1.1.1 2004-04-15 01:52:11 phoenix Exp $
15
 */
16
 
17
#include <linux/mtd/jedec.h>
18
 
19
static struct mtd_info *jedec_probe(struct map_info *);
20
static int jedec_probe8(struct map_info *map,unsigned long base,
21
                  struct jedec_private *priv);
22
static int jedec_probe16(struct map_info *map,unsigned long base,
23
                  struct jedec_private *priv);
24
static int jedec_probe32(struct map_info *map,unsigned long base,
25
                  struct jedec_private *priv);
26
static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,
27
                            unsigned long len);
28
static int flash_erase(struct mtd_info *mtd, struct erase_info *instr);
29
static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
30
                       size_t *retlen, const u_char *buf);
31
 
32
static unsigned long my_bank_size;
33
 
34
/* Listing of parts and sizes. We need this table to learn the sector
35
   size of the chip and the total length */
36
static const struct JEDECTable JEDEC_table[] =
37
  {{0x013D,"AMD Am29F017D",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
38
   {0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
39
   {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH},
40
   {0x01A4,"AMD Am29F040",512*1024,64*1024,MTD_CAP_NORFLASH},
41
   {0x20E3,"AMD Am29W040B",512*1024,64*1024,MTD_CAP_NORFLASH},
42
   {0xC2AD,"Macronix MX29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
43
   {}};
44
 
45
static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
46
static void jedec_sync(struct mtd_info *mtd) {};
47
static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
48
                      size_t *retlen, u_char *buf);
49
static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
50
                             size_t *retlen, u_char *buf);
51
 
52
static struct mtd_info *jedec_probe(struct map_info *map);
53
 
54
 
55
 
56
static struct mtd_chip_driver jedec_chipdrv = {
57
        probe: jedec_probe,
58
        name: "jedec",
59
        module: THIS_MODULE
60
};
61
 
62
/* Probe entry point */
63
 
64
static struct mtd_info *jedec_probe(struct map_info *map)
65
{
66
   struct mtd_info *MTD;
67
   struct jedec_private *priv;
68
   unsigned long Base;
69
   unsigned long SectorSize;
70
   unsigned count;
71
   unsigned I,Uniq;
72
   char Part[200];
73
   memset(&priv,0,sizeof(priv));
74
 
75
   MTD = kmalloc(sizeof(struct mtd_info) + sizeof(struct jedec_private), GFP_KERNEL);
76
   if (!MTD)
77
           return NULL;
78
 
79
   memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
80
   priv = (struct jedec_private *)&MTD[1];
81
 
82
   my_bank_size = map->size;
83
 
84
   if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
85
   {
86
      printk("mtd: Increase MAX_JEDEC_CHIPS, too many banks.\n");
87
      kfree(MTD);
88
      return 0;
89
   }
90
 
91
   for (Base = 0; Base < map->size; Base += my_bank_size)
92
   {
93
      // Perhaps zero could designate all tests?
94
      if (map->buswidth == 0)
95
         map->buswidth = 1;
96
 
97
      if (map->buswidth == 1){
98
         if (jedec_probe8(map,Base,priv) == 0) {
99
                 printk("did recognize jedec chip\n");
100
                 kfree(MTD);
101
                 return 0;
102
         }
103
      }
104
      if (map->buswidth == 2)
105
         jedec_probe16(map,Base,priv);
106
      if (map->buswidth == 4)
107
         jedec_probe32(map,Base,priv);
108
   }
109
 
110
   // Get the biggest sector size
111
   SectorSize = 0;
112
   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
113
   {
114
           //      printk("priv->chips[%d].jedec is %x\n",I,priv->chips[I].jedec);
115
           //      printk("priv->chips[%d].sectorsize is %lx\n",I,priv->chips[I].sectorsize);
116
      if (priv->chips[I].sectorsize > SectorSize)
117
         SectorSize = priv->chips[I].sectorsize;
118
   }
119
 
120
   // Quickly ensure that the other sector sizes are factors of the largest
121
   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
122
   {
123
      if ((SectorSize/priv->chips[I].sectorsize)*priv->chips[I].sectorsize != SectorSize)
124
      {
125
         printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
126
         kfree(MTD);
127
         return 0;
128
      }
129
   }
130
 
131
   /* Generate a part name that includes the number of different chips and
132
      other configuration information */
133
   count = 1;
134
   strncpy(Part,map->name,sizeof(Part)-10);
135
   Part[sizeof(Part)-11] = 0;
136
   strcat(Part," ");
137
   Uniq = 0;
138
   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
139
   {
140
      const struct JEDECTable *JEDEC;
141
 
142
      if (priv->chips[I+1].jedec == priv->chips[I].jedec)
143
      {
144
         count++;
145
         continue;
146
      }
147
 
148
      // Locate the chip in the jedec table
149
      JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
150
      if (JEDEC == 0)
151
      {
152
         printk("mtd: Internal Error, JEDEC not set\n");
153
         kfree(MTD);
154
         return 0;
155
      }
156
 
157
      if (Uniq != 0)
158
         strcat(Part,",");
159
      Uniq++;
160
 
161
      if (count != 1)
162
         sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
163
      else
164
         sprintf(Part+strlen(Part),"%s",JEDEC->name);
165
      if (strlen(Part) > sizeof(Part)*2/3)
166
         break;
167
      count = 1;
168
   }
169
 
170
   /* Determine if the chips are organized in a linear fashion, or if there
171
      are empty banks. Note, the last bank does not count here, only the
172
      first banks are important. Holes on non-bank boundaries can not exist
173
      due to the way the detection algorithm works. */
174
   if (priv->size < my_bank_size)
175
      my_bank_size = priv->size;
176
   priv->is_banked = 0;
177
   //printk("priv->size is %x, my_bank_size is %x\n",priv->size,my_bank_size);
178
   //printk("priv->bank_fill[0] is %x\n",priv->bank_fill[0]);
179
   if (!priv->size) {
180
           printk("priv->size is zero\n");
181
           kfree(MTD);
182
           return 0;
183
   }
184
   if (priv->size/my_bank_size) {
185
           if (priv->size/my_bank_size == 1) {
186
                   priv->size = my_bank_size;
187
           }
188
           else {
189
                   for (I = 0; I != priv->size/my_bank_size - 1; I++)
190
                   {
191
                      if (priv->bank_fill[I] != my_bank_size)
192
                         priv->is_banked = 1;
193
 
194
                      /* This even could be eliminated, but new de-optimized read/write
195
                         functions have to be written */
196
                      printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
197
                      if (priv->bank_fill[I] != priv->bank_fill[0])
198
                      {
199
                         printk("mtd: Failed. Cannot handle unsymmetric banking\n");
200
                         kfree(MTD);
201
                         return 0;
202
                      }
203
                   }
204
           }
205
   }
206
   if (priv->is_banked == 1)
207
      strcat(Part,", banked");
208
 
209
   //   printk("Part: '%s'\n",Part);
210
 
211
   memset(MTD,0,sizeof(*MTD));
212
  // strncpy(MTD->name,Part,sizeof(MTD->name));
213
  // MTD->name[sizeof(MTD->name)-1] = 0;
214
   MTD->name = map->name;
215
   MTD->type = MTD_NORFLASH;
216
   MTD->flags = MTD_CAP_NORFLASH;
217
   MTD->erasesize = SectorSize*(map->buswidth);
218
   //   printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize);
219
   MTD->size = priv->size;
220
   //   printk("MTD->size is %x\n",(unsigned int)MTD->size);
221
   //MTD->module = THIS_MODULE; // ? Maybe this should be the low level module?
222
   MTD->erase = flash_erase;
223
   if (priv->is_banked == 1)
224
      MTD->read = jedec_read_banked;
225
   else
226
      MTD->read = jedec_read;
227
   MTD->write = flash_write;
228
   MTD->sync = jedec_sync;
229
   MTD->priv = map;
230
   map->fldrv_priv = priv;
231
   map->fldrv = &jedec_chipdrv;
232
   MOD_INC_USE_COUNT;
233
   return MTD;
234
}
235
 
236
/* Helper for the JEDEC function, JEDEC numbers all have odd parity */
237
static int checkparity(u_char C)
238
{
239
   u_char parity = 0;
240
   while (C != 0)
241
   {
242
      parity ^= C & 1;
243
      C >>= 1;
244
   }
245
 
246
   return parity == 1;
247
}
248
 
249
 
250
/* Take an array of JEDEC numbers that represent interleved flash chips
251
   and process them. Check to make sure they are good JEDEC numbers, look
252
   them up and then add them to the chip list */
253
static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
254
                  unsigned long base,struct jedec_private *priv)
255
{
256
   unsigned I,J;
257
   unsigned long Size;
258
   unsigned long SectorSize;
259
   const struct JEDECTable *JEDEC;
260
 
261
   // Test #2 JEDEC numbers exhibit odd parity
262
   for (I = 0; I != Count; I++)
263
   {
264
      if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
265
         return 0;
266
   }
267
 
268
   // Finally, just make sure all the chip sizes are the same
269
   JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
270
 
271
   if (JEDEC == 0)
272
   {
273
      printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
274
      return 0;
275
   }
276
 
277
   Size = JEDEC->size;
278
   SectorSize = JEDEC->sectorsize;
279
   for (I = 0; I != Count; I++)
280
   {
281
      JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
282
      if (JEDEC == 0)
283
      {
284
         printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
285
         return 0;
286
      }
287
 
288
      if (Size != JEDEC->size || SectorSize != JEDEC->sectorsize)
289
      {
290
         printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
291
         return 0;
292
      }
293
   }
294
 
295
   // Load the Chips
296
   for (I = 0; I != MAX_JEDEC_CHIPS; I++)
297
   {
298
      if (priv->chips[I].jedec == 0)
299
         break;
300
   }
301
 
302
   if (I + Count > MAX_JEDEC_CHIPS)
303
   {
304
      printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
305
      return 0;
306
   }
307
 
308
   // Add them to the table
309
   for (J = 0; J != Count; J++)
310
   {
311
      unsigned long Bank;
312
 
313
      JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
314
      priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
315
      priv->chips[I].size = JEDEC->size;
316
      priv->chips[I].sectorsize = JEDEC->sectorsize;
317
      priv->chips[I].base = base + J;
318
      priv->chips[I].datashift = J*8;
319
      priv->chips[I].capabilities = JEDEC->capabilities;
320
      priv->chips[I].offset = priv->size + J;
321
 
322
      // log2 n :|
323
      priv->chips[I].addrshift = 0;
324
      for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
325
 
326
      // Determine how filled this bank is.
327
      Bank = base & (~(my_bank_size-1));
328
      if (priv->bank_fill[Bank/my_bank_size] < base +
329
          (JEDEC->size << priv->chips[I].addrshift) - Bank)
330
         priv->bank_fill[Bank/my_bank_size] =  base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
331
      I++;
332
   }
333
 
334
   priv->size += priv->chips[I-1].size*Count;
335
 
336
   return priv->chips[I-1].size;
337
}
338
 
339
/* Lookup the chip information from the JEDEC ID table. */
340
static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
341
{
342
   __u16 Id = (mfr << 8) | id;
343
   unsigned long I = 0;
344
   for (I = 0; JEDEC_table[I].jedec != 0; I++)
345
      if (JEDEC_table[I].jedec == Id)
346
         return JEDEC_table + I;
347
   return 0;
348
}
349
 
350
// Look for flash using an 8 bit bus interface
351
static int jedec_probe8(struct map_info *map,unsigned long base,
352
                  struct jedec_private *priv)
353
{
354
   #define flread(x) map->read8(map,base+x)
355
   #define flwrite(v,x) map->write8(map,v,base+x)
356
 
357
   const unsigned long AutoSel1 = 0xAA;
358
   const unsigned long AutoSel2 = 0x55;
359
   const unsigned long AutoSel3 = 0x90;
360
   const unsigned long Reset = 0xF0;
361
   __u32 OldVal;
362
   __u8 Mfg[1];
363
   __u8 Id[1];
364
   unsigned I;
365
   unsigned long Size;
366
 
367
   // Wait for any write/erase operation to settle
368
   OldVal = flread(base);
369
   for (I = 0; OldVal != flread(base) && I < 10000; I++)
370
      OldVal = flread(base);
371
 
372
   // Reset the chip
373
   flwrite(Reset,0x555);
374
 
375
   // Send the sequence
376
   flwrite(AutoSel1,0x555);
377
   flwrite(AutoSel2,0x2AA);
378
   flwrite(AutoSel3,0x555);
379
 
380
   //  Get the JEDEC numbers
381
   Mfg[0] = flread(0);
382
   Id[0] = flread(1);
383
   //   printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
384
 
385
   Size = handle_jedecs(map,Mfg,Id,1,base,priv);
386
   //   printk("handle_jedecs Size is %x\n",(unsigned int)Size);
387
   if (Size == 0)
388
   {
389
      flwrite(Reset,0x555);
390
      return 0;
391
   }
392
 
393
 
394
   // Reset.
395
   flwrite(Reset,0x555);
396
 
397
   return 1;
398
 
399
   #undef flread
400
   #undef flwrite
401
}
402
 
403
// Look for flash using a 16 bit bus interface (ie 2 8-bit chips)
404
static int jedec_probe16(struct map_info *map,unsigned long base,
405
                  struct jedec_private *priv)
406
{
407
   return 0;
408
}
409
 
410
// Look for flash using a 32 bit bus interface (ie 4 8-bit chips)
411
static int jedec_probe32(struct map_info *map,unsigned long base,
412
                  struct jedec_private *priv)
413
{
414
   #define flread(x) map->read32(map,base+((x)<<2))
415
   #define flwrite(v,x) map->write32(map,v,base+((x)<<2))
416
 
417
   const unsigned long AutoSel1 = 0xAAAAAAAA;
418
   const unsigned long AutoSel2 = 0x55555555;
419
   const unsigned long AutoSel3 = 0x90909090;
420
   const unsigned long Reset = 0xF0F0F0F0;
421
   __u32 OldVal;
422
   __u8 Mfg[4];
423
   __u8 Id[4];
424
   unsigned I;
425
   unsigned long Size;
426
 
427
   // Wait for any write/erase operation to settle
428
   OldVal = flread(base);
429
   for (I = 0; OldVal != flread(base) && I < 10000; I++)
430
      OldVal = flread(base);
431
 
432
   // Reset the chip
433
   flwrite(Reset,0x555);
434
 
435
   // Send the sequence
436
   flwrite(AutoSel1,0x555);
437
   flwrite(AutoSel2,0x2AA);
438
   flwrite(AutoSel3,0x555);
439
 
440
   // Test #1, JEDEC numbers are readable from 0x??00/0x??01
441
   if (flread(0) != flread(0x100) ||
442
       flread(1) != flread(0x101))
443
   {
444
      flwrite(Reset,0x555);
445
      return 0;
446
   }
447
 
448
   // Split up the JEDEC numbers
449
   OldVal = flread(0);
450
   for (I = 0; I != 4; I++)
451
      Mfg[I] = (OldVal >> (I*8));
452
   OldVal = flread(1);
453
   for (I = 0; I != 4; I++)
454
      Id[I] = (OldVal >> (I*8));
455
 
456
   Size = handle_jedecs(map,Mfg,Id,4,base,priv);
457
   if (Size == 0)
458
   {
459
      flwrite(Reset,0x555);
460
      return 0;
461
   }
462
 
463
   /* Check if there is address wrap around within a single bank, if this
464
      returns JEDEC numbers then we assume that it is wrap around. Notice
465
      we call this routine with the JEDEC return still enabled, if two or
466
      more flashes have a truncated address space the probe test will still
467
      work */
468
   if (base + (Size<<2)+0x555 < map->size &&
469
       base + (Size<<2)+0x555 < (base & (~(my_bank_size-1))) + my_bank_size)
470
   {
471
      if (flread(base+Size) != flread(base+Size + 0x100) ||
472
          flread(base+Size + 1) != flread(base+Size + 0x101))
473
      {
474
         jedec_probe32(map,base+Size,priv);
475
      }
476
   }
477
 
478
   // Reset.
479
   flwrite(0xF0F0F0F0,0x555);
480
 
481
   return 1;
482
 
483
   #undef flread
484
   #undef flwrite
485
}
486
 
487
/* Linear read. */
488
static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
489
                      size_t *retlen, u_char *buf)
490
{
491
   struct map_info *map = (struct map_info *)mtd->priv;
492
 
493
   map->copy_from(map, buf, from, len);
494
   *retlen = len;
495
   return 0;
496
}
497
 
498
/* Banked read. Take special care to jump past the holes in the bank
499
   mapping. This version assumes symetry in the holes.. */
500
static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
501
                             size_t *retlen, u_char *buf)
502
{
503
   struct map_info *map = (struct map_info *)mtd->priv;
504
   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
505
 
506
   *retlen = 0;
507
   while (len > 0)
508
   {
509
      // Determine what bank and offset into that bank the first byte is
510
      unsigned long bank = from & (~(priv->bank_fill[0]-1));
511
      unsigned long offset = from & (priv->bank_fill[0]-1);
512
      unsigned long get = len;
513
      if (priv->bank_fill[0] - offset < len)
514
         get = priv->bank_fill[0] - offset;
515
 
516
      bank /= priv->bank_fill[0];
517
      map->copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
518
 
519
      len -= get;
520
      *retlen += get;
521
      from += get;
522
   }
523
   return 0;
524
}
525
 
526
/* Pass the flags value that the flash return before it re-entered read
527
   mode. */
528
static void jedec_flash_failed(unsigned char code)
529
{
530
   /* Bit 5 being high indicates that there was an internal device
531
      failure, erasure time limits exceeded or something */
532
   if ((code & (1 << 5)) != 0)
533
   {
534
      printk("mtd: Internal Flash failure\n");
535
      return;
536
   }
537
   printk("mtd: Programming didn't take\n");
538
}
539
 
540
/* This uses the erasure function described in the AMD Flash Handbook,
541
   it will work for flashes with a fixed sector size only. Flashes with
542
   a selection of sector sizes (ie the AMD Am29F800B) will need a different
543
   routine. This routine tries to parallize erasing multiple chips/sectors
544
   where possible */
545
static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
546
{
547
   // Does IO to the currently selected chip
548
   #define flread(x) map->read8(map,chip->base+((x)<<chip->addrshift))
549
   #define flwrite(v,x) map->write8(map,v,chip->base+((x)<<chip->addrshift))
550
 
551
   unsigned long Time = 0;
552
   unsigned long NoTime = 0;
553
   unsigned long start = instr->addr, len = instr->len;
554
   unsigned int I;
555
   struct map_info *map = (struct map_info *)mtd->priv;
556
   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
557
 
558
   // Verify the arguments..
559
   if (start + len > mtd->size ||
560
       (start % mtd->erasesize) != 0 ||
561
       (len % mtd->erasesize) != 0 ||
562
       (len/mtd->erasesize) == 0)
563
      return -EINVAL;
564
 
565
   jedec_flash_chip_scan(priv,start,len);
566
 
567
   // Start the erase sequence on each chip
568
   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
569
   {
570
      unsigned long off;
571
      struct jedec_flash_chip *chip = priv->chips + I;
572
 
573
      if (chip->length == 0)
574
         continue;
575
 
576
      if (chip->start + chip->length > chip->size)
577
      {
578
         printk("DIE\n");
579
         return -EIO;
580
      }
581
 
582
      flwrite(0xF0,chip->start + 0x555);
583
      flwrite(0xAA,chip->start + 0x555);
584
      flwrite(0x55,chip->start + 0x2AA);
585
      flwrite(0x80,chip->start + 0x555);
586
      flwrite(0xAA,chip->start + 0x555);
587
      flwrite(0x55,chip->start + 0x2AA);
588
 
589
      /* Once we start selecting the erase sectors the delay between each
590
         command must not exceed 50us or it will immediately start erasing
591
         and ignore the other sectors */
592
      for (off = 0; off < len; off += chip->sectorsize)
593
      {
594
         // Check to make sure we didn't timeout
595
         flwrite(0x30,chip->start + off);
596
         if (off == 0)
597
            continue;
598
         if ((flread(chip->start + off) & (1 << 3)) != 0)
599
         {
600
            printk("mtd: Ack! We timed out the erase timer!\n");
601
            return -EIO;
602
         }
603
      }
604
   }
605
 
606
   /* We could split this into a timer routine and return early, performing
607
      background erasure.. Maybe later if the need warrents */
608
 
609
   /* Poll the flash for erasure completion, specs say this can take as long
610
      as 480 seconds to do all the sectors (for a 2 meg flash).
611
      Erasure time is dependant on chip age, temp and wear.. */
612
 
613
   /* This being a generic routine assumes a 32 bit bus. It does read32s
614
      and bundles interleved chips into the same grouping. This will work
615
      for all bus widths */
616
   Time = 0;
617
   NoTime = 0;
618
   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
619
   {
620
      struct jedec_flash_chip *chip = priv->chips + I;
621
      unsigned long off = 0;
622
      unsigned todo[4] = {0,0,0,0};
623
      unsigned todo_left = 0;
624
      unsigned J;
625
 
626
      if (chip->length == 0)
627
         continue;
628
 
629
      /* Find all chips in this data line, realistically this is all
630
         or nothing up to the interleve count */
631
      for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
632
      {
633
         if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
634
             (chip->base & (~((1<<chip->addrshift)-1))))
635
         {
636
            todo_left++;
637
            todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
638
         }
639
      }
640
 
641
      /*      printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
642
              (short)todo[2],(short)todo[3]);
643
      */
644
      while (1)
645
      {
646
         __u32 Last[4];
647
         unsigned long Count = 0;
648
 
649
         /* During erase bit 7 is held low and bit 6 toggles, we watch this,
650
            should it stop toggling or go high then the erase is completed,
651
            or this is not really flash ;> */
652
         switch (map->buswidth) {
653
         case 1:
654
            Last[0] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
655
            Last[1] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
656
            Last[2] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
657
            break;
658
         case 2:
659
            Last[0] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
660
            Last[1] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
661
            Last[2] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
662
            break;
663
         case 3:
664
            Last[0] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
665
            Last[1] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
666
            Last[2] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
667
            break;
668
         }
669
         Count = 3;
670
         while (todo_left != 0)
671
         {
672
            for (J = 0; J != 4; J++)
673
            {
674
               __u8 Byte1 = (Last[(Count-1)%4] >> (J*8)) & 0xFF;
675
               __u8 Byte2 = (Last[(Count-2)%4] >> (J*8)) & 0xFF;
676
               __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
677
               if (todo[J] == 0)
678
                  continue;
679
 
680
               if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
681
               {
682
//                printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
683
                  continue;
684
               }
685
 
686
               if (Byte1 == Byte2)
687
               {
688
                  jedec_flash_failed(Byte3);
689
                  return -EIO;
690
               }
691
 
692
               todo[J] = 0;
693
               todo_left--;
694
            }
695
 
696
/*          if (NoTime == 0)
697
               Time += HZ/10 - schedule_timeout(HZ/10);*/
698
            NoTime = 0;
699
 
700
            switch (map->buswidth) {
701
            case 1:
702
               Last[Count % 4] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
703
              break;
704
            case 2:
705
               Last[Count % 4] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
706
              break;
707
            case 4:
708
               Last[Count % 4] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
709
              break;
710
            }
711
            Count++;
712
 
713
/*          // Count time, max of 15s per sector (according to AMD)
714
            if (Time > 15*len/mtd->erasesize*HZ)
715
            {
716
               printk("mtd: Flash Erase Timed out\n");
717
               return -EIO;
718
            }       */
719
         }
720
 
721
         // Skip to the next chip if we used chip erase
722
         if (chip->length == chip->size)
723
            off = chip->size;
724
         else
725
            off += chip->sectorsize;
726
 
727
         if (off >= chip->length)
728
            break;
729
         NoTime = 1;
730
      }
731
 
732
      for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
733
      {
734
         if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
735
             (chip->base & (~((1<<chip->addrshift)-1))))
736
            priv->chips[J].length = 0;
737
      }
738
   }
739
 
740
   //printk("done\n");
741
   instr->state = MTD_ERASE_DONE;
742
   if (instr->callback)
743
        instr->callback(instr);
744
   return 0;
745
 
746
   #undef flread
747
   #undef flwrite
748
}
749
 
750
/* This is the simple flash writing function. It writes to every byte, in
751
   sequence. It takes care of how to properly address the flash if
752
   the flash is interleved. It can only be used if all the chips in the
753
   array are identical!*/
754
static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
755
                       size_t *retlen, const u_char *buf)
756
{
757
   /* Does IO to the currently selected chip. It takes the bank addressing
758
      base (which is divisable by the chip size) adds the necesary lower bits
759
      of addrshift (interleve index) and then adds the control register index. */
760
   #define flread(x) map->read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
761
   #define flwrite(v,x) map->write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
762
 
763
   struct map_info *map = (struct map_info *)mtd->priv;
764
   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
765
   unsigned long base;
766
   unsigned long off;
767
   size_t save_len = len;
768
 
769
   if (start + len > mtd->size)
770
      return -EIO;
771
 
772
   //printk("Here");
773
 
774
   //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
775
   while (len != 0)
776
   {
777
      struct jedec_flash_chip *chip = priv->chips;
778
      unsigned long bank;
779
      unsigned long boffset;
780
 
781
      // Compute the base of the flash.
782
      off = ((unsigned long)start) % (chip->size << chip->addrshift);
783
      base = start - off;
784
 
785
      // Perform banked addressing translation.
786
      bank = base & (~(priv->bank_fill[0]-1));
787
      boffset = base & (priv->bank_fill[0]-1);
788
      bank = (bank/priv->bank_fill[0])*my_bank_size;
789
      base = bank + boffset;
790
 
791
    //  printk("Flasing %X %X %X\n",base,chip->size,len);
792
     // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
793
 
794
      // Loop over this page
795
      for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
796
      {
797
         unsigned char oldbyte = map->read8(map,base+off);
798
         unsigned char Last[4];
799
         unsigned long Count = 0;
800
 
801
         if (oldbyte == *buf) {
802
        //       printk("oldbyte and *buf is %x,len is %x\n",oldbyte,len);
803
            continue;
804
         }
805
         if (((~oldbyte) & *buf) != 0)
806
            printk("mtd: warn: Trying to set a 0 to a 1\n");
807
 
808
         // Write
809
         flwrite(0xAA,0x555);
810
         flwrite(0x55,0x2AA);
811
         flwrite(0xA0,0x555);
812
         map->write8(map,*buf,base + off);
813
         Last[0] = map->read8(map,base + off);
814
         Last[1] = map->read8(map,base + off);
815
         Last[2] = map->read8(map,base + off);
816
 
817
         /* Wait for the flash to finish the operation. We store the last 4
818
            status bytes that have been retrieved so we can determine why
819
            it failed. The toggle bits keep toggling when there is a
820
            failure */
821
         for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
822
              Count < 10000; Count++)
823
            Last[Count % 4] = map->read8(map,base + off);
824
         if (Last[(Count - 1) % 4] != *buf)
825
         {
826
            jedec_flash_failed(Last[(Count - 3) % 4]);
827
            return -EIO;
828
         }
829
      }
830
   }
831
   *retlen = save_len;
832
   return 0;
833
}
834
 
835
/* This is used to enhance the speed of the erase routine,
836
   when things are being done to multiple chips it is possible to
837
   parallize the operations, particularly full memory erases of multi
838
   chip memories benifit */
839
static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,
840
                     unsigned long len)
841
{
842
   unsigned int I;
843
 
844
   // Zero the records
845
   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
846
      priv->chips[I].start = priv->chips[I].length = 0;
847
 
848
   // Intersect the region with each chip
849
   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
850
   {
851
      struct jedec_flash_chip *chip = priv->chips + I;
852
      unsigned long ByteStart;
853
      unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
854
 
855
      // End is before this chip or the start is after it
856
      if (start+len < chip->offset ||
857
          ChipEndByte - (1 << chip->addrshift) < start)
858
         continue;
859
 
860
      if (start < chip->offset)
861
      {
862
         ByteStart = chip->offset;
863
         chip->start = 0;
864
      }
865
      else
866
      {
867
         chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;
868
         ByteStart = start;
869
      }
870
 
871
      if (start + len >= ChipEndByte)
872
         chip->length = (ChipEndByte - ByteStart) >> chip->addrshift;
873
      else
874
         chip->length = (start + len - ByteStart + (1 << chip->addrshift)-1) >> chip->addrshift;
875
   }
876
}
877
 
878
int __init jedec_init(void)
879
{
880
        register_mtd_chip_driver(&jedec_chipdrv);
881
        return 0;
882
}
883
 
884
static void __exit jedec_exit(void)
885
{
886
        unregister_mtd_chip_driver(&jedec_chipdrv);
887
}
888
 
889
module_init(jedec_init);
890
module_exit(jedec_exit);
891
 
892
MODULE_LICENSE("GPL");
893
MODULE_AUTHOR("Jason Gunthorpe <jgg@deltatee.com> et al.");
894
MODULE_DESCRIPTION("Old MTD chip driver for JEDEC-compliant flash chips");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.