Merge branch 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[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 = NAND_BBT_SCAN2NDPAGE,
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, int sector_number)
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                                 if (flctl->page_size)
187                                         index = (512 * sector_number) +
188                                                 (data >> 16);
189                                 else
190                                         index = data >> 16;
191
192                                 org = flctl->done_buff[index];
193                                 flctl->done_buff[index] = org ^ (data & 0xFF);
194                                 checked[i] = 1;
195                         }
196                 }
197
198                 writel(0, FL4ECCCR(flctl));
199         }
200
201         printk(KERN_ERR "wait_recfifo_ready(): Timeout occured \n");
202         return 1;       /* timeout */
203 }
204
205 static void wait_wecfifo_ready(struct sh_flctl *flctl)
206 {
207         uint32_t timeout = LOOP_TIMEOUT_MAX;
208         uint32_t len;
209
210         while (timeout--) {
211                 /* check FLECFIFO */
212                 len = (readl(FLDTCNTR(flctl)) >> 24) & 0xFF;
213                 if (len >= 4)
214                         return;
215                 udelay(1);
216         }
217         printk(KERN_ERR "wait_wecfifo_ready(): Timeout occured \n");
218 }
219
220 static void read_datareg(struct sh_flctl *flctl, int offset)
221 {
222         unsigned long data;
223         unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
224
225         wait_completion(flctl);
226
227         data = readl(FLDATAR(flctl));
228         *buf = le32_to_cpu(data);
229 }
230
231 static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
232 {
233         int i, len_4align;
234         unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
235         void *fifo_addr = (void *)FLDTFIFO(flctl);
236
237         len_4align = (rlen + 3) / 4;
238
239         for (i = 0; i < len_4align; i++) {
240                 wait_rfifo_ready(flctl);
241                 buf[i] = readl(fifo_addr);
242                 buf[i] = be32_to_cpu(buf[i]);
243         }
244 }
245
246 static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
247 {
248         int i;
249         unsigned long *ecc_buf = (unsigned long *)buff;
250         void *fifo_addr = (void *)FLECFIFO(flctl);
251
252         for (i = 0; i < 4; i++) {
253                 if (wait_recfifo_ready(flctl , sector))
254                         return 1;
255                 ecc_buf[i] = readl(fifo_addr);
256                 ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
257         }
258
259         return 0;
260 }
261
262 static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
263 {
264         int i, len_4align;
265         unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
266         void *fifo_addr = (void *)FLDTFIFO(flctl);
267
268         len_4align = (rlen + 3) / 4;
269         for (i = 0; i < len_4align; i++) {
270                 wait_wfifo_ready(flctl);
271                 writel(cpu_to_be32(data[i]), fifo_addr);
272         }
273 }
274
275 static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
276 {
277         struct sh_flctl *flctl = mtd_to_flctl(mtd);
278         uint32_t flcmncr_val = readl(FLCMNCR(flctl));
279         uint32_t flcmdcr_val, addr_len_bytes = 0;
280
281         /* Set SNAND bit if page size is 2048byte */
282         if (flctl->page_size)
283                 flcmncr_val |= SNAND_E;
284         else
285                 flcmncr_val &= ~SNAND_E;
286
287         /* default FLCMDCR val */
288         flcmdcr_val = DOCMD1_E | DOADR_E;
289
290         /* Set for FLCMDCR */
291         switch (cmd) {
292         case NAND_CMD_ERASE1:
293                 addr_len_bytes = flctl->erase_ADRCNT;
294                 flcmdcr_val |= DOCMD2_E;
295                 break;
296         case NAND_CMD_READ0:
297         case NAND_CMD_READOOB:
298                 addr_len_bytes = flctl->rw_ADRCNT;
299                 flcmdcr_val |= CDSRC_E;
300                 break;
301         case NAND_CMD_SEQIN:
302                 /* This case is that cmd is READ0 or READ1 or READ00 */
303                 flcmdcr_val &= ~DOADR_E;        /* ONLY execute 1st cmd */
304                 break;
305         case NAND_CMD_PAGEPROG:
306                 addr_len_bytes = flctl->rw_ADRCNT;
307                 flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW;
308                 break;
309         case NAND_CMD_READID:
310                 flcmncr_val &= ~SNAND_E;
311                 addr_len_bytes = ADRCNT_1;
312                 break;
313         case NAND_CMD_STATUS:
314         case NAND_CMD_RESET:
315                 flcmncr_val &= ~SNAND_E;
316                 flcmdcr_val &= ~(DOADR_E | DOSR_E);
317                 break;
318         default:
319                 break;
320         }
321
322         /* Set address bytes parameter */
323         flcmdcr_val |= addr_len_bytes;
324
325         /* Now actually write */
326         writel(flcmncr_val, FLCMNCR(flctl));
327         writel(flcmdcr_val, FLCMDCR(flctl));
328         writel(flcmcdr_val, FLCMCDR(flctl));
329 }
330
331 static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
332                                 uint8_t *buf, int page)
333 {
334         int i, eccsize = chip->ecc.size;
335         int eccbytes = chip->ecc.bytes;
336         int eccsteps = chip->ecc.steps;
337         uint8_t *p = buf;
338         struct sh_flctl *flctl = mtd_to_flctl(mtd);
339
340         for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
341                 chip->read_buf(mtd, p, eccsize);
342
343         for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
344                 if (flctl->hwecc_cant_correct[i])
345                         mtd->ecc_stats.failed++;
346                 else
347                         mtd->ecc_stats.corrected += 0;
348         }
349
350         return 0;
351 }
352
353 static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
354                                    const uint8_t *buf)
355 {
356         int i, eccsize = chip->ecc.size;
357         int eccbytes = chip->ecc.bytes;
358         int eccsteps = chip->ecc.steps;
359         const uint8_t *p = buf;
360
361         for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
362                 chip->write_buf(mtd, p, eccsize);
363 }
364
365 static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
366 {
367         struct sh_flctl *flctl = mtd_to_flctl(mtd);
368         int sector, page_sectors;
369
370         if (flctl->page_size)
371                 page_sectors = 4;
372         else
373                 page_sectors = 1;
374
375         writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
376                  FLCMNCR(flctl));
377
378         set_cmd_regs(mtd, NAND_CMD_READ0,
379                 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
380
381         for (sector = 0; sector < page_sectors; sector++) {
382                 int ret;
383
384                 empty_fifo(flctl);
385                 writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
386                 writel(page_addr << 2 | sector, FLADR(flctl));
387
388                 start_translation(flctl);
389                 read_fiforeg(flctl, 512, 512 * sector);
390
391                 ret = read_ecfiforeg(flctl,
392                         &flctl->done_buff[mtd->writesize + 16 * sector],
393                         sector);
394
395                 if (ret)
396                         flctl->hwecc_cant_correct[sector] = 1;
397
398                 writel(0x0, FL4ECCCR(flctl));
399                 wait_completion(flctl);
400         }
401         writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),
402                         FLCMNCR(flctl));
403 }
404
405 static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
406 {
407         struct sh_flctl *flctl = mtd_to_flctl(mtd);
408
409         set_cmd_regs(mtd, NAND_CMD_READ0,
410                 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
411
412         empty_fifo(flctl);
413         if (flctl->page_size) {
414                 int i;
415                 /* In case that the page size is 2k */
416                 for (i = 0; i < 16 * 3; i++)
417                         flctl->done_buff[i] = 0xFF;
418
419                 set_addr(mtd, 3 * 528 + 512, page_addr);
420                 writel(16, FLDTCNTR(flctl));
421
422                 start_translation(flctl);
423                 read_fiforeg(flctl, 16, 16 * 3);
424                 wait_completion(flctl);
425         } else {
426                 /* In case that the page size is 512b */
427                 set_addr(mtd, 512, page_addr);
428                 writel(16, FLDTCNTR(flctl));
429
430                 start_translation(flctl);
431                 read_fiforeg(flctl, 16, 0);
432                 wait_completion(flctl);
433         }
434 }
435
436 static void execmd_write_page_sector(struct mtd_info *mtd)
437 {
438         struct sh_flctl *flctl = mtd_to_flctl(mtd);
439         int i, page_addr = flctl->seqin_page_addr;
440         int sector, page_sectors;
441
442         if (flctl->page_size)
443                 page_sectors = 4;
444         else
445                 page_sectors = 1;
446
447         writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
448
449         set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
450                         (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
451
452         for (sector = 0; sector < page_sectors; sector++) {
453                 empty_fifo(flctl);
454                 writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
455                 writel(page_addr << 2 | sector, FLADR(flctl));
456
457                 start_translation(flctl);
458                 write_fiforeg(flctl, 512, 512 * sector);
459
460                 for (i = 0; i < 4; i++) {
461                         wait_wecfifo_ready(flctl); /* wait for write ready */
462                         writel(0xFFFFFFFF, FLECFIFO(flctl));
463                 }
464                 wait_completion(flctl);
465         }
466
467         writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));
468 }
469
470 static void execmd_write_oob(struct mtd_info *mtd)
471 {
472         struct sh_flctl *flctl = mtd_to_flctl(mtd);
473         int page_addr = flctl->seqin_page_addr;
474         int sector, page_sectors;
475
476         if (flctl->page_size) {
477                 sector = 3;
478                 page_sectors = 4;
479         } else {
480                 sector = 0;
481                 page_sectors = 1;
482         }
483
484         set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
485                         (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
486
487         for (; sector < page_sectors; sector++) {
488                 empty_fifo(flctl);
489                 set_addr(mtd, sector * 528 + 512, page_addr);
490                 writel(16, FLDTCNTR(flctl));    /* set read size */
491
492                 start_translation(flctl);
493                 write_fiforeg(flctl, 16, 16 * sector);
494                 wait_completion(flctl);
495         }
496 }
497
498 static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,
499                         int column, int page_addr)
500 {
501         struct sh_flctl *flctl = mtd_to_flctl(mtd);
502         uint32_t read_cmd = 0;
503
504         flctl->read_bytes = 0;
505         if (command != NAND_CMD_PAGEPROG)
506                 flctl->index = 0;
507
508         switch (command) {
509         case NAND_CMD_READ1:
510         case NAND_CMD_READ0:
511                 if (flctl->hwecc) {
512                         /* read page with hwecc */
513                         execmd_read_page_sector(mtd, page_addr);
514                         break;
515                 }
516                 empty_fifo(flctl);
517                 if (flctl->page_size)
518                         set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
519                                 | command);
520                 else
521                         set_cmd_regs(mtd, command, command);
522
523                 set_addr(mtd, 0, page_addr);
524
525                 flctl->read_bytes = mtd->writesize + mtd->oobsize;
526                 flctl->index += column;
527                 goto read_normal_exit;
528
529         case NAND_CMD_READOOB:
530                 if (flctl->hwecc) {
531                         /* read page with hwecc */
532                         execmd_read_oob(mtd, page_addr);
533                         break;
534                 }
535
536                 empty_fifo(flctl);
537                 if (flctl->page_size) {
538                         set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
539                                 | NAND_CMD_READ0);
540                         set_addr(mtd, mtd->writesize, page_addr);
541                 } else {
542                         set_cmd_regs(mtd, command, command);
543                         set_addr(mtd, 0, page_addr);
544                 }
545                 flctl->read_bytes = mtd->oobsize;
546                 goto read_normal_exit;
547
548         case NAND_CMD_READID:
549                 empty_fifo(flctl);
550                 set_cmd_regs(mtd, command, command);
551                 set_addr(mtd, 0, 0);
552
553                 flctl->read_bytes = 4;
554                 writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
555                 start_translation(flctl);
556                 read_datareg(flctl, 0); /* read and end */
557                 break;
558
559         case NAND_CMD_ERASE1:
560                 flctl->erase1_page_addr = page_addr;
561                 break;
562
563         case NAND_CMD_ERASE2:
564                 set_cmd_regs(mtd, NAND_CMD_ERASE1,
565                         (command << 8) | NAND_CMD_ERASE1);
566                 set_addr(mtd, -1, flctl->erase1_page_addr);
567                 start_translation(flctl);
568                 wait_completion(flctl);
569                 break;
570
571         case NAND_CMD_SEQIN:
572                 if (!flctl->page_size) {
573                         /* output read command */
574                         if (column >= mtd->writesize) {
575                                 column -= mtd->writesize;
576                                 read_cmd = NAND_CMD_READOOB;
577                         } else if (column < 256) {
578                                 read_cmd = NAND_CMD_READ0;
579                         } else {
580                                 column -= 256;
581                                 read_cmd = NAND_CMD_READ1;
582                         }
583                 }
584                 flctl->seqin_column = column;
585                 flctl->seqin_page_addr = page_addr;
586                 flctl->seqin_read_cmd = read_cmd;
587                 break;
588
589         case NAND_CMD_PAGEPROG:
590                 empty_fifo(flctl);
591                 if (!flctl->page_size) {
592                         set_cmd_regs(mtd, NAND_CMD_SEQIN,
593                                         flctl->seqin_read_cmd);
594                         set_addr(mtd, -1, -1);
595                         writel(0, FLDTCNTR(flctl));     /* set 0 size */
596                         start_translation(flctl);
597                         wait_completion(flctl);
598                 }
599                 if (flctl->hwecc) {
600                         /* write page with hwecc */
601                         if (flctl->seqin_column == mtd->writesize)
602                                 execmd_write_oob(mtd);
603                         else if (!flctl->seqin_column)
604                                 execmd_write_page_sector(mtd);
605                         else
606                                 printk(KERN_ERR "Invalid address !?\n");
607                         break;
608                 }
609                 set_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN);
610                 set_addr(mtd, flctl->seqin_column, flctl->seqin_page_addr);
611                 writel(flctl->index, FLDTCNTR(flctl));  /* set write size */
612                 start_translation(flctl);
613                 write_fiforeg(flctl, flctl->index, 0);
614                 wait_completion(flctl);
615                 break;
616
617         case NAND_CMD_STATUS:
618                 set_cmd_regs(mtd, command, command);
619                 set_addr(mtd, -1, -1);
620
621                 flctl->read_bytes = 1;
622                 writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
623                 start_translation(flctl);
624                 read_datareg(flctl, 0); /* read and end */
625                 break;
626
627         case NAND_CMD_RESET:
628                 set_cmd_regs(mtd, command, command);
629                 set_addr(mtd, -1, -1);
630
631                 writel(0, FLDTCNTR(flctl));     /* set 0 size */
632                 start_translation(flctl);
633                 wait_completion(flctl);
634                 break;
635
636         default:
637                 break;
638         }
639         return;
640
641 read_normal_exit:
642         writel(flctl->read_bytes, FLDTCNTR(flctl));     /* set read size */
643         start_translation(flctl);
644         read_fiforeg(flctl, flctl->read_bytes, 0);
645         wait_completion(flctl);
646         return;
647 }
648
649 static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
650 {
651         struct sh_flctl *flctl = mtd_to_flctl(mtd);
652         uint32_t flcmncr_val = readl(FLCMNCR(flctl));
653
654         switch (chipnr) {
655         case -1:
656                 flcmncr_val &= ~CE0_ENABLE;
657                 writel(flcmncr_val, FLCMNCR(flctl));
658                 break;
659         case 0:
660                 flcmncr_val |= CE0_ENABLE;
661                 writel(flcmncr_val, FLCMNCR(flctl));
662                 break;
663         default:
664                 BUG();
665         }
666 }
667
668 static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
669 {
670         struct sh_flctl *flctl = mtd_to_flctl(mtd);
671         int i, index = flctl->index;
672
673         for (i = 0; i < len; i++)
674                 flctl->done_buff[index + i] = buf[i];
675         flctl->index += len;
676 }
677
678 static uint8_t flctl_read_byte(struct mtd_info *mtd)
679 {
680         struct sh_flctl *flctl = mtd_to_flctl(mtd);
681         int index = flctl->index;
682         uint8_t data;
683
684         data = flctl->done_buff[index];
685         flctl->index++;
686         return data;
687 }
688
689 static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
690 {
691         int i;
692
693         for (i = 0; i < len; i++)
694                 buf[i] = flctl_read_byte(mtd);
695 }
696
697 static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
698 {
699         int i;
700
701         for (i = 0; i < len; i++)
702                 if (buf[i] != flctl_read_byte(mtd))
703                         return -EFAULT;
704         return 0;
705 }
706
707 static void flctl_register_init(struct sh_flctl *flctl, unsigned long val)
708 {
709         writel(val, FLCMNCR(flctl));
710 }
711
712 static int flctl_chip_init_tail(struct mtd_info *mtd)
713 {
714         struct sh_flctl *flctl = mtd_to_flctl(mtd);
715         struct nand_chip *chip = &flctl->chip;
716
717         if (mtd->writesize == 512) {
718                 flctl->page_size = 0;
719                 if (chip->chipsize > (32 << 20)) {
720                         /* big than 32MB */
721                         flctl->rw_ADRCNT = ADRCNT_4;
722                         flctl->erase_ADRCNT = ADRCNT_3;
723                 } else if (chip->chipsize > (2 << 16)) {
724                         /* big than 128KB */
725                         flctl->rw_ADRCNT = ADRCNT_3;
726                         flctl->erase_ADRCNT = ADRCNT_2;
727                 } else {
728                         flctl->rw_ADRCNT = ADRCNT_2;
729                         flctl->erase_ADRCNT = ADRCNT_1;
730                 }
731         } else {
732                 flctl->page_size = 1;
733                 if (chip->chipsize > (128 << 20)) {
734                         /* big than 128MB */
735                         flctl->rw_ADRCNT = ADRCNT2_E;
736                         flctl->erase_ADRCNT = ADRCNT_3;
737                 } else if (chip->chipsize > (8 << 16)) {
738                         /* big than 512KB */
739                         flctl->rw_ADRCNT = ADRCNT_4;
740                         flctl->erase_ADRCNT = ADRCNT_2;
741                 } else {
742                         flctl->rw_ADRCNT = ADRCNT_3;
743                         flctl->erase_ADRCNT = ADRCNT_1;
744                 }
745         }
746
747         if (flctl->hwecc) {
748                 if (mtd->writesize == 512) {
749                         chip->ecc.layout = &flctl_4secc_oob_16;
750                         chip->badblock_pattern = &flctl_4secc_smallpage;
751                 } else {
752                         chip->ecc.layout = &flctl_4secc_oob_64;
753                         chip->badblock_pattern = &flctl_4secc_largepage;
754                 }
755
756                 chip->ecc.size = 512;
757                 chip->ecc.bytes = 10;
758                 chip->ecc.read_page = flctl_read_page_hwecc;
759                 chip->ecc.write_page = flctl_write_page_hwecc;
760                 chip->ecc.mode = NAND_ECC_HW;
761
762                 /* 4 symbols ECC enabled */
763                 writel(readl(FLCMNCR(flctl)) | _4ECCEN | ECCPOS2 | ECCPOS_02,
764                                 FLCMNCR(flctl));
765         } else {
766                 chip->ecc.mode = NAND_ECC_SOFT;
767         }
768
769         return 0;
770 }
771
772 static int __init flctl_probe(struct platform_device *pdev)
773 {
774         struct resource *res;
775         struct sh_flctl *flctl;
776         struct mtd_info *flctl_mtd;
777         struct nand_chip *nand;
778         struct sh_flctl_platform_data *pdata;
779         int ret;
780
781         pdata = pdev->dev.platform_data;
782         if (pdata == NULL) {
783                 printk(KERN_ERR "sh_flctl platform_data not found.\n");
784                 return -ENODEV;
785         }
786
787         flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
788         if (!flctl) {
789                 printk(KERN_ERR "Unable to allocate NAND MTD dev structure.\n");
790                 return -ENOMEM;
791         }
792
793         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
794         if (!res) {
795                 printk(KERN_ERR "%s: resource not found.\n", __func__);
796                 ret = -ENODEV;
797                 goto err;
798         }
799
800         flctl->reg = ioremap(res->start, res->end - res->start + 1);
801         if (flctl->reg == NULL) {
802                 printk(KERN_ERR "%s: ioremap error.\n", __func__);
803                 ret = -ENOMEM;
804                 goto err;
805         }
806
807         platform_set_drvdata(pdev, flctl);
808         flctl_mtd = &flctl->mtd;
809         nand = &flctl->chip;
810         flctl_mtd->priv = nand;
811         flctl->hwecc = pdata->has_hwecc;
812
813         flctl_register_init(flctl, pdata->flcmncr_val);
814
815         nand->options = NAND_NO_AUTOINCR;
816
817         /* Set address of hardware control function */
818         /* 20 us command delay time */
819         nand->chip_delay = 20;
820
821         nand->read_byte = flctl_read_byte;
822         nand->write_buf = flctl_write_buf;
823         nand->read_buf = flctl_read_buf;
824         nand->verify_buf = flctl_verify_buf;
825         nand->select_chip = flctl_select_chip;
826         nand->cmdfunc = flctl_cmdfunc;
827
828         ret = nand_scan_ident(flctl_mtd, 1);
829         if (ret)
830                 goto err;
831
832         ret = flctl_chip_init_tail(flctl_mtd);
833         if (ret)
834                 goto err;
835
836         ret = nand_scan_tail(flctl_mtd);
837         if (ret)
838                 goto err;
839
840         add_mtd_partitions(flctl_mtd, pdata->parts, pdata->nr_parts);
841
842         return 0;
843
844 err:
845         kfree(flctl);
846         return ret;
847 }
848
849 static int __exit flctl_remove(struct platform_device *pdev)
850 {
851         struct sh_flctl *flctl = platform_get_drvdata(pdev);
852
853         nand_release(&flctl->mtd);
854         kfree(flctl);
855
856         return 0;
857 }
858
859 static struct platform_driver flctl_driver = {
860         .remove         = flctl_remove,
861         .driver = {
862                 .name   = "sh_flctl",
863                 .owner  = THIS_MODULE,
864         },
865 };
866
867 static int __init flctl_nand_init(void)
868 {
869         return platform_driver_probe(&flctl_driver, flctl_probe);
870 }
871
872 static void __exit flctl_nand_cleanup(void)
873 {
874         platform_driver_unregister(&flctl_driver);
875 }
876
877 module_init(flctl_nand_init);
878 module_exit(flctl_nand_cleanup);
879
880 MODULE_LICENSE("GPL");
881 MODULE_AUTHOR("Yoshihiro Shimoda");
882 MODULE_DESCRIPTION("SuperH FLCTL driver");
883 MODULE_ALIAS("platform:sh_flctl");