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 2008/10/15 03:26:35 james26_jang 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
65struct mtd_info *sharp_probe(struct map_info *);
66
67static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);
68
69static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
70	size_t *retlen, u_char *buf);
71static int sharp_write(struct mtd_info *mtd, loff_t from, size_t len,
72	size_t *retlen, const u_char *buf);
73static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr);
74static void sharp_sync(struct mtd_info *mtd);
75static int sharp_suspend(struct mtd_info *mtd);
76static void sharp_resume(struct mtd_info *mtd);
77static void sharp_destroy(struct mtd_info *mtd);
78
79static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
80	unsigned long adr, __u32 datum);
81static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
82	unsigned long adr);
83#ifdef AUTOUNLOCK
84static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
85	unsigned long adr);
86#endif
87
88
89struct sharp_info{
90	struct flchip *chip;
91	int bogus;
92	int chipshift;
93	int numchips;
94	struct flchip chips[1];
95};
96
97struct mtd_info *sharp_probe(struct map_info *map);
98static void sharp_destroy(struct mtd_info *mtd);
99
100static struct mtd_chip_driver sharp_chipdrv = {
101	probe: sharp_probe,
102	destroy: sharp_destroy,
103	name: "sharp",
104	module: THIS_MODULE
105};
106
107
108struct 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
159static 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		default:
189			printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n",
190				read0,read4);
191		}
192	}else if((map->read32(map, base+0) == CMD_READ_ID)){
193		/* RAM, probably */
194		printk("Looks like RAM\n");
195		map->write32(map, tmp, base+0);
196	}else{
197		printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n",
198			read0,read4);
199	}
200
201	return 0;
202}
203
204/* This function returns with the chip->mutex lock held. */
205static int sharp_wait(struct map_info *map, struct flchip *chip)
206{
207	__u16 status;
208	unsigned long timeo = jiffies + HZ;
209	DECLARE_WAITQUEUE(wait, current);
210	int adr = 0;
211
212retry:
213	spin_lock_bh(chip->mutex);
214
215	switch(chip->state){
216	case FL_READY:
217		map->write32(map,CMD_READ_STATUS,adr);
218		chip->state = FL_STATUS;
219	case FL_STATUS:
220		status = map->read32(map,adr);
221//printk("status=%08x\n",status);
222
223		udelay(100);
224		if((status & SR_READY)!=SR_READY){
225//printk(".status=%08x\n",status);
226			udelay(100);
227		}
228		break;
229	default:
230		printk("Waiting for chip\n");
231
232		set_current_state(TASK_INTERRUPTIBLE);
233		add_wait_queue(&chip->wq, &wait);
234
235		spin_unlock_bh(chip->mutex);
236
237		schedule();
238		remove_wait_queue(&chip->wq, &wait);
239
240		if(signal_pending(current))
241			return -EINTR;
242
243		timeo = jiffies + HZ;
244
245		goto retry;
246	}
247
248	map->write32(map,CMD_RESET, adr);
249
250	chip->state = FL_READY;
251
252	return 0;
253}
254
255static void sharp_release(struct flchip *chip)
256{
257	wake_up(&chip->wq);
258	spin_unlock_bh(chip->mutex);
259}
260
261static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
262	size_t *retlen, u_char *buf)
263{
264	struct map_info *map = mtd->priv;
265	struct sharp_info *sharp = map->fldrv_priv;
266	int chipnum;
267	int ret = 0;
268	int ofs = 0;
269
270	chipnum = (from >> sharp->chipshift);
271	ofs = from & ((1 << sharp->chipshift)-1);
272
273	*retlen = 0;
274
275	while(len){
276		unsigned long thislen;
277
278		if(chipnum>=sharp->numchips)
279			break;
280
281		thislen = len;
282		if(ofs+thislen >= (1<<sharp->chipshift))
283			thislen = (1<<sharp->chipshift) - ofs;
284
285		ret = sharp_wait(map,&sharp->chips[chipnum]);
286		if(ret<0)
287			break;
288
289		map->copy_from(map,buf,ofs,thislen);
290
291		sharp_release(&sharp->chips[chipnum]);
292
293		*retlen += thislen;
294		len -= thislen;
295		buf += thislen;
296
297		ofs = 0;
298		chipnum++;
299	}
300	return ret;
301}
302
303static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len,
304	size_t *retlen, const u_char *buf)
305{
306	struct map_info *map = mtd->priv;
307	struct sharp_info *sharp = map->fldrv_priv;
308	int ret = 0;
309	int i,j;
310	int chipnum;
311	unsigned long ofs;
312	union { u32 l; unsigned char uc[4]; } tbuf;
313
314	*retlen = 0;
315
316	while(len){
317		tbuf.l = 0xffffffff;
318		chipnum = to >> sharp->chipshift;
319		ofs = to & ((1<<sharp->chipshift)-1);
320
321		j=0;
322		for(i=ofs&3;i<4 && len;i++){
323			tbuf.uc[i] = *buf;
324			buf++;
325			to++;
326			len--;
327			j++;
328		}
329		sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l);
330		if(ret<0)
331			return ret;
332		(*retlen)+=j;
333	}
334
335	return 0;
336}
337
338static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
339	unsigned long adr, __u32 datum)
340{
341	int ret;
342	int timeo;
343	int try;
344	int i;
345	int status = 0;
346
347	ret = sharp_wait(map,chip);
348
349	for(try=0;try<10;try++){
350		map->write32(map,CMD_BYTE_WRITE,adr);
351		/* cpu_to_le32 -> hack to fix the writel be->le conversion */
352		map->write32(map,cpu_to_le32(datum),adr);
353
354		chip->state = FL_WRITING;
355
356		timeo = jiffies + (HZ/2);
357
358		map->write32(map,CMD_READ_STATUS,adr);
359		for(i=0;i<100;i++){
360			status = map->read32(map,adr);
361			if((status & SR_READY)==SR_READY)
362				break;
363		}
364		if(i==100){
365			printk("sharp: timed out writing\n");
366		}
367
368		if(!(status&SR_ERRORS))
369			break;
370
371		printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status);
372
373		map->write32(map,CMD_CLEAR_STATUS,adr);
374	}
375	map->write32(map,CMD_RESET,adr);
376	chip->state = FL_READY;
377
378	wake_up(&chip->wq);
379	spin_unlock_bh(chip->mutex);
380
381	return 0;
382}
383
384static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
385{
386	struct map_info *map = mtd->priv;
387	struct sharp_info *sharp = map->fldrv_priv;
388	unsigned long adr,len;
389	int chipnum, ret=0;
390
391//printk("sharp_erase()\n");
392	if(instr->addr & (mtd->erasesize - 1))
393		return -EINVAL;
394	if(instr->len & (mtd->erasesize - 1))
395		return -EINVAL;
396	if(instr->len + instr->addr > mtd->size)
397		return -EINVAL;
398
399	chipnum = instr->addr >> sharp->chipshift;
400	adr = instr->addr & ((1<<sharp->chipshift)-1);
401	len = instr->len;
402
403	while(len){
404		ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr);
405		if(ret)return ret;
406
407		adr += mtd->erasesize;
408		len -= mtd->erasesize;
409		if(adr >> sharp->chipshift){
410			adr = 0;
411			chipnum++;
412			if(chipnum>=sharp->numchips)
413				break;
414		}
415	}
416
417	if(instr->callback)
418		instr->callback(instr);
419
420	return 0;
421}
422
423static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
424	unsigned long adr)
425{
426	int ret;
427	int timeo;
428	int status;
429	DECLARE_WAITQUEUE(wait, current);
430
431	map->write32(map,CMD_READ_STATUS,adr);
432	status = map->read32(map,adr);
433
434	timeo = jiffies + HZ;
435
436	while(time_before(jiffies, timeo)){
437		map->write32(map,CMD_READ_STATUS,adr);
438		status = map->read32(map,adr);
439		if((status & SR_READY)==SR_READY){
440			ret = 0;
441			goto out;
442		}
443		set_current_state(TASK_INTERRUPTIBLE);
444		add_wait_queue(&chip->wq, &wait);
445
446		//spin_unlock_bh(chip->mutex);
447
448		schedule_timeout(1);
449		schedule();
450		remove_wait_queue(&chip->wq, &wait);
451
452		//spin_lock_bh(chip->mutex);
453
454		if (signal_pending(current)){
455			ret = -EINTR;
456			goto out;
457		}
458
459	}
460	ret = -ETIME;
461out:
462	return ret;
463}
464
465static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
466	unsigned long adr)
467{
468	int ret;
469	//int timeo;
470	int status;
471	//int i;
472
473//printk("sharp_erase_oneblock()\n");
474
475#ifdef AUTOUNLOCK
476	/* This seems like a good place to do an unlock */
477	sharp_unlock_oneblock(map,chip,adr);
478#endif
479
480	map->write32(map,CMD_BLOCK_ERASE_1,adr);
481	map->write32(map,CMD_BLOCK_ERASE_2,adr);
482
483	chip->state = FL_ERASING;
484
485	ret = sharp_do_wait_for_ready(map,chip,adr);
486	if(ret<0)return ret;
487
488	map->write32(map,CMD_READ_STATUS,adr);
489	status = map->read32(map,adr);
490
491	if(!(status&SR_ERRORS)){
492		map->write32(map,CMD_RESET,adr);
493		chip->state = FL_READY;
494		//spin_unlock_bh(chip->mutex);
495		return 0;
496	}
497
498	printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status);
499	map->write32(map,CMD_CLEAR_STATUS,adr);
500
501	//spin_unlock_bh(chip->mutex);
502
503	return -EIO;
504}
505
506#ifdef AUTOUNLOCK
507static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
508	unsigned long adr)
509{
510	int i;
511	int status;
512
513	map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
514	map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
515
516	udelay(100);
517
518	status = map->read32(map,adr);
519	printk("status=%08x\n",status);
520
521	for(i=0;i<1000;i++){
522		//map->write32(map,CMD_READ_STATUS,adr);
523		status = map->read32(map,adr);
524		if((status & SR_READY)==SR_READY)
525			break;
526		udelay(100);
527	}
528	if(i==1000){
529		printk("sharp: timed out unlocking block\n");
530	}
531
532	if(!(status&SR_ERRORS)){
533		map->write32(map,CMD_RESET,adr);
534		chip->state = FL_READY;
535		return;
536	}
537
538	printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status);
539	map->write32(map,CMD_CLEAR_STATUS,adr);
540}
541#endif
542
543static void sharp_sync(struct mtd_info *mtd)
544{
545	//printk("sharp_sync()\n");
546}
547
548static int sharp_suspend(struct mtd_info *mtd)
549{
550	printk("sharp_suspend()\n");
551	return -EINVAL;
552}
553
554static void sharp_resume(struct mtd_info *mtd)
555{
556	printk("sharp_resume()\n");
557
558}
559
560static void sharp_destroy(struct mtd_info *mtd)
561{
562	printk("sharp_destroy()\n");
563
564}
565
566int __init sharp_probe_init(void)
567{
568	printk("MTD Sharp chip driver <ds@lineo.com>\n");
569
570	register_mtd_chip_driver(&sharp_chipdrv);
571
572	return 0;
573}
574
575static void __exit sharp_probe_exit(void)
576{
577	unregister_mtd_chip_driver(&sharp_chipdrv);
578}
579
580module_init(sharp_probe_init);
581module_exit(sharp_probe_exit);
582
583
584MODULE_LICENSE("GPL");
585MODULE_AUTHOR("David Schleef <ds@schleef.org>");
586MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");
587