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