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