cleanup
[linux-2.4.21-pre4.git] / drivers / mtd / chips / sharp.c
1 /*
2  * MTD chip driver for pre-CFI Sharp flash chips
3  *
4  * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
5  *           2000,2001 Lineo, Inc.
6  *
7  * $Id: sharp.c,v 1.1.1.1 2005/04/11 02:50:25 jack Exp $
8  *
9  * Devices supported:
10  *   LH28F016SCT Symmetrical block flash memory, 2Mx8
11  *   LH28F008SCT Symmetrical block flash memory, 1Mx8
12  *
13  * Documentation:
14  *   http://www.sharpmeg.com/datasheets/memic/flashcmp/
15  *   http://www.sharpmeg.com/datasheets/memic/flashcmp/01symf/16m/016sctl9.pdf
16  *   016sctl9.pdf
17  *
18  * Limitations:
19  *   This driver only supports 4x1 arrangement of chips.
20  *   Not tested on anything but PowerPC.
21  */
22
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/version.h>
26 #include <linux/types.h>
27 #include <linux/sched.h>
28 #include <linux/errno.h>
29 #include <linux/interrupt.h>
30 #include <linux/mtd/map.h>
31 #include <linux/mtd/cfi.h>
32 #include <linux/delay.h>
33
34 #define CMD_RESET               0xffffffff
35 #define CMD_READ_ID             0x90909090
36 #define CMD_READ_STATUS         0x70707070
37 #define CMD_CLEAR_STATUS        0x50505050
38 #define CMD_BLOCK_ERASE_1       0x20202020
39 #define CMD_BLOCK_ERASE_2       0xd0d0d0d0
40 #define CMD_BYTE_WRITE          0x40404040
41 #define CMD_SUSPEND             0xb0b0b0b0
42 #define CMD_RESUME              0xd0d0d0d0
43 #define CMD_SET_BLOCK_LOCK_1    0x60606060
44 #define CMD_SET_BLOCK_LOCK_2    0x01010101
45 #define CMD_SET_MASTER_LOCK_1   0x60606060
46 #define CMD_SET_MASTER_LOCK_2   0xf1f1f1f1
47 #define CMD_CLEAR_BLOCK_LOCKS_1 0x60606060
48 #define CMD_CLEAR_BLOCK_LOCKS_2 0xd0d0d0d0
49
50 #define SR_READY                0x80808080 // 1 = ready
51 #define SR_ERASE_SUSPEND        0x40404040 // 1 = block erase suspended
52 #define SR_ERROR_ERASE          0x20202020 // 1 = error in block erase or clear lock bits
53 #define SR_ERROR_WRITE          0x10101010 // 1 = error in byte write or set lock bit
54 #define SR_VPP                  0x08080808 // 1 = Vpp is low
55 #define SR_WRITE_SUSPEND        0x04040404 // 1 = byte write suspended
56 #define SR_PROTECT              0x02020202 // 1 = lock bit set
57 #define SR_RESERVED             0x01010101
58
59 #define SR_ERRORS (SR_ERROR_ERASE|SR_ERROR_WRITE|SR_VPP|SR_PROTECT)
60
61 /* Configuration options */
62
63 #undef AUTOUNLOCK  /* automatically unlocks blocks before erasing */
64
65 struct mtd_info *sharp_probe(struct map_info *);
66
67 static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);
68
69 static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
70         size_t *retlen, u_char *buf);
71 static int sharp_write(struct mtd_info *mtd, loff_t from, size_t len,
72         size_t *retlen, const u_char *buf);
73 static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr);
74 static void sharp_sync(struct mtd_info *mtd);
75 static int sharp_suspend(struct mtd_info *mtd);
76 static void sharp_resume(struct mtd_info *mtd);
77 static void sharp_destroy(struct mtd_info *mtd);
78
79 static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
80         unsigned long adr, __u32 datum);
81 static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
82         unsigned long adr);
83 #ifdef AUTOUNLOCK
84 static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
85         unsigned long adr);
86 #endif
87
88
89 struct sharp_info{
90         struct flchip *chip;
91         int bogus;
92         int chipshift;
93         int numchips;
94         struct flchip chips[1];
95 };
96
97 struct mtd_info *sharp_probe(struct map_info *map);
98 static void sharp_destroy(struct mtd_info *mtd);
99
100 static struct mtd_chip_driver sharp_chipdrv = {
101         probe: sharp_probe,
102         destroy: sharp_destroy,
103         name: "sharp",
104         module: THIS_MODULE
105 };
106
107
108 struct mtd_info *sharp_probe(struct map_info *map)
109 {
110         struct mtd_info *mtd = NULL;
111         struct sharp_info *sharp = NULL;
112         int width;
113
114         mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
115         if(!mtd)
116                 return NULL;
117
118         sharp = kmalloc(sizeof(*sharp), GFP_KERNEL);
119         if(!sharp)
120                 return NULL;
121
122         memset(mtd, 0, sizeof(*mtd));
123
124         width = sharp_probe_map(map,mtd);
125         if(!width){
126                 kfree(mtd);
127                 kfree(sharp);
128                 return NULL;
129         }
130
131         mtd->priv = map;
132         mtd->type = MTD_NORFLASH;
133         mtd->erase = sharp_erase;
134         mtd->read = sharp_read;
135         mtd->write = sharp_write;
136         mtd->sync = sharp_sync;
137         mtd->suspend = sharp_suspend;
138         mtd->resume = sharp_resume;
139         mtd->flags = MTD_CAP_NORFLASH;
140         mtd->name = map->name;
141
142         memset(sharp, 0, sizeof(*sharp));
143         sharp->chipshift = 23;
144         sharp->numchips = 1;
145         sharp->chips[0].start = 0;
146         sharp->chips[0].state = FL_READY;
147         sharp->chips[0].mutex = &sharp->chips[0]._spinlock;
148         sharp->chips[0].word_write_time = 0;
149         init_waitqueue_head(&sharp->chips[0].wq);
150         spin_lock_init(&sharp->chips[0]._spinlock);
151
152         map->fldrv = &sharp_chipdrv;
153         map->fldrv_priv = sharp;
154
155         MOD_INC_USE_COUNT;
156         return mtd;
157 }
158
159 static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
160 {
161         unsigned long tmp;
162         unsigned long base = 0;
163         u32 read0, read4;
164         int width = 4;
165
166         tmp = map->read32(map, base+0);
167
168         map->write32(map, CMD_READ_ID, base+0);
169
170         read0=map->read32(map, base+0);
171         read4=map->read32(map, base+4);
172         if(read0 == 0x89898989){
173                 printk("Looks like sharp flash\n");
174                 switch(read4){
175                 case 0xaaaaaaaa:
176                 case 0xa0a0a0a0:
177                         /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
178                         /* a0 - LH28F016SCT-Z4  2Mx8, 32 64k blocks*/
179                         mtd->erasesize = 0x10000 * width;
180                         mtd->size = 0x200000 * width;
181                         return width;
182                 case 0xa6a6a6a6:
183                         /* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/
184                         /* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/
185                         mtd->erasesize = 0x10000 * width;
186                         mtd->size = 0x100000 * width;
187                         return width;
188 #if 0
189                 case 0x00000000: /* unknown */
190                         /* XX - LH28F004SCT 512kx8, 8 64k blocks*/
191                         mtd->erasesize = 0x10000 * width;
192                         mtd->size = 0x80000 * width;
193                         return width;
194 #endif
195                 default:
196                         printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n",
197                                 read0,read4);
198                 }
199         }else if((map->read32(map, base+0) == CMD_READ_ID)){
200                 /* RAM, probably */
201                 printk("Looks like RAM\n");
202                 map->write32(map, tmp, base+0);
203         }else{
204                 printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n",
205                         read0,read4);
206         }
207
208         return 0;
209 }
210
211 /* This function returns with the chip->mutex lock held. */
212 static int sharp_wait(struct map_info *map, struct flchip *chip)
213 {
214         __u16 status;
215         unsigned long timeo = jiffies + HZ;
216         DECLARE_WAITQUEUE(wait, current);
217         int adr = 0;
218
219 retry:
220         spin_lock_bh(chip->mutex);
221
222         switch(chip->state){
223         case FL_READY:
224                 map->write32(map,CMD_READ_STATUS,adr);
225                 chip->state = FL_STATUS;
226         case FL_STATUS:
227                 status = map->read32(map,adr);
228 //printk("status=%08x\n",status);
229
230                 udelay(100);
231                 if((status & SR_READY)!=SR_READY){
232 //printk(".status=%08x\n",status);
233                         udelay(100);
234                 }
235                 break;
236         default:
237                 printk("Waiting for chip\n");
238
239                 set_current_state(TASK_INTERRUPTIBLE);
240                 add_wait_queue(&chip->wq, &wait);
241
242                 spin_unlock_bh(chip->mutex);
243
244                 schedule();
245                 remove_wait_queue(&chip->wq, &wait);
246
247                 if(signal_pending(current))
248                         return -EINTR;
249
250                 timeo = jiffies + HZ;
251
252                 goto retry;
253         }
254
255         map->write32(map,CMD_RESET, adr);
256
257         chip->state = FL_READY;
258
259         return 0;
260 }
261
262 static void sharp_release(struct flchip *chip)
263 {
264         wake_up(&chip->wq);
265         spin_unlock_bh(chip->mutex);
266 }
267
268 static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
269         size_t *retlen, u_char *buf)
270 {
271         struct map_info *map = mtd->priv;
272         struct sharp_info *sharp = map->fldrv_priv;
273         int chipnum;
274         int ret = 0;
275         int ofs = 0;
276
277         chipnum = (from >> sharp->chipshift);
278         ofs = from & ((1 << sharp->chipshift)-1);
279
280         *retlen = 0;
281
282         while(len){
283                 unsigned long thislen;
284
285                 if(chipnum>=sharp->numchips)
286                         break;
287
288                 thislen = len;
289                 if(ofs+thislen >= (1<<sharp->chipshift))
290                         thislen = (1<<sharp->chipshift) - ofs;
291
292                 ret = sharp_wait(map,&sharp->chips[chipnum]);
293                 if(ret<0)
294                         break;
295
296                 map->copy_from(map,buf,ofs,thislen);
297
298                 sharp_release(&sharp->chips[chipnum]);
299
300                 *retlen += thislen;
301                 len -= thislen;
302                 buf += thislen;
303
304                 ofs = 0;
305                 chipnum++;
306         }
307         return ret;
308 }
309
310 static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len,
311         size_t *retlen, const u_char *buf)
312 {
313         struct map_info *map = mtd->priv;
314         struct sharp_info *sharp = map->fldrv_priv;
315         int ret = 0;
316         int i,j;
317         int chipnum;
318         unsigned long ofs;
319         union { u32 l; unsigned char uc[4]; } tbuf;
320
321         *retlen = 0;
322
323         while(len){
324                 tbuf.l = 0xffffffff;
325                 chipnum = to >> sharp->chipshift;
326                 ofs = to & ((1<<sharp->chipshift)-1);
327
328                 j=0;
329                 for(i=ofs&3;i<4 && len;i++){
330                         tbuf.uc[i] = *buf;
331                         buf++;
332                         to++;
333                         len--;
334                         j++;
335                 }
336                 sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l);
337                 if(ret<0)
338                         return ret;
339                 (*retlen)+=j;
340         }
341
342         return 0;
343 }
344
345 static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
346         unsigned long adr, __u32 datum)
347 {
348         int ret;
349         int timeo;
350         int try;
351         int i;
352         int status = 0;
353
354         ret = sharp_wait(map,chip);
355
356         for(try=0;try<10;try++){
357                 map->write32(map,CMD_BYTE_WRITE,adr);
358                 /* cpu_to_le32 -> hack to fix the writel be->le conversion */
359                 map->write32(map,cpu_to_le32(datum),adr);
360
361                 chip->state = FL_WRITING;
362
363                 timeo = jiffies + (HZ/2);
364
365                 map->write32(map,CMD_READ_STATUS,adr);
366                 for(i=0;i<100;i++){
367                         status = map->read32(map,adr);
368                         if((status & SR_READY)==SR_READY)
369                                 break;
370                 }
371                 if(i==100){
372                         printk("sharp: timed out writing\n");
373                 }
374
375                 if(!(status&SR_ERRORS))
376                         break;
377
378                 printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status);
379
380                 map->write32(map,CMD_CLEAR_STATUS,adr);
381         }
382         map->write32(map,CMD_RESET,adr);
383         chip->state = FL_READY;
384
385         wake_up(&chip->wq);
386         spin_unlock_bh(chip->mutex);
387
388         return 0;
389 }
390
391 static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
392 {
393         struct map_info *map = mtd->priv;
394         struct sharp_info *sharp = map->fldrv_priv;
395         unsigned long adr,len;
396         int chipnum, ret=0;
397
398 //printk("sharp_erase()\n");
399         if(instr->addr & (mtd->erasesize - 1))
400                 return -EINVAL;
401         if(instr->len & (mtd->erasesize - 1))
402                 return -EINVAL;
403         if(instr->len + instr->addr > mtd->size)
404                 return -EINVAL;
405
406         chipnum = instr->addr >> sharp->chipshift;
407         adr = instr->addr & ((1<<sharp->chipshift)-1);
408         len = instr->len;
409
410         while(len){
411                 ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr);
412                 if(ret)return ret;
413
414                 adr += mtd->erasesize;
415                 len -= mtd->erasesize;
416                 if(adr >> sharp->chipshift){
417                         adr = 0;
418                         chipnum++;
419                         if(chipnum>=sharp->numchips)
420                                 break;
421                 }
422         }
423
424         instr->state = MTD_ERASE_DONE;
425         if(instr->callback)
426                 instr->callback(instr);
427
428         return 0;
429 }
430
431 static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
432         unsigned long adr)
433 {
434         int ret;
435         int timeo;
436         int status;
437         DECLARE_WAITQUEUE(wait, current);
438
439         map->write32(map,CMD_READ_STATUS,adr);
440         status = map->read32(map,adr);
441
442         timeo = jiffies + HZ;
443
444         while(time_before(jiffies, timeo)){
445                 map->write32(map,CMD_READ_STATUS,adr);
446                 status = map->read32(map,adr);
447                 if((status & SR_READY)==SR_READY){
448                         ret = 0;
449                         goto out;
450                 }
451                 set_current_state(TASK_INTERRUPTIBLE);
452                 add_wait_queue(&chip->wq, &wait);
453
454                 //spin_unlock_bh(chip->mutex);
455
456                 schedule_timeout(1);
457                 schedule();
458                 remove_wait_queue(&chip->wq, &wait);
459
460                 //spin_lock_bh(chip->mutex);
461                 
462                 if (signal_pending(current)){
463                         ret = -EINTR;
464                         goto out;
465                 }
466                 
467         }
468         ret = -ETIME;
469 out:
470         return ret;
471 }
472
473 static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
474         unsigned long adr)
475 {
476         int ret;
477         //int timeo;
478         int status;
479         //int i;
480
481 //printk("sharp_erase_oneblock()\n");
482
483 #ifdef AUTOUNLOCK
484         /* This seems like a good place to do an unlock */
485         sharp_unlock_oneblock(map,chip,adr);
486 #endif
487
488         map->write32(map,CMD_BLOCK_ERASE_1,adr);
489         map->write32(map,CMD_BLOCK_ERASE_2,adr);
490
491         chip->state = FL_ERASING;
492
493         ret = sharp_do_wait_for_ready(map,chip,adr);
494         if(ret<0)return ret;
495
496         map->write32(map,CMD_READ_STATUS,adr);
497         status = map->read32(map,adr);
498
499         if(!(status&SR_ERRORS)){
500                 map->write32(map,CMD_RESET,adr);
501                 chip->state = FL_READY;
502                 //spin_unlock_bh(chip->mutex);
503                 return 0;
504         }
505
506         printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status);
507         map->write32(map,CMD_CLEAR_STATUS,adr);
508
509         //spin_unlock_bh(chip->mutex);
510
511         return -EIO;
512 }
513
514 #ifdef AUTOUNLOCK
515 static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
516         unsigned long adr)
517 {
518         int i;
519         int status;
520
521         map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
522         map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
523
524         udelay(100);
525
526         status = map->read32(map,adr);
527         printk("status=%08x\n",status);
528
529         for(i=0;i<1000;i++){
530                 //map->write32(map,CMD_READ_STATUS,adr);
531                 status = map->read32(map,adr);
532                 if((status & SR_READY)==SR_READY)
533                         break;
534                 udelay(100);
535         }
536         if(i==1000){
537                 printk("sharp: timed out unlocking block\n");
538         }
539
540         if(!(status&SR_ERRORS)){
541                 map->write32(map,CMD_RESET,adr);
542                 chip->state = FL_READY;
543                 return;
544         }
545
546         printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status);
547         map->write32(map,CMD_CLEAR_STATUS,adr);
548 }
549 #endif
550
551 static void sharp_sync(struct mtd_info *mtd)
552 {
553         //printk("sharp_sync()\n");
554 }
555
556 static int sharp_suspend(struct mtd_info *mtd)
557 {
558         printk("sharp_suspend()\n");
559         return -EINVAL;
560 }
561
562 static void sharp_resume(struct mtd_info *mtd)
563 {
564         printk("sharp_resume()\n");
565         
566 }
567
568 static void sharp_destroy(struct mtd_info *mtd)
569 {
570         printk("sharp_destroy()\n");
571
572 }
573
574 int __init sharp_probe_init(void)
575 {
576         printk("MTD Sharp chip driver <ds@lineo.com>\n");
577
578         register_mtd_chip_driver(&sharp_chipdrv);
579
580         return 0;
581 }
582
583 static void __exit sharp_probe_exit(void)
584 {
585         unregister_mtd_chip_driver(&sharp_chipdrv);
586 }
587
588 module_init(sharp_probe_init);
589 module_exit(sharp_probe_exit);
590
591
592 MODULE_LICENSE("GPL");
593 MODULE_AUTHOR("David Schleef <ds@schleef.org>");
594 MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");