aboutsummaryrefslogtreecommitdiffstats
path: root/packages/linux/compulab-pxa270-2.6.20/0004-nand-driver.patch
blob: f8e05c3c2227062e7b48f0282ee2325fa154c45d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
From nobody Mon Sep 17 00:00:00 2001
From: Cliff Brake <cbrake@happy.dev.bec-systems.com>
Date: Tue Apr 3 11:38:59 2007 -0400
Subject: [PATCH] nand driver

2.6.20 NAND flash driver for cm-x270

---

 drivers/mtd/nand/Kconfig       |    4 +
 drivers/mtd/nand/Makefile      |    1 
 drivers/mtd/nand/cmx270-nand.c |  271 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 276 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/cmx270-nand.c

base a34beb5936e5819d8b2d51b153434825700463ef
last deaa2960bd8fb1f706a935cd7a87321977e6f568
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 358f55a82dbe4ebb73b1b0ee460063a6145e3f0e..c80272bcc69b6e13ab0c4403e4635a8a4076dc6c 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -247,6 +247,10 @@ config MTD_NAND_AT91
 	help
 	  Enables support for NAND Flash / Smart Media Card interface
 	  on Atmel AT91 processors.
+ 
+config MTD_NAND_CM_X270
+  	tristate "Support for NAND Flash on CompuLab CM-X270"
+  	depends on MTD_NAND && ARCH_PXA
 
 config MTD_NAND_NANDSIM
 	tristate "Support for NAND Flash Simulator"
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index f7a53f0b70177451680402a2c2cce4c98991cd6e..d5abbca6d5ae18e287af0b02075f99838d35dc85 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_MTD_NAND_NANDSIM)		+= nandsim.o
 obj-$(CONFIG_MTD_NAND_CS553X)		+= cs553x_nand.o
 obj-$(CONFIG_MTD_NAND_NDFC)		+= ndfc.o
 obj-$(CONFIG_MTD_NAND_AT91)		+= at91_nand.o
+obj-$(CONFIG_MTD_NAND_CM_X270)		+= cmx270-nand.o
 
 nand-objs := nand_base.o nand_bbt.o
 cafe_nand-objs := cafe.o cafe_ecc.o
diff --git a/drivers/mtd/nand/cmx270-nand.c b/drivers/mtd/nand/cmx270-nand.c
new file mode 100644
index 0000000000000000000000000000000000000000..1cd531e610dee846e246b4b1d56bb4119939682b
--- /dev/null
+++ b/drivers/mtd/nand/cmx270-nand.c
@@ -0,0 +1,271 @@
+/*
+ *  drivers/mtd/nand/cmx270-nand.c
+ *
+ *  Copyright (C) 2005 Compulab, Ltd. (mike@compulab.co.il)
+ *                2007 BEC Systems, LLC (cbrake@bec-systems.com)
+ *                     - updated to 2.6.20 NAND API
+ *
+ *  Derived from drivers/mtd/nand/h1910.c
+ *       Copyright (C) 2002 Marius Gr�ger (mag@sysgo.de)
+ *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Overview:
+ *   This is a device driver for the NAND flash device found on the
+ *   CM-X270 board.
+ */
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+
+#define GPIO_NAND_CS	(11)
+#define GPIO_NAND_RB	(89)
+
+#define DRAIN_WB() \
+	do { \
+		unsigned char dummy; \
+		asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); \
+		dummy=*((volatile unsigned char*)UNCACHED_ADDR); \
+	} while(0);
+
+/*
+ * MTD structure for CM-X270 board
+ */
+static struct mtd_info *cmx270_nand_mtd = NULL;
+
+/*
+ * Module stuff
+ */
+
+#ifdef CONFIG_MTD_PARTITIONS
+/*
+ * Define static partitions for flash device
+ */
+static struct mtd_partition partition_info[] = {
+	{
+		.name = "app",
+		.offset = 0,
+		.size = 64*1024*1024
+	},
+	{
+		.name = "data",
+		.offset = MTDPART_OFS_APPEND,
+		.size = MTDPART_SIZ_FULL
+	}
+};
+
+#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
+
+#endif
+
+
+static 	u_char cmx270_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	return (readl(this->IO_ADDR_R) >> 16);
+}
+
+static void cmx270_write_byte(struct mtd_info *mtd, u_char byte)
+{
+	struct nand_chip *this = mtd->priv;
+	writel((byte << 16), this->IO_ADDR_W);
+}
+
+static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+
+	for (i=0; i<len; i++) {
+		writel((*buf++ << 16), this->IO_ADDR_W);
+	}
+}
+
+static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+
+	for (i=0; i<len; i++) {
+		*buf++ = readl(this->IO_ADDR_R) >> 16;
+	}
+}
+
+static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+
+	for (i=0; i<len; i++) {
+		if ( buf[i] != (u_char)(readl(this->IO_ADDR_R) >> 16) )
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
+static inline void nand_cs_on(void)
+{
+	GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+}
+
+static void nand_cs_off(void)
+{
+	DRAIN_WB();
+
+	GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+}
+
+/*
+ *	hardware specific access to control-lines
+ *
+ *	NAND_NCE: bit 0 - GPIO_NAND_CS
+ *	NAND_CLE: bit 1 - address bit 2
+ *	NAND_ALE: bit 2 - address bit 3
+ */
+static void cmx270_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip* chip = mtd->priv;
+
+	DRAIN_WB();
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_NCE) nand_cs_on();
+		else nand_cs_off();
+	}
+
+
+	if (cmd != NAND_CMD_NONE) {
+		writel(cmd << 16, (unsigned int)(chip->IO_ADDR_W) | ((ctrl & 0x6) << 1 ));
+	}
+
+	DRAIN_WB();
+}
+
+/*
+ *	read device ready pin
+ */
+static int cmx270_device_ready(struct mtd_info *mtd)
+{
+	DRAIN_WB();
+	return ( GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB) );
+}
+
+/*
+ * Main initialization routine
+ */
+static int __init cmx270_init (void)
+{
+	struct nand_chip *this;
+	const char *part_type = 0;
+	int mtd_parts_nb = 0;
+	struct mtd_partition *mtd_parts = 0;
+	static unsigned int nandaddr = 0;
+
+
+	/* Allocate memory for MTD device structure and private data */
+	cmx270_nand_mtd = kmalloc(sizeof(struct mtd_info) +
+				    sizeof(struct nand_chip),
+				    GFP_KERNEL);
+	if (!cmx270_nand_mtd) {
+		printk("Unable to allocate CM-X270 NAND MTD device structure.\n");
+		return -ENOMEM;
+	}
+
+	nandaddr = (volatile unsigned int)ioremap(PXA_CS1_PHYS, 100);
+
+	/* Get pointer to private data */
+	this = (struct nand_chip *) (&cmx270_nand_mtd[1]);
+
+	/* Initialize structures */
+	memset((char *) cmx270_nand_mtd, 0, sizeof(struct mtd_info));
+	memset((char *) this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	cmx270_nand_mtd->priv = this;
+	cmx270_nand_mtd->owner = THIS_MODULE;
+
+	/* insert callbacks */
+	this->IO_ADDR_R = (void __iomem *)nandaddr;
+	this->IO_ADDR_W = (void __iomem *)nandaddr;
+	this->cmd_ctrl = cmx270_hwcontrol;
+/* 	this->dev_ready = cmx270_device_ready;	/\* unknown whether that was correct or not so we will just do it like this *\/ */
+
+	/* 15 us command delay time */
+	this->chip_delay = 50;
+	this->ecc.mode = NAND_ECC_SOFT;
+
+	/* read/write functions */
+	this->read_byte = cmx270_read_byte;
+	//this->write_byte = cmx270_write_byte;
+	this->read_buf = cmx270_read_buf;
+	this->write_buf = cmx270_write_buf;
+	this->verify_buf = cmx270_verify_buf;
+
+	/* Scan to find existence of the device */
+	if (nand_scan (cmx270_nand_mtd, 1)) {
+		printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
+		iounmap((void*)nandaddr);
+		kfree (cmx270_nand_mtd);
+		return -ENXIO;
+	}
+
+//#ifdef CONFIG_MTD_CMDLINE_PARTS
+#if 0
+	mtd_parts_nb = parse_cmdline_partitions(cmx270_nand_mtd, &mtd_parts,
+						"cmx270");
+	if (mtd_parts_nb > 0)
+	  part_type = "command line";
+	else
+	  mtd_parts_nb = 0;
+#endif
+	if (mtd_parts_nb == 0)
+	{
+		mtd_parts = partition_info;
+		mtd_parts_nb = NUM_PARTITIONS;
+		part_type = "static";
+	}
+
+	/* Register the partitions */
+	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+	add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb);
+
+	/* Return happy */
+	return 0;
+}
+module_init(cmx270_init);
+
+/*
+ * Clean up routine
+ */
+static void __exit cmx270_cleanup (void)
+{
+	struct nand_chip *this;
+
+	this = (struct nand_chip *) (&cmx270_nand_mtd[1]);
+	iounmap(this->IO_ADDR_R);
+
+	/* Release resources, unregister device */
+	nand_release (cmx270_nand_mtd);
+
+	/* Free the MTD device structure */
+	kfree (cmx270_nand_mtd);
+}
+module_exit(cmx270_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mike Rapoport <mike at compulab dot co dot il>");
+MODULE_DESCRIPTION("NAND flash driver for Compulab CM-X270 Core");
-- 
1.4.4.4