uboot/drivers/mtd/onenand/onenand_base.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/mtd/onenand/onenand_base.c
   3 *
   4 *  Copyright (C) 2005-2007 Samsung Electronics
   5 *  Kyungmin Park <kyungmin.park@samsung.com>
   6 *
   7 *  Credits:
   8 *      Adrian Hunter <ext-adrian.hunter@nokia.com>:
   9 *      auto-placement support, read-while load support, various fixes
  10 *      Copyright (C) Nokia Corporation, 2007
  11 *
  12 *      Rohit Hagargundgi <h.rohit at samsung.com>,
  13 *      Amul Kumar Saha <amul.saha@samsung.com>:
  14 *      Flex-OneNAND support
  15 *      Copyright (C) Samsung Electronics, 2009
  16 *
  17 * This program is free software; you can redistribute it and/or modify
  18 * it under the terms of the GNU General Public License version 2 as
  19 * published by the Free Software Foundation.
  20 */
  21
  22#include <common.h>
  23#include <linux/compat.h>
  24#include <linux/mtd/mtd.h>
  25#include "linux/mtd/flashchip.h"
  26#include <linux/mtd/onenand.h>
  27
  28#include <asm/io.h>
  29#include <asm/errno.h>
  30#include <malloc.h>
  31
  32/* It should access 16-bit instead of 8-bit */
  33static void *memcpy_16(void *dst, const void *src, unsigned int len)
  34{
  35        void *ret = dst;
  36        short *d = dst;
  37        const short *s = src;
  38
  39        len >>= 1;
  40        while (len-- > 0)
  41                *d++ = *s++;
  42        return ret;
  43}
  44
  45/**
  46 *  onenand_oob_128 - oob info for Flex-Onenand with 4KB page
  47 *  For now, we expose only 64 out of 80 ecc bytes
  48 */
  49static struct nand_ecclayout onenand_oob_128 = {
  50        .eccbytes       = 64,
  51        .eccpos         = {
  52                6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  53                22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  54                38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  55                54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  56                70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  57                86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  58                102, 103, 104, 105
  59                },
  60        .oobfree        = {
  61                {2, 4}, {18, 4}, {34, 4}, {50, 4},
  62                {66, 4}, {82, 4}, {98, 4}, {114, 4}
  63        }
  64};
  65
  66/**
  67 * onenand_oob_64 - oob info for large (2KB) page
  68 */
  69static struct nand_ecclayout onenand_oob_64 = {
  70        .eccbytes       = 20,
  71        .eccpos         = {
  72                8, 9, 10, 11, 12,
  73                24, 25, 26, 27, 28,
  74                40, 41, 42, 43, 44,
  75                56, 57, 58, 59, 60,
  76                },
  77        .oobfree        = {
  78                {2, 3}, {14, 2}, {18, 3}, {30, 2},
  79                {34, 3}, {46, 2}, {50, 3}, {62, 2}
  80        }
  81};
  82
  83/**
  84 * onenand_oob_32 - oob info for middle (1KB) page
  85 */
  86static struct nand_ecclayout onenand_oob_32 = {
  87        .eccbytes       = 10,
  88        .eccpos         = {
  89                8, 9, 10, 11, 12,
  90                24, 25, 26, 27, 28,
  91                },
  92        .oobfree        = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
  93};
  94
  95/*
  96 * Warning! This array is used with the memcpy_16() function, thus
  97 * it must be aligned to 2 bytes. GCC can make this array unaligned
  98 * as the array is made of unsigned char, which memcpy16() doesn't
  99 * like and will cause unaligned access.
 100 */
 101static const unsigned char __aligned(2) ffchars[] = {
 102        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 103        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
 104        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 105        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
 106        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 107        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
 108        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 109        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
 110        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 111        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 80 */
 112        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 113        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 96 */
 114        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 115        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 112 */
 116        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 117        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 128 */
 118};
 119
 120/**
 121 * onenand_readw - [OneNAND Interface] Read OneNAND register
 122 * @param addr          address to read
 123 *
 124 * Read OneNAND register
 125 */
 126static unsigned short onenand_readw(void __iomem * addr)
 127{
 128        return readw(addr);
 129}
 130
 131/**
 132 * onenand_writew - [OneNAND Interface] Write OneNAND register with value
 133 * @param value         value to write
 134 * @param addr          address to write
 135 *
 136 * Write OneNAND register with value
 137 */
 138static void onenand_writew(unsigned short value, void __iomem * addr)
 139{
 140        writew(value, addr);
 141}
 142
 143/**
 144 * onenand_block_address - [DEFAULT] Get block address
 145 * @param device        the device id
 146 * @param block         the block
 147 * @return              translated block address if DDP, otherwise same
 148 *
 149 * Setup Start Address 1 Register (F100h)
 150 */
 151static int onenand_block_address(struct onenand_chip *this, int block)
 152{
 153        /* Device Flash Core select, NAND Flash Block Address */
 154        if (block & this->density_mask)
 155                return ONENAND_DDP_CHIP1 | (block ^ this->density_mask);
 156
 157        return block;
 158}
 159
 160/**
 161 * onenand_bufferram_address - [DEFAULT] Get bufferram address
 162 * @param device        the device id
 163 * @param block         the block
 164 * @return              set DBS value if DDP, otherwise 0
 165 *
 166 * Setup Start Address 2 Register (F101h) for DDP
 167 */
 168static int onenand_bufferram_address(struct onenand_chip *this, int block)
 169{
 170        /* Device BufferRAM Select */
 171        if (block & this->density_mask)
 172                return ONENAND_DDP_CHIP1;
 173
 174        return ONENAND_DDP_CHIP0;
 175}
 176
 177/**
 178 * onenand_page_address - [DEFAULT] Get page address
 179 * @param page          the page address
 180 * @param sector        the sector address
 181 * @return              combined page and sector address
 182 *
 183 * Setup Start Address 8 Register (F107h)
 184 */
 185static int onenand_page_address(int page, int sector)
 186{
 187        /* Flash Page Address, Flash Sector Address */
 188        int fpa, fsa;
 189
 190        fpa = page & ONENAND_FPA_MASK;
 191        fsa = sector & ONENAND_FSA_MASK;
 192
 193        return ((fpa << ONENAND_FPA_SHIFT) | fsa);
 194}
 195
 196/**
 197 * onenand_buffer_address - [DEFAULT] Get buffer address
 198 * @param dataram1      DataRAM index
 199 * @param sectors       the sector address
 200 * @param count         the number of sectors
 201 * @return              the start buffer value
 202 *
 203 * Setup Start Buffer Register (F200h)
 204 */
 205static int onenand_buffer_address(int dataram1, int sectors, int count)
 206{
 207        int bsa, bsc;
 208
 209        /* BufferRAM Sector Address */
 210        bsa = sectors & ONENAND_BSA_MASK;
 211
 212        if (dataram1)
 213                bsa |= ONENAND_BSA_DATARAM1;    /* DataRAM1 */
 214        else
 215                bsa |= ONENAND_BSA_DATARAM0;    /* DataRAM0 */
 216
 217        /* BufferRAM Sector Count */
 218        bsc = count & ONENAND_BSC_MASK;
 219
 220        return ((bsa << ONENAND_BSA_SHIFT) | bsc);
 221}
 222
 223/**
 224 * flexonenand_block - Return block number for flash address
 225 * @param this          - OneNAND device structure
 226 * @param addr          - Address for which block number is needed
 227 */
 228static unsigned int flexonenand_block(struct onenand_chip *this, loff_t addr)
 229{
 230        unsigned int boundary, blk, die = 0;
 231
 232        if (ONENAND_IS_DDP(this) && addr >= this->diesize[0]) {
 233                die = 1;
 234                addr -= this->diesize[0];
 235        }
 236
 237        boundary = this->boundary[die];
 238
 239        blk = addr >> (this->erase_shift - 1);
 240        if (blk > boundary)
 241                blk = (blk + boundary + 1) >> 1;
 242
 243        blk += die ? this->density_mask : 0;
 244        return blk;
 245}
 246
 247unsigned int onenand_block(struct onenand_chip *this, loff_t addr)
 248{
 249        if (!FLEXONENAND(this))
 250                return addr >> this->erase_shift;
 251        return flexonenand_block(this, addr);
 252}
 253
 254/**
 255 * flexonenand_addr - Return address of the block
 256 * @this:               OneNAND device structure
 257 * @block:              Block number on Flex-OneNAND
 258 *
 259 * Return address of the block
 260 */
 261static loff_t flexonenand_addr(struct onenand_chip *this, int block)
 262{
 263        loff_t ofs = 0;
 264        int die = 0, boundary;
 265
 266        if (ONENAND_IS_DDP(this) && block >= this->density_mask) {
 267                block -= this->density_mask;
 268                die = 1;
 269                ofs = this->diesize[0];
 270        }
 271
 272        boundary = this->boundary[die];
 273        ofs += (loff_t) block << (this->erase_shift - 1);
 274        if (block > (boundary + 1))
 275                ofs += (loff_t) (block - boundary - 1)
 276                        << (this->erase_shift - 1);
 277        return ofs;
 278}
 279
 280loff_t onenand_addr(struct onenand_chip *this, int block)
 281{
 282        if (!FLEXONENAND(this))
 283                return (loff_t) block << this->erase_shift;
 284        return flexonenand_addr(this, block);
 285}
 286
 287/**
 288 * flexonenand_region - [Flex-OneNAND] Return erase region of addr
 289 * @param mtd           MTD device structure
 290 * @param addr          address whose erase region needs to be identified
 291 */
 292int flexonenand_region(struct mtd_info *mtd, loff_t addr)
 293{
 294        int i;
 295
 296        for (i = 0; i < mtd->numeraseregions; i++)
 297                if (addr < mtd->eraseregions[i].offset)
 298                        break;
 299        return i - 1;
 300}
 301
 302/**
 303 * onenand_get_density - [DEFAULT] Get OneNAND density
 304 * @param dev_id        OneNAND device ID
 305 *
 306 * Get OneNAND density from device ID
 307 */
 308static inline int onenand_get_density(int dev_id)
 309{
 310        int density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
 311        return (density & ONENAND_DEVICE_DENSITY_MASK);
 312}
 313
 314/**
 315 * onenand_command - [DEFAULT] Send command to OneNAND device
 316 * @param mtd           MTD device structure
 317 * @param cmd           the command to be sent
 318 * @param addr          offset to read from or write to
 319 * @param len           number of bytes to read or write
 320 *
 321 * Send command to OneNAND device. This function is used for middle/large page
 322 * devices (1KB/2KB Bytes per page)
 323 */
 324static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
 325                           size_t len)
 326{
 327        struct onenand_chip *this = mtd->priv;
 328        int value;
 329        int block, page;
 330
 331        /* Now we use page size operation */
 332        int sectors = 0, count = 0;
 333
 334        /* Address translation */
 335        switch (cmd) {
 336        case ONENAND_CMD_UNLOCK:
 337        case ONENAND_CMD_LOCK:
 338        case ONENAND_CMD_LOCK_TIGHT:
 339        case ONENAND_CMD_UNLOCK_ALL:
 340                block = -1;
 341                page = -1;
 342                break;
 343
 344        case FLEXONENAND_CMD_PI_ACCESS:
 345                /* addr contains die index */
 346                block = addr * this->density_mask;
 347                page = -1;
 348                break;
 349
 350        case ONENAND_CMD_ERASE:
 351        case ONENAND_CMD_BUFFERRAM:
 352                block = onenand_block(this, addr);
 353                page = -1;
 354                break;
 355
 356        case FLEXONENAND_CMD_READ_PI:
 357                cmd = ONENAND_CMD_READ;
 358                block = addr * this->density_mask;
 359                page = 0;
 360                break;
 361
 362        default:
 363                block = onenand_block(this, addr);
 364                page = (int) (addr
 365                        - onenand_addr(this, block)) >> this->page_shift;
 366                page &= this->page_mask;
 367                break;
 368        }
 369
 370        /* NOTE: The setting order of the registers is very important! */
 371        if (cmd == ONENAND_CMD_BUFFERRAM) {
 372                /* Select DataRAM for DDP */
 373                value = onenand_bufferram_address(this, block);
 374                this->write_word(value,
 375                                 this->base + ONENAND_REG_START_ADDRESS2);
 376
 377                if (ONENAND_IS_4KB_PAGE(this))
 378                        ONENAND_SET_BUFFERRAM0(this);
 379                else
 380                        /* Switch to the next data buffer */
 381                        ONENAND_SET_NEXT_BUFFERRAM(this);
 382
 383                return 0;
 384        }
 385
 386        if (block != -1) {
 387                /* Write 'DFS, FBA' of Flash */
 388                value = onenand_block_address(this, block);
 389                this->write_word(value,
 390                                 this->base + ONENAND_REG_START_ADDRESS1);
 391
 392                /* Select DataRAM for DDP */
 393                value = onenand_bufferram_address(this, block);
 394                this->write_word(value,
 395                                 this->base + ONENAND_REG_START_ADDRESS2);
 396        }
 397
 398        if (page != -1) {
 399                int dataram;
 400
 401                switch (cmd) {
 402                case FLEXONENAND_CMD_RECOVER_LSB:
 403                case ONENAND_CMD_READ:
 404                case ONENAND_CMD_READOOB:
 405                        if (ONENAND_IS_4KB_PAGE(this))
 406                                dataram = ONENAND_SET_BUFFERRAM0(this);
 407                        else
 408                                dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
 409
 410                        break;
 411
 412                default:
 413                        dataram = ONENAND_CURRENT_BUFFERRAM(this);
 414                        break;
 415                }
 416
 417                /* Write 'FPA, FSA' of Flash */
 418                value = onenand_page_address(page, sectors);
 419                this->write_word(value,
 420                                 this->base + ONENAND_REG_START_ADDRESS8);
 421
 422                /* Write 'BSA, BSC' of DataRAM */
 423                value = onenand_buffer_address(dataram, sectors, count);
 424                this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
 425        }
 426
 427        /* Interrupt clear */
 428        this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
 429        /* Write command */
 430        this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
 431
 432        return 0;
 433}
 434
 435/**
 436 * onenand_read_ecc - return ecc status
 437 * @param this          onenand chip structure
 438 */
 439static int onenand_read_ecc(struct onenand_chip *this)
 440{
 441        int ecc, i;
 442
 443        if (!FLEXONENAND(this))
 444                return this->read_word(this->base + ONENAND_REG_ECC_STATUS);
 445
 446        for (i = 0; i < 4; i++) {
 447                ecc = this->read_word(this->base
 448                                + ((ONENAND_REG_ECC_STATUS + i) << 1));
 449                if (likely(!ecc))
 450                        continue;
 451                if (ecc & FLEXONENAND_UNCORRECTABLE_ERROR)
 452                        return ONENAND_ECC_2BIT_ALL;
 453        }
 454
 455        return 0;
 456}
 457
 458/**
 459 * onenand_wait - [DEFAULT] wait until the command is done
 460 * @param mtd           MTD device structure
 461 * @param state         state to select the max. timeout value
 462 *
 463 * Wait for command done. This applies to all OneNAND command
 464 * Read can take up to 30us, erase up to 2ms and program up to 350us
 465 * according to general OneNAND specs
 466 */
 467static int onenand_wait(struct mtd_info *mtd, int state)
 468{
 469        struct onenand_chip *this = mtd->priv;
 470        unsigned int flags = ONENAND_INT_MASTER;
 471        unsigned int interrupt = 0;
 472        unsigned int ctrl;
 473
 474        while (1) {
 475                interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
 476                if (interrupt & flags)
 477                        break;
 478        }
 479
 480        ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
 481
 482        if (interrupt & ONENAND_INT_READ) {
 483                int ecc = onenand_read_ecc(this);
 484                if (ecc & ONENAND_ECC_2BIT_ALL) {
 485                        printk("onenand_wait: ECC error = 0x%04x\n", ecc);
 486                        return -EBADMSG;
 487                }
 488        }
 489
 490        if (ctrl & ONENAND_CTRL_ERROR) {
 491                printk("onenand_wait: controller error = 0x%04x\n", ctrl);
 492                if (ctrl & ONENAND_CTRL_LOCK)
 493                        printk("onenand_wait: it's locked error = 0x%04x\n",
 494                                ctrl);
 495
 496                return -EIO;
 497        }
 498
 499
 500        return 0;
 501}
 502
 503/**
 504 * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
 505 * @param mtd           MTD data structure
 506 * @param area          BufferRAM area
 507 * @return              offset given area
 508 *
 509 * Return BufferRAM offset given area
 510 */
 511static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
 512{
 513        struct onenand_chip *this = mtd->priv;
 514
 515        if (ONENAND_CURRENT_BUFFERRAM(this)) {
 516                if (area == ONENAND_DATARAM)
 517                        return mtd->writesize;
 518                if (area == ONENAND_SPARERAM)
 519                        return mtd->oobsize;
 520        }
 521
 522        return 0;
 523}
 524
 525/**
 526 * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
 527 * @param mtd           MTD data structure
 528 * @param area          BufferRAM area
 529 * @param buffer        the databuffer to put/get data
 530 * @param offset        offset to read from or write to
 531 * @param count         number of bytes to read/write
 532 *
 533 * Read the BufferRAM area
 534 */
 535static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
 536                                  unsigned char *buffer, int offset,
 537                                  size_t count)
 538{
 539        struct onenand_chip *this = mtd->priv;
 540        void __iomem *bufferram;
 541
 542        bufferram = this->base + area;
 543        bufferram += onenand_bufferram_offset(mtd, area);
 544
 545        memcpy_16(buffer, bufferram + offset, count);
 546
 547        return 0;
 548}
 549
 550/**
 551 * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
 552 * @param mtd           MTD data structure
 553 * @param area          BufferRAM area
 554 * @param buffer        the databuffer to put/get data
 555 * @param offset        offset to read from or write to
 556 * @param count         number of bytes to read/write
 557 *
 558 * Read the BufferRAM area with Sync. Burst Mode
 559 */
 560static int onenand_sync_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
 561                                       unsigned char *buffer, int offset,
 562                                       size_t count)
 563{
 564        struct onenand_chip *this = mtd->priv;
 565        void __iomem *bufferram;
 566
 567        bufferram = this->base + area;
 568        bufferram += onenand_bufferram_offset(mtd, area);
 569
 570        this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
 571
 572        memcpy_16(buffer, bufferram + offset, count);
 573
 574        this->mmcontrol(mtd, 0);
 575
 576        return 0;
 577}
 578
 579/**
 580 * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
 581 * @param mtd           MTD data structure
 582 * @param area          BufferRAM area
 583 * @param buffer        the databuffer to put/get data
 584 * @param offset        offset to read from or write to
 585 * @param count         number of bytes to read/write
 586 *
 587 * Write the BufferRAM area
 588 */
 589static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
 590                                   const unsigned char *buffer, int offset,
 591                                   size_t count)
 592{
 593        struct onenand_chip *this = mtd->priv;
 594        void __iomem *bufferram;
 595
 596        bufferram = this->base + area;
 597        bufferram += onenand_bufferram_offset(mtd, area);
 598
 599        memcpy_16(bufferram + offset, buffer, count);
 600
 601        return 0;
 602}
 603
 604/**
 605 * onenand_get_2x_blockpage - [GENERIC] Get blockpage at 2x program mode
 606 * @param mtd           MTD data structure
 607 * @param addr          address to check
 608 * @return              blockpage address
 609 *
 610 * Get blockpage address at 2x program mode
 611 */
 612static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr)
 613{
 614        struct onenand_chip *this = mtd->priv;
 615        int blockpage, block, page;
 616
 617        /* Calculate the even block number */
 618        block = (int) (addr >> this->erase_shift) & ~1;
 619        /* Is it the odd plane? */
 620        if (addr & this->writesize)
 621                block++;
 622        page = (int) (addr >> (this->page_shift + 1)) & this->page_mask;
 623        blockpage = (block << 7) | page;
 624
 625        return blockpage;
 626}
 627
 628/**
 629 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
 630 * @param mtd           MTD data structure
 631 * @param addr          address to check
 632 * @return              1 if there are valid data, otherwise 0
 633 *
 634 * Check bufferram if there is data we required
 635 */
 636static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
 637{
 638        struct onenand_chip *this = mtd->priv;
 639        int blockpage, found = 0;
 640        unsigned int i;
 641
 642        if (ONENAND_IS_2PLANE(this))
 643                blockpage = onenand_get_2x_blockpage(mtd, addr);
 644        else
 645                blockpage = (int) (addr >> this->page_shift);
 646
 647        /* Is there valid data? */
 648        i = ONENAND_CURRENT_BUFFERRAM(this);
 649        if (this->bufferram[i].blockpage == blockpage)
 650                found = 1;
 651        else {
 652                /* Check another BufferRAM */
 653                i = ONENAND_NEXT_BUFFERRAM(this);
 654                if (this->bufferram[i].blockpage == blockpage) {
 655                        ONENAND_SET_NEXT_BUFFERRAM(this);
 656                        found = 1;
 657                }
 658        }
 659
 660        if (found && ONENAND_IS_DDP(this)) {
 661                /* Select DataRAM for DDP */
 662                int block = onenand_block(this, addr);
 663                int value = onenand_bufferram_address(this, block);
 664                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
 665        }
 666
 667        return found;
 668}
 669
 670/**
 671 * onenand_update_bufferram - [GENERIC] Update BufferRAM information
 672 * @param mtd           MTD data structure
 673 * @param addr          address to update
 674 * @param valid         valid flag
 675 *
 676 * Update BufferRAM information
 677 */
 678static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
 679                                    int valid)
 680{
 681        struct onenand_chip *this = mtd->priv;
 682        int blockpage;
 683        unsigned int i;
 684
 685        if (ONENAND_IS_2PLANE(this))
 686                blockpage = onenand_get_2x_blockpage(mtd, addr);
 687        else
 688                blockpage = (int)(addr >> this->page_shift);
 689
 690        /* Invalidate another BufferRAM */
 691        i = ONENAND_NEXT_BUFFERRAM(this);
 692        if (this->bufferram[i].blockpage == blockpage)
 693                this->bufferram[i].blockpage = -1;
 694
 695        /* Update BufferRAM */
 696        i = ONENAND_CURRENT_BUFFERRAM(this);
 697        if (valid)
 698                this->bufferram[i].blockpage = blockpage;
 699        else
 700                this->bufferram[i].blockpage = -1;
 701
 702        return 0;
 703}
 704
 705/**
 706 * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
 707 * @param mtd           MTD data structure
 708 * @param addr          start address to invalidate
 709 * @param len           length to invalidate
 710 *
 711 * Invalidate BufferRAM information
 712 */
 713static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
 714                                         unsigned int len)
 715{
 716        struct onenand_chip *this = mtd->priv;
 717        int i;
 718        loff_t end_addr = addr + len;
 719
 720        /* Invalidate BufferRAM */
 721        for (i = 0; i < MAX_BUFFERRAM; i++) {
 722                loff_t buf_addr = this->bufferram[i].blockpage << this->page_shift;
 723
 724                if (buf_addr >= addr && buf_addr < end_addr)
 725                        this->bufferram[i].blockpage = -1;
 726        }
 727}
 728
 729/**
 730 * onenand_get_device - [GENERIC] Get chip for selected access
 731 * @param mtd           MTD device structure
 732 * @param new_state     the state which is requested
 733 *
 734 * Get the device and lock it for exclusive access
 735 */
 736static void onenand_get_device(struct mtd_info *mtd, int new_state)
 737{
 738        /* Do nothing */
 739}
 740
 741/**
 742 * onenand_release_device - [GENERIC] release chip
 743 * @param mtd           MTD device structure
 744 *
 745 * Deselect, release chip lock and wake up anyone waiting on the device
 746 */
 747static void onenand_release_device(struct mtd_info *mtd)
 748{
 749        /* Do nothing */
 750}
 751
 752/**
 753 * onenand_transfer_auto_oob - [INTERN] oob auto-placement transfer
 754 * @param mtd           MTD device structure
 755 * @param buf           destination address
 756 * @param column        oob offset to read from
 757 * @param thislen       oob length to read
 758 */
 759static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf,
 760                                        int column, int thislen)
 761{
 762        struct onenand_chip *this = mtd->priv;
 763        struct nand_oobfree *free;
 764        int readcol = column;
 765        int readend = column + thislen;
 766        int lastgap = 0;
 767        unsigned int i;
 768        uint8_t *oob_buf = this->oob_buf;
 769
 770        free = this->ecclayout->oobfree;
 771        for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
 772             i++, free++) {
 773                if (readcol >= lastgap)
 774                        readcol += free->offset - lastgap;
 775                if (readend >= lastgap)
 776                        readend += free->offset - lastgap;
 777                lastgap = free->offset + free->length;
 778        }
 779        this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
 780        free = this->ecclayout->oobfree;
 781        for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
 782             i++, free++) {
 783                int free_end = free->offset + free->length;
 784                if (free->offset < readend && free_end > readcol) {
 785                        int st = max_t(int,free->offset,readcol);
 786                        int ed = min_t(int,free_end,readend);
 787                        int n = ed - st;
 788                        memcpy(buf, oob_buf + st, n);
 789                        buf += n;
 790                } else if (column == 0)
 791                        break;
 792        }
 793        return 0;
 794}
 795
 796/**
 797 * onenand_recover_lsb - [Flex-OneNAND] Recover LSB page data
 798 * @param mtd           MTD device structure
 799 * @param addr          address to recover
 800 * @param status        return value from onenand_wait
 801 *
 802 * MLC NAND Flash cell has paired pages - LSB page and MSB page. LSB page has
 803 * lower page address and MSB page has higher page address in paired pages.
 804 * If power off occurs during MSB page program, the paired LSB page data can
 805 * become corrupt. LSB page recovery read is a way to read LSB page though page
 806 * data are corrupted. When uncorrectable error occurs as a result of LSB page
 807 * read after power up, issue LSB page recovery read.
 808 */
 809static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status)
 810{
 811        struct onenand_chip *this = mtd->priv;
 812        int i;
 813
 814        /* Recovery is only for Flex-OneNAND */
 815        if (!FLEXONENAND(this))
 816                return status;
 817
 818        /* check if we failed due to uncorrectable error */
 819        if (!mtd_is_eccerr(status) && status != ONENAND_BBT_READ_ECC_ERROR)
 820                return status;
 821
 822        /* check if address lies in MLC region */
 823        i = flexonenand_region(mtd, addr);
 824        if (mtd->eraseregions[i].erasesize < (1 << this->erase_shift))
 825                return status;
 826
 827        printk("onenand_recover_lsb:"
 828                "Attempting to recover from uncorrectable read\n");
 829
 830        /* Issue the LSB page recovery command */
 831        this->command(mtd, FLEXONENAND_CMD_RECOVER_LSB, addr, this->writesize);
 832        return this->wait(mtd, FL_READING);
 833}
 834
 835/**
 836 * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band
 837 * @param mtd           MTD device structure
 838 * @param from          offset to read from
 839 * @param ops           oob operation description structure
 840 *
 841 * OneNAND read main and/or out-of-band data
 842 */
 843static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
 844                struct mtd_oob_ops *ops)
 845{
 846        struct onenand_chip *this = mtd->priv;
 847        struct mtd_ecc_stats stats;
 848        size_t len = ops->len;
 849        size_t ooblen = ops->ooblen;
 850        u_char *buf = ops->datbuf;
 851        u_char *oobbuf = ops->oobbuf;
 852        int read = 0, column, thislen;
 853        int oobread = 0, oobcolumn, thisooblen, oobsize;
 854        int ret = 0, boundary = 0;
 855        int writesize = this->writesize;
 856
 857        MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
 858
 859        if (ops->mode == MTD_OPS_AUTO_OOB)
 860                oobsize = this->ecclayout->oobavail;
 861        else
 862                oobsize = mtd->oobsize;
 863
 864        oobcolumn = from & (mtd->oobsize - 1);
 865
 866        /* Do not allow reads past end of device */
 867        if ((from + len) > mtd->size) {
 868                printk(KERN_ERR "onenand_read_ops_nolock: Attempt read beyond end of device\n");
 869                ops->retlen = 0;
 870                ops->oobretlen = 0;
 871                return -EINVAL;
 872        }
 873
 874        stats = mtd->ecc_stats;
 875
 876        /* Read-while-load method */
 877        /* Note: We can't use this feature in MLC */
 878
 879        /* Do first load to bufferRAM */
 880        if (read < len) {
 881                if (!onenand_check_bufferram(mtd, from)) {
 882                        this->main_buf = buf;
 883                        this->command(mtd, ONENAND_CMD_READ, from, writesize);
 884                        ret = this->wait(mtd, FL_READING);
 885                        if (unlikely(ret))
 886                                ret = onenand_recover_lsb(mtd, from, ret);
 887                        onenand_update_bufferram(mtd, from, !ret);
 888                        if (ret == -EBADMSG)
 889                                ret = 0;
 890                }
 891        }
 892
 893        thislen = min_t(int, writesize, len - read);
 894        column = from & (writesize - 1);
 895        if (column + thislen > writesize)
 896                thislen = writesize - column;
 897
 898        while (!ret) {
 899                /* If there is more to load then start next load */
 900                from += thislen;
 901                if (!ONENAND_IS_4KB_PAGE(this) && read + thislen < len) {
 902                        this->main_buf = buf + thislen;
 903                        this->command(mtd, ONENAND_CMD_READ, from, writesize);
 904                        /*
 905                         * Chip boundary handling in DDP
 906                         * Now we issued chip 1 read and pointed chip 1
 907                         * bufferam so we have to point chip 0 bufferam.
 908                         */
 909                        if (ONENAND_IS_DDP(this) &&
 910                                        unlikely(from == (this->chipsize >> 1))) {
 911                                this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2);
 912                                boundary = 1;
 913                        } else
 914                                boundary = 0;
 915                        ONENAND_SET_PREV_BUFFERRAM(this);
 916                }
 917
 918                /* While load is going, read from last bufferRAM */
 919                this->read_bufferram(mtd, from - thislen, ONENAND_DATARAM, buf, column, thislen);
 920
 921                /* Read oob area if needed */
 922                if (oobbuf) {
 923                        thisooblen = oobsize - oobcolumn;
 924                        thisooblen = min_t(int, thisooblen, ooblen - oobread);
 925
 926                        if (ops->mode == MTD_OPS_AUTO_OOB)
 927                                onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
 928                        else
 929                                this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
 930                        oobread += thisooblen;
 931                        oobbuf += thisooblen;
 932                        oobcolumn = 0;
 933                }
 934
 935                if (ONENAND_IS_4KB_PAGE(this) && (read + thislen < len)) {
 936                        this->command(mtd, ONENAND_CMD_READ, from, writesize);
 937                        ret = this->wait(mtd, FL_READING);
 938                        if (unlikely(ret))
 939                                ret = onenand_recover_lsb(mtd, from, ret);
 940                        onenand_update_bufferram(mtd, from, !ret);
 941                        if (mtd_is_eccerr(ret))
 942                                ret = 0;
 943                }
 944
 945                /* See if we are done */
 946                read += thislen;
 947                if (read == len)
 948                        break;
 949                /* Set up for next read from bufferRAM */
 950                if (unlikely(boundary))
 951                        this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
 952                if (!ONENAND_IS_4KB_PAGE(this))
 953                        ONENAND_SET_NEXT_BUFFERRAM(this);
 954                buf += thislen;
 955                thislen = min_t(int, writesize, len - read);
 956                column = 0;
 957
 958                if (!ONENAND_IS_4KB_PAGE(this)) {
 959                        /* Now wait for load */
 960                        ret = this->wait(mtd, FL_READING);
 961                        onenand_update_bufferram(mtd, from, !ret);
 962                        if (mtd_is_eccerr(ret))
 963                                ret = 0;
 964                }
 965        }
 966
 967        /*
 968         * Return success, if no ECC failures, else -EBADMSG
 969         * fs driver will take care of that, because
 970         * retlen == desired len and result == -EBADMSG
 971         */
 972        ops->retlen = read;
 973        ops->oobretlen = oobread;
 974
 975        if (ret)
 976                return ret;
 977
 978        if (mtd->ecc_stats.failed - stats.failed)
 979                return -EBADMSG;
 980
 981        /* return max bitflips per ecc step; ONENANDs correct 1 bit only */
 982        return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0;
 983}
 984
 985/**
 986 * onenand_read_oob_nolock - [MTD Interface] OneNAND read out-of-band
 987 * @param mtd           MTD device structure
 988 * @param from          offset to read from
 989 * @param ops           oob operation description structure
 990 *
 991 * OneNAND read out-of-band data from the spare area
 992 */
 993static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
 994                struct mtd_oob_ops *ops)
 995{
 996        struct onenand_chip *this = mtd->priv;
 997        struct mtd_ecc_stats stats;
 998        int read = 0, thislen, column, oobsize;
 999        size_t len = ops->ooblen;
1000        unsigned int mode = ops->mode;
1001        u_char *buf = ops->oobbuf;
1002        int ret = 0, readcmd;
1003
1004        from += ops->ooboffs;
1005
1006        MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
1007
1008        /* Initialize return length value */
1009        ops->oobretlen = 0;
1010
1011        if (mode == MTD_OPS_AUTO_OOB)
1012                oobsize = this->ecclayout->oobavail;
1013        else
1014                oobsize = mtd->oobsize;
1015
1016        column = from & (mtd->oobsize - 1);
1017
1018        if (unlikely(column >= oobsize)) {
1019                printk(KERN_ERR "onenand_read_oob_nolock: Attempted to start read outside oob\n");
1020                return -EINVAL;
1021        }
1022
1023        /* Do not allow reads past end of device */
1024        if (unlikely(from >= mtd->size ||
1025                column + len > ((mtd->size >> this->page_shift) -
1026                                (from >> this->page_shift)) * oobsize)) {
1027                printk(KERN_ERR "onenand_read_oob_nolock: Attempted to read beyond end of device\n");
1028                return -EINVAL;
1029        }
1030
1031        stats = mtd->ecc_stats;
1032
1033        readcmd = ONENAND_IS_4KB_PAGE(this) ?
1034                ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1035
1036        while (read < len) {
1037                thislen = oobsize - column;
1038                thislen = min_t(int, thislen, len);
1039
1040                this->spare_buf = buf;
1041                this->command(mtd, readcmd, from, mtd->oobsize);
1042
1043                onenand_update_bufferram(mtd, from, 0);
1044
1045                ret = this->wait(mtd, FL_READING);
1046                if (unlikely(ret))
1047                        ret = onenand_recover_lsb(mtd, from, ret);
1048
1049                if (ret && ret != -EBADMSG) {
1050                        printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
1051                        break;
1052                }
1053
1054                if (mode == MTD_OPS_AUTO_OOB)
1055                        onenand_transfer_auto_oob(mtd, buf, column, thislen);
1056                else
1057                        this->read_bufferram(mtd, 0, ONENAND_SPARERAM, buf, column, thislen);
1058
1059                read += thislen;
1060
1061                if (read == len)
1062                        break;
1063
1064                buf += thislen;
1065
1066                /* Read more? */
1067                if (read < len) {
1068                        /* Page size */
1069                        from += mtd->writesize;
1070                        column = 0;
1071                }
1072        }
1073
1074        ops->oobretlen = read;
1075
1076        if (ret)
1077                return ret;
1078
1079        if (mtd->ecc_stats.failed - stats.failed)
1080                return -EBADMSG;
1081
1082        return 0;
1083}
1084
1085/**
1086 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
1087 * @param mtd           MTD device structure
1088 * @param from          offset to read from
1089 * @param len           number of bytes to read
1090 * @param retlen        pointer to variable to store the number of read bytes
1091 * @param buf           the databuffer to put data
1092 *
1093 * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
1094*/
1095int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1096                 size_t * retlen, u_char * buf)
1097{
1098        struct mtd_oob_ops ops = {
1099                .len    = len,
1100                .ooblen = 0,
1101                .datbuf = buf,
1102                .oobbuf = NULL,
1103        };
1104        int ret;
1105
1106        onenand_get_device(mtd, FL_READING);
1107        ret = onenand_read_ops_nolock(mtd, from, &ops);
1108        onenand_release_device(mtd);
1109
1110        *retlen = ops.retlen;
1111        return ret;
1112}
1113
1114/**
1115 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
1116 * @param mtd           MTD device structure
1117 * @param from          offset to read from
1118 * @param ops           oob operations description structure
1119 *
1120 * OneNAND main and/or out-of-band
1121 */
1122int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1123                        struct mtd_oob_ops *ops)
1124{
1125        int ret;
1126
1127        switch (ops->mode) {
1128        case MTD_OPS_PLACE_OOB:
1129        case MTD_OPS_AUTO_OOB:
1130                break;
1131        case MTD_OPS_RAW:
1132                /* Not implemented yet */
1133        default:
1134                return -EINVAL;
1135        }
1136
1137        onenand_get_device(mtd, FL_READING);
1138        if (ops->datbuf)
1139                ret = onenand_read_ops_nolock(mtd, from, ops);
1140        else
1141                ret = onenand_read_oob_nolock(mtd, from, ops);
1142        onenand_release_device(mtd);
1143
1144        return ret;
1145}
1146
1147/**
1148 * onenand_bbt_wait - [DEFAULT] wait until the command is done
1149 * @param mtd           MTD device structure
1150 * @param state         state to select the max. timeout value
1151 *
1152 * Wait for command done.
1153 */
1154static int onenand_bbt_wait(struct mtd_info *mtd, int state)
1155{
1156        struct onenand_chip *this = mtd->priv;
1157        unsigned int flags = ONENAND_INT_MASTER;
1158        unsigned int interrupt;
1159        unsigned int ctrl;
1160
1161        while (1) {
1162                interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1163                if (interrupt & flags)
1164                        break;
1165        }
1166
1167        /* To get correct interrupt status in timeout case */
1168        interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1169        ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
1170
1171        if (interrupt & ONENAND_INT_READ) {
1172                int ecc = onenand_read_ecc(this);
1173                if (ecc & ONENAND_ECC_2BIT_ALL) {
1174                        printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x"
1175                                ", controller = 0x%04x\n", ecc, ctrl);
1176                        return ONENAND_BBT_READ_ERROR;
1177                }
1178        } else {
1179                printk(KERN_ERR "onenand_bbt_wait: read timeout!"
1180                                "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
1181                return ONENAND_BBT_READ_FATAL_ERROR;
1182        }
1183
1184        /* Initial bad block case: 0x2400 or 0x0400 */
1185        if (ctrl & ONENAND_CTRL_ERROR) {
1186                printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl);
1187                return ONENAND_BBT_READ_ERROR;
1188        }
1189
1190        return 0;
1191}
1192
1193/**
1194 * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
1195 * @param mtd           MTD device structure
1196 * @param from          offset to read from
1197 * @param ops           oob operation description structure
1198 *
1199 * OneNAND read out-of-band data from the spare area for bbt scan
1200 */
1201int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1202                struct mtd_oob_ops *ops)
1203{
1204        struct onenand_chip *this = mtd->priv;
1205        int read = 0, thislen, column;
1206        int ret = 0, readcmd;
1207        size_t len = ops->ooblen;
1208        u_char *buf = ops->oobbuf;
1209
1210        MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n", (unsigned int) from, len);
1211
1212        readcmd = ONENAND_IS_4KB_PAGE(this) ?
1213                ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1214
1215        /* Initialize return value */
1216        ops->oobretlen = 0;
1217
1218        /* Do not allow reads past end of device */
1219        if (unlikely((from + len) > mtd->size)) {
1220                printk(KERN_ERR "onenand_bbt_read_oob: Attempt read beyond end of device\n");
1221                return ONENAND_BBT_READ_FATAL_ERROR;
1222        }
1223
1224        /* Grab the lock and see if the device is available */
1225        onenand_get_device(mtd, FL_READING);
1226
1227        column = from & (mtd->oobsize - 1);
1228
1229        while (read < len) {
1230
1231                thislen = mtd->oobsize - column;
1232                thislen = min_t(int, thislen, len);
1233
1234                this->spare_buf = buf;
1235                this->command(mtd, readcmd, from, mtd->oobsize);
1236
1237                onenand_update_bufferram(mtd, from, 0);
1238
1239                ret = this->bbt_wait(mtd, FL_READING);
1240                if (unlikely(ret))
1241                        ret = onenand_recover_lsb(mtd, from, ret);
1242
1243                if (ret)
1244                        break;
1245
1246                this->read_bufferram(mtd, 0, ONENAND_SPARERAM, buf, column, thislen);
1247                read += thislen;
1248                if (read == len)
1249                        break;
1250
1251                buf += thislen;
1252
1253                /* Read more? */
1254                if (read < len) {
1255                        /* Update Page size */
1256                        from += this->writesize;
1257                        column = 0;
1258                }
1259        }
1260
1261        /* Deselect and wake up anyone waiting on the device */
1262        onenand_release_device(mtd);
1263
1264        ops->oobretlen = read;
1265        return ret;
1266}
1267
1268
1269#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
1270/**
1271 * onenand_verify_oob - [GENERIC] verify the oob contents after a write
1272 * @param mtd           MTD device structure
1273 * @param buf           the databuffer to verify
1274 * @param to            offset to read from
1275 */
1276static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
1277{
1278        struct onenand_chip *this = mtd->priv;
1279        u_char *oob_buf = this->oob_buf;
1280        int status, i, readcmd;
1281
1282        readcmd = ONENAND_IS_4KB_PAGE(this) ?
1283                ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1284
1285        this->command(mtd, readcmd, to, mtd->oobsize);
1286        onenand_update_bufferram(mtd, to, 0);
1287        status = this->wait(mtd, FL_READING);
1288        if (status)
1289                return status;
1290
1291        this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
1292        for (i = 0; i < mtd->oobsize; i++)
1293                if (buf[i] != 0xFF && buf[i] != oob_buf[i])
1294                        return -EBADMSG;
1295
1296        return 0;
1297}
1298
1299/**
1300 * onenand_verify - [GENERIC] verify the chip contents after a write
1301 * @param mtd          MTD device structure
1302 * @param buf          the databuffer to verify
1303 * @param addr         offset to read from
1304 * @param len          number of bytes to read and compare
1305 */
1306static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
1307{
1308        struct onenand_chip *this = mtd->priv;
1309        void __iomem *dataram;
1310        int ret = 0;
1311        int thislen, column;
1312
1313        while (len != 0) {
1314                thislen = min_t(int, this->writesize, len);
1315                column = addr & (this->writesize - 1);
1316                if (column + thislen > this->writesize)
1317                        thislen = this->writesize - column;
1318
1319                this->command(mtd, ONENAND_CMD_READ, addr, this->writesize);
1320
1321                onenand_update_bufferram(mtd, addr, 0);
1322
1323                ret = this->wait(mtd, FL_READING);
1324                if (ret)
1325                        return ret;
1326
1327                onenand_update_bufferram(mtd, addr, 1);
1328
1329                dataram = this->base + ONENAND_DATARAM;
1330                dataram += onenand_bufferram_offset(mtd, ONENAND_DATARAM);
1331
1332                if (memcmp(buf, dataram + column, thislen))
1333                        return -EBADMSG;
1334
1335                len -= thislen;
1336                buf += thislen;
1337                addr += thislen;
1338        }
1339
1340        return 0;
1341}
1342#else
1343#define onenand_verify(...)             (0)
1344#define onenand_verify_oob(...)         (0)
1345#endif
1346
1347#define NOTALIGNED(x)   ((x & (this->subpagesize - 1)) != 0)
1348
1349/**
1350 * onenand_fill_auto_oob - [INTERN] oob auto-placement transfer
1351 * @param mtd           MTD device structure
1352 * @param oob_buf       oob buffer
1353 * @param buf           source address
1354 * @param column        oob offset to write to
1355 * @param thislen       oob length to write
1356 */
1357static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
1358                const u_char *buf, int column, int thislen)
1359{
1360        struct onenand_chip *this = mtd->priv;
1361        struct nand_oobfree *free;
1362        int writecol = column;
1363        int writeend = column + thislen;
1364        int lastgap = 0;
1365        unsigned int i;
1366
1367        free = this->ecclayout->oobfree;
1368        for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
1369             i++, free++) {
1370                if (writecol >= lastgap)
1371                        writecol += free->offset - lastgap;
1372                if (writeend >= lastgap)
1373                        writeend += free->offset - lastgap;
1374                lastgap = free->offset + free->length;
1375        }
1376        free = this->ecclayout->oobfree;
1377        for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length;
1378             i++, free++) {
1379                int free_end = free->offset + free->length;
1380                if (free->offset < writeend && free_end > writecol) {
1381                        int st = max_t(int,free->offset,writecol);
1382                        int ed = min_t(int,free_end,writeend);
1383                        int n = ed - st;
1384                        memcpy(oob_buf + st, buf, n);
1385                        buf += n;
1386                } else if (column == 0)
1387                        break;
1388        }
1389        return 0;
1390}
1391
1392/**
1393 * onenand_write_ops_nolock - [OneNAND Interface] write main and/or out-of-band
1394 * @param mtd           MTD device structure
1395 * @param to            offset to write to
1396 * @param ops           oob operation description structure
1397 *
1398 * Write main and/or oob with ECC
1399 */
1400static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1401                struct mtd_oob_ops *ops)
1402{
1403        struct onenand_chip *this = mtd->priv;
1404        int written = 0, column, thislen, subpage;
1405        int oobwritten = 0, oobcolumn, thisooblen, oobsize;
1406        size_t len = ops->len;
1407        size_t ooblen = ops->ooblen;
1408        const u_char *buf = ops->datbuf;
1409        const u_char *oob = ops->oobbuf;
1410        u_char *oobbuf;
1411        int ret = 0;
1412
1413        MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ops_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
1414
1415        /* Initialize retlen, in case of early exit */
1416        ops->retlen = 0;
1417        ops->oobretlen = 0;
1418
1419        /* Reject writes, which are not page aligned */
1420        if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
1421                printk(KERN_ERR "onenand_write_ops_nolock: Attempt to write not page aligned data\n");
1422                return -EINVAL;
1423        }
1424
1425        if (ops->mode == MTD_OPS_AUTO_OOB)
1426                oobsize = this->ecclayout->oobavail;
1427        else
1428                oobsize = mtd->oobsize;
1429
1430        oobcolumn = to & (mtd->oobsize - 1);
1431
1432        column = to & (mtd->writesize - 1);
1433
1434        /* Loop until all data write */
1435        while (written < len) {
1436                u_char *wbuf = (u_char *) buf;
1437
1438                thislen = min_t(int, mtd->writesize - column, len - written);
1439                thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
1440
1441                this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1442
1443                /* Partial page write */
1444                subpage = thislen < mtd->writesize;
1445                if (subpage) {
1446                        memset(this->page_buf, 0xff, mtd->writesize);
1447                        memcpy(this->page_buf + column, buf, thislen);
1448                        wbuf = this->page_buf;
1449                }
1450
1451                this->write_bufferram(mtd, to, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1452
1453                if (oob) {
1454                        oobbuf = this->oob_buf;
1455
1456                        /* We send data to spare ram with oobsize
1457                         *                          * to prevent byte access */
1458                        memset(oobbuf, 0xff, mtd->oobsize);
1459                        if (ops->mode == MTD_OPS_AUTO_OOB)
1460                                onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
1461                        else
1462                                memcpy(oobbuf + oobcolumn, oob, thisooblen);
1463
1464                        oobwritten += thisooblen;
1465                        oob += thisooblen;
1466                        oobcolumn = 0;
1467                } else
1468                        oobbuf = (u_char *) ffchars;
1469
1470                this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1471
1472                this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1473
1474                ret = this->wait(mtd, FL_WRITING);
1475
1476                /* In partial page write we don't update bufferram */
1477                onenand_update_bufferram(mtd, to, !ret && !subpage);
1478                if (ONENAND_IS_2PLANE(this)) {
1479                        ONENAND_SET_BUFFERRAM1(this);
1480                        onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
1481                }
1482
1483                if (ret) {
1484                        printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
1485                        break;
1486                }
1487
1488                /* Only check verify write turn on */
1489                ret = onenand_verify(mtd, buf, to, thislen);
1490                if (ret) {
1491                        printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
1492                        break;
1493                }
1494
1495                written += thislen;
1496
1497                if (written == len)
1498                        break;
1499
1500                column = 0;
1501                to += thislen;
1502                buf += thislen;
1503        }
1504
1505        ops->retlen = written;
1506
1507        return ret;
1508}
1509
1510/**
1511 * onenand_write_oob_nolock - [INTERN] OneNAND write out-of-band
1512 * @param mtd           MTD device structure
1513 * @param to            offset to write to
1514 * @param len           number of bytes to write
1515 * @param retlen        pointer to variable to store the number of written bytes
1516 * @param buf           the data to write
1517 * @param mode          operation mode
1518 *
1519 * OneNAND write out-of-band
1520 */
1521static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1522                struct mtd_oob_ops *ops)
1523{
1524        struct onenand_chip *this = mtd->priv;
1525        int column, ret = 0, oobsize;
1526        int written = 0, oobcmd;
1527        u_char *oobbuf;
1528        size_t len = ops->ooblen;
1529        const u_char *buf = ops->oobbuf;
1530        unsigned int mode = ops->mode;
1531
1532        to += ops->ooboffs;
1533
1534        MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
1535
1536        /* Initialize retlen, in case of early exit */
1537        ops->oobretlen = 0;
1538
1539        if (mode == MTD_OPS_AUTO_OOB)
1540                oobsize = this->ecclayout->oobavail;
1541        else
1542                oobsize = mtd->oobsize;
1543
1544        column = to & (mtd->oobsize - 1);
1545
1546        if (unlikely(column >= oobsize)) {
1547                printk(KERN_ERR "onenand_write_oob_nolock: Attempted to start write outside oob\n");
1548                return -EINVAL;
1549        }
1550
1551        /* For compatibility with NAND: Do not allow write past end of page */
1552        if (unlikely(column + len > oobsize)) {
1553                printk(KERN_ERR "onenand_write_oob_nolock: "
1554                                "Attempt to write past end of page\n");
1555                return -EINVAL;
1556        }
1557
1558        /* Do not allow reads past end of device */
1559        if (unlikely(to >= mtd->size ||
1560                                column + len > ((mtd->size >> this->page_shift) -
1561                                        (to >> this->page_shift)) * oobsize)) {
1562                printk(KERN_ERR "onenand_write_oob_nolock: Attempted to write past end of device\n");
1563                return -EINVAL;
1564        }
1565
1566        oobbuf = this->oob_buf;
1567
1568        oobcmd = ONENAND_IS_4KB_PAGE(this) ?
1569                ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
1570
1571        /* Loop until all data write */
1572        while (written < len) {
1573                int thislen = min_t(int, oobsize, len - written);
1574
1575                this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
1576
1577                /* We send data to spare ram with oobsize
1578                 * to prevent byte access */
1579                memset(oobbuf, 0xff, mtd->oobsize);
1580                if (mode == MTD_OPS_AUTO_OOB)
1581                        onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
1582                else
1583                        memcpy(oobbuf + column, buf, thislen);
1584                this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1585
1586                if (ONENAND_IS_4KB_PAGE(this)) {
1587                        /* Set main area of DataRAM to 0xff*/
1588                        memset(this->page_buf, 0xff, mtd->writesize);
1589                        this->write_bufferram(mtd, 0, ONENAND_DATARAM,
1590                                this->page_buf, 0, mtd->writesize);
1591                }
1592
1593                this->command(mtd, oobcmd, to, mtd->oobsize);
1594
1595                onenand_update_bufferram(mtd, to, 0);
1596                if (ONENAND_IS_2PLANE(this)) {
1597                        ONENAND_SET_BUFFERRAM1(this);
1598                        onenand_update_bufferram(mtd, to + this->writesize, 0);
1599                }
1600
1601                ret = this->wait(mtd, FL_WRITING);
1602                if (ret) {
1603                        printk(KERN_ERR "onenand_write_oob_nolock: write failed %d\n", ret);
1604                        break;
1605                }
1606
1607                ret = onenand_verify_oob(mtd, oobbuf, to);
1608                if (ret) {
1609                        printk(KERN_ERR "onenand_write_oob_nolock: verify failed %d\n", ret);
1610                        break;
1611                }
1612
1613                written += thislen;
1614                if (written == len)
1615                        break;
1616
1617                to += mtd->writesize;
1618                buf += thislen;
1619                column = 0;
1620        }
1621
1622        ops->oobretlen = written;
1623
1624        return ret;
1625}
1626
1627/**
1628 * onenand_write - [MTD Interface] compability function for onenand_write_ecc
1629 * @param mtd           MTD device structure
1630 * @param to            offset to write to
1631 * @param len           number of bytes to write
1632 * @param retlen        pointer to variable to store the number of written bytes
1633 * @param buf           the data to write
1634 *
1635 * Write with ECC
1636 */
1637int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1638                  size_t * retlen, const u_char * buf)
1639{
1640        struct mtd_oob_ops ops = {
1641                .len    = len,
1642                .ooblen = 0,
1643                .datbuf = (u_char *) buf,
1644                .oobbuf = NULL,
1645        };
1646        int ret;
1647
1648        onenand_get_device(mtd, FL_WRITING);
1649        ret = onenand_write_ops_nolock(mtd, to, &ops);
1650        onenand_release_device(mtd);
1651
1652        *retlen = ops.retlen;
1653        return ret;
1654}
1655
1656/**
1657 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
1658 * @param mtd           MTD device structure
1659 * @param to            offset to write to
1660 * @param ops           oob operation description structure
1661 *
1662 * OneNAND write main and/or out-of-band
1663 */
1664int onenand_write_oob(struct mtd_info *mtd, loff_t to,
1665                        struct mtd_oob_ops *ops)
1666{
1667        int ret;
1668
1669        switch (ops->mode) {
1670        case MTD_OPS_PLACE_OOB:
1671        case MTD_OPS_AUTO_OOB:
1672                break;
1673        case MTD_OPS_RAW:
1674                /* Not implemented yet */
1675        default:
1676                return -EINVAL;
1677        }
1678
1679        onenand_get_device(mtd, FL_WRITING);
1680        if (ops->datbuf)
1681                ret = onenand_write_ops_nolock(mtd, to, ops);
1682        else
1683                ret = onenand_write_oob_nolock(mtd, to, ops);
1684        onenand_release_device(mtd);
1685
1686        return ret;
1687
1688}
1689
1690/**
1691 * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
1692 * @param mtd           MTD device structure
1693 * @param ofs           offset from device start
1694 * @param allowbbt      1, if its allowed to access the bbt area
1695 *
1696 * Check, if the block is bad, Either by reading the bad block table or
1697 * calling of the scan function.
1698 */
1699static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
1700{
1701        struct onenand_chip *this = mtd->priv;
1702        struct bbm_info *bbm = this->bbm;
1703
1704        /* Return info from the table */
1705        return bbm->isbad_bbt(mtd, ofs, allowbbt);
1706}
1707
1708
1709/**
1710 * onenand_erase - [MTD Interface] erase block(s)
1711 * @param mtd           MTD device structure
1712 * @param instr         erase instruction
1713 *
1714 * Erase one ore more blocks
1715 */
1716int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1717{
1718        struct onenand_chip *this = mtd->priv;
1719        unsigned int block_size;
1720        loff_t addr = instr->addr;
1721        unsigned int len = instr->len;
1722        int ret = 0, i;
1723        struct mtd_erase_region_info *region = NULL;
1724        unsigned int region_end = 0;
1725
1726        MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n",
1727                        (unsigned int) addr, len);
1728
1729        if (FLEXONENAND(this)) {
1730                /* Find the eraseregion of this address */
1731                i = flexonenand_region(mtd, addr);
1732                region = &mtd->eraseregions[i];
1733
1734                block_size = region->erasesize;
1735                region_end = region->offset
1736                        + region->erasesize * region->numblocks;
1737
1738                /* Start address within region must align on block boundary.
1739                 * Erase region's start offset is always block start address.
1740                 */
1741                if (unlikely((addr - region->offset) & (block_size - 1))) {
1742                        MTDDEBUG(MTD_DEBUG_LEVEL0, "onenand_erase:"
1743                                " Unaligned address\n");
1744                        return -EINVAL;
1745                }
1746        } else {
1747                block_size = 1 << this->erase_shift;
1748
1749                /* Start address must align on block boundary */
1750                if (unlikely(addr & (block_size - 1))) {
1751                        MTDDEBUG(MTD_DEBUG_LEVEL0, "onenand_erase:"
1752                                                "Unaligned address\n");
1753                        return -EINVAL;
1754                }
1755        }
1756
1757        /* Length must align on block boundary */
1758        if (unlikely(len & (block_size - 1))) {
1759                MTDDEBUG (MTD_DEBUG_LEVEL0,
1760                         "onenand_erase: Length not block aligned\n");
1761                return -EINVAL;
1762        }
1763
1764        /* Grab the lock and see if the device is available */
1765        onenand_get_device(mtd, FL_ERASING);
1766
1767        /* Loop throught the pages */
1768        instr->state = MTD_ERASING;
1769
1770        while (len) {
1771
1772                /* Check if we have a bad block, we do not erase bad blocks */
1773                if (instr->priv == 0 && onenand_block_isbad_nolock(mtd, addr, 0)) {
1774                        printk(KERN_WARNING "onenand_erase: attempt to erase"
1775                                " a bad block at addr 0x%08x\n",
1776                                (unsigned int) addr);
1777                        instr->state = MTD_ERASE_FAILED;
1778                        goto erase_exit;
1779                }
1780
1781                this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
1782
1783                onenand_invalidate_bufferram(mtd, addr, block_size);
1784
1785                ret = this->wait(mtd, FL_ERASING);
1786                /* Check, if it is write protected */
1787                if (ret) {
1788                        if (ret == -EPERM)
1789                                MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_erase: "
1790                                          "Device is write protected!!!\n");
1791                        else
1792                                MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_erase: "
1793                                          "Failed erase, block %d\n",
1794                                        onenand_block(this, addr));
1795                        instr->state = MTD_ERASE_FAILED;
1796                        instr->fail_addr = addr;
1797
1798                        goto erase_exit;
1799                }
1800
1801                len -= block_size;
1802                addr += block_size;
1803
1804                if (addr == region_end) {
1805                        if (!len)
1806                                break;
1807                        region++;
1808
1809                        block_size = region->erasesize;
1810                        region_end = region->offset
1811                                + region->erasesize * region->numblocks;
1812
1813                        if (len & (block_size - 1)) {
1814                                /* This has been checked at MTD
1815                                 * partitioning level. */
1816                                printk("onenand_erase: Unaligned address\n");
1817                                goto erase_exit;
1818                        }
1819                }
1820        }
1821
1822        instr->state = MTD_ERASE_DONE;
1823
1824erase_exit:
1825
1826        ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
1827        /* Do call back function */
1828        if (!ret)
1829                mtd_erase_callback(instr);
1830
1831        /* Deselect and wake up anyone waiting on the device */
1832        onenand_release_device(mtd);
1833
1834        return ret;
1835}
1836
1837/**
1838 * onenand_sync - [MTD Interface] sync
1839 * @param mtd           MTD device structure
1840 *
1841 * Sync is actually a wait for chip ready function
1842 */
1843void onenand_sync(struct mtd_info *mtd)
1844{
1845        MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
1846
1847        /* Grab the lock and see if the device is available */
1848        onenand_get_device(mtd, FL_SYNCING);
1849
1850        /* Release it and go back */
1851        onenand_release_device(mtd);
1852}
1853
1854/**
1855 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
1856 * @param mtd           MTD device structure
1857 * @param ofs           offset relative to mtd start
1858 *
1859 * Check whether the block is bad
1860 */
1861int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
1862{
1863        int ret;
1864
1865        /* Check for invalid offset */
1866        if (ofs > mtd->size)
1867                return -EINVAL;
1868
1869        onenand_get_device(mtd, FL_READING);
1870        ret = onenand_block_isbad_nolock(mtd,ofs, 0);
1871        onenand_release_device(mtd);
1872        return ret;
1873}
1874
1875/**
1876 * onenand_default_block_markbad - [DEFAULT] mark a block bad
1877 * @param mtd           MTD device structure
1878 * @param ofs           offset from device start
1879 *
1880 * This is the default implementation, which can be overridden by
1881 * a hardware specific driver.
1882 */
1883static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1884{
1885        struct onenand_chip *this = mtd->priv;
1886        struct bbm_info *bbm = this->bbm;
1887        u_char buf[2] = {0, 0};
1888        struct mtd_oob_ops ops = {
1889                .mode = MTD_OPS_PLACE_OOB,
1890                .ooblen = 2,
1891                .oobbuf = buf,
1892                .ooboffs = 0,
1893        };
1894        int block;
1895
1896        /* Get block number */
1897        block = onenand_block(this, ofs);
1898        if (bbm->bbt)
1899                bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
1900
1901        /* We write two bytes, so we dont have to mess with 16 bit access */
1902        ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1903        return onenand_write_oob_nolock(mtd, ofs, &ops);
1904}
1905
1906/**
1907 * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
1908 * @param mtd           MTD device structure
1909 * @param ofs           offset relative to mtd start
1910 *
1911 * Mark the block as bad
1912 */
1913int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1914{
1915        int ret;
1916
1917        ret = onenand_block_isbad(mtd, ofs);
1918        if (ret) {
1919                /* If it was bad already, return success and do nothing */
1920                if (ret > 0)
1921                        return 0;
1922                return ret;
1923        }
1924
1925        ret = mtd_block_markbad(mtd, ofs);
1926        return ret;
1927}
1928
1929/**
1930 * onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s)
1931 * @param mtd           MTD device structure
1932 * @param ofs           offset relative to mtd start
1933 * @param len           number of bytes to lock or unlock
1934 * @param cmd           lock or unlock command
1935 *
1936 * Lock or unlock one or more blocks
1937 */
1938static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
1939{
1940        struct onenand_chip *this = mtd->priv;
1941        int start, end, block, value, status;
1942
1943        start = onenand_block(this, ofs);
1944        end = onenand_block(this, ofs + len);
1945
1946        /* Continuous lock scheme */
1947        if (this->options & ONENAND_HAS_CONT_LOCK) {
1948                /* Set start block address */
1949                this->write_word(start,
1950                                 this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1951                /* Set end block address */
1952                this->write_word(end - 1,
1953                                 this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1954                /* Write unlock command */
1955                this->command(mtd, cmd, 0, 0);
1956
1957                /* There's no return value */
1958                this->wait(mtd, FL_UNLOCKING);
1959
1960                /* Sanity check */
1961                while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1962                       & ONENAND_CTRL_ONGO)
1963                        continue;
1964
1965                /* Check lock status */
1966                status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1967                if (!(status & ONENAND_WP_US))
1968                        printk(KERN_ERR "wp status = 0x%x\n", status);
1969
1970                return 0;
1971        }
1972
1973        /* Block lock scheme */
1974        for (block = start; block < end; block++) {
1975                /* Set block address */
1976                value = onenand_block_address(this, block);
1977                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1978                /* Select DataRAM for DDP */
1979                value = onenand_bufferram_address(this, block);
1980                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
1981
1982                /* Set start block address */
1983                this->write_word(block,
1984                                 this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1985                /* Write unlock command */
1986                this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1987
1988                /* There's no return value */
1989                this->wait(mtd, FL_UNLOCKING);
1990
1991                /* Sanity check */
1992                while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1993                       & ONENAND_CTRL_ONGO)
1994                        continue;
1995
1996                /* Check lock status */
1997                status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1998                if (!(status & ONENAND_WP_US))
1999                        printk(KERN_ERR "block = %d, wp status = 0x%x\n",
2000                               block, status);
2001        }
2002
2003        return 0;
2004}
2005
2006#ifdef ONENAND_LINUX
2007/**
2008 * onenand_lock - [MTD Interface] Lock block(s)
2009 * @param mtd           MTD device structure
2010 * @param ofs           offset relative to mtd start
2011 * @param len           number of bytes to unlock
2012 *
2013 * Lock one or more blocks
2014 */
2015static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
2016{
2017        int ret;
2018
2019        onenand_get_device(mtd, FL_LOCKING);
2020        ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
2021        onenand_release_device(mtd);
2022        return ret;
2023}
2024
2025/**
2026 * onenand_unlock - [MTD Interface] Unlock block(s)
2027 * @param mtd           MTD device structure
2028 * @param ofs           offset relative to mtd start
2029 * @param len           number of bytes to unlock
2030 *
2031 * Unlock one or more blocks
2032 */
2033static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
2034{
2035        int ret;
2036
2037        onenand_get_device(mtd, FL_LOCKING);
2038        ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2039        onenand_release_device(mtd);
2040        return ret;
2041}
2042#endif
2043
2044/**
2045 * onenand_check_lock_status - [OneNAND Interface] Check lock status
2046 * @param this          onenand chip data structure
2047 *
2048 * Check lock status
2049 */
2050static int onenand_check_lock_status(struct onenand_chip *this)
2051{
2052        unsigned int value, block, status;
2053        unsigned int end;
2054
2055        end = this->chipsize >> this->erase_shift;
2056        for (block = 0; block < end; block++) {
2057                /* Set block address */
2058                value = onenand_block_address(this, block);
2059                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
2060                /* Select DataRAM for DDP */
2061                value = onenand_bufferram_address(this, block);
2062                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
2063                /* Set start block address */
2064                this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2065
2066                /* Check lock status */
2067                status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2068                if (!(status & ONENAND_WP_US)) {
2069                        printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
2070                        return 0;
2071                }
2072        }
2073
2074        return 1;
2075}
2076
2077/**
2078 * onenand_unlock_all - [OneNAND Interface] unlock all blocks
2079 * @param mtd           MTD device structure
2080 *
2081 * Unlock all blocks
2082 */
2083static void onenand_unlock_all(struct mtd_info *mtd)
2084{
2085        struct onenand_chip *this = mtd->priv;
2086        loff_t ofs = 0;
2087        size_t len = mtd->size;
2088
2089        if (this->options & ONENAND_HAS_UNLOCK_ALL) {
2090                /* Set start block address */
2091                this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2092                /* Write unlock command */
2093                this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
2094
2095                /* There's no return value */
2096                this->wait(mtd, FL_LOCKING);
2097
2098                /* Sanity check */
2099                while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2100                                & ONENAND_CTRL_ONGO)
2101                        continue;
2102
2103                /* Check lock status */
2104                if (onenand_check_lock_status(this))
2105                        return;
2106
2107                /* Workaround for all block unlock in DDP */
2108                if (ONENAND_IS_DDP(this) && !FLEXONENAND(this)) {
2109                        /* All blocks on another chip */
2110                        ofs = this->chipsize >> 1;
2111                        len = this->chipsize >> 1;
2112                }
2113        }
2114
2115        onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2116}
2117
2118
2119/**
2120 * onenand_check_features - Check and set OneNAND features
2121 * @param mtd           MTD data structure
2122 *
2123 * Check and set OneNAND features
2124 * - lock scheme
2125 * - two plane
2126 */
2127static void onenand_check_features(struct mtd_info *mtd)
2128{
2129        struct onenand_chip *this = mtd->priv;
2130        unsigned int density, process;
2131
2132        /* Lock scheme depends on density and process */
2133        density = onenand_get_density(this->device_id);
2134        process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
2135
2136        /* Lock scheme */
2137        switch (density) {
2138        case ONENAND_DEVICE_DENSITY_4Gb:
2139                if (ONENAND_IS_DDP(this))
2140                        this->options |= ONENAND_HAS_2PLANE;
2141                else
2142                        this->options |= ONENAND_HAS_4KB_PAGE;
2143
2144        case ONENAND_DEVICE_DENSITY_2Gb:
2145                /* 2Gb DDP don't have 2 plane */
2146                if (!ONENAND_IS_DDP(this))
2147                        this->options |= ONENAND_HAS_2PLANE;
2148                this->options |= ONENAND_HAS_UNLOCK_ALL;
2149
2150        case ONENAND_DEVICE_DENSITY_1Gb:
2151                /* A-Die has all block unlock */
2152                if (process)
2153                        this->options |= ONENAND_HAS_UNLOCK_ALL;
2154                break;
2155
2156        default:
2157                /* Some OneNAND has continuous lock scheme */
2158                if (!process)
2159                        this->options |= ONENAND_HAS_CONT_LOCK;
2160                break;
2161        }
2162
2163        if (ONENAND_IS_MLC(this))
2164                this->options |= ONENAND_HAS_4KB_PAGE;
2165
2166        if (ONENAND_IS_4KB_PAGE(this))
2167                this->options &= ~ONENAND_HAS_2PLANE;
2168
2169        if (FLEXONENAND(this)) {
2170                this->options &= ~ONENAND_HAS_CONT_LOCK;
2171                this->options |= ONENAND_HAS_UNLOCK_ALL;
2172        }
2173
2174        if (this->options & ONENAND_HAS_CONT_LOCK)
2175                printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
2176        if (this->options & ONENAND_HAS_UNLOCK_ALL)
2177                printk(KERN_DEBUG "Chip support all block unlock\n");
2178        if (this->options & ONENAND_HAS_2PLANE)
2179                printk(KERN_DEBUG "Chip has 2 plane\n");
2180        if (this->options & ONENAND_HAS_4KB_PAGE)
2181                printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
2182
2183}
2184
2185/**
2186 * onenand_print_device_info - Print device ID
2187 * @param device        device ID
2188 *
2189 * Print device ID
2190 */
2191char *onenand_print_device_info(int device, int version)
2192{
2193        int vcc, demuxed, ddp, density, flexonenand;
2194        char *dev_info = malloc(80);
2195        char *p = dev_info;
2196
2197        vcc = device & ONENAND_DEVICE_VCC_MASK;
2198        demuxed = device & ONENAND_DEVICE_IS_DEMUX;
2199        ddp = device & ONENAND_DEVICE_IS_DDP;
2200        density = onenand_get_density(device);
2201        flexonenand = device & DEVICE_IS_FLEXONENAND;
2202        p += sprintf(dev_info, "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)",
2203               demuxed ? "" : "Muxed ",
2204               flexonenand ? "Flex-" : "",
2205               ddp ? "(DDP)" : "",
2206               (16 << density), vcc ? "2.65/3.3" : "1.8", device);
2207
2208        sprintf(p, "\nOneNAND version = 0x%04x", version);
2209        printk("%s\n", dev_info);
2210
2211        return dev_info;
2212}
2213
2214static const struct onenand_manufacturers onenand_manuf_ids[] = {
2215        {ONENAND_MFR_NUMONYX, "Numonyx"},
2216        {ONENAND_MFR_SAMSUNG, "Samsung"},
2217};
2218
2219/**
2220 * onenand_check_maf - Check manufacturer ID
2221 * @param manuf         manufacturer ID
2222 *
2223 * Check manufacturer ID
2224 */
2225static int onenand_check_maf(int manuf)
2226{
2227        int size = ARRAY_SIZE(onenand_manuf_ids);
2228        int i;
2229#ifdef ONENAND_DEBUG
2230        char *name;
2231#endif
2232
2233        for (i = 0; i < size; i++)
2234                if (manuf == onenand_manuf_ids[i].id)
2235                        break;
2236
2237#ifdef ONENAND_DEBUG
2238        if (i < size)
2239                name = onenand_manuf_ids[i].name;
2240        else
2241                name = "Unknown";
2242
2243        printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
2244#endif
2245
2246        return i == size;
2247}
2248
2249/**
2250* flexonenand_get_boundary      - Reads the SLC boundary
2251* @param onenand_info           - onenand info structure
2252*
2253* Fill up boundary[] field in onenand_chip
2254**/
2255static int flexonenand_get_boundary(struct mtd_info *mtd)
2256{
2257        struct onenand_chip *this = mtd->priv;
2258        unsigned int die, bdry;
2259        int syscfg, locked;
2260
2261        /* Disable ECC */
2262        syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
2263        this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1);
2264
2265        for (die = 0; die < this->dies; die++) {
2266                this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
2267                this->wait(mtd, FL_SYNCING);
2268
2269                this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
2270                this->wait(mtd, FL_READING);
2271
2272                bdry = this->read_word(this->base + ONENAND_DATARAM);
2273                if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
2274                        locked = 0;
2275                else
2276                        locked = 1;
2277                this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
2278
2279                this->command(mtd, ONENAND_CMD_RESET, 0, 0);
2280                this->wait(mtd, FL_RESETING);
2281
2282                printk(KERN_INFO "Die %d boundary: %d%s\n", die,
2283                       this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
2284        }
2285
2286        /* Enable ECC */
2287        this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
2288        return 0;
2289}
2290
2291/**
2292 * flexonenand_get_size - Fill up fields in onenand_chip and mtd_info
2293 *                        boundary[], diesize[], mtd->size, mtd->erasesize,
2294 *                        mtd->eraseregions
2295 * @param mtd           - MTD device structure
2296 */
2297static void flexonenand_get_size(struct mtd_info *mtd)
2298{
2299        struct onenand_chip *this = mtd->priv;
2300        int die, i, eraseshift, density;
2301        int blksperdie, maxbdry;
2302        loff_t ofs;
2303
2304        density = onenand_get_density(this->device_id);
2305        blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift);
2306        blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
2307        maxbdry = blksperdie - 1;
2308        eraseshift = this->erase_shift - 1;
2309
2310        mtd->numeraseregions = this->dies << 1;
2311
2312        /* This fills up the device boundary */
2313        flexonenand_get_boundary(mtd);
2314        die = 0;
2315        ofs = 0;
2316        i = -1;
2317        for (; die < this->dies; die++) {
2318                if (!die || this->boundary[die-1] != maxbdry) {
2319                        i++;
2320                        mtd->eraseregions[i].offset = ofs;
2321                        mtd->eraseregions[i].erasesize = 1 << eraseshift;
2322                        mtd->eraseregions[i].numblocks =
2323                                                        this->boundary[die] + 1;
2324                        ofs += mtd->eraseregions[i].numblocks << eraseshift;
2325                        eraseshift++;
2326                } else {
2327                        mtd->numeraseregions -= 1;
2328                        mtd->eraseregions[i].numblocks +=
2329                                                        this->boundary[die] + 1;
2330                        ofs += (this->boundary[die] + 1) << (eraseshift - 1);
2331                }
2332                if (this->boundary[die] != maxbdry) {
2333                        i++;
2334                        mtd->eraseregions[i].offset = ofs;
2335                        mtd->eraseregions[i].erasesize = 1 << eraseshift;
2336                        mtd->eraseregions[i].numblocks = maxbdry ^
2337                                                         this->boundary[die];
2338                        ofs += mtd->eraseregions[i].numblocks << eraseshift;
2339                        eraseshift--;
2340                } else
2341                        mtd->numeraseregions -= 1;
2342        }
2343
2344        /* Expose MLC erase size except when all blocks are SLC */
2345        mtd->erasesize = 1 << this->erase_shift;
2346        if (mtd->numeraseregions == 1)
2347                mtd->erasesize >>= 1;
2348
2349        printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions);
2350        for (i = 0; i < mtd->numeraseregions; i++)
2351                printk(KERN_INFO "[offset: 0x%08llx, erasesize: 0x%05x,"
2352                        " numblocks: %04u]\n", mtd->eraseregions[i].offset,
2353                        mtd->eraseregions[i].erasesize,
2354                        mtd->eraseregions[i].numblocks);
2355
2356        for (die = 0, mtd->size = 0; die < this->dies; die++) {
2357                this->diesize[die] = (loff_t) (blksperdie << this->erase_shift);
2358                this->diesize[die] -= (loff_t) (this->boundary[die] + 1)
2359                                                 << (this->erase_shift - 1);
2360                mtd->size += this->diesize[die];
2361        }
2362}
2363
2364/**
2365 * flexonenand_check_blocks_erased - Check if blocks are erased
2366 * @param mtd_info      - mtd info structure
2367 * @param start         - first erase block to check
2368 * @param end           - last erase block to check
2369 *
2370 * Converting an unerased block from MLC to SLC
2371 * causes byte values to change. Since both data and its ECC
2372 * have changed, reads on the block give uncorrectable error.
2373 * This might lead to the block being detected as bad.
2374 *
2375 * Avoid this by ensuring that the block to be converted is
2376 * erased.
2377 */
2378static int flexonenand_check_blocks_erased(struct mtd_info *mtd,
2379                                        int start, int end)
2380{
2381        struct onenand_chip *this = mtd->priv;
2382        int i, ret;
2383        int block;
2384        struct mtd_oob_ops ops = {
2385                .mode = MTD_OPS_PLACE_OOB,
2386                .ooboffs = 0,
2387                .ooblen = mtd->oobsize,
2388                .datbuf = NULL,
2389                .oobbuf = this->oob_buf,
2390        };
2391        loff_t addr;
2392
2393        printk(KERN_DEBUG "Check blocks from %d to %d\n", start, end);
2394
2395        for (block = start; block <= end; block++) {
2396                addr = flexonenand_addr(this, block);
2397                if (onenand_block_isbad_nolock(mtd, addr, 0))
2398                        continue;
2399
2400                /*
2401                 * Since main area write results in ECC write to spare,
2402                 * it is sufficient to check only ECC bytes for change.
2403                 */
2404                ret = onenand_read_oob_nolock(mtd, addr, &ops);
2405                if (ret)
2406                        return ret;
2407
2408                for (i = 0; i < mtd->oobsize; i++)
2409                        if (this->oob_buf[i] != 0xff)
2410                                break;
2411
2412                if (i != mtd->oobsize) {
2413                        printk(KERN_WARNING "Block %d not erased.\n", block);
2414                        return 1;
2415                }
2416        }
2417
2418        return 0;
2419}
2420
2421/**
2422 * flexonenand_set_boundary     - Writes the SLC boundary
2423 * @param mtd                   - mtd info structure
2424 */
2425int flexonenand_set_boundary(struct mtd_info *mtd, int die,
2426                                    int boundary, int lock)
2427{
2428        struct onenand_chip *this = mtd->priv;
2429        int ret, density, blksperdie, old, new, thisboundary;
2430        loff_t addr;
2431
2432        if (die >= this->dies)
2433                return -EINVAL;
2434
2435        if (boundary == this->boundary[die])
2436                return 0;
2437
2438        density = onenand_get_density(this->device_id);
2439        blksperdie = ((16 << density) << 20) >> this->erase_shift;
2440        blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
2441
2442        if (boundary >= blksperdie) {
2443                printk("flexonenand_set_boundary:"
2444                        "Invalid boundary value. "
2445                        "Boundary not changed.\n");
2446                return -EINVAL;
2447        }
2448
2449        /* Check if converting blocks are erased */
2450        old = this->boundary[die] + (die * this->density_mask);
2451        new = boundary + (die * this->density_mask);
2452        ret = flexonenand_check_blocks_erased(mtd, min(old, new)
2453                                                + 1, max(old, new));
2454        if (ret) {
2455                printk(KERN_ERR "flexonenand_set_boundary: Please erase blocks before boundary change\n");
2456                return ret;
2457        }
2458
2459        this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
2460        this->wait(mtd, FL_SYNCING);
2461
2462        /* Check is boundary is locked */
2463        this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
2464        ret = this->wait(mtd, FL_READING);
2465
2466        thisboundary = this->read_word(this->base + ONENAND_DATARAM);
2467        if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
2468                printk(KERN_ERR "flexonenand_set_boundary: boundary locked\n");
2469                goto out;
2470        }
2471
2472        printk(KERN_INFO "flexonenand_set_boundary: Changing die %d boundary: %d%s\n",
2473                        die, boundary, lock ? "(Locked)" : "(Unlocked)");
2474
2475        boundary &= FLEXONENAND_PI_MASK;
2476        boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT);
2477
2478        addr = die ? this->diesize[0] : 0;
2479        this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
2480        ret = this->wait(mtd, FL_ERASING);
2481        if (ret) {
2482                printk("flexonenand_set_boundary:"
2483                        "Failed PI erase for Die %d\n", die);
2484                goto out;
2485        }
2486
2487        this->write_word(boundary, this->base + ONENAND_DATARAM);
2488        this->command(mtd, ONENAND_CMD_PROG, addr, 0);
2489        ret = this->wait(mtd, FL_WRITING);
2490        if (ret) {
2491                printk("flexonenand_set_boundary:"
2492                        "Failed PI write for Die %d\n", die);
2493                goto out;
2494        }
2495
2496        this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0);
2497        ret = this->wait(mtd, FL_WRITING);
2498out:
2499        this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND);
2500        this->wait(mtd, FL_RESETING);
2501        if (!ret)
2502                /* Recalculate device size on boundary change*/
2503                flexonenand_get_size(mtd);
2504
2505        return ret;
2506}
2507
2508/**
2509 * onenand_chip_probe - [OneNAND Interface] Probe the OneNAND chip
2510 * @param mtd           MTD device structure
2511 *
2512 * OneNAND detection method:
2513 *   Compare the the values from command with ones from register
2514 */
2515static int onenand_chip_probe(struct mtd_info *mtd)
2516{
2517        struct onenand_chip *this = mtd->priv;
2518        int bram_maf_id, bram_dev_id, maf_id, dev_id;
2519        int syscfg;
2520
2521        /* Save system configuration 1 */
2522        syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
2523
2524        /* Clear Sync. Burst Read mode to read BootRAM */
2525        this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ),
2526                         this->base + ONENAND_REG_SYS_CFG1);
2527
2528        /* Send the command for reading device ID from BootRAM */
2529        this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
2530
2531        /* Read manufacturer and device IDs from BootRAM */
2532        bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
2533        bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
2534
2535        /* Reset OneNAND to read default register values */
2536        this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
2537
2538        /* Wait reset */
2539        this->wait(mtd, FL_RESETING);
2540
2541        /* Restore system configuration 1 */
2542        this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
2543
2544        /* Check manufacturer ID */
2545        if (onenand_check_maf(bram_maf_id))
2546                return -ENXIO;
2547
2548        /* Read manufacturer and device IDs from Register */
2549        maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
2550        dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
2551
2552        /* Check OneNAND device */
2553        if (maf_id != bram_maf_id || dev_id != bram_dev_id)
2554                return -ENXIO;
2555
2556        return 0;
2557}
2558
2559/**
2560 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
2561 * @param mtd           MTD device structure
2562 *
2563 * OneNAND detection method:
2564 *   Compare the the values from command with ones from register
2565 */
2566int onenand_probe(struct mtd_info *mtd)
2567{
2568        struct onenand_chip *this = mtd->priv;
2569        int dev_id, ver_id;
2570        int density;
2571        int ret;
2572
2573        ret = this->chip_probe(mtd);
2574        if (ret)
2575                return ret;
2576
2577        /* Read device IDs from Register */
2578        dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
2579        ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
2580        this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
2581
2582        /* Flash device information */
2583        mtd->name = onenand_print_device_info(dev_id, ver_id);
2584        this->device_id = dev_id;
2585        this->version_id = ver_id;
2586
2587        /* Check OneNAND features */
2588        onenand_check_features(mtd);
2589
2590        density = onenand_get_density(dev_id);
2591        if (FLEXONENAND(this)) {
2592                this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
2593                /* Maximum possible erase regions */
2594                mtd->numeraseregions = this->dies << 1;
2595                mtd->eraseregions = malloc(sizeof(struct mtd_erase_region_info)
2596                                        * (this->dies << 1));
2597                if (!mtd->eraseregions)
2598                        return -ENOMEM;
2599        }
2600
2601        /*
2602         * For Flex-OneNAND, chipsize represents maximum possible device size.
2603         * mtd->size represents the actual device size.
2604         */
2605        this->chipsize = (16 << density) << 20;
2606
2607        /* OneNAND page size & block size */
2608        /* The data buffer size is equal to page size */
2609        mtd->writesize =
2610            this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
2611        /* We use the full BufferRAM */
2612        if (ONENAND_IS_4KB_PAGE(this))
2613                mtd->writesize <<= 1;
2614
2615        mtd->oobsize = mtd->writesize >> 5;
2616        /* Pagers per block is always 64 in OneNAND */
2617        mtd->erasesize = mtd->writesize << 6;
2618        /*
2619         * Flex-OneNAND SLC area has 64 pages per block.
2620         * Flex-OneNAND MLC area has 128 pages per block.
2621         * Expose MLC erase size to find erase_shift and page_mask.
2622         */
2623        if (FLEXONENAND(this))
2624                mtd->erasesize <<= 1;
2625
2626        this->erase_shift = ffs(mtd->erasesize) - 1;
2627        this->page_shift = ffs(mtd->writesize) - 1;
2628        this->ppb_shift = (this->erase_shift - this->page_shift);
2629        this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
2630        /* Set density mask. it is used for DDP */
2631        if (ONENAND_IS_DDP(this))
2632                this->density_mask = this->chipsize >> (this->erase_shift + 1);
2633        /* It's real page size */
2634        this->writesize = mtd->writesize;
2635
2636        /* REVIST: Multichip handling */
2637
2638        if (FLEXONENAND(this))
2639                flexonenand_get_size(mtd);
2640        else
2641                mtd->size = this->chipsize;
2642
2643        mtd->flags = MTD_CAP_NANDFLASH;
2644        mtd->_erase = onenand_erase;
2645        mtd->_read = onenand_read;
2646        mtd->_write = onenand_write;
2647        mtd->_read_oob = onenand_read_oob;
2648        mtd->_write_oob = onenand_write_oob;
2649        mtd->_sync = onenand_sync;
2650        mtd->_block_isbad = onenand_block_isbad;
2651        mtd->_block_markbad = onenand_block_markbad;
2652
2653        return 0;
2654}
2655
2656/**
2657 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
2658 * @param mtd           MTD device structure
2659 * @param maxchips      Number of chips to scan for
2660 *
2661 * This fills out all the not initialized function pointers
2662 * with the defaults.
2663 * The flash ID is read and the mtd/chip structures are
2664 * filled with the appropriate values.
2665 */
2666int onenand_scan(struct mtd_info *mtd, int maxchips)
2667{
2668        int i;
2669        struct onenand_chip *this = mtd->priv;
2670
2671        if (!this->read_word)
2672                this->read_word = onenand_readw;
2673        if (!this->write_word)
2674                this->write_word = onenand_writew;
2675
2676        if (!this->command)
2677                this->command = onenand_command;
2678        if (!this->wait)
2679                this->wait = onenand_wait;
2680        if (!this->bbt_wait)
2681                this->bbt_wait = onenand_bbt_wait;
2682
2683        if (!this->read_bufferram)
2684                this->read_bufferram = onenand_read_bufferram;
2685        if (!this->write_bufferram)
2686                this->write_bufferram = onenand_write_bufferram;
2687
2688        if (!this->chip_probe)
2689                this->chip_probe = onenand_chip_probe;
2690
2691        if (!this->block_markbad)
2692                this->block_markbad = onenand_default_block_markbad;
2693        if (!this->scan_bbt)
2694                this->scan_bbt = onenand_default_bbt;
2695
2696        if (onenand_probe(mtd))
2697                return -ENXIO;
2698
2699        /* Set Sync. Burst Read after probing */
2700        if (this->mmcontrol) {
2701                printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
2702                this->read_bufferram = onenand_sync_read_bufferram;
2703        }
2704
2705        /* Allocate buffers, if necessary */
2706        if (!this->page_buf) {
2707                this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
2708                if (!this->page_buf) {
2709                        printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
2710                        return -ENOMEM;
2711                }
2712                this->options |= ONENAND_PAGEBUF_ALLOC;
2713        }
2714        if (!this->oob_buf) {
2715                this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
2716                if (!this->oob_buf) {
2717                        printk(KERN_ERR "onenand_scan: Can't allocate oob_buf\n");
2718                        if (this->options & ONENAND_PAGEBUF_ALLOC) {
2719                                this->options &= ~ONENAND_PAGEBUF_ALLOC;
2720                                kfree(this->page_buf);
2721                        }
2722                        return -ENOMEM;
2723                }
2724                this->options |= ONENAND_OOBBUF_ALLOC;
2725        }
2726
2727        this->state = FL_READY;
2728
2729        /*
2730         * Allow subpage writes up to oobsize.
2731         */
2732        switch (mtd->oobsize) {
2733        case 128:
2734                this->ecclayout = &onenand_oob_128;
2735                mtd->subpage_sft = 0;
2736                break;
2737
2738        case 64:
2739                this->ecclayout = &onenand_oob_64;
2740                mtd->subpage_sft = 2;
2741                break;
2742
2743        case 32:
2744                this->ecclayout = &onenand_oob_32;
2745                mtd->subpage_sft = 1;
2746                break;
2747
2748        default:
2749                printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
2750                        mtd->oobsize);
2751                mtd->subpage_sft = 0;
2752                /* To prevent kernel oops */
2753                this->ecclayout = &onenand_oob_32;
2754                break;
2755        }
2756
2757        this->subpagesize = mtd->writesize >> mtd->subpage_sft;
2758
2759        /*
2760         * The number of bytes available for a client to place data into
2761         * the out of band area
2762         */
2763        this->ecclayout->oobavail = 0;
2764
2765        for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE &&
2766            this->ecclayout->oobfree[i].length; i++)
2767                this->ecclayout->oobavail +=
2768                        this->ecclayout->oobfree[i].length;
2769        mtd->oobavail = this->ecclayout->oobavail;
2770
2771        mtd->ecclayout = this->ecclayout;
2772
2773        /* Unlock whole block */
2774        onenand_unlock_all(mtd);
2775
2776        return this->scan_bbt(mtd);
2777}
2778
2779/**
2780 * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
2781 * @param mtd           MTD device structure
2782 */
2783void onenand_release(struct mtd_info *mtd)
2784{
2785}
2786