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