1
2
3
4
5
6#include <linux/slab.h>
7#include <linux/module.h>
8#include <linux/interrupt.h>
9#include <linux/mtd/mtd.h>
10#include <linux/mtd/rawnand.h>
11#include <linux/mtd/partitions.h>
12#include <linux/platform_device.h>
13#include <asm/io.h>
14#include <asm/mach-au1x00/au1000.h>
15#include <asm/mach-au1x00/au1550nd.h>
16
17
18struct au1550nd_ctx {
19 struct nand_chip chip;
20
21 int cs;
22 void __iomem *base;
23 void (*write_byte)(struct nand_chip *, u_char);
24};
25
26
27
28
29
30
31
32static u_char au_read_byte(struct nand_chip *this)
33{
34 u_char ret = readb(this->legacy.IO_ADDR_R);
35 wmb();
36 return ret;
37}
38
39
40
41
42
43
44
45
46static void au_write_byte(struct nand_chip *this, u_char byte)
47{
48 writeb(byte, this->legacy.IO_ADDR_W);
49 wmb();
50}
51
52
53
54
55
56
57
58static u_char au_read_byte16(struct nand_chip *this)
59{
60 u_char ret = (u_char) cpu_to_le16(readw(this->legacy.IO_ADDR_R));
61 wmb();
62 return ret;
63}
64
65
66
67
68
69
70
71
72static void au_write_byte16(struct nand_chip *this, u_char byte)
73{
74 writew(le16_to_cpu((u16) byte), this->legacy.IO_ADDR_W);
75 wmb();
76}
77
78
79
80
81
82
83
84
85
86static void au_write_buf(struct nand_chip *this, const u_char *buf, int len)
87{
88 int i;
89
90 for (i = 0; i < len; i++) {
91 writeb(buf[i], this->legacy.IO_ADDR_W);
92 wmb();
93 }
94}
95
96
97
98
99
100
101
102
103
104static void au_read_buf(struct nand_chip *this, u_char *buf, int len)
105{
106 int i;
107
108 for (i = 0; i < len; i++) {
109 buf[i] = readb(this->legacy.IO_ADDR_R);
110 wmb();
111 }
112}
113
114
115
116
117
118
119
120
121
122static void au_write_buf16(struct nand_chip *this, const u_char *buf, int len)
123{
124 int i;
125 u16 *p = (u16 *) buf;
126 len >>= 1;
127
128 for (i = 0; i < len; i++) {
129 writew(p[i], this->legacy.IO_ADDR_W);
130 wmb();
131 }
132
133}
134
135
136
137
138
139
140
141
142
143static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
144{
145 int i;
146 struct nand_chip *this = mtd_to_nand(mtd);
147 u16 *p = (u16 *) buf;
148 len >>= 1;
149
150 for (i = 0; i < len; i++) {
151 p[i] = readw(this->legacy.IO_ADDR_R);
152 wmb();
153 }
154}
155
156
157#define NAND_CTL_SETNCE 1
158
159#define NAND_CTL_CLRNCE 2
160
161#define NAND_CTL_SETCLE 3
162
163#define NAND_CTL_CLRCLE 4
164
165#define NAND_CTL_SETALE 5
166
167#define NAND_CTL_CLRALE 6
168
169static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
170{
171 struct nand_chip *this = mtd_to_nand(mtd);
172 struct au1550nd_ctx *ctx = container_of(this, struct au1550nd_ctx,
173 chip);
174
175 switch (cmd) {
176
177 case NAND_CTL_SETCLE:
178 this->legacy.IO_ADDR_W = ctx->base + MEM_STNAND_CMD;
179 break;
180
181 case NAND_CTL_CLRCLE:
182 this->legacy.IO_ADDR_W = ctx->base + MEM_STNAND_DATA;
183 break;
184
185 case NAND_CTL_SETALE:
186 this->legacy.IO_ADDR_W = ctx->base + MEM_STNAND_ADDR;
187 break;
188
189 case NAND_CTL_CLRALE:
190 this->legacy.IO_ADDR_W = ctx->base + MEM_STNAND_DATA;
191
192
193 udelay(1);
194 break;
195
196 case NAND_CTL_SETNCE:
197
198 alchemy_wrsmem((1 << (4 + ctx->cs)), AU1000_MEM_STNDCTL);
199 break;
200
201 case NAND_CTL_CLRNCE:
202
203 alchemy_wrsmem(0, AU1000_MEM_STNDCTL);
204 break;
205 }
206
207 this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W;
208
209 wmb();
210}
211
212int au1550_device_ready(struct nand_chip *this)
213{
214 return (alchemy_rdsmem(AU1000_MEM_STSTAT) & 0x1) ? 1 : 0;
215}
216
217
218
219
220
221
222
223
224
225
226
227
228
229static void au1550_select_chip(struct nand_chip *this, int chip)
230{
231}
232
233
234
235
236
237
238
239
240static void au1550_command(struct nand_chip *this, unsigned command,
241 int column, int page_addr)
242{
243 struct mtd_info *mtd = nand_to_mtd(this);
244 struct au1550nd_ctx *ctx = container_of(this, struct au1550nd_ctx,
245 chip);
246 int ce_override = 0, i;
247 unsigned long flags = 0;
248
249
250 au1550_hwcontrol(mtd, NAND_CTL_SETCLE);
251
252
253
254 if (command == NAND_CMD_SEQIN) {
255 int readcmd;
256
257 if (column >= mtd->writesize) {
258
259 column -= mtd->writesize;
260 readcmd = NAND_CMD_READOOB;
261 } else if (column < 256) {
262
263 readcmd = NAND_CMD_READ0;
264 } else {
265 column -= 256;
266 readcmd = NAND_CMD_READ1;
267 }
268 ctx->write_byte(this, readcmd);
269 }
270 ctx->write_byte(this, command);
271
272
273 au1550_hwcontrol(mtd, NAND_CTL_CLRCLE);
274
275 if (column != -1 || page_addr != -1) {
276 au1550_hwcontrol(mtd, NAND_CTL_SETALE);
277
278
279 if (column != -1) {
280
281 if (this->options & NAND_BUSWIDTH_16 &&
282 !nand_opcode_8bits(command))
283 column >>= 1;
284 ctx->write_byte(this, column);
285 }
286 if (page_addr != -1) {
287 ctx->write_byte(this, (u8)(page_addr & 0xff));
288
289 if (command == NAND_CMD_READ0 ||
290 command == NAND_CMD_READ1 ||
291 command == NAND_CMD_READOOB) {
292
293
294
295
296
297
298
299
300 ce_override = 1;
301 local_irq_save(flags);
302 au1550_hwcontrol(mtd, NAND_CTL_SETNCE);
303 }
304
305 ctx->write_byte(this, (u8)(page_addr >> 8));
306
307 if (this->options & NAND_ROW_ADDR_3)
308 ctx->write_byte(this,
309 ((page_addr >> 16) & 0x0f));
310 }
311
312 au1550_hwcontrol(mtd, NAND_CTL_CLRALE);
313 }
314
315
316
317
318
319 switch (command) {
320
321 case NAND_CMD_PAGEPROG:
322 case NAND_CMD_ERASE1:
323 case NAND_CMD_ERASE2:
324 case NAND_CMD_SEQIN:
325 case NAND_CMD_STATUS:
326 return;
327
328 case NAND_CMD_RESET:
329 break;
330
331 case NAND_CMD_READ0:
332 case NAND_CMD_READ1:
333 case NAND_CMD_READOOB:
334
335 if (unlikely(!ce_override))
336 break;
337
338
339 ndelay(100);
340
341 for (i = this->legacy.chip_delay;
342 !this->legacy.dev_ready(this) && i > 0; --i)
343 udelay(1);
344
345
346 au1550_hwcontrol(mtd, NAND_CTL_CLRNCE);
347 local_irq_restore(flags);
348 return;
349 }
350
351 ndelay(100);
352
353 while(!this->legacy.dev_ready(this));
354}
355
356static int find_nand_cs(unsigned long nand_base)
357{
358 void __iomem *base =
359 (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR);
360 unsigned long addr, staddr, start, mask, end;
361 int i;
362
363 for (i = 0; i < 4; i++) {
364 addr = 0x1000 + (i * 0x10);
365 staddr = __raw_readl(base + addr + 0x08);
366
367 start = (staddr << 4) & 0xfffc0000;
368 mask = (staddr << 18) & 0xfffc0000;
369 end = (start | (start - 1)) & ~(start ^ mask);
370 if ((nand_base >= start) && (nand_base < end))
371 return i;
372 }
373
374 return -ENODEV;
375}
376
377static int au1550nd_probe(struct platform_device *pdev)
378{
379 struct au1550nd_platdata *pd;
380 struct au1550nd_ctx *ctx;
381 struct nand_chip *this;
382 struct mtd_info *mtd;
383 struct resource *r;
384 int ret, cs;
385
386 pd = dev_get_platdata(&pdev->dev);
387 if (!pd) {
388 dev_err(&pdev->dev, "missing platform data\n");
389 return -ENODEV;
390 }
391
392 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
393 if (!ctx)
394 return -ENOMEM;
395
396 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
397 if (!r) {
398 dev_err(&pdev->dev, "no NAND memory resource\n");
399 ret = -ENODEV;
400 goto out1;
401 }
402 if (request_mem_region(r->start, resource_size(r), "au1550-nand")) {
403 dev_err(&pdev->dev, "cannot claim NAND memory area\n");
404 ret = -ENOMEM;
405 goto out1;
406 }
407
408 ctx->base = ioremap_nocache(r->start, 0x1000);
409 if (!ctx->base) {
410 dev_err(&pdev->dev, "cannot remap NAND memory area\n");
411 ret = -ENODEV;
412 goto out2;
413 }
414
415 this = &ctx->chip;
416 mtd = nand_to_mtd(this);
417 mtd->dev.parent = &pdev->dev;
418
419
420 cs = find_nand_cs(r->start);
421 if (cs < 0) {
422 dev_err(&pdev->dev, "cannot detect NAND chipselect\n");
423 ret = -ENODEV;
424 goto out3;
425 }
426 ctx->cs = cs;
427
428 this->legacy.dev_ready = au1550_device_ready;
429 this->legacy.select_chip = au1550_select_chip;
430 this->legacy.cmdfunc = au1550_command;
431
432
433 this->legacy.chip_delay = 30;
434 this->ecc.mode = NAND_ECC_SOFT;
435 this->ecc.algo = NAND_ECC_HAMMING;
436
437 if (pd->devwidth)
438 this->options |= NAND_BUSWIDTH_16;
439
440 this->legacy.read_byte = (pd->devwidth) ? au_read_byte16 : au_read_byte;
441 ctx->write_byte = (pd->devwidth) ? au_write_byte16 : au_write_byte;
442 this->legacy.write_buf = (pd->devwidth) ? au_write_buf16 : au_write_buf;
443 this->legacy.read_buf = (pd->devwidth) ? au_read_buf16 : au_read_buf;
444
445 ret = nand_scan(this, 1);
446 if (ret) {
447 dev_err(&pdev->dev, "NAND scan failed with %d\n", ret);
448 goto out3;
449 }
450
451 mtd_device_register(mtd, pd->parts, pd->num_parts);
452
453 platform_set_drvdata(pdev, ctx);
454
455 return 0;
456
457out3:
458 iounmap(ctx->base);
459out2:
460 release_mem_region(r->start, resource_size(r));
461out1:
462 kfree(ctx);
463 return ret;
464}
465
466static int au1550nd_remove(struct platform_device *pdev)
467{
468 struct au1550nd_ctx *ctx = platform_get_drvdata(pdev);
469 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
470
471 nand_release(&ctx->chip);
472 iounmap(ctx->base);
473 release_mem_region(r->start, 0x1000);
474 kfree(ctx);
475 return 0;
476}
477
478static struct platform_driver au1550nd_driver = {
479 .driver = {
480 .name = "au1550-nand",
481 },
482 .probe = au1550nd_probe,
483 .remove = au1550nd_remove,
484};
485
486module_platform_driver(au1550nd_driver);
487
488MODULE_LICENSE("GPL");
489MODULE_AUTHOR("Embedded Edge, LLC");
490MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on Pb1550 board");
491