LANANA: Fix dates
[pandora-kernel.git] / drivers / mtd / nand / sh_flctl.c
1 /*
2  * SuperH FLCTL nand controller
3  *
4  * Copyright © 2008 Renesas Solutions Corp.
5  * Copyright © 2008 Atom Create Engineering Co., Ltd.
6  *
7  * Based on fsl_elbc_nand.c, Copyright © 2006-2007 Freescale Semiconductor
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; version 2 of the License.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/delay.h>
27 #include <linux/io.h>
28 #include <linux/platform_device.h>
29
30 #include <linux/mtd/mtd.h>
31 #include <linux/mtd/nand.h>
32 #include <linux/mtd/partitions.h>
33 #include <linux/mtd/sh_flctl.h>
34
35 static struct nand_ecclayout flctl_4secc_oob_16 = {
36         .eccbytes = 10,
37         .eccpos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
38         .oobfree = {
39                 {.offset = 12,
40                 . length = 4} },
41 };
42
43 static struct nand_ecclayout flctl_4secc_oob_64 = {
44         .eccbytes = 10,
45         .eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57},
46         .oobfree = {
47                 {.offset = 60,
48                 . length = 4} },
49 };
50
51 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
52
53 static struct nand_bbt_descr flctl_4secc_smallpage = {
54         .options = NAND_BBT_SCAN2NDPAGE,
55         .offs = 11,
56         .len = 1,
57         .pattern = scan_ff_pattern,
58 };
59
60 static struct nand_bbt_descr flctl_4secc_largepage = {
61         .options = 0,
62         .offs = 58,
63         .len = 2,
64         .pattern = scan_ff_pattern,
65 };
66
67 static void empty_fifo(struct sh_flctl *flctl)
68 {
69         writel(0x000c0000, FLINTDMACR(flctl));  /* FIFO Clear */
70         writel(0x00000000, FLINTDMACR(flctl));  /* Clear Error flags */
71 }
72
73 static void start_translation(struct sh_flctl *flctl)
74 {
75         writeb(TRSTRT, FLTRCR(flctl));
76 }
77
78 static void wait_completion(struct sh_flctl *flctl)
79 {
80         uint32_t timeout = LOOP_TIMEOUT_MAX;
81
82         while (timeout--) {
83                 if (readb(FLTRCR(flctl)) & TREND) {
84                         writeb(0x0, FLTRCR(flctl));
85                         return;
86                 }
87                 udelay(1);
88         }
89
90         printk(KERN_ERR "wait_completion(): Timeout occured \n");
91         writeb(0x0, FLTRCR(flctl));
92 }
93
94 static void set_addr(struct mtd_info *mtd, int column, int page_addr)
95 {
96         struct sh_flctl *flctl = mtd_to_flctl(mtd);
97         uint32_t addr = 0;
98
99         if (column == -1) {
100                 addr = page_addr;       /* ERASE1 */
101         } else if (page_addr != -1) {
102                 /* SEQIN, READ0, etc.. */
103                 if (flctl->page_size) {
104                         addr = column & 0x0FFF;
105                         addr |= (page_addr & 0xff) << 16;
106                         addr |= ((page_addr >> 8) & 0xff) << 24;
107                         /* big than 128MB */
108                         if (flctl->rw_ADRCNT == ADRCNT2_E) {
109                                 uint32_t        addr2;
110                                 addr2 = (page_addr >> 16) & 0xff;
111                                 writel(addr2, FLADR2(flctl));
112                         }
113                 } else {
114                         addr = column;
115                         addr |= (page_addr & 0xff) << 8;
116                         addr |= ((page_addr >> 8) & 0xff) << 16;
117                         addr |= ((page_addr >> 16) & 0xff) << 24;
118                 }
119         }
120         writel(addr, FLADR(flctl));
121 }
122
123 static void wait_rfifo_ready(struct sh_flctl *flctl)
124 {
125         uint32_t timeout = LOOP_TIMEOUT_MAX;
126
127         while (timeout--) {
128                 uint32_t val;
129                 /* check FIFO */
130                 val = readl(FLDTCNTR(flctl)) >> 16;
131                 if (val & 0xFF)
132                         return;
133                 udelay(1);
134         }
135         printk(KERN_ERR "wait_rfifo_ready(): Timeout occured \n");
136 }
137
138 static void wait_wfifo_ready(struct sh_flctl *flctl)
139 {
140         uint32_t len, timeout = LOOP_TIMEOUT_MAX;
141
142         while (timeout--) {
143                 /* check FIFO */
144                 len = (readl(FLDTCNTR(flctl)) >> 16) & 0xFF;
145                 if (len >= 4)
146                         return;
147                 udelay(1);
148         }
149         printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n");
150 }
151
152 static int wait_recfifo_ready(struct sh_flctl *flctl)
153 {
154         uint32_t timeout = LOOP_TIMEOUT_MAX;
155         int checked[4];
156         void __iomem *ecc_reg[4];
157         int i;
158         uint32_t data, size;
159
160         memset(checked, 0, sizeof(checked));
161
162         while (timeout--) {
163                 size = readl(FLDTCNTR(flctl)) >> 24;
164                 if (size & 0xFF)
165                         return 0;       /* success */
166
167                 if (readl(FL4ECCCR(flctl)) & _4ECCFA)
168                         return 1;       /* can't correct */
169
170                 udelay(1);
171                 if (!(readl(FL4ECCCR(flctl)) & _4ECCEND))
172                         continue;
173
174                 /* start error correction */
175                 ecc_reg[0] = FL4ECCRESULT0(flctl);
176                 ecc_reg[1] = FL4ECCRESULT1(flctl);
177                 ecc_reg[2] = FL4ECCRESULT2(flctl);
178                 ecc_reg[3] = FL4ECCRESULT3(flctl);
179
180                 for (i = 0; i < 3; i++) {
181                         data = readl(ecc_reg[i]);
182                         if (data != INIT_FL4ECCRESULT_VAL && !checked[i]) {
183                                 uint8_t org;
184                                 int index;
185
186                                 index = data >> 16;
187                                 org = flctl->done_buff[index];
188                                 flctl->done_buff[index] = org ^ (data & 0xFF);
189                                 checked[i] = 1;
190                         }
191                 }
192
193                 writel(0, FL4ECCCR(flctl));
194         }
195
196         printk(KERN_ERR "wait_recfifo_ready(): Timeout occured \n");
197         return 1;       /* timeout */
198 }
199
200 static void wait_wecfifo_ready(struct sh_flctl *flctl)
201 {
202         uint32_t timeout = LOOP_TIMEOUT_MAX;
203         uint32_t len;
204
205         while (timeout--) {
206                 /* check FLECFIFO */
207                 len = (readl(FLDTCNTR(flctl)) >> 24) & 0xFF;
208                 if (len >= 4)
209                         return;
210                 udelay(1);
211         }
212         printk(KERN_ERR "wait_wecfifo_ready(): Timeout occured \n");
213 }
214
215 static void read_datareg(struct sh_flctl *flctl, int offset)
216 {
217         unsigned long data;
218         unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
219
220         wait_completion(flctl);
221
222         data = readl(FLDATAR(flctl));
223         *buf = le32_to_cpu(data);
224 }
225
226 static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
227 {
228         int i, len_4align;
229         unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
230         void *fifo_addr = (void *)FLDTFIFO(flctl);
231
232         len_4align = (rlen + 3) / 4;
233
234         for (i = 0; i < len_4align; i++) {
235                 wait_rfifo_ready(flctl);
236                 buf[i] = readl(fifo_addr);
237                 buf[i] = be32_to_cpu(buf[i]);
238         }
239 }
240
241 static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff)
242 {
243         int i;
244         unsigned long *ecc_buf = (unsigned long *)buff;
245         void *fifo_addr = (void *)FLECFIFO(flctl);
246
247         for (i = 0; i < 4; i++) {
248                 if (wait_recfifo_ready(flctl))
249                         return 1;
250                 ecc_buf[i] = readl(fifo_addr);
251                 ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
252         }
253
254         return 0;
255 }
256
257 static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
258 {
259         int i, len_4align;
260         unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
261         void *fifo_addr = (void *)FLDTFIFO(flctl);
262
263         len_4align = (rlen + 3) / 4;
264         for (i = 0; i < len_4align; i++) {
265                 wait_wfifo_ready(flctl);
266                 writel(cpu_to_be32(data[i]), fifo_addr);
267         }
268 }
269
270 static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
271 {
272         struct sh_flctl *flctl = mtd_to_flctl(mtd);
273         uint32_t flcmncr_val = readl(FLCMNCR(flctl));
274         uint32_t flcmdcr_val, addr_len_bytes = 0;
275
276         /* Set SNAND bit if page size is 2048byte */
277         if (flctl->page_size)
278                 flcmncr_val |= SNAND_E;
279         else
280                 flcmncr_val &= ~SNAND_E;
281
282         /* default FLCMDCR val */
283         flcmdcr_val = DOCMD1_E | DOADR_E;
284
285         /* Set for FLCMDCR */
286         switch (cmd) {
287         case NAND_CMD_ERASE1:
288                 addr_len_bytes = flctl->erase_ADRCNT;
289                 flcmdcr_val |= DOCMD2_E;
290                 break;
291         case NAND_CMD_READ0:
292         case NAND_CMD_READOOB:
293                 addr_len_bytes = flctl->rw_ADRCNT;
294                 flcmdcr_val |= CDSRC_E;
295                 break;
296         case NAND_CMD_SEQIN:
297                 /* This case is that cmd is READ0 or READ1 or READ00 */
298                 flcmdcr_val &= ~DOADR_E;        /* ONLY execute 1st cmd */
299                 break;
300         case NAND_CMD_PAGEPROG:
301                 addr_len_bytes = flctl->rw_ADRCNT;
302                 flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW;
303                 break;
304         case NAND_CMD_READID:
305                 flcmncr_val &= ~SNAND_E;
306                 addr_len_bytes = ADRCNT_1;
307                 break;
308         case NAND_CMD_STATUS:
309         case NAND_CMD_RESET:
310                 flcmncr_val &= ~SNAND_E;
311                 flcmdcr_val &= ~(DOADR_E | DOSR_E);
312                 break;
313         default:
314                 break;
315         }
316
317         /* Set address bytes parameter */
318         flcmdcr_val |= addr_len_bytes;
319
320         /* Now actually write */
321         writel(flcmncr_val, FLCMNCR(flctl));
322         writel(flcmdcr_val, FLCMDCR(flctl));
323         writel(flcmcdr_val, FLCMCDR(flctl));
324 }
325
326 static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
327                                 uint8_t *buf)
328 {
329         int i, eccsize = chip->ecc.size;
330         int eccbytes = chip->ecc.bytes;
331         int eccsteps = chip->ecc.steps;
332         uint8_t *p = buf;
333         struct sh_flctl *flctl = mtd_to_flctl(mtd);
334
335         for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
336                 chip->read_buf(mtd, p, eccsize);
337
338         for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
339                 if (flctl->hwecc_cant_correct[i])
340                         mtd->ecc_stats.failed++;
341                 else
342                         mtd->ecc_stats.corrected += 0;
343         }
344
345         return 0;
346 }
347
348 static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
349                                    const uint8_t *buf)
350 {
351         int i, eccsize = chip->ecc.size;
352         int eccbytes = chip->ecc.bytes;
353         int eccsteps = chip->ecc.steps;
354         const uint8_t *p = buf;
355
356         for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
357                 chip->write_buf(mtd, p, eccsize);
358 }
359
360 static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
361 {
362         struct sh_flctl *flctl = mtd_to_flctl(mtd);
363         int sector, page_sectors;
364
365         if (flctl->page_size)
366                 page_sectors = 4;
367         else
368                 page_sectors = 1;
369
370         writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
371                  FLCMNCR(flctl));
372
373         set_cmd_regs(mtd, NAND_CMD_READ0,
374                 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
375
376         for (sector = 0; sector < page_sectors; sector++) {
377                 int ret;
378
379                 empty_fifo(flctl);
380                 writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
381                 writel(page_addr << 2 | sector, FLADR(flctl));
382
383                 start_translation(flctl);
384                 read_fiforeg(flctl, 512, 512 * sector);
385
386                 ret = read_ecfiforeg(flctl,
387                         &flctl->done_buff[mtd->writesize + 16 * sector]);
388
389                 if (ret)
390                         flctl->hwecc_cant_correct[sector] = 1;
391
392                 writel(0x0, FL4ECCCR(flctl));
393                 wait_completion(flctl);
394         }
395         writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),
396                         FLCMNCR(flctl));
397 }
398
399 static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
400 {
401         struct sh_flctl *flctl = mtd_to_flctl(mtd);
402
403         set_cmd_regs(mtd, NAND_CMD_READ0,
404                 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
405
406         empty_fifo(flctl);
407         if (flctl->page_size) {
408                 int i;
409                 /* In case that the page size is 2k */
410                 for (i = 0; i < 16 * 3; i++)
411                         flctl->done_buff[i] = 0xFF;
412
413                 set_addr(mtd, 3 * 528 + 512, page_addr);
414                 writel(16, FLDTCNTR(flctl));
415
416                 start_translation(flctl);
417                 read_fiforeg(flctl, 16, 16 * 3);
418                 wait_completion(flctl);
419         } else {
420                 /* In case that the page size is 512b */
421                 set_addr(mtd, 512, page_addr);
422                 writel(16, FLDTCNTR(flctl));
423
424                 start_translation(flctl);
425                 read_fiforeg(flctl, 16, 0);
426                 wait_completion(flctl);
427         }
428 }
429
430 static void execmd_write_page_sector(struct mtd_info *mtd)
431 {
432         struct sh_flctl *flctl = mtd_to_flctl(mtd);
433         int i, page_addr = flctl->seqin_page_addr;
434         int sector, page_sectors;
435
436         if (flctl->page_size)
437                 page_sectors = 4;
438         else
439                 page_sectors = 1;
440
441         writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
442
443         set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
444                         (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
445
446         for (sector = 0; sector < page_sectors; sector++) {
447                 empty_fifo(flctl);
448                 writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
449                 writel(page_addr << 2 | sector, FLADR(flctl));
450
451                 start_translation(flctl);
452                 write_fiforeg(flctl, 512, 512 * sector);
453
454                 for (i = 0; i < 4; i++) {
455                         wait_wecfifo_ready(flctl); /* wait for write ready */
456                         writel(0xFFFFFFFF, FLECFIFO(flctl));
457                 }
458                 wait_completion(flctl);
459         }
460
461         writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));
462 }
463
464 static void execmd_write_oob(struct mtd_info *mtd)
465 {
466         struct sh_flctl *flctl = mtd_to_flctl(mtd);
467         int page_addr = flctl->seqin_page_addr;
468         int sector, page_sectors;
469
470         if (flctl->page_size) {
471                 sector = 3;
472                 page_sectors = 4;
473         } else {
474                 sector = 0;
475                 page_sectors = 1;
476         }
477
478         set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
479                         (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
480
481         for (; sector < page_sectors; sector++) {
482                 empty_fifo(flctl);
483                 set_addr(mtd, sector * 528 + 512, page_addr);
484                 writel(16, FLDTCNTR(flctl));    /* set read size */
485
486                 start_translation(flctl);
487                 write_fiforeg(flctl, 16, 16 * sector);
488                 wait_completion(flctl);
489         }
490 }
491
492 static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,
493                         int column, int page_addr)
494 {
495         struct sh_flctl *flctl = mtd_to_flctl(mtd);
496         uint32_t read_cmd = 0;
497
498         flctl->read_bytes = 0;
499         if (command != NAND_CMD_PAGEPROG)
500                 flctl->index = 0;
501
502         switch (command) {
503         case NAND_CMD_READ1:
504         case NAND_CMD_READ0:
505                 if (flctl->hwecc) {
506                         /* read page with hwecc */
507                         execmd_read_page_sector(mtd, page_addr);
508                         break;
509                 }
510                 empty_fifo(flctl);
511                 if (flctl->page_size)
512                         set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
513                                 | command);
514                 else
515                         set_cmd_regs(mtd, command, command);
516
517                 set_addr(mtd, 0, page_addr);
518
519                 flctl->read_bytes = mtd->writesize + mtd->oobsize;
520                 flctl->index += column;
521                 goto read_normal_exit;
522
523         case NAND_CMD_READOOB:
524                 if (flctl->hwecc) {
525                         /* read page with hwecc */
526                         execmd_read_oob(mtd, page_addr);
527                         break;
528                 }
529
530                 empty_fifo(flctl);
531                 if (flctl->page_size) {
532                         set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
533                                 | NAND_CMD_READ0);
534                         set_addr(mtd, mtd->writesize, page_addr);
535                 } else {
536                         set_cmd_regs(mtd, command, command);
537                         set_addr(mtd, 0, page_addr);
538                 }
539                 flctl->read_bytes = mtd->oobsize;
540                 goto read_normal_exit;
541
542         case NAND_CMD_READID:
543                 empty_fifo(flctl);
544                 set_cmd_regs(mtd, command, command);
545                 set_addr(mtd, 0, 0);
546
547                 flctl->read_bytes = 4;
548                 writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
549                 start_translation(flctl);
550                 read_datareg(flctl, 0); /* read and end */
551                 break;
552
553         case NAND_CMD_ERASE1:
554                 flctl->erase1_page_addr = page_addr;
555                 break;
556
557         case NAND_CMD_ERASE2:
558                 set_cmd_regs(mtd, NAND_CMD_ERASE1,
559                         (command << 8) | NAND_CMD_ERASE1);
560                 set_addr(mtd, -1, flctl->erase1_page_addr);
561                 start_translation(flctl);
562                 wait_completion(flctl);
563                 break;
564
565         case NAND_CMD_SEQIN:
566                 if (!flctl->page_size) {
567                         /* output read command */
568                         if (column >= mtd->writesize) {
569                                 column -= mtd->writesize;
570                                 read_cmd = NAND_CMD_READOOB;
571                         } else if (column < 256) {
572                                 read_cmd = NAND_CMD_READ0;
573                         } else {
574                                 column -= 256;
575                                 read_cmd = NAND_CMD_READ1;
576                         }
577                 }
578                 flctl->seqin_column = column;
579                 flctl->seqin_page_addr = page_addr;
580                 flctl->seqin_read_cmd = read_cmd;
581                 break;
582
583         case NAND_CMD_PAGEPROG:
584                 empty_fifo(flctl);
585                 if (!flctl->page_size) {
586                         set_cmd_regs(mtd, NAND_CMD_SEQIN,
587                                         flctl->seqin_read_cmd);
588                         set_addr(mtd, -1, -1);
589                         writel(0, FLDTCNTR(flctl));     /* set 0 size */
590                         start_translation(flctl);
591                         wait_completion(flctl);
592                 }
593                 if (flctl->hwecc) {
594                         /* write page with hwecc */
595                         if (flctl->seqin_column == mtd->writesize)
596                                 execmd_write_oob(mtd);
597                         else if (!flctl->seqin_column)
598                                 execmd_write_page_sector(mtd);
599                         else
600                                 printk(KERN_ERR "Invalid address !?\n");
601                         break;
602                 }
603                 set_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN);
604                 set_addr(mtd, flctl->seqin_column, flctl->seqin_page_addr);
605                 writel(flctl->index, FLDTCNTR(flctl));  /* set write size */
606                 start_translation(flctl);
607                 write_fiforeg(flctl, flctl->index, 0);
608                 wait_completion(flctl);
609                 break;
610
611         case NAND_CMD_STATUS:
612                 set_cmd_regs(mtd, command, command);
613                 set_addr(mtd, -1, -1);
614
615                 flctl->read_bytes = 1;
616                 writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
617                 start_translation(flctl);
618                 read_datareg(flctl, 0); /* read and end */
619                 break;
620
621         case NAND_CMD_RESET:
622                 set_cmd_regs(mtd, command, command);
623                 set_addr(mtd, -1, -1);
624
625                 writel(0, FLDTCNTR(flctl));     /* set 0 size */
626                 start_translation(flctl);
627                 wait_completion(flctl);
628                 break;
629
630         default:
631                 break;
632         }
633         return;
634
635 read_normal_exit:
636         writel(flctl->read_bytes, FLDTCNTR(flctl));     /* set read size */
637         start_translation(flctl);
638         read_fiforeg(flctl, flctl->read_bytes, 0);
639         wait_completion(flctl);
640         return;
641 }
642
643 static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
644 {
645         struct sh_flctl *flctl = mtd_to_flctl(mtd);
646         uint32_t flcmncr_val = readl(FLCMNCR(flctl));
647
648         switch (chipnr) {
649         case -1:
650                 flcmncr_val &= ~CE0_ENABLE;
651                 writel(flcmncr_val, FLCMNCR(flctl));
652                 break;
653         case 0:
654                 flcmncr_val |= CE0_ENABLE;
655                 writel(flcmncr_val, FLCMNCR(flctl));
656                 break;
657         default:
658                 BUG();
659         }
660 }
661
662 static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
663 {
664         struct sh_flctl *flctl = mtd_to_flctl(mtd);
665         int i, index = flctl->index;
666
667         for (i = 0; i < len; i++)
668                 flctl->done_buff[index + i] = buf[i];
669         flctl->index += len;
670 }
671
672 static uint8_t flctl_read_byte(struct mtd_info *mtd)
673 {
674         struct sh_flctl *flctl = mtd_to_flctl(mtd);
675         int index = flctl->index;
676         uint8_t data;
677
678         data = flctl->done_buff[index];
679         flctl->index++;
680         return data;
681 }
682
683 static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
684 {
685         int i;
686
687         for (i = 0; i < len; i++)
688                 buf[i] = flctl_read_byte(mtd);
689 }
690
691 static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
692 {
693         int i;
694
695         for (i = 0; i < len; i++)
696                 if (buf[i] != flctl_read_byte(mtd))
697                         return -EFAULT;
698         return 0;
699 }
700
701 static void flctl_register_init(struct sh_flctl *flctl, unsigned long val)
702 {
703         writel(val, FLCMNCR(flctl));
704 }
705
706 static int flctl_chip_init_tail(struct mtd_info *mtd)
707 {
708         struct sh_flctl *flctl = mtd_to_flctl(mtd);
709         struct nand_chip *chip = &flctl->chip;
710
711         if (mtd->writesize == 512) {
712                 flctl->page_size = 0;
713                 if (chip->chipsize > (32 << 20)) {
714                         /* big than 32MB */
715                         flctl->rw_ADRCNT = ADRCNT_4;
716                         flctl->erase_ADRCNT = ADRCNT_3;
717                 } else if (chip->chipsize > (2 << 16)) {
718                         /* big than 128KB */
719                         flctl->rw_ADRCNT = ADRCNT_3;
720                         flctl->erase_ADRCNT = ADRCNT_2;
721                 } else {
722                         flctl->rw_ADRCNT = ADRCNT_2;
723                         flctl->erase_ADRCNT = ADRCNT_1;
724                 }
725         } else {
726                 flctl->page_size = 1;
727                 if (chip->chipsize > (128 << 20)) {
728                         /* big than 128MB */
729                         flctl->rw_ADRCNT = ADRCNT2_E;
730                         flctl->erase_ADRCNT = ADRCNT_3;
731                 } else if (chip->chipsize > (8 << 16)) {
732                         /* big than 512KB */
733                         flctl->rw_ADRCNT = ADRCNT_4;
734                         flctl->erase_ADRCNT = ADRCNT_2;
735                 } else {
736                         flctl->rw_ADRCNT = ADRCNT_3;
737                         flctl->erase_ADRCNT = ADRCNT_1;
738                 }
739         }
740
741         if (flctl->hwecc) {
742                 if (mtd->writesize == 512) {
743                         chip->ecc.layout = &flctl_4secc_oob_16;
744                         chip->badblock_pattern = &flctl_4secc_smallpage;
745                 } else {
746                         chip->ecc.layout = &flctl_4secc_oob_64;
747                         chip->badblock_pattern = &flctl_4secc_largepage;
748                 }
749
750                 chip->ecc.size = 512;
751                 chip->ecc.bytes = 10;
752                 chip->ecc.read_page = flctl_read_page_hwecc;
753                 chip->ecc.write_page = flctl_write_page_hwecc;
754                 chip->ecc.mode = NAND_ECC_HW;
755
756                 /* 4 symbols ECC enabled */
757                 writel(readl(FLCMNCR(flctl)) | _4ECCEN | ECCPOS2 | ECCPOS_02,
758                                 FLCMNCR(flctl));
759         } else {
760                 chip->ecc.mode = NAND_ECC_SOFT;
761         }
762
763         return 0;
764 }
765
766 static int __init flctl_probe(struct platform_device *pdev)
767 {
768         struct resource *res;
769         struct sh_flctl *flctl;
770         struct mtd_info *flctl_mtd;
771         struct nand_chip *nand;
772         struct sh_flctl_platform_data *pdata;
773         int ret;
774
775         pdata = pdev->dev.platform_data;
776         if (pdata == NULL) {
777                 printk(KERN_ERR "sh_flctl platform_data not found.\n");
778                 return -ENODEV;
779         }
780
781         flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
782         if (!flctl) {
783                 printk(KERN_ERR "Unable to allocate NAND MTD dev structure.\n");
784                 return -ENOMEM;
785         }
786
787         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
788         if (!res) {
789                 printk(KERN_ERR "%s: resource not found.\n", __func__);
790                 ret = -ENODEV;
791                 goto err;
792         }
793
794         flctl->reg = ioremap(res->start, res->end - res->start + 1);
795         if (flctl->reg == NULL) {
796                 printk(KERN_ERR "%s: ioremap error.\n", __func__);
797                 ret = -ENOMEM;
798                 goto err;
799         }
800
801         platform_set_drvdata(pdev, flctl);
802         flctl_mtd = &flctl->mtd;
803         nand = &flctl->chip;
804         flctl_mtd->priv = nand;
805         flctl->hwecc = pdata->has_hwecc;
806
807         flctl_register_init(flctl, pdata->flcmncr_val);
808
809         nand->options = NAND_NO_AUTOINCR;
810
811         /* Set address of hardware control function */
812         /* 20 us command delay time */
813         nand->chip_delay = 20;
814
815         nand->read_byte = flctl_read_byte;
816         nand->write_buf = flctl_write_buf;
817         nand->read_buf = flctl_read_buf;
818         nand->verify_buf = flctl_verify_buf;
819         nand->select_chip = flctl_select_chip;
820         nand->cmdfunc = flctl_cmdfunc;
821
822         ret = nand_scan_ident(flctl_mtd, 1);
823         if (ret)
824                 goto err;
825
826         ret = flctl_chip_init_tail(flctl_mtd);
827         if (ret)
828                 goto err;
829
830         ret = nand_scan_tail(flctl_mtd);
831         if (ret)
832                 goto err;
833
834         add_mtd_partitions(flctl_mtd, pdata->parts, pdata->nr_parts);
835
836         return 0;
837
838 err:
839         kfree(flctl);
840         return ret;
841 }
842
843 static int __exit flctl_remove(struct platform_device *pdev)
844 {
845         struct sh_flctl *flctl = platform_get_drvdata(pdev);
846
847         nand_release(&flctl->mtd);
848         kfree(flctl);
849
850         return 0;
851 }
852
853 static struct platform_driver flctl_driver = {
854         .probe          = flctl_probe,
855         .remove         = flctl_remove,
856         .driver = {
857                 .name   = "sh_flctl",
858                 .owner  = THIS_MODULE,
859         },
860 };
861
862 static int __init flctl_nand_init(void)
863 {
864         return platform_driver_register(&flctl_driver);
865 }
866
867 static void __exit flctl_nand_cleanup(void)
868 {
869         platform_driver_unregister(&flctl_driver);
870 }
871
872 module_init(flctl_nand_init);
873 module_exit(flctl_nand_cleanup);
874
875 MODULE_LICENSE("GPL");
876 MODULE_AUTHOR("Yoshihiro Shimoda");
877 MODULE_DESCRIPTION("SuperH FLCTL driver");
878 MODULE_ALIAS("platform:sh_flctl");