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
1840        /* Deselect and wake up anyone waiting on the device */
1841        onenand_release_device(mtd);
1842
1843        return ret;
1844}
1845
1846/**
1847 * onenand_sync - [MTD Interface] sync
1848 * @param mtd           MTD device structure
1849 *
1850 * Sync is actually a wait for chip ready function
1851 */
1852void onenand_sync(struct mtd_info *mtd)
1853{
1854        pr_debug("onenand_sync: called\n");
1855
1856        /* Grab the lock and see if the device is available */
1857        onenand_get_device(mtd, FL_SYNCING);
1858
1859        /* Release it and go back */
1860        onenand_release_device(mtd);
1861}
1862
1863/**
1864 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
1865 * @param mtd           MTD device structure
1866 * @param ofs           offset relative to mtd start
1867 *
1868 * Check whether the block is bad
1869 */
1870int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
1871{
1872        int ret;
1873
1874        /* Check for invalid offset */
1875        if (ofs > mtd->size)
1876                return -EINVAL;
1877
1878        onenand_get_device(mtd, FL_READING);
1879        ret = onenand_block_isbad_nolock(mtd,ofs, 0);
1880        onenand_release_device(mtd);
1881        return ret;
1882}
1883
1884/**
1885 * onenand_default_block_markbad - [DEFAULT] mark a block bad
1886 * @param mtd           MTD device structure
1887 * @param ofs           offset from device start
1888 *
1889 * This is the default implementation, which can be overridden by
1890 * a hardware specific driver.
1891 */
1892static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1893{
1894        struct onenand_chip *this = mtd->priv;
1895        struct bbm_info *bbm = this->bbm;
1896        u_char buf[2] = {0, 0};
1897        struct mtd_oob_ops ops = {
1898                .mode = MTD_OPS_PLACE_OOB,
1899                .ooblen = 2,
1900                .oobbuf = buf,
1901                .ooboffs = 0,
1902        };
1903        int block;
1904
1905        /* Get block number */
1906        block = onenand_block(this, ofs);
1907        if (bbm->bbt)
1908                bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
1909
1910        /* We write two bytes, so we dont have to mess with 16 bit access */
1911        ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1912        return onenand_write_oob_nolock(mtd, ofs, &ops);
1913}
1914
1915/**
1916 * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
1917 * @param mtd           MTD device structure
1918 * @param ofs           offset relative to mtd start
1919 *
1920 * Mark the block as bad
1921 */
1922int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1923{
1924        struct onenand_chip *this = mtd->priv;
1925        int ret;
1926
1927        ret = onenand_block_isbad(mtd, ofs);
1928        if (ret) {
1929                /* If it was bad already, return success and do nothing */
1930                if (ret > 0)
1931                        return 0;
1932                return ret;
1933        }
1934
1935        onenand_get_device(mtd, FL_WRITING);
1936        ret = this->block_markbad(mtd, ofs);
1937        onenand_release_device(mtd);
1938
1939        return ret;
1940}
1941
1942/**
1943 * onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s)
1944 * @param mtd           MTD device structure
1945 * @param ofs           offset relative to mtd start
1946 * @param len           number of bytes to lock or unlock
1947 * @param cmd           lock or unlock command
1948 *
1949 * Lock or unlock one or more blocks
1950 */
1951static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
1952{
1953        struct onenand_chip *this = mtd->priv;
1954        int start, end, block, value, status;
1955
1956        start = onenand_block(this, ofs);
1957        end = onenand_block(this, ofs + len);
1958
1959        /* Continuous lock scheme */
1960        if (this->options & ONENAND_HAS_CONT_LOCK) {
1961                /* Set start block address */
1962                this->write_word(start,
1963                                 this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1964                /* Set end block address */
1965                this->write_word(end - 1,
1966                                 this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1967                /* Write unlock command */
1968                this->command(mtd, cmd, 0, 0);
1969
1970                /* There's no return value */
1971                this->wait(mtd, FL_UNLOCKING);
1972
1973                /* Sanity check */
1974                while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1975                       & ONENAND_CTRL_ONGO)
1976                        continue;
1977
1978                /* Check lock status */
1979                status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1980                if (!(status & ONENAND_WP_US))
1981                        printk(KERN_ERR "wp status = 0x%x\n", status);
1982
1983                return 0;
1984        }
1985
1986        /* Block lock scheme */
1987        for (block = start; block < end; block++) {
1988                /* Set block address */
1989                value = onenand_block_address(this, block);
1990                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1991                /* Select DataRAM for DDP */
1992                value = onenand_bufferram_address(this, block);
1993                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
1994
1995                /* Set start block address */
1996                this->write_word(block,
1997                                 this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1998                /* Write unlock command */
1999                this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
2000
2001                /* There's no return value */
2002                this->wait(mtd, FL_UNLOCKING);
2003
2004                /* Sanity check */
2005                while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2006                       & ONENAND_CTRL_ONGO)
2007                        continue;
2008
2009                /* Check lock status */
2010                status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2011                if (!(status & ONENAND_WP_US))
2012                        printk(KERN_ERR "block = %d, wp status = 0x%x\n",
2013                               block, status);
2014        }
2015
2016        return 0;
2017}
2018
2019#ifdef ONENAND_LINUX
2020/**
2021 * onenand_lock - [MTD Interface] Lock block(s)
2022 * @param mtd           MTD device structure
2023 * @param ofs           offset relative to mtd start
2024 * @param len           number of bytes to unlock
2025 *
2026 * Lock one or more blocks
2027 */
2028static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
2029{
2030        int ret;
2031
2032        onenand_get_device(mtd, FL_LOCKING);
2033        ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
2034        onenand_release_device(mtd);
2035        return ret;
2036}
2037
2038/**
2039 * onenand_unlock - [MTD Interface] Unlock block(s)
2040 * @param mtd           MTD device structure
2041 * @param ofs           offset relative to mtd start
2042 * @param len           number of bytes to unlock
2043 *
2044 * Unlock one or more blocks
2045 */
2046static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
2047{
2048        int ret;
2049
2050        onenand_get_device(mtd, FL_LOCKING);
2051        ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2052        onenand_release_device(mtd);
2053        return ret;
2054}
2055#endif
2056
2057/**
2058 * onenand_check_lock_status - [OneNAND Interface] Check lock status
2059 * @param this          onenand chip data structure
2060 *
2061 * Check lock status
2062 */
2063static int onenand_check_lock_status(struct onenand_chip *this)
2064{
2065        unsigned int value, block, status;
2066        unsigned int end;
2067
2068        end = this->chipsize >> this->erase_shift;
2069        for (block = 0; block < end; block++) {
2070                /* Set block address */
2071                value = onenand_block_address(this, block);
2072                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
2073                /* Select DataRAM for DDP */
2074                value = onenand_bufferram_address(this, block);
2075                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
2076                /* Set start block address */
2077                this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2078
2079                /* Check lock status */
2080                status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2081                if (!(status & ONENAND_WP_US)) {
2082                        printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
2083                        return 0;
2084                }
2085        }
2086
2087        return 1;
2088}
2089
2090/**
2091 * onenand_unlock_all - [OneNAND Interface] unlock all blocks
2092 * @param mtd           MTD device structure
2093 *
2094 * Unlock all blocks
2095 */
2096static void onenand_unlock_all(struct mtd_info *mtd)
2097{
2098        struct onenand_chip *this = mtd->priv;
2099        loff_t ofs = 0;
2100        size_t len = mtd->size;
2101
2102        if (this->options & ONENAND_HAS_UNLOCK_ALL) {
2103                /* Set start block address */
2104                this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2105                /* Write unlock command */
2106                this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
2107
2108                /* There's no return value */
2109                this->wait(mtd, FL_LOCKING);
2110
2111                /* Sanity check */
2112                while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
2113                                & ONENAND_CTRL_ONGO)
2114                        continue;
2115
2116                /* Check lock status */
2117                if (onenand_check_lock_status(this))
2118                        return;
2119
2120                /* Workaround for all block unlock in DDP */
2121                if (ONENAND_IS_DDP(this) && !FLEXONENAND(this)) {
2122                        /* All blocks on another chip */
2123                        ofs = this->chipsize >> 1;
2124                        len = this->chipsize >> 1;
2125                }
2126        }
2127
2128        onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2129}
2130
2131
2132/**
2133 * onenand_check_features - Check and set OneNAND features
2134 * @param mtd           MTD data structure
2135 *
2136 * Check and set OneNAND features
2137 * - lock scheme
2138 * - two plane
2139 */
2140static void onenand_check_features(struct mtd_info *mtd)
2141{
2142        struct onenand_chip *this = mtd->priv;
2143        unsigned int density, process;
2144
2145        /* Lock scheme depends on density and process */
2146        density = onenand_get_density(this->device_id);
2147        process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
2148
2149        /* Lock scheme */
2150        switch (density) {
2151        case ONENAND_DEVICE_DENSITY_4Gb:
2152                if (ONENAND_IS_DDP(this))
2153                        this->options |= ONENAND_HAS_2PLANE;
2154                else
2155                        this->options |= ONENAND_HAS_4KB_PAGE;
2156
2157        case ONENAND_DEVICE_DENSITY_2Gb:
2158                /* 2Gb DDP don't have 2 plane */
2159                if (!ONENAND_IS_DDP(this))
2160                        this->options |= ONENAND_HAS_2PLANE;
2161                this->options |= ONENAND_HAS_UNLOCK_ALL;
2162
2163        case ONENAND_DEVICE_DENSITY_1Gb:
2164                /* A-Die has all block unlock */
2165                if (process)
2166                        this->options |= ONENAND_HAS_UNLOCK_ALL;
2167                break;
2168
2169        default:
2170                /* Some OneNAND has continuous lock scheme */
2171                if (!process)
2172                        this->options |= ONENAND_HAS_CONT_LOCK;
2173                break;
2174        }
2175
2176        if (ONENAND_IS_MLC(this))
2177                this->options |= ONENAND_HAS_4KB_PAGE;
2178
2179        if (ONENAND_IS_4KB_PAGE(this))
2180                this->options &= ~ONENAND_HAS_2PLANE;
2181
2182        if (FLEXONENAND(this)) {
2183                this->options &= ~ONENAND_HAS_CONT_LOCK;
2184                this->options |= ONENAND_HAS_UNLOCK_ALL;
2185        }
2186
2187        if (this->options & ONENAND_HAS_CONT_LOCK)
2188                printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
2189        if (this->options & ONENAND_HAS_UNLOCK_ALL)
2190                printk(KERN_DEBUG "Chip support all block unlock\n");
2191        if (this->options & ONENAND_HAS_2PLANE)
2192                printk(KERN_DEBUG "Chip has 2 plane\n");
2193        if (this->options & ONENAND_HAS_4KB_PAGE)
2194                printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
2195
2196}
2197
2198/**
2199 * onenand_print_device_info - Print device ID
2200 * @param device        device ID
2201 *
2202 * Print device ID
2203 */
2204char *onenand_print_device_info(int device, int version)
2205{
2206        int vcc, demuxed, ddp, density, flexonenand;
2207        char *dev_info = malloc(80);
2208        char *p = dev_info;
2209
2210        vcc = device & ONENAND_DEVICE_VCC_MASK;
2211        demuxed = device & ONENAND_DEVICE_IS_DEMUX;
2212        ddp = device & ONENAND_DEVICE_IS_DDP;
2213        density = onenand_get_density(device);
2214        flexonenand = device & DEVICE_IS_FLEXONENAND;
2215        p += sprintf(dev_info, "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)",
2216               demuxed ? "" : "Muxed ",
2217               flexonenand ? "Flex-" : "",
2218               ddp ? "(DDP)" : "",
2219               (16 << density), vcc ? "2.65/3.3" : "1.8", device);
2220
2221        sprintf(p, "\nOneNAND version = 0x%04x", version);
2222        printk("%s\n", dev_info);
2223
2224        return dev_info;
2225}
2226
2227static const struct onenand_manufacturers onenand_manuf_ids[] = {
2228        {ONENAND_MFR_NUMONYX, "Numonyx"},
2229        {ONENAND_MFR_SAMSUNG, "Samsung"},
2230};
2231
2232/**
2233 * onenand_check_maf - Check manufacturer ID
2234 * @param manuf         manufacturer ID
2235 *
2236 * Check manufacturer ID
2237 */
2238static int onenand_check_maf(int manuf)
2239{
2240        int size = ARRAY_SIZE(onenand_manuf_ids);
2241        int i;
2242#ifdef ONENAND_DEBUG
2243        char *name;
2244#endif
2245
2246        for (i = 0; i < size; i++)
2247                if (manuf == onenand_manuf_ids[i].id)
2248                        break;
2249
2250#ifdef ONENAND_DEBUG
2251        if (i < size)
2252                name = onenand_manuf_ids[i].name;
2253        else
2254                name = "Unknown";
2255
2256        printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
2257#endif
2258
2259        return i == size;
2260}
2261
2262/**
2263* flexonenand_get_boundary      - Reads the SLC boundary
2264* @param onenand_info           - onenand info structure
2265*
2266* Fill up boundary[] field in onenand_chip
2267**/
2268static int flexonenand_get_boundary(struct mtd_info *mtd)
2269{
2270        struct onenand_chip *this = mtd->priv;
2271        unsigned int die, bdry;
2272        int syscfg, locked;
2273
2274        /* Disable ECC */
2275        syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
2276        this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1);
2277
2278        for (die = 0; die < this->dies; die++) {
2279                this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
2280                this->wait(mtd, FL_SYNCING);
2281
2282                this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
2283                this->wait(mtd, FL_READING);
2284
2285                bdry = this->read_word(this->base + ONENAND_DATARAM);
2286                if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
2287                        locked = 0;
2288                else
2289                        locked = 1;
2290                this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
2291
2292                this->command(mtd, ONENAND_CMD_RESET, 0, 0);
2293                this->wait(mtd, FL_RESETING);
2294
2295                printk(KERN_INFO "Die %d boundary: %d%s\n", die,
2296                       this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
2297        }
2298
2299        /* Enable ECC */
2300        this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
2301        return 0;
2302}
2303
2304/**
2305 * flexonenand_get_size - Fill up fields in onenand_chip and mtd_info
2306 *                        boundary[], diesize[], mtd->size, mtd->erasesize,
2307 *                        mtd->eraseregions
2308 * @param mtd           - MTD device structure
2309 */
2310static void flexonenand_get_size(struct mtd_info *mtd)
2311{
2312        struct onenand_chip *this = mtd->priv;
2313        int die, i, eraseshift, density;
2314        int blksperdie, maxbdry;
2315        loff_t ofs;
2316
2317        density = onenand_get_density(this->device_id);
2318        blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift);
2319        blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
2320        maxbdry = blksperdie - 1;
2321        eraseshift = this->erase_shift - 1;
2322
2323        mtd->numeraseregions = this->dies << 1;
2324
2325        /* This fills up the device boundary */
2326        flexonenand_get_boundary(mtd);
2327        die = 0;
2328        ofs = 0;
2329        i = -1;
2330        for (; die < this->dies; die++) {
2331                if (!die || this->boundary[die-1] != maxbdry) {
2332                        i++;
2333                        mtd->eraseregions[i].offset = ofs;
2334                        mtd->eraseregions[i].erasesize = 1 << eraseshift;
2335                        mtd->eraseregions[i].numblocks =
2336                                                        this->boundary[die] + 1;
2337                        ofs += mtd->eraseregions[i].numblocks << eraseshift;
2338                        eraseshift++;
2339                } else {
2340                        mtd->numeraseregions -= 1;
2341                        mtd->eraseregions[i].numblocks +=
2342                                                        this->boundary[die] + 1;
2343                        ofs += (this->boundary[die] + 1) << (eraseshift - 1);
2344                }
2345                if (this->boundary[die] != maxbdry) {
2346                        i++;
2347                        mtd->eraseregions[i].offset = ofs;
2348                        mtd->eraseregions[i].erasesize = 1 << eraseshift;
2349                        mtd->eraseregions[i].numblocks = maxbdry ^
2350                                                         this->boundary[die];
2351                        ofs += mtd->eraseregions[i].numblocks << eraseshift;
2352                        eraseshift--;
2353                } else
2354                        mtd->numeraseregions -= 1;
2355        }
2356
2357        /* Expose MLC erase size except when all blocks are SLC */
2358        mtd->erasesize = 1 << this->erase_shift;
2359        if (mtd->numeraseregions == 1)
2360                mtd->erasesize >>= 1;
2361
2362        printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions);
2363        for (i = 0; i < mtd->numeraseregions; i++)
2364                printk(KERN_INFO "[offset: 0x%08llx, erasesize: 0x%05x,"
2365                        " numblocks: %04u]\n", mtd->eraseregions[i].offset,
2366                        mtd->eraseregions[i].erasesize,
2367                        mtd->eraseregions[i].numblocks);
2368
2369        for (die = 0, mtd->size = 0; die < this->dies; die++) {
2370                this->diesize[die] = (loff_t) (blksperdie << this->erase_shift);
2371                this->diesize[die] -= (loff_t) (this->boundary[die] + 1)
2372                                                 << (this->erase_shift - 1);
2373                mtd->size += this->diesize[die];
2374        }
2375}
2376
2377/**
2378 * flexonenand_check_blocks_erased - Check if blocks are erased
2379 * @param mtd_info      - mtd info structure
2380 * @param start         - first erase block to check
2381 * @param end           - last erase block to check
2382 *
2383 * Converting an unerased block from MLC to SLC
2384 * causes byte values to change. Since both data and its ECC
2385 * have changed, reads on the block give uncorrectable error.
2386 * This might lead to the block being detected as bad.
2387 *
2388 * Avoid this by ensuring that the block to be converted is
2389 * erased.
2390 */
2391static int flexonenand_check_blocks_erased(struct mtd_info *mtd,
2392                                        int start, int end)
2393{
2394        struct onenand_chip *this = mtd->priv;
2395        int i, ret;
2396        int block;
2397        struct mtd_oob_ops ops = {
2398                .mode = MTD_OPS_PLACE_OOB,
2399                .ooboffs = 0,
2400                .ooblen = mtd->oobsize,
2401                .datbuf = NULL,
2402                .oobbuf = this->oob_buf,
2403        };
2404        loff_t addr;
2405
2406        printk(KERN_DEBUG "Check blocks from %d to %d\n", start, end);
2407
2408        for (block = start; block <= end; block++) {
2409                addr = flexonenand_addr(this, block);
2410                if (onenand_block_isbad_nolock(mtd, addr, 0))
2411                        continue;
2412
2413                /*
2414                 * Since main area write results in ECC write to spare,
2415                 * it is sufficient to check only ECC bytes for change.
2416                 */
2417                ret = onenand_read_oob_nolock(mtd, addr, &ops);
2418                if (ret)
2419                        return ret;
2420
2421                for (i = 0; i < mtd->oobsize; i++)
2422                        if (this->oob_buf[i] != 0xff)
2423                                break;
2424
2425                if (i != mtd->oobsize) {
2426                        printk(KERN_WARNING "Block %d not erased.\n", block);
2427                        return 1;
2428                }
2429        }
2430
2431        return 0;
2432}
2433
2434/**
2435 * flexonenand_set_boundary     - Writes the SLC boundary
2436 * @param mtd                   - mtd info structure
2437 */
2438int flexonenand_set_boundary(struct mtd_info *mtd, int die,
2439                                    int boundary, int lock)
2440{
2441        struct onenand_chip *this = mtd->priv;
2442        int ret, density, blksperdie, old, new, thisboundary;
2443        loff_t addr;
2444
2445        if (die >= this->dies)
2446                return -EINVAL;
2447
2448        if (boundary == this->boundary[die])
2449                return 0;
2450
2451        density = onenand_get_density(this->device_id);
2452        blksperdie = ((16 << density) << 20) >> this->erase_shift;
2453        blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
2454
2455        if (boundary >= blksperdie) {
2456                printk("flexonenand_set_boundary:"
2457                        "Invalid boundary value. "
2458                        "Boundary not changed.\n");
2459                return -EINVAL;
2460        }
2461
2462        /* Check if converting blocks are erased */
2463        old = this->boundary[die] + (die * this->density_mask);
2464        new = boundary + (die * this->density_mask);
2465        ret = flexonenand_check_blocks_erased(mtd, min(old, new)
2466                                                + 1, max(old, new));
2467        if (ret) {
2468                printk(KERN_ERR "flexonenand_set_boundary: Please erase blocks before boundary change\n");
2469                return ret;
2470        }
2471
2472        this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
2473        this->wait(mtd, FL_SYNCING);
2474
2475        /* Check is boundary is locked */
2476        this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
2477        ret = this->wait(mtd, FL_READING);
2478
2479        thisboundary = this->read_word(this->base + ONENAND_DATARAM);
2480        if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
2481                printk(KERN_ERR "flexonenand_set_boundary: boundary locked\n");
2482                goto out;
2483        }
2484
2485        printk(KERN_INFO "flexonenand_set_boundary: Changing die %d boundary: %d%s\n",
2486                        die, boundary, lock ? "(Locked)" : "(Unlocked)");
2487
2488        boundary &= FLEXONENAND_PI_MASK;
2489        boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT);
2490
2491        addr = die ? this->diesize[0] : 0;
2492        this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
2493        ret = this->wait(mtd, FL_ERASING);
2494        if (ret) {
2495                printk("flexonenand_set_boundary:"
2496                        "Failed PI erase for Die %d\n", die);
2497                goto out;
2498        }
2499
2500        this->write_word(boundary, this->base + ONENAND_DATARAM);
2501        this->command(mtd, ONENAND_CMD_PROG, addr, 0);
2502        ret = this->wait(mtd, FL_WRITING);
2503        if (ret) {
2504                printk("flexonenand_set_boundary:"
2505                        "Failed PI write for Die %d\n", die);
2506                goto out;
2507        }
2508
2509        this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0);
2510        ret = this->wait(mtd, FL_WRITING);
2511out:
2512        this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND);
2513        this->wait(mtd, FL_RESETING);
2514        if (!ret)
2515                /* Recalculate device size on boundary change*/
2516                flexonenand_get_size(mtd);
2517
2518        return ret;
2519}
2520
2521/**
2522 * onenand_chip_probe - [OneNAND Interface] Probe the OneNAND chip
2523 * @param mtd           MTD device structure
2524 *
2525 * OneNAND detection method:
2526 *   Compare the the values from command with ones from register
2527 */
2528static int onenand_chip_probe(struct mtd_info *mtd)
2529{
2530        struct onenand_chip *this = mtd->priv;
2531        int bram_maf_id, bram_dev_id, maf_id, dev_id;
2532        int syscfg;
2533
2534        /* Save system configuration 1 */
2535        syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
2536
2537        /* Clear Sync. Burst Read mode to read BootRAM */
2538        this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ),
2539                         this->base + ONENAND_REG_SYS_CFG1);
2540
2541        /* Send the command for reading device ID from BootRAM */
2542        this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
2543
2544        /* Read manufacturer and device IDs from BootRAM */
2545        bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
2546        bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
2547
2548        /* Reset OneNAND to read default register values */
2549        this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
2550
2551        /* Wait reset */
2552        if (this->wait(mtd, FL_RESETING))
2553                return -ENXIO;
2554
2555        /* Restore system configuration 1 */
2556        this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
2557
2558        /* Check manufacturer ID */
2559        if (onenand_check_maf(bram_maf_id))
2560                return -ENXIO;
2561
2562        /* Read manufacturer and device IDs from Register */
2563        maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
2564        dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
2565
2566        /* Check OneNAND device */
2567        if (maf_id != bram_maf_id || dev_id != bram_dev_id)
2568                return -ENXIO;
2569
2570        return 0;
2571}
2572
2573/**
2574 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
2575 * @param mtd           MTD device structure
2576 *
2577 * OneNAND detection method:
2578 *   Compare the the values from command with ones from register
2579 */
2580int onenand_probe(struct mtd_info *mtd)
2581{
2582        struct onenand_chip *this = mtd->priv;
2583        int dev_id, ver_id;
2584        int density;
2585        int ret;
2586
2587        ret = this->chip_probe(mtd);
2588        if (ret)
2589                return ret;
2590
2591        /* Read device IDs from Register */
2592        dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
2593        ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
2594        this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
2595
2596        /* Flash device information */
2597        mtd->name = onenand_print_device_info(dev_id, ver_id);
2598        this->device_id = dev_id;
2599        this->version_id = ver_id;
2600
2601        /* Check OneNAND features */
2602        onenand_check_features(mtd);
2603
2604        density = onenand_get_density(dev_id);
2605        if (FLEXONENAND(this)) {
2606                this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
2607                /* Maximum possible erase regions */
2608                mtd->numeraseregions = this->dies << 1;
2609                mtd->eraseregions = malloc(sizeof(struct mtd_erase_region_info)
2610                                        * (this->dies << 1));
2611                if (!mtd->eraseregions)
2612                        return -ENOMEM;
2613        }
2614
2615        /*
2616         * For Flex-OneNAND, chipsize represents maximum possible device size.
2617         * mtd->size represents the actual device size.
2618         */
2619        this->chipsize = (16 << density) << 20;
2620
2621        /* OneNAND page size & block size */
2622        /* The data buffer size is equal to page size */
2623        mtd->writesize =
2624            this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
2625        /* We use the full BufferRAM */
2626        if (ONENAND_IS_4KB_PAGE(this))
2627                mtd->writesize <<= 1;
2628
2629        mtd->oobsize = mtd->writesize >> 5;
2630        /* Pagers per block is always 64 in OneNAND */
2631        mtd->erasesize = mtd->writesize << 6;
2632        /*
2633         * Flex-OneNAND SLC area has 64 pages per block.
2634         * Flex-OneNAND MLC area has 128 pages per block.
2635         * Expose MLC erase size to find erase_shift and page_mask.
2636         */
2637        if (FLEXONENAND(this))
2638                mtd->erasesize <<= 1;
2639
2640        this->erase_shift = ffs(mtd->erasesize) - 1;
2641        this->page_shift = ffs(mtd->writesize) - 1;
2642        this->ppb_shift = (this->erase_shift - this->page_shift);
2643        this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
2644        /* Set density mask. it is used for DDP */
2645        if (ONENAND_IS_DDP(this))
2646                this->density_mask = this->chipsize >> (this->erase_shift + 1);
2647        /* It's real page size */
2648        this->writesize = mtd->writesize;
2649
2650        /* REVIST: Multichip handling */
2651
2652        if (FLEXONENAND(this))
2653                flexonenand_get_size(mtd);
2654        else
2655                mtd->size = this->chipsize;
2656
2657        mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH;
2658        mtd->flags = MTD_CAP_NANDFLASH;
2659        mtd->_erase = onenand_erase;
2660        mtd->_read_oob = onenand_read_oob;
2661        mtd->_write_oob = onenand_write_oob;
2662        mtd->_sync = onenand_sync;
2663        mtd->_block_isbad = onenand_block_isbad;
2664        mtd->_block_markbad = onenand_block_markbad;
2665        mtd->writebufsize = mtd->writesize;
2666
2667        return 0;
2668}
2669
2670/**
2671 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
2672 * @param mtd           MTD device structure
2673 * @param maxchips      Number of chips to scan for
2674 *
2675 * This fills out all the not initialized function pointers
2676 * with the defaults.
2677 * The flash ID is read and the mtd/chip structures are
2678 * filled with the appropriate values.
2679 */
2680int onenand_scan(struct mtd_info *mtd, int maxchips)
2681{
2682        int i;
2683        struct onenand_chip *this = mtd->priv;
2684
2685        if (!this->read_word)
2686                this->read_word = onenand_readw;
2687        if (!this->write_word)
2688                this->write_word = onenand_writew;
2689
2690        if (!this->command)
2691                this->command = onenand_command;
2692        if (!this->wait)
2693                this->wait = onenand_wait;
2694        if (!this->bbt_wait)
2695                this->bbt_wait = onenand_bbt_wait;
2696
2697        if (!this->read_bufferram)
2698                this->read_bufferram = onenand_read_bufferram;
2699        if (!this->write_bufferram)
2700                this->write_bufferram = onenand_write_bufferram;
2701
2702        if (!this->chip_probe)
2703                this->chip_probe = onenand_chip_probe;
2704
2705        if (!this->block_markbad)
2706                this->block_markbad = onenand_default_block_markbad;
2707        if (!this->scan_bbt)
2708                this->scan_bbt = onenand_default_bbt;
2709
2710        if (onenand_probe(mtd))
2711                return -ENXIO;
2712
2713        /* Set Sync. Burst Read after probing */
2714        if (this->mmcontrol) {
2715                printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
2716                this->read_bufferram = onenand_sync_read_bufferram;
2717        }
2718
2719        /* Allocate buffers, if necessary */
2720        if (!this->page_buf) {
2721                this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
2722                if (!this->page_buf) {
2723                        printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
2724                        return -ENOMEM;
2725                }
2726                this->options |= ONENAND_PAGEBUF_ALLOC;
2727        }
2728        if (!this->oob_buf) {
2729                this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
2730                if (!this->oob_buf) {
2731                        printk(KERN_ERR "onenand_scan: Can't allocate oob_buf\n");
2732                        if (this->options & ONENAND_PAGEBUF_ALLOC) {
2733                                this->options &= ~ONENAND_PAGEBUF_ALLOC;
2734                                kfree(this->page_buf);
2735                        }
2736                        return -ENOMEM;
2737                }
2738                this->options |= ONENAND_OOBBUF_ALLOC;
2739        }
2740
2741        this->state = FL_READY;
2742
2743        /*
2744         * Allow subpage writes up to oobsize.
2745         */
2746        switch (mtd->oobsize) {
2747        case 128:
2748                this->ecclayout = &onenand_oob_128;
2749                mtd->subpage_sft = 0;
2750                break;
2751
2752        case 64:
2753                this->ecclayout = &onenand_oob_64;
2754                mtd->subpage_sft = 2;
2755                break;
2756
2757        case 32:
2758                this->ecclayout = &onenand_oob_32;
2759                mtd->subpage_sft = 1;
2760                break;
2761
2762        default:
2763                printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
2764                        mtd->oobsize);
2765                mtd->subpage_sft = 0;
2766                /* To prevent kernel oops */
2767                this->ecclayout = &onenand_oob_32;
2768                break;
2769        }
2770
2771        this->subpagesize = mtd->writesize >> mtd->subpage_sft;
2772
2773        /*
2774         * The number of bytes available for a client to place data into
2775         * the out of band area
2776         */
2777        this->ecclayout->oobavail = 0;
2778
2779        for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE &&
2780            this->ecclayout->oobfree[i].length; i++)
2781                this->ecclayout->oobavail +=
2782                        this->ecclayout->oobfree[i].length;
2783        mtd->oobavail = this->ecclayout->oobavail;
2784
2785        mtd->ecclayout = this->ecclayout;
2786
2787        /* Unlock whole block */
2788        onenand_unlock_all(mtd);
2789
2790        return this->scan_bbt(mtd);
2791}
2792
2793/**
2794 * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
2795 * @param mtd           MTD device structure
2796 */
2797void onenand_release(struct mtd_info *mtd)
2798{
2799}
2800