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