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