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