aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@tglx.tec.linutronix.de>2005-07-06 05:40:12 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-07-06 05:40:12 -0400
commitba9fb37ba07219fa251edbab1a50fdc7b33da5fa (patch)
tree7ed287761585f965830e4142ecc2a6230245f007 /drivers
parent0c80336e5e81846fcb028d5a677794f08201fa1c (diff)
[MTD] NAND: Remove unmaintained tx49xx board drivers
The drivers are unmaintained since long and reference include files which are not available in the kernel. Original author is not longer responsible and no new maintainer showed up within 3 month. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/Kconfig14
-rw-r--r--drivers/mtd/nand/Makefile2
-rw-r--r--drivers/mtd/nand/tx4925ndfmc.c416
-rw-r--r--drivers/mtd/nand/tx4938ndfmc.c406
4 files changed, 0 insertions, 838 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 94b1d0e3ec85..36d34e5e5a5a 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -58,20 +58,6 @@ config MTD_NAND_TOTO
58config MTD_NAND_IDS 58config MTD_NAND_IDS
59 tristate 59 tristate
60 60
61config MTD_NAND_TX4925NDFMC
62 tristate "SmartMedia Card on Toshiba RBTX4925 reference board"
63 depends on TOSHIBA_RBTX4925 && MTD_NAND && TOSHIBA_RBTX4925_MPLEX_NAND
64 help
65 This enables the driver for the NAND flash device found on the
66 Toshiba RBTX4925 reference board, which is a SmartMediaCard.
67
68config MTD_NAND_TX4938NDFMC
69 tristate "NAND Flash device on Toshiba RBTX4938 reference board"
70 depends on TOSHIBA_RBTX4938 && MTD_NAND && TOSHIBA_RBTX4938_MPLEX_NAND
71 help
72 This enables the driver for the NAND flash device found on the
73 Toshiba RBTX4938 reference board.
74
75config MTD_NAND_AU1550 61config MTD_NAND_AU1550
76 tristate "Au1550 NAND support" 62 tristate "Au1550 NAND support"
77 depends on SOC_AU1550 && MTD_NAND 63 depends on SOC_AU1550 && MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d9dc8cc2da8c..41742026a52e 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -10,8 +10,6 @@ obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
10obj-$(CONFIG_MTD_NAND_TOTO) += toto.o 10obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
11obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o 11obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
12obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o 12obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
13obj-$(CONFIG_MTD_NAND_TX4925NDFMC) += tx4925ndfmc.o
14obj-$(CONFIG_MTD_NAND_TX4938NDFMC) += tx4938ndfmc.o
15obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o 13obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
16obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o 14obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
17obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o 15obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
diff --git a/drivers/mtd/nand/tx4925ndfmc.c b/drivers/mtd/nand/tx4925ndfmc.c
deleted file mode 100644
index bba688830c9b..000000000000
--- a/drivers/mtd/nand/tx4925ndfmc.c
+++ /dev/null
@@ -1,416 +0,0 @@
1/*
2 * drivers/mtd/tx4925ndfmc.c
3 *
4 * Overview:
5 * This is a device driver for the NAND flash device found on the
6 * Toshiba RBTX4925 reference board, which is a SmartMediaCard. It supports
7 * 16MiB, 32MiB and 64MiB cards.
8 *
9 * Author: MontaVista Software, Inc. source@mvista.com
10 *
11 * Derived from drivers/mtd/autcpu12.c
12 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
13 *
14 * $Id: tx4925ndfmc.c,v 1.5 2004/10/05 13:50:20 gleixner Exp $
15 *
16 * Copyright (C) 2001 Toshiba Corporation
17 *
18 * 2003 (c) MontaVista Software, Inc. This file is licensed under
19 * the terms of the GNU General Public License version 2. This program
20 * is licensed "as is" without any warranty of any kind, whether express
21 * or implied.
22 *
23 */
24
25#include <linux/slab.h>
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/mtd/mtd.h>
29#include <linux/mtd/nand.h>
30#include <linux/mtd/partitions.h>
31#include <linux/delay.h>
32#include <asm/io.h>
33#include <asm/tx4925/tx4925_nand.h>
34
35extern struct nand_oobinfo jffs2_oobinfo;
36
37/*
38 * MTD structure for RBTX4925 board
39 */
40static struct mtd_info *tx4925ndfmc_mtd = NULL;
41
42/*
43 * Define partitions for flash devices
44 */
45
46static struct mtd_partition partition_info16k[] = {
47 { .name = "RBTX4925 flash partition 1",
48 .offset = 0,
49 .size = 8 * 0x00100000 },
50 { .name = "RBTX4925 flash partition 2",
51 .offset = 8 * 0x00100000,
52 .size = 8 * 0x00100000 },
53};
54
55static struct mtd_partition partition_info32k[] = {
56 { .name = "RBTX4925 flash partition 1",
57 .offset = 0,
58 .size = 8 * 0x00100000 },
59 { .name = "RBTX4925 flash partition 2",
60 .offset = 8 * 0x00100000,
61 .size = 24 * 0x00100000 },
62};
63
64static struct mtd_partition partition_info64k[] = {
65 { .name = "User FS",
66 .offset = 0,
67 .size = 16 * 0x00100000 },
68 { .name = "RBTX4925 flash partition 2",
69 .offset = 16 * 0x00100000,
70 .size = 48 * 0x00100000},
71};
72
73static struct mtd_partition partition_info128k[] = {
74 { .name = "Skip bad section",
75 .offset = 0,
76 .size = 16 * 0x00100000 },
77 { .name = "User FS",
78 .offset = 16 * 0x00100000,
79 .size = 112 * 0x00100000 },
80};
81#define NUM_PARTITIONS16K 2
82#define NUM_PARTITIONS32K 2
83#define NUM_PARTITIONS64K 2
84#define NUM_PARTITIONS128K 2
85
86/*
87 * hardware specific access to control-lines
88*/
89static void tx4925ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
90{
91
92 switch(cmd){
93
94 case NAND_CTL_SETCLE:
95 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CLE;
96 break;
97 case NAND_CTL_CLRCLE:
98 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CLE;
99 break;
100 case NAND_CTL_SETALE:
101 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ALE;
102 break;
103 case NAND_CTL_CLRALE:
104 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ALE;
105 break;
106 case NAND_CTL_SETNCE:
107 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CE;
108 break;
109 case NAND_CTL_CLRNCE:
110 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CE;
111 break;
112 case NAND_CTL_SETWP:
113 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_WE;
114 break;
115 case NAND_CTL_CLRWP:
116 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_WE;
117 break;
118 }
119}
120
121/*
122* read device ready pin
123*/
124static int tx4925ndfmc_device_ready(struct mtd_info *mtd)
125{
126 int ready;
127 ready = (tx4925_ndfmcptr->sr & TX4925_NDSFR_BUSY) ? 0 : 1;
128 return ready;
129}
130void tx4925ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
131{
132 /* reset first */
133 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_MASK;
134 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
135 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_ENAB;
136}
137static void tx4925ndfmc_disable_ecc(void)
138{
139 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
140}
141static void tx4925ndfmc_enable_read_ecc(void)
142{
143 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
144 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_READ;
145}
146void tx4925ndfmc_readecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code){
147 int i;
148 u_char *ecc = ecc_code;
149 tx4925ndfmc_enable_read_ecc();
150 for (i = 0;i < 6;i++,ecc++)
151 *ecc = tx4925_read_nfmc(&(tx4925_ndfmcptr->dtr));
152 tx4925ndfmc_disable_ecc();
153}
154void tx4925ndfmc_device_setup(void)
155{
156
157 *(unsigned char *)0xbb005000 &= ~0x08;
158
159 /* reset NDFMC */
160 tx4925_ndfmcptr->rstr |= TX4925_NDFRSTR_RST;
161 while (tx4925_ndfmcptr->rstr & TX4925_NDFRSTR_RST);
162
163 /* setup BusSeparete, Hold Time, Strobe Pulse Width */
164 tx4925_ndfmcptr->mcr = TX4925_BSPRT ? TX4925_NDFMCR_BSPRT : 0;
165 tx4925_ndfmcptr->spr = TX4925_HOLD << 4 | TX4925_SPW;
166}
167static u_char tx4925ndfmc_nand_read_byte(struct mtd_info *mtd)
168{
169 struct nand_chip *this = mtd->priv;
170 return tx4925_read_nfmc(this->IO_ADDR_R);
171}
172
173static void tx4925ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
174{
175 struct nand_chip *this = mtd->priv;
176 tx4925_write_nfmc(byte, this->IO_ADDR_W);
177}
178
179static void tx4925ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
180{
181 int i;
182 struct nand_chip *this = mtd->priv;
183
184 for (i=0; i<len; i++)
185 tx4925_write_nfmc(buf[i], this->IO_ADDR_W);
186}
187
188static void tx4925ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
189{
190 int i;
191 struct nand_chip *this = mtd->priv;
192
193 for (i=0; i<len; i++)
194 buf[i] = tx4925_read_nfmc(this->IO_ADDR_R);
195}
196
197static int tx4925ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
198{
199 int i;
200 struct nand_chip *this = mtd->priv;
201
202 for (i=0; i<len; i++)
203 if (buf[i] != tx4925_read_nfmc(this->IO_ADDR_R))
204 return -EFAULT;
205
206 return 0;
207}
208
209/*
210 * Send command to NAND device
211 */
212static void tx4925ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
213{
214 register struct nand_chip *this = mtd->priv;
215
216 /* Begin command latch cycle */
217 this->hwcontrol(mtd, NAND_CTL_SETCLE);
218 /*
219 * Write out the command to the device.
220 */
221 if (command == NAND_CMD_SEQIN) {
222 int readcmd;
223
224 if (column >= mtd->oobblock) {
225 /* OOB area */
226 column -= mtd->oobblock;
227 readcmd = NAND_CMD_READOOB;
228 } else if (column < 256) {
229 /* First 256 bytes --> READ0 */
230 readcmd = NAND_CMD_READ0;
231 } else {
232 column -= 256;
233 readcmd = NAND_CMD_READ1;
234 }
235 this->write_byte(mtd, readcmd);
236 }
237 this->write_byte(mtd, command);
238
239 /* Set ALE and clear CLE to start address cycle */
240 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
241
242 if (column != -1 || page_addr != -1) {
243 this->hwcontrol(mtd, NAND_CTL_SETALE);
244
245 /* Serially input address */
246 if (column != -1)
247 this->write_byte(mtd, column);
248 if (page_addr != -1) {
249 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
250 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
251 /* One more address cycle for higher density devices */
252 if (mtd->size & 0x0c000000)
253 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
254 }
255 /* Latch in address */
256 this->hwcontrol(mtd, NAND_CTL_CLRALE);
257 }
258
259 /*
260 * program and erase have their own busy handlers
261 * status and sequential in needs no delay
262 */
263 switch (command) {
264
265 case NAND_CMD_PAGEPROG:
266 /* Turn off WE */
267 this->hwcontrol (mtd, NAND_CTL_CLRWP);
268 return;
269
270 case NAND_CMD_SEQIN:
271 /* Turn on WE */
272 this->hwcontrol (mtd, NAND_CTL_SETWP);
273 return;
274
275 case NAND_CMD_ERASE1:
276 case NAND_CMD_ERASE2:
277 case NAND_CMD_STATUS:
278 return;
279
280 case NAND_CMD_RESET:
281 if (this->dev_ready)
282 break;
283 this->hwcontrol(mtd, NAND_CTL_SETCLE);
284 this->write_byte(mtd, NAND_CMD_STATUS);
285 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
286 while ( !(this->read_byte(mtd) & 0x40));
287 return;
288
289 /* This applies to read commands */
290 default:
291 /*
292 * If we don't have access to the busy pin, we apply the given
293 * command delay
294 */
295 if (!this->dev_ready) {
296 udelay (this->chip_delay);
297 return;
298 }
299 }
300
301 /* wait until command is processed */
302 while (!this->dev_ready(mtd));
303}
304
305#ifdef CONFIG_MTD_CMDLINE_PARTS
306extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio
307n **pparts, char *);
308#endif
309
310/*
311 * Main initialization routine
312 */
313extern int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
314int __init tx4925ndfmc_init (void)
315{
316 struct nand_chip *this;
317 int err = 0;
318
319 /* Allocate memory for MTD device structure and private data */
320 tx4925ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
321 GFP_KERNEL);
322 if (!tx4925ndfmc_mtd) {
323 printk ("Unable to allocate RBTX4925 NAND MTD device structure.\n");
324 err = -ENOMEM;
325 goto out;
326 }
327
328 tx4925ndfmc_device_setup();
329
330 /* io is indirect via a register so don't need to ioremap address */
331
332 /* Get pointer to private data */
333 this = (struct nand_chip *) (&tx4925ndfmc_mtd[1]);
334
335 /* Initialize structures */
336 memset((char *) tx4925ndfmc_mtd, 0, sizeof(struct mtd_info));
337 memset((char *) this, 0, sizeof(struct nand_chip));
338
339 /* Link the private data with the MTD structure */
340 tx4925ndfmc_mtd->priv = this;
341
342 /* Set address of NAND IO lines */
343 this->IO_ADDR_R = (void __iomem *)&(tx4925_ndfmcptr->dtr);
344 this->IO_ADDR_W = (void __iomem *)&(tx4925_ndfmcptr->dtr);
345 this->hwcontrol = tx4925ndfmc_hwcontrol;
346 this->enable_hwecc = tx4925ndfmc_enable_hwecc;
347 this->calculate_ecc = tx4925ndfmc_readecc;
348 this->correct_data = nand_correct_data;
349 this->eccmode = NAND_ECC_HW6_512;
350 this->dev_ready = tx4925ndfmc_device_ready;
351 /* 20 us command delay time */
352 this->chip_delay = 20;
353 this->read_byte = tx4925ndfmc_nand_read_byte;
354 this->write_byte = tx4925ndfmc_nand_write_byte;
355 this->cmdfunc = tx4925ndfmc_nand_command;
356 this->write_buf = tx4925ndfmc_nand_write_buf;
357 this->read_buf = tx4925ndfmc_nand_read_buf;
358 this->verify_buf = tx4925ndfmc_nand_verify_buf;
359
360 /* Scan to find existance of the device */
361 if (nand_scan (tx4925ndfmc_mtd, 1)) {
362 err = -ENXIO;
363 goto out_ior;
364 }
365
366 /* Register the partitions */
367#ifdef CONFIG_MTD_CMDLINE_PARTS
368 {
369 int mtd_parts_nb = 0;
370 struct mtd_partition *mtd_parts = 0;
371 mtd_parts_nb = parse_cmdline_partitions(tx4925ndfmc_mtd, &mtd_parts, "tx4925ndfmc");
372 if (mtd_parts_nb > 0)
373 add_mtd_partitions(tx4925ndfmc_mtd, mtd_parts, mtd_parts_nb);
374 else
375 add_mtd_device(tx4925ndfmc_mtd);
376 }
377#else /* ifdef CONFIG_MTD_CMDLINE_PARTS */
378 switch(tx4925ndfmc_mtd->size){
379 case 0x01000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info16k, NUM_PARTITIONS16K); break;
380 case 0x02000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info32k, NUM_PARTITIONS32K); break;
381 case 0x04000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info64k, NUM_PARTITIONS64K); break;
382 case 0x08000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info128k, NUM_PARTITIONS128K); break;
383 default: {
384 printk ("Unsupported SmartMedia device\n");
385 err = -ENXIO;
386 goto out_ior;
387 }
388 }
389#endif /* ifdef CONFIG_MTD_CMDLINE_PARTS */
390 goto out;
391
392out_ior:
393out:
394 return err;
395}
396
397module_init(tx4925ndfmc_init);
398
399/*
400 * Clean up routine
401 */
402#ifdef MODULE
403static void __exit tx4925ndfmc_cleanup (void)
404{
405 /* Release resources, unregister device */
406 nand_release (tx4925ndfmc_mtd);
407
408 /* Free the MTD device structure */
409 kfree (tx4925ndfmc_mtd);
410}
411module_exit(tx4925ndfmc_cleanup);
412#endif
413
414MODULE_LICENSE("GPL");
415MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
416MODULE_DESCRIPTION("Glue layer for SmartMediaCard on Toshiba RBTX4925");
diff --git a/drivers/mtd/nand/tx4938ndfmc.c b/drivers/mtd/nand/tx4938ndfmc.c
deleted file mode 100644
index df26e58820b3..000000000000
--- a/drivers/mtd/nand/tx4938ndfmc.c
+++ /dev/null
@@ -1,406 +0,0 @@
1/*
2 * drivers/mtd/nand/tx4938ndfmc.c
3 *
4 * Overview:
5 * This is a device driver for the NAND flash device connected to
6 * TX4938 internal NAND Memory Controller.
7 * TX4938 NDFMC is almost same as TX4925 NDFMC, but register size are 64 bit.
8 *
9 * Author: source@mvista.com
10 *
11 * Based on spia.c by Steven J. Hill
12 *
13 * $Id: tx4938ndfmc.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $
14 *
15 * Copyright (C) 2000-2001 Toshiba Corporation
16 *
17 * 2003 (c) MontaVista Software, Inc. This file is licensed under the
18 * terms of the GNU General Public License version 2. This program is
19 * licensed "as is" without any warranty of any kind, whether express
20 * or implied.
21 */
22#include <linux/config.h>
23#include <linux/slab.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/mtd/mtd.h>
27#include <linux/mtd/nand.h>
28#include <linux/mtd/nand_ecc.h>
29#include <linux/mtd/partitions.h>
30#include <asm/io.h>
31#include <asm/bootinfo.h>
32#include <linux/delay.h>
33#include <asm/tx4938/rbtx4938.h>
34
35extern struct nand_oobinfo jffs2_oobinfo;
36
37/*
38 * MTD structure for TX4938 NDFMC
39 */
40static struct mtd_info *tx4938ndfmc_mtd;
41
42/*
43 * Define partitions for flash device
44 */
45#define flush_wb() (void)tx4938_ndfmcptr->mcr;
46
47#define NUM_PARTITIONS 3
48#define NUMBER_OF_CIS_BLOCKS 24
49#define SIZE_OF_BLOCK 0x00004000
50#define NUMBER_OF_BLOCK_PER_ZONE 1024
51#define SIZE_OF_ZONE (NUMBER_OF_BLOCK_PER_ZONE * SIZE_OF_BLOCK)
52#ifndef CONFIG_MTD_CMDLINE_PARTS
53/*
54 * You can use the following sample of MTD partitions
55 * on the NAND Flash Memory 32MB or more.
56 *
57 * The following figure shows the image of the sample partition on
58 * the 32MB NAND Flash Memory.
59 *
60 * Block No.
61 * 0 +-----------------------------+ ------
62 * | CIS | ^
63 * 24 +-----------------------------+ |
64 * | kernel image | | Zone 0
65 * | | |
66 * +-----------------------------+ |
67 * 1023 | unused area | v
68 * +-----------------------------+ ------
69 * 1024 | JFFS2 | ^
70 * | | |
71 * | | | Zone 1
72 * | | |
73 * | | |
74 * | | v
75 * 2047 +-----------------------------+ ------
76 *
77 */
78static struct mtd_partition partition_info[NUM_PARTITIONS] = {
79 {
80 .name = "RBTX4938 CIS Area",
81 .offset = 0,
82 .size = (NUMBER_OF_CIS_BLOCKS * SIZE_OF_BLOCK),
83 .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
84 },
85 {
86 .name = "RBTX4938 kernel image",
87 .offset = MTDPART_OFS_APPEND,
88 .size = 8 * 0x00100000, /* 8MB (Depends on size of kernel image) */
89 .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
90 },
91 {
92 .name = "Root FS (JFFS2)",
93 .offset = (0 + SIZE_OF_ZONE), /* start address of next zone */
94 .size = MTDPART_SIZ_FULL
95 },
96};
97#endif
98
99static void tx4938ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
100{
101 switch (cmd) {
102 case NAND_CTL_SETCLE:
103 tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CLE;
104 break;
105 case NAND_CTL_CLRCLE:
106 tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CLE;
107 break;
108 case NAND_CTL_SETALE:
109 tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_ALE;
110 break;
111 case NAND_CTL_CLRALE:
112 tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_ALE;
113 break;
114 /* TX4938_NDFMCR_CE bit is 0:high 1:low */
115 case NAND_CTL_SETNCE:
116 tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CE;
117 break;
118 case NAND_CTL_CLRNCE:
119 tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CE;
120 break;
121 case NAND_CTL_SETWP:
122 tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_WE;
123 break;
124 case NAND_CTL_CLRWP:
125 tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_WE;
126 break;
127 }
128}
129static int tx4938ndfmc_dev_ready(struct mtd_info *mtd)
130{
131 flush_wb();
132 return !(tx4938_ndfmcptr->sr & TX4938_NDFSR_BUSY);
133}
134static void tx4938ndfmc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
135{
136 u32 mcr = tx4938_ndfmcptr->mcr;
137 mcr &= ~TX4938_NDFMCR_ECC_ALL;
138 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
139 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_READ;
140 ecc_code[1] = tx4938_ndfmcptr->dtr;
141 ecc_code[0] = tx4938_ndfmcptr->dtr;
142 ecc_code[2] = tx4938_ndfmcptr->dtr;
143 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
144}
145static void tx4938ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
146{
147 u32 mcr = tx4938_ndfmcptr->mcr;
148 mcr &= ~TX4938_NDFMCR_ECC_ALL;
149 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_RESET;
150 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
151 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_ON;
152}
153
154static u_char tx4938ndfmc_nand_read_byte(struct mtd_info *mtd)
155{
156 struct nand_chip *this = mtd->priv;
157 return tx4938_read_nfmc(this->IO_ADDR_R);
158}
159
160static void tx4938ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
161{
162 struct nand_chip *this = mtd->priv;
163 tx4938_write_nfmc(byte, this->IO_ADDR_W);
164}
165
166static void tx4938ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
167{
168 int i;
169 struct nand_chip *this = mtd->priv;
170
171 for (i=0; i<len; i++)
172 tx4938_write_nfmc(buf[i], this->IO_ADDR_W);
173}
174
175static void tx4938ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
176{
177 int i;
178 struct nand_chip *this = mtd->priv;
179
180 for (i=0; i<len; i++)
181 buf[i] = tx4938_read_nfmc(this->IO_ADDR_R);
182}
183
184static int tx4938ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
185{
186 int i;
187 struct nand_chip *this = mtd->priv;
188
189 for (i=0; i<len; i++)
190 if (buf[i] != tx4938_read_nfmc(this->IO_ADDR_R))
191 return -EFAULT;
192
193 return 0;
194}
195
196/*
197 * Send command to NAND device
198 */
199static void tx4938ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
200{
201 register struct nand_chip *this = mtd->priv;
202
203 /* Begin command latch cycle */
204 this->hwcontrol(mtd, NAND_CTL_SETCLE);
205 /*
206 * Write out the command to the device.
207 */
208 if (command == NAND_CMD_SEQIN) {
209 int readcmd;
210
211 if (column >= mtd->oobblock) {
212 /* OOB area */
213 column -= mtd->oobblock;
214 readcmd = NAND_CMD_READOOB;
215 } else if (column < 256) {
216 /* First 256 bytes --> READ0 */
217 readcmd = NAND_CMD_READ0;
218 } else {
219 column -= 256;
220 readcmd = NAND_CMD_READ1;
221 }
222 this->write_byte(mtd, readcmd);
223 }
224 this->write_byte(mtd, command);
225
226 /* Set ALE and clear CLE to start address cycle */
227 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
228
229 if (column != -1 || page_addr != -1) {
230 this->hwcontrol(mtd, NAND_CTL_SETALE);
231
232 /* Serially input address */
233 if (column != -1)
234 this->write_byte(mtd, column);
235 if (page_addr != -1) {
236 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
237 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
238 /* One more address cycle for higher density devices */
239 if (mtd->size & 0x0c000000)
240 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
241 }
242 /* Latch in address */
243 this->hwcontrol(mtd, NAND_CTL_CLRALE);
244 }
245
246 /*
247 * program and erase have their own busy handlers
248 * status and sequential in needs no delay
249 */
250 switch (command) {
251
252 case NAND_CMD_PAGEPROG:
253 /* Turn off WE */
254 this->hwcontrol (mtd, NAND_CTL_CLRWP);
255 return;
256
257 case NAND_CMD_SEQIN:
258 /* Turn on WE */
259 this->hwcontrol (mtd, NAND_CTL_SETWP);
260 return;
261
262 case NAND_CMD_ERASE1:
263 case NAND_CMD_ERASE2:
264 case NAND_CMD_STATUS:
265 return;
266
267 case NAND_CMD_RESET:
268 if (this->dev_ready)
269 break;
270 this->hwcontrol(mtd, NAND_CTL_SETCLE);
271 this->write_byte(mtd, NAND_CMD_STATUS);
272 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
273 while ( !(this->read_byte(mtd) & 0x40));
274 return;
275
276 /* This applies to read commands */
277 default:
278 /*
279 * If we don't have access to the busy pin, we apply the given
280 * command delay
281 */
282 if (!this->dev_ready) {
283 udelay (this->chip_delay);
284 return;
285 }
286 }
287
288 /* wait until command is processed */
289 while (!this->dev_ready(mtd));
290}
291
292#ifdef CONFIG_MTD_CMDLINE_PARTS
293extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
294#endif
295/*
296 * Main initialization routine
297 */
298int __init tx4938ndfmc_init (void)
299{
300 struct nand_chip *this;
301 int bsprt = 0, hold = 0xf, spw = 0xf;
302 int protected = 0;
303
304 if ((*rbtx4938_piosel_ptr & 0x0c) != 0x08) {
305 printk("TX4938 NDFMC: disabled by IOC PIOSEL\n");
306 return -ENODEV;
307 }
308 bsprt = 1;
309 hold = 2;
310 spw = 9 - 1; /* 8 GBUSCLK = 80ns (@ GBUSCLK 100MHz) */
311
312 if ((tx4938_ccfgptr->pcfg &
313 (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL))
314 != TX4938_PCFG_NDF_SEL) {
315 printk("TX4938 NDFMC: disabled by PCFG.\n");
316 return -ENODEV;
317 }
318
319 /* reset NDFMC */
320 tx4938_ndfmcptr->rstr |= TX4938_NDFRSTR_RST;
321 while (tx4938_ndfmcptr->rstr & TX4938_NDFRSTR_RST)
322 ;
323 /* setup BusSeparete, Hold Time, Strobe Pulse Width */
324 tx4938_ndfmcptr->mcr = bsprt ? TX4938_NDFMCR_BSPRT : 0;
325 tx4938_ndfmcptr->spr = hold << 4 | spw;
326
327 /* Allocate memory for MTD device structure and private data */
328 tx4938ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
329 GFP_KERNEL);
330 if (!tx4938ndfmc_mtd) {
331 printk ("Unable to allocate TX4938 NDFMC MTD device structure.\n");
332 return -ENOMEM;
333 }
334
335 /* Get pointer to private data */
336 this = (struct nand_chip *) (&tx4938ndfmc_mtd[1]);
337
338 /* Initialize structures */
339 memset((char *) tx4938ndfmc_mtd, 0, sizeof(struct mtd_info));
340 memset((char *) this, 0, sizeof(struct nand_chip));
341
342 /* Link the private data with the MTD structure */
343 tx4938ndfmc_mtd->priv = this;
344
345 /* Set address of NAND IO lines */
346 this->IO_ADDR_R = (unsigned long)&tx4938_ndfmcptr->dtr;
347 this->IO_ADDR_W = (unsigned long)&tx4938_ndfmcptr->dtr;
348 this->hwcontrol = tx4938ndfmc_hwcontrol;
349 this->dev_ready = tx4938ndfmc_dev_ready;
350 this->calculate_ecc = tx4938ndfmc_calculate_ecc;
351 this->correct_data = nand_correct_data;
352 this->enable_hwecc = tx4938ndfmc_enable_hwecc;
353 this->eccmode = NAND_ECC_HW3_256;
354 this->chip_delay = 100;
355 this->read_byte = tx4938ndfmc_nand_read_byte;
356 this->write_byte = tx4938ndfmc_nand_write_byte;
357 this->cmdfunc = tx4938ndfmc_nand_command;
358 this->write_buf = tx4938ndfmc_nand_write_buf;
359 this->read_buf = tx4938ndfmc_nand_read_buf;
360 this->verify_buf = tx4938ndfmc_nand_verify_buf;
361
362 /* Scan to find existance of the device */
363 if (nand_scan (tx4938ndfmc_mtd, 1)) {
364 kfree (tx4938ndfmc_mtd);
365 return -ENXIO;
366 }
367
368 if (protected) {
369 printk(KERN_INFO "TX4938 NDFMC: write protected.\n");
370 tx4938ndfmc_mtd->flags &= ~(MTD_WRITEABLE | MTD_ERASEABLE);
371 }
372
373#ifdef CONFIG_MTD_CMDLINE_PARTS
374 {
375 int mtd_parts_nb = 0;
376 struct mtd_partition *mtd_parts = 0;
377 mtd_parts_nb = parse_cmdline_partitions(tx4938ndfmc_mtd, &mtd_parts, "tx4938ndfmc");
378 if (mtd_parts_nb > 0)
379 add_mtd_partitions(tx4938ndfmc_mtd, mtd_parts, mtd_parts_nb);
380 else
381 add_mtd_device(tx4938ndfmc_mtd);
382 }
383#else
384 add_mtd_partitions(tx4938ndfmc_mtd, partition_info, NUM_PARTITIONS );
385#endif
386
387 return 0;
388}
389module_init(tx4938ndfmc_init);
390
391/*
392 * Clean up routine
393 */
394static void __exit tx4938ndfmc_cleanup (void)
395{
396 /* Release resources, unregister device */
397 nand_release (tx4938ndfmc_mtd);
398
399 /* Free the MTD device structure */
400 kfree (tx4938ndfmc_mtd);
401}
402module_exit(tx4938ndfmc_cleanup);
403
404MODULE_LICENSE("GPL");
405MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
406MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on TX4938 NDFMC");