linux/drivers/mtd/nand/sh_flctl.c
<<
>>
Prefs
   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