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