2 * drivers/mtd/nand/au1550nd.c
4 * Copyright (C) 2004 Embedded Edge, LLC
6 * $Id: au1550nd.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $
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.
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>
22 /* fixme: this is ugly */
23 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
24 #include <asm/mach-au1x00/au1000.h>
25 #ifdef CONFIG_MIPS_PB1550
26 #include <asm/mach-pb1x00/pb1550.h>
28 #ifdef CONFIG_MIPS_DB1550
29 #include <asm/mach-db1x00/db1x00.h>
32 #include <asm/au1000.h>
33 #ifdef CONFIG_MIPS_PB1550
34 #include <asm/pb1550.h>
36 #ifdef CONFIG_MIPS_DB1550
37 #include <asm/db1x00.h>
42 * MTD structure for NAND controller
44 static struct mtd_info
*au1550_mtd
= NULL
;
45 static void __iomem
*p_nand
;
46 static int nand_width
= 1; /* default x8*/
51 * Define partitions for flash device
53 const static struct mtd_partition partition_info
[] = {
54 #ifdef CONFIG_MIPS_PB1550
55 #define NUM_PARTITIONS 2
57 .name
= "Pb1550 NAND FS 0",
62 .name
= "Pb1550 NAND FS 1",
63 .offset
= MTDPART_OFS_APPEND
,
64 .size
= MTDPART_SIZ_FULL
67 #ifdef CONFIG_MIPS_DB1550
68 #define NUM_PARTITIONS 2
70 .name
= "Db1550 NAND FS 0",
75 .name
= "Db1550 NAND FS 1",
76 .offset
= MTDPART_OFS_APPEND
,
77 .size
= MTDPART_SIZ_FULL
84 * au_read_byte - read one byte from the chip
85 * @mtd: MTD device structure
87 * read function for 8bit buswith
89 static u_char
au_read_byte(struct mtd_info
*mtd
)
91 struct nand_chip
*this = mtd
->priv
;
92 u_char ret
= readb(this->IO_ADDR_R
);
98 * au_write_byte - write one byte to the chip
99 * @mtd: MTD device structure
100 * @byte: pointer to data byte to write
102 * write function for 8it buswith
104 static void au_write_byte(struct mtd_info
*mtd
, u_char byte
)
106 struct nand_chip
*this = mtd
->priv
;
107 writeb(byte
, this->IO_ADDR_W
);
112 * au_read_byte16 - read one byte endianess aware from the chip
113 * @mtd: MTD device structure
115 * read function for 16bit buswith with
116 * endianess conversion
118 static u_char
au_read_byte16(struct mtd_info
*mtd
)
120 struct nand_chip
*this = mtd
->priv
;
121 u_char ret
= (u_char
) cpu_to_le16(readw(this->IO_ADDR_R
));
127 * au_write_byte16 - write one byte endianess aware to the chip
128 * @mtd: MTD device structure
129 * @byte: pointer to data byte to write
131 * write function for 16bit buswith with
132 * endianess conversion
134 static void au_write_byte16(struct mtd_info
*mtd
, u_char byte
)
136 struct nand_chip
*this = mtd
->priv
;
137 writew(le16_to_cpu((u16
) byte
), this->IO_ADDR_W
);
142 * au_read_word - read one word from the chip
143 * @mtd: MTD device structure
145 * read function for 16bit buswith without
146 * endianess conversion
148 static u16
au_read_word(struct mtd_info
*mtd
)
150 struct nand_chip
*this = mtd
->priv
;
151 u16 ret
= readw(this->IO_ADDR_R
);
157 * au_write_word - write one word to the chip
158 * @mtd: MTD device structure
159 * @word: data word to write
161 * write function for 16bit buswith without
162 * endianess conversion
164 static void au_write_word(struct mtd_info
*mtd
, u16 word
)
166 struct nand_chip
*this = mtd
->priv
;
167 writew(word
, this->IO_ADDR_W
);
172 * au_write_buf - write buffer to chip
173 * @mtd: MTD device structure
175 * @len: number of bytes to write
177 * write function for 8bit buswith
179 static void au_write_buf(struct mtd_info
*mtd
, const u_char
*buf
, int len
)
182 struct nand_chip
*this = mtd
->priv
;
184 for (i
=0; i
<len
; i
++) {
185 writeb(buf
[i
], this->IO_ADDR_W
);
191 * au_read_buf - read chip data into buffer
192 * @mtd: MTD device structure
193 * @buf: buffer to store date
194 * @len: number of bytes to read
196 * read function for 8bit buswith
198 static void au_read_buf(struct mtd_info
*mtd
, u_char
*buf
, int len
)
201 struct nand_chip
*this = mtd
->priv
;
203 for (i
=0; i
<len
; i
++) {
204 buf
[i
] = readb(this->IO_ADDR_R
);
210 * au_verify_buf - Verify chip data against buffer
211 * @mtd: MTD device structure
212 * @buf: buffer containing the data to compare
213 * @len: number of bytes to compare
215 * verify function for 8bit buswith
217 static int au_verify_buf(struct mtd_info
*mtd
, const u_char
*buf
, int len
)
220 struct nand_chip
*this = mtd
->priv
;
222 for (i
=0; i
<len
; i
++) {
223 if (buf
[i
] != readb(this->IO_ADDR_R
))
232 * au_write_buf16 - write buffer to chip
233 * @mtd: MTD device structure
235 * @len: number of bytes to write
237 * write function for 16bit buswith
239 static void au_write_buf16(struct mtd_info
*mtd
, const u_char
*buf
, int len
)
242 struct nand_chip
*this = mtd
->priv
;
243 u16
*p
= (u16
*) buf
;
246 for (i
=0; i
<len
; i
++) {
247 writew(p
[i
], this->IO_ADDR_W
);
254 * au_read_buf16 - read chip data into buffer
255 * @mtd: MTD device structure
256 * @buf: buffer to store date
257 * @len: number of bytes to read
259 * read function for 16bit buswith
261 static void au_read_buf16(struct mtd_info
*mtd
, u_char
*buf
, int len
)
264 struct nand_chip
*this = mtd
->priv
;
265 u16
*p
= (u16
*) buf
;
268 for (i
=0; i
<len
; i
++) {
269 p
[i
] = readw(this->IO_ADDR_R
);
275 * au_verify_buf16 - Verify chip data against buffer
276 * @mtd: MTD device structure
277 * @buf: buffer containing the data to compare
278 * @len: number of bytes to compare
280 * verify function for 16bit buswith
282 static int au_verify_buf16(struct mtd_info
*mtd
, const u_char
*buf
, int len
)
285 struct nand_chip
*this = mtd
->priv
;
286 u16
*p
= (u16
*) buf
;
289 for (i
=0; i
<len
; i
++) {
290 if (p
[i
] != readw(this->IO_ADDR_R
))
298 static void au1550_hwcontrol(struct mtd_info
*mtd
, int cmd
)
300 register struct nand_chip
*this = mtd
->priv
;
304 case NAND_CTL_SETCLE
: this->IO_ADDR_W
= p_nand
+ MEM_STNAND_CMD
; break;
305 case NAND_CTL_CLRCLE
: this->IO_ADDR_W
= p_nand
+ MEM_STNAND_DATA
; break;
307 case NAND_CTL_SETALE
: this->IO_ADDR_W
= p_nand
+ MEM_STNAND_ADDR
; break;
308 case NAND_CTL_CLRALE
:
309 this->IO_ADDR_W
= p_nand
+ MEM_STNAND_DATA
;
310 /* FIXME: Nobody knows why this is neccecary,
311 * but it works only that way */
315 case NAND_CTL_SETNCE
:
316 /* assert (force assert) chip enable */
317 au_writel((1<<(4+NAND_CS
)) , MEM_STNDCTL
); break;
320 case NAND_CTL_CLRNCE
:
321 /* deassert chip enable */
322 au_writel(0, MEM_STNDCTL
); break;
326 this->IO_ADDR_R
= this->IO_ADDR_W
;
328 /* Drain the writebuffer */
332 int au1550_device_ready(struct mtd_info
*mtd
)
334 int ret
= (au_readl(MEM_STSTAT
) & 0x1) ? 1 : 0;
340 * Main initialization routine
342 int __init
au1550_init (void)
344 struct nand_chip
*this;
345 u16 boot_swapboot
= 0; /* default value */
348 /* Allocate memory for MTD device structure and private data */
349 au1550_mtd
= kmalloc (sizeof(struct mtd_info
) +
350 sizeof (struct nand_chip
), GFP_KERNEL
);
352 printk ("Unable to allocate NAND MTD dev structure.\n");
356 /* Get pointer to private data */
357 this = (struct nand_chip
*) (&au1550_mtd
[1]);
359 /* Initialize structures */
360 memset((char *) au1550_mtd
, 0, sizeof(struct mtd_info
));
361 memset((char *) this, 0, sizeof(struct nand_chip
));
363 /* Link the private data with the MTD structure */
364 au1550_mtd
->priv
= this;
367 /* MEM_STNDCTL: disable ints, disable nand boot */
368 au_writel(0, MEM_STNDCTL
);
370 #ifdef CONFIG_MIPS_PB1550
371 /* set gpio206 high */
372 au_writel(au_readl(GPIO2_DIR
) & ~(1<<6), GPIO2_DIR
);
374 boot_swapboot
= (au_readl(MEM_STSTAT
) & (0x7<<1)) |
375 ((bcsr
->status
>> 6) & 0x1);
376 switch (boot_swapboot
) {
394 printk("Pb1550 NAND: bad boot:swap\n");
400 /* Configure RCE1 - should be done by YAMON */
401 au_writel(0x5 | (nand_width
<< 22), 0xB4001010); /* MEM_STCFG1 */
402 au_writel(NAND_TIMING
, 0xB4001014); /* MEM_STTIME1 */
405 /* setup and enable chip select, MEM_STADDR1 */
406 /* we really need to decode offsets only up till 0x20 */
407 au_writel((1<<28) | (NAND_PHYS_ADDR
>>4) |
408 (((NAND_PHYS_ADDR
+ 0x1000)-1) & (0x3fff<<18)>>18),
412 p_nand
= ioremap(NAND_PHYS_ADDR
, 0x1000);
414 /* Set address of hardware control function */
415 this->hwcontrol
= au1550_hwcontrol
;
416 this->dev_ready
= au1550_device_ready
;
417 /* 30 us command delay time */
418 this->chip_delay
= 30;
419 this->eccmode
= NAND_ECC_SOFT
;
421 this->options
= NAND_NO_AUTOINCR
;
424 this->options
|= NAND_BUSWIDTH_16
;
426 this->read_byte
= (!nand_width
) ? au_read_byte16
: au_read_byte
;
427 this->write_byte
= (!nand_width
) ? au_write_byte16
: au_write_byte
;
428 this->write_word
= au_write_word
;
429 this->read_word
= au_read_word
;
430 this->write_buf
= (!nand_width
) ? au_write_buf16
: au_write_buf
;
431 this->read_buf
= (!nand_width
) ? au_read_buf16
: au_read_buf
;
432 this->verify_buf
= (!nand_width
) ? au_verify_buf16
: au_verify_buf
;
434 /* Scan to find existence of the device */
435 if (nand_scan (au1550_mtd
, 1)) {
440 /* Register the partitions */
441 add_mtd_partitions(au1550_mtd
, partition_info
, NUM_PARTITIONS
);
446 iounmap ((void *)p_nand
);
453 module_init(au1550_init
);
459 static void __exit
au1550_cleanup (void)
461 struct nand_chip
*this = (struct nand_chip
*) &au1550_mtd
[1];
463 /* Release resources, unregister device */
464 nand_release (au1550_mtd
);
466 /* Free the MTD device structure */
470 iounmap ((void *)p_nand
);
472 module_exit(au1550_cleanup
);
475 MODULE_LICENSE("GPL");
476 MODULE_AUTHOR("Embedded Edge, LLC");
477 MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on Pb1550 board");