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