Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / mtd / nand / au1550nd.c
1 /*
2  *  drivers/mtd/nand/au1550nd.c
3  *
4  *  Copyright (C) 2004 Embedded Edge, LLC
5  *
6  * $Id: au1550nd.c,v 1.13 2005/11/07 11:14:30 gleixner Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  */
13
14 #include <linux/slab.h>
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/mtd/mtd.h>
18 #include <linux/mtd/nand.h>
19 #include <linux/mtd/partitions.h>
20 #include <linux/version.h>
21 #include <asm/io.h>
22
23 /* fixme: this is ugly */
24 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
25 #include <asm/mach-au1x00/au1xxx.h>
26 #else
27 #include <asm/au1000.h>
28 #ifdef CONFIG_MIPS_PB1550
29 #include <asm/pb1550.h>
30 #endif
31 #ifdef CONFIG_MIPS_DB1550
32 #include <asm/db1x00.h>
33 #endif
34 #endif
35
36 /*
37  * MTD structure for NAND controller
38  */
39 static struct mtd_info *au1550_mtd = NULL;
40 static void __iomem *p_nand;
41 static int nand_width = 1; /* default x8*/
42
43 /*
44  * Define partitions for flash device
45  */
46 static const struct mtd_partition partition_info[] = {
47         {
48                 .name   = "NAND FS 0",
49                 .offset = 0,
50                 .size   = 8*1024*1024
51         },
52         {
53                 .name   = "NAND FS 1",
54                 .offset =  MTDPART_OFS_APPEND,
55                 .size   =    MTDPART_SIZ_FULL
56         }
57 };
58
59 /**
60  * au_read_byte -  read one byte from the chip
61  * @mtd:        MTD device structure
62  *
63  *  read function for 8bit buswith
64  */
65 static u_char au_read_byte(struct mtd_info *mtd)
66 {
67         struct nand_chip *this = mtd->priv;
68         u_char ret = readb(this->IO_ADDR_R);
69         au_sync();
70         return ret;
71 }
72
73 /**
74  * au_write_byte -  write one byte to the chip
75  * @mtd:        MTD device structure
76  * @byte:       pointer to data byte to write
77  *
78  *  write function for 8it buswith
79  */
80 static void au_write_byte(struct mtd_info *mtd, u_char byte)
81 {
82         struct nand_chip *this = mtd->priv;
83         writeb(byte, this->IO_ADDR_W);
84         au_sync();
85 }
86
87 /**
88  * au_read_byte16 -  read one byte endianess aware from the chip
89  * @mtd:        MTD device structure
90  *
91  *  read function for 16bit buswith with
92  * endianess conversion
93  */
94 static u_char au_read_byte16(struct mtd_info *mtd)
95 {
96         struct nand_chip *this = mtd->priv;
97         u_char ret = (u_char) cpu_to_le16(readw(this->IO_ADDR_R));
98         au_sync();
99         return ret;
100 }
101
102 /**
103  * au_write_byte16 -  write one byte endianess aware to the chip
104  * @mtd:        MTD device structure
105  * @byte:       pointer to data byte to write
106  *
107  *  write function for 16bit buswith with
108  * endianess conversion
109  */
110 static void au_write_byte16(struct mtd_info *mtd, u_char byte)
111 {
112         struct nand_chip *this = mtd->priv;
113         writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
114         au_sync();
115 }
116
117 /**
118  * au_read_word -  read one word from the chip
119  * @mtd:        MTD device structure
120  *
121  *  read function for 16bit buswith without
122  * endianess conversion
123  */
124 static u16 au_read_word(struct mtd_info *mtd)
125 {
126         struct nand_chip *this = mtd->priv;
127         u16 ret = readw(this->IO_ADDR_R);
128         au_sync();
129         return ret;
130 }
131
132 /**
133  * au_write_word -  write one word to the chip
134  * @mtd:        MTD device structure
135  * @word:       data word to write
136  *
137  *  write function for 16bit buswith without
138  * endianess conversion
139  */
140 static void au_write_word(struct mtd_info *mtd, u16 word)
141 {
142         struct nand_chip *this = mtd->priv;
143         writew(word, this->IO_ADDR_W);
144         au_sync();
145 }
146
147 /**
148  * au_write_buf -  write buffer to chip
149  * @mtd:        MTD device structure
150  * @buf:        data buffer
151  * @len:        number of bytes to write
152  *
153  *  write function for 8bit buswith
154  */
155 static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
156 {
157         int i;
158         struct nand_chip *this = mtd->priv;
159
160         for (i=0; i<len; i++) {
161                 writeb(buf[i], this->IO_ADDR_W);
162                 au_sync();
163         }
164 }
165
166 /**
167  * au_read_buf -  read chip data into buffer
168  * @mtd:        MTD device structure
169  * @buf:        buffer to store date
170  * @len:        number of bytes to read
171  *
172  *  read function for 8bit buswith
173  */
174 static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
175 {
176         int i;
177         struct nand_chip *this = mtd->priv;
178
179         for (i=0; i<len; i++) {
180                 buf[i] = readb(this->IO_ADDR_R);
181                 au_sync();
182         }
183 }
184
185 /**
186  * au_verify_buf -  Verify chip data against buffer
187  * @mtd:        MTD device structure
188  * @buf:        buffer containing the data to compare
189  * @len:        number of bytes to compare
190  *
191  *  verify function for 8bit buswith
192  */
193 static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
194 {
195         int i;
196         struct nand_chip *this = mtd->priv;
197
198         for (i=0; i<len; i++) {
199                 if (buf[i] != readb(this->IO_ADDR_R))
200                         return -EFAULT;
201                 au_sync();
202         }
203
204         return 0;
205 }
206
207 /**
208  * au_write_buf16 -  write buffer to chip
209  * @mtd:        MTD device structure
210  * @buf:        data buffer
211  * @len:        number of bytes to write
212  *
213  *  write function for 16bit buswith
214  */
215 static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
216 {
217         int i;
218         struct nand_chip *this = mtd->priv;
219         u16 *p = (u16 *) buf;
220         len >>= 1;
221
222         for (i=0; i<len; i++) {
223                 writew(p[i], this->IO_ADDR_W);
224                 au_sync();
225         }
226
227 }
228
229 /**
230  * au_read_buf16 -  read chip data into buffer
231  * @mtd:        MTD device structure
232  * @buf:        buffer to store date
233  * @len:        number of bytes to read
234  *
235  *  read function for 16bit buswith
236  */
237 static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
238 {
239         int i;
240         struct nand_chip *this = mtd->priv;
241         u16 *p = (u16 *) buf;
242         len >>= 1;
243
244         for (i=0; i<len; i++) {
245                 p[i] = readw(this->IO_ADDR_R);
246                 au_sync();
247         }
248 }
249
250 /**
251  * au_verify_buf16 -  Verify chip data against buffer
252  * @mtd:        MTD device structure
253  * @buf:        buffer containing the data to compare
254  * @len:        number of bytes to compare
255  *
256  *  verify function for 16bit buswith
257  */
258 static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
259 {
260         int i;
261         struct nand_chip *this = mtd->priv;
262         u16 *p = (u16 *) buf;
263         len >>= 1;
264
265         for (i=0; i<len; i++) {
266                 if (p[i] != readw(this->IO_ADDR_R))
267                         return -EFAULT;
268                 au_sync();
269         }
270         return 0;
271 }
272
273
274 static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
275 {
276         register struct nand_chip *this = mtd->priv;
277
278         switch(cmd){
279
280         case NAND_CTL_SETCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_CMD; break;
281         case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break;
282
283         case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
284         case NAND_CTL_CLRALE:
285                 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
286                 /* FIXME: Nobody knows why this is neccecary,
287                  * but it works only that way */
288                 udelay(1);
289                 break;
290
291         case NAND_CTL_SETNCE:
292                 /* assert (force assert) chip enable */
293                 au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break;
294                 break;
295
296         case NAND_CTL_CLRNCE:
297                 /* deassert chip enable */
298                 au_writel(0, MEM_STNDCTL); break;
299                 break;
300         }
301
302         this->IO_ADDR_R = this->IO_ADDR_W;
303
304         /* Drain the writebuffer */
305         au_sync();
306 }
307
308 int au1550_device_ready(struct mtd_info *mtd)
309 {
310         int ret = (au_readl(MEM_STSTAT) & 0x1) ? 1 : 0;
311         au_sync();
312         return ret;
313 }
314
315 /*
316  * Main initialization routine
317  */
318 int __init au1xxx_nand_init (void)
319 {
320         struct nand_chip *this;
321         u16 boot_swapboot = 0; /* default value */
322         int retval;
323         u32 mem_staddr;
324         u32 nand_phys;
325
326         /* Allocate memory for MTD device structure and private data */
327         au1550_mtd = kmalloc (sizeof(struct mtd_info) +
328                         sizeof (struct nand_chip), GFP_KERNEL);
329         if (!au1550_mtd) {
330                 printk ("Unable to allocate NAND MTD dev structure.\n");
331                 return -ENOMEM;
332         }
333
334         /* Get pointer to private data */
335         this = (struct nand_chip *) (&au1550_mtd[1]);
336
337         /* Initialize structures */
338         memset((char *) au1550_mtd, 0, sizeof(struct mtd_info));
339         memset((char *) this, 0, sizeof(struct nand_chip));
340
341         /* Link the private data with the MTD structure */
342         au1550_mtd->priv = this;
343
344
345         /* disable interrupts */
346         au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL);
347
348         /* disable NAND boot */
349         au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
350
351 #ifdef CONFIG_MIPS_PB1550
352         /* set gpio206 high */
353         au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR);
354
355         boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
356                 ((bcsr->status >> 6)  & 0x1);
357         switch (boot_swapboot) {
358                 case 0:
359                 case 2:
360                 case 8:
361                 case 0xC:
362                 case 0xD:
363                         /* x16 NAND Flash */
364                         nand_width = 0;
365                         break;
366                 case 1:
367                 case 9:
368                 case 3:
369                 case 0xE:
370                 case 0xF:
371                         /* x8 NAND Flash */
372                         nand_width = 1;
373                         break;
374                 default:
375                         printk("Pb1550 NAND: bad boot:swap\n");
376                         retval = -EINVAL;
377                         goto outmem;
378         }
379 #endif
380
381         /* Configure chip-select; normally done by boot code, e.g. YAMON */
382 #ifdef NAND_STCFG
383         if (NAND_CS == 0) {
384                 au_writel(NAND_STCFG,  MEM_STCFG0);
385                 au_writel(NAND_STTIME, MEM_STTIME0);
386                 au_writel(NAND_STADDR, MEM_STADDR0);
387         }
388         if (NAND_CS == 1) {
389                 au_writel(NAND_STCFG,  MEM_STCFG1);
390                 au_writel(NAND_STTIME, MEM_STTIME1);
391                 au_writel(NAND_STADDR, MEM_STADDR1);
392         }
393         if (NAND_CS == 2) {
394                 au_writel(NAND_STCFG,  MEM_STCFG2);
395                 au_writel(NAND_STTIME, MEM_STTIME2);
396                 au_writel(NAND_STADDR, MEM_STADDR2);
397         }
398         if (NAND_CS == 3) {
399                 au_writel(NAND_STCFG,  MEM_STCFG3);
400                 au_writel(NAND_STTIME, MEM_STTIME3);
401                 au_writel(NAND_STADDR, MEM_STADDR3);
402         }
403 #endif
404
405         /* Locate NAND chip-select in order to determine NAND phys address */
406         mem_staddr = 0x00000000;
407         if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0))
408                 mem_staddr = au_readl(MEM_STADDR0);
409         else if (((au_readl(MEM_STCFG1) & 0x7) == 0x5) && (NAND_CS == 1))
410                 mem_staddr = au_readl(MEM_STADDR1);
411         else if (((au_readl(MEM_STCFG2) & 0x7) == 0x5) && (NAND_CS == 2))
412                 mem_staddr = au_readl(MEM_STADDR2);
413         else if (((au_readl(MEM_STCFG3) & 0x7) == 0x5) && (NAND_CS == 3))
414                 mem_staddr = au_readl(MEM_STADDR3);
415
416         if (mem_staddr == 0x00000000) {
417                 printk("Au1xxx NAND: ERROR WITH NAND CHIP-SELECT\n");
418                 kfree(au1550_mtd);
419                 return 1;
420         }
421         nand_phys = (mem_staddr << 4) & 0xFFFC0000;
422
423         p_nand = (void __iomem *)ioremap(nand_phys, 0x1000);
424
425         /* make controller and MTD agree */
426         if (NAND_CS == 0)
427                 nand_width = au_readl(MEM_STCFG0) & (1<<22);
428         if (NAND_CS == 1)
429                 nand_width = au_readl(MEM_STCFG1) & (1<<22);
430         if (NAND_CS == 2)
431                 nand_width = au_readl(MEM_STCFG2) & (1<<22);
432         if (NAND_CS == 3)
433                 nand_width = au_readl(MEM_STCFG3) & (1<<22);
434
435
436         /* Set address of hardware control function */
437         this->hwcontrol = au1550_hwcontrol;
438         this->dev_ready = au1550_device_ready;
439         /* 30 us command delay time */
440         this->chip_delay = 30;
441         this->eccmode = NAND_ECC_SOFT;
442
443         this->options = NAND_NO_AUTOINCR;
444
445         if (!nand_width)
446                 this->options |= NAND_BUSWIDTH_16;
447
448         this->read_byte = (!nand_width) ? au_read_byte16 : au_read_byte;
449         this->write_byte = (!nand_width) ? au_write_byte16 : au_write_byte;
450         this->write_word = au_write_word;
451         this->read_word = au_read_word;
452         this->write_buf = (!nand_width) ? au_write_buf16 : au_write_buf;
453         this->read_buf = (!nand_width) ? au_read_buf16 : au_read_buf;
454         this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf;
455
456         /* Scan to find existence of the device */
457         if (nand_scan (au1550_mtd, 1)) {
458                 retval = -ENXIO;
459                 goto outio;
460         }
461
462         /* Register the partitions */
463         add_mtd_partitions(au1550_mtd, partition_info, ARRAY_SIZE(partition_info));
464
465         return 0;
466
467  outio:
468         iounmap ((void *)p_nand);
469
470  outmem:
471         kfree (au1550_mtd);
472         return retval;
473 }
474
475 module_init(au1xxx_nand_init);
476
477 /*
478  * Clean up routine
479  */
480 #ifdef MODULE
481 static void __exit au1550_cleanup (void)
482 {
483         struct nand_chip *this = (struct nand_chip *) &au1550_mtd[1];
484
485         /* Release resources, unregister device */
486         nand_release (au1550_mtd);
487
488         /* Free the MTD device structure */
489         kfree (au1550_mtd);
490
491         /* Unmap */
492         iounmap ((void *)p_nand);
493 }
494 module_exit(au1550_cleanup);
495 #endif
496
497 MODULE_LICENSE("GPL");
498 MODULE_AUTHOR("Embedded Edge, LLC");
499 MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on Pb1550 board");