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