[TG3]: Add tagged status support.
[linux-2.6/verdex.git] / drivers / mtd / chips / sharp.c
blobc3cf0f63bc93639ad151a35b8867e554452548a7
1 /*
2 * MTD chip driver for pre-CFI Sharp flash chips
4 * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
5 * 2000,2001 Lineo, Inc.
7 * $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $
9 * Devices supported:
10 * LH28F016SCT Symmetrical block flash memory, 2Mx8
11 * LH28F008SCT Symmetrical block flash memory, 1Mx8
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
18 * Limitations:
19 * This driver only supports 4x1 arrangement of chips.
20 * Not tested on anything but PowerPC.
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>
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
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
60 #define SR_ERRORS (SR_ERROR_ERASE|SR_ERROR_WRITE|SR_VPP|SR_PROTECT)
62 /* Configuration options */
64 #undef AUTOUNLOCK /* automatically unlocks blocks before erasing */
66 struct mtd_info *sharp_probe(struct map_info *);
68 static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);
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);
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
90 struct sharp_info{
91 struct flchip *chip;
92 int bogus;
93 int chipshift;
94 int numchips;
95 struct flchip chips[1];
98 struct mtd_info *sharp_probe(struct map_info *map);
99 static void sharp_destroy(struct mtd_info *mtd);
101 static struct mtd_chip_driver sharp_chipdrv = {
102 .probe = sharp_probe,
103 .destroy = sharp_destroy,
104 .name = "sharp",
105 .module = THIS_MODULE
109 struct mtd_info *sharp_probe(struct map_info *map)
111 struct mtd_info *mtd = NULL;
112 struct sharp_info *sharp = NULL;
113 int width;
115 mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
116 if(!mtd)
117 return NULL;
119 sharp = kmalloc(sizeof(*sharp), GFP_KERNEL);
120 if(!sharp) {
121 kfree(mtd);
122 return NULL;
125 memset(mtd, 0, sizeof(*mtd));
127 width = sharp_probe_map(map,mtd);
128 if(!width){
129 kfree(mtd);
130 kfree(sharp);
131 return NULL;
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;
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);
155 map->fldrv = &sharp_chipdrv;
156 map->fldrv_priv = sharp;
158 __module_get(THIS_MODULE);
159 return mtd;
162 static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
164 unsigned long tmp;
165 unsigned long base = 0;
166 u32 read0, read4;
167 int width = 4;
169 tmp = map_read32(map, base+0);
171 map_write32(map, CMD_READ_ID, base+0);
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);
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);
211 return 0;
214 /* This function returns with the chip->mutex lock held. */
215 static int sharp_wait(struct map_info *map, struct flchip *chip)
217 __u16 status;
218 unsigned long timeo = jiffies + HZ;
219 DECLARE_WAITQUEUE(wait, current);
220 int adr = 0;
222 retry:
223 spin_lock_bh(chip->mutex);
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);
233 udelay(100);
234 if((status & SR_READY)!=SR_READY){
235 //printk(".status=%08x\n",status);
236 udelay(100);
238 break;
239 default:
240 printk("Waiting for chip\n");
242 set_current_state(TASK_INTERRUPTIBLE);
243 add_wait_queue(&chip->wq, &wait);
245 spin_unlock_bh(chip->mutex);
247 schedule();
248 remove_wait_queue(&chip->wq, &wait);
250 if(signal_pending(current))
251 return -EINTR;
253 timeo = jiffies + HZ;
255 goto retry;
258 map_write32(map,CMD_RESET, adr);
260 chip->state = FL_READY;
262 return 0;
265 static void sharp_release(struct flchip *chip)
267 wake_up(&chip->wq);
268 spin_unlock_bh(chip->mutex);
271 static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
272 size_t *retlen, u_char *buf)
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;
280 chipnum = (from >> sharp->chipshift);
281 ofs = from & ((1 << sharp->chipshift)-1);
283 *retlen = 0;
285 while(len){
286 unsigned long thislen;
288 if(chipnum>=sharp->numchips)
289 break;
291 thislen = len;
292 if(ofs+thislen >= (1<<sharp->chipshift))
293 thislen = (1<<sharp->chipshift) - ofs;
295 ret = sharp_wait(map,&sharp->chips[chipnum]);
296 if(ret<0)
297 break;
299 map_copy_from(map,buf,ofs,thislen);
301 sharp_release(&sharp->chips[chipnum]);
303 *retlen += thislen;
304 len -= thislen;
305 buf += thislen;
307 ofs = 0;
308 chipnum++;
310 return ret;
313 static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len,
314 size_t *retlen, const u_char *buf)
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;
324 *retlen = 0;
326 while(len){
327 tbuf.l = 0xffffffff;
328 chipnum = to >> sharp->chipshift;
329 ofs = to & ((1<<sharp->chipshift)-1);
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++;
339 sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l);
340 if(ret<0)
341 return ret;
342 (*retlen)+=j;
345 return 0;
348 static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
349 unsigned long adr, __u32 datum)
351 int ret;
352 int timeo;
353 int try;
354 int i;
355 int status = 0;
357 ret = sharp_wait(map,chip);
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);
364 chip->state = FL_WRITING;
366 timeo = jiffies + (HZ/2);
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;
374 if(i==100){
375 printk("sharp: timed out writing\n");
378 if(!(status&SR_ERRORS))
379 break;
381 printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status);
383 map_write32(map,CMD_CLEAR_STATUS,adr);
385 map_write32(map,CMD_RESET,adr);
386 chip->state = FL_READY;
388 wake_up(&chip->wq);
389 spin_unlock_bh(chip->mutex);
391 return 0;
394 static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
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;
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;
409 chipnum = instr->addr >> sharp->chipshift;
410 adr = instr->addr & ((1<<sharp->chipshift)-1);
411 len = instr->len;
413 while(len){
414 ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr);
415 if(ret)return ret;
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;
427 instr->state = MTD_ERASE_DONE;
428 mtd_erase_callback(instr);
430 return 0;
433 static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
434 unsigned long adr)
436 int ret;
437 unsigned long timeo;
438 int status;
439 DECLARE_WAITQUEUE(wait, current);
441 map_write32(map,CMD_READ_STATUS,adr);
442 status = map_read32(map,adr);
444 timeo = jiffies + HZ;
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;
453 set_current_state(TASK_INTERRUPTIBLE);
454 add_wait_queue(&chip->wq, &wait);
456 //spin_unlock_bh(chip->mutex);
458 schedule_timeout(1);
459 schedule();
460 remove_wait_queue(&chip->wq, &wait);
462 //spin_lock_bh(chip->mutex);
464 if (signal_pending(current)){
465 ret = -EINTR;
466 goto out;
470 ret = -ETIME;
471 out:
472 return ret;
475 static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
476 unsigned long adr)
478 int ret;
479 //int timeo;
480 int status;
481 //int i;
483 //printk("sharp_erase_oneblock()\n");
485 #ifdef AUTOUNLOCK
486 /* This seems like a good place to do an unlock */
487 sharp_unlock_oneblock(map,chip,adr);
488 #endif
490 map_write32(map,CMD_BLOCK_ERASE_1,adr);
491 map_write32(map,CMD_BLOCK_ERASE_2,adr);
493 chip->state = FL_ERASING;
495 ret = sharp_do_wait_for_ready(map,chip,adr);
496 if(ret<0)return ret;
498 map_write32(map,CMD_READ_STATUS,adr);
499 status = map_read32(map,adr);
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;
508 printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status);
509 map_write32(map,CMD_CLEAR_STATUS,adr);
511 //spin_unlock_bh(chip->mutex);
513 return -EIO;
516 #ifdef AUTOUNLOCK
517 static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
518 unsigned long adr)
520 int i;
521 int status;
523 map_write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
524 map_write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
526 udelay(100);
528 status = map_read32(map,adr);
529 printk("status=%08x\n",status);
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);
538 if(i==1000){
539 printk("sharp: timed out unlocking block\n");
542 if(!(status&SR_ERRORS)){
543 map_write32(map,CMD_RESET,adr);
544 chip->state = FL_READY;
545 return;
548 printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status);
549 map_write32(map,CMD_CLEAR_STATUS,adr);
551 #endif
553 static void sharp_sync(struct mtd_info *mtd)
555 //printk("sharp_sync()\n");
558 static int sharp_suspend(struct mtd_info *mtd)
560 printk("sharp_suspend()\n");
561 return -EINVAL;
564 static void sharp_resume(struct mtd_info *mtd)
566 printk("sharp_resume()\n");
570 static void sharp_destroy(struct mtd_info *mtd)
572 printk("sharp_destroy()\n");
576 int __init sharp_probe_init(void)
578 printk("MTD Sharp chip driver <ds@lineo.com>\n");
580 register_mtd_chip_driver(&sharp_chipdrv);
582 return 0;
585 static void __exit sharp_probe_exit(void)
587 unregister_mtd_chip_driver(&sharp_chipdrv);
590 module_init(sharp_probe_init);
591 module_exit(sharp_probe_exit);
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");