uboot/drivers/mtd/at45.c
<<
>>
Prefs
   1/* Driver for ATMEL DataFlash support
   2 * Author : Hamid Ikdoumi (Atmel)
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License as
   6 * published by the Free Software Foundation; either version 2 of
   7 * the License, or (at your option) any later version.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write to the Free Software
  16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  17 * MA 02111-1307 USA
  18 *
  19 */
  20
  21#include <config.h>
  22#include <common.h>
  23#include <dataflash.h>
  24
  25/*
  26 * spi.c API
  27 */
  28extern unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc);
  29extern void AT91F_SpiEnable(int cs);
  30
  31#define AT91C_TIMEOUT_WRDY                      200000
  32
  33/*----------------------------------------------------------------------*/
  34/* \fn    AT91F_DataFlashSendCommand                                    */
  35/* \brief Generic function to send a command to the dataflash           */
  36/*----------------------------------------------------------------------*/
  37AT91S_DataFlashStatus AT91F_DataFlashSendCommand(AT91PS_DataFlash pDataFlash,
  38                                                 unsigned char OpCode,
  39                                                 unsigned int CmdSize,
  40                                                 unsigned int DataflashAddress)
  41{
  42        unsigned int adr;
  43
  44        if ((pDataFlash->pDataFlashDesc->state) != IDLE)
  45                return DATAFLASH_BUSY;
  46
  47        /* process the address to obtain page address and byte address */
  48        adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) <<
  49                pDataFlash->pDevice->page_offset) +
  50                        (DataflashAddress % (pDataFlash->pDevice->pages_size));
  51
  52        /* fill the command buffer */
  53        pDataFlash->pDataFlashDesc->command[0] = OpCode;
  54        if (pDataFlash->pDevice->pages_number >= 16384) {
  55                pDataFlash->pDataFlashDesc->command[1] =
  56                        (unsigned char)((adr & 0x0F000000) >> 24);
  57                pDataFlash->pDataFlashDesc->command[2] =
  58                        (unsigned char)((adr & 0x00FF0000) >> 16);
  59                pDataFlash->pDataFlashDesc->command[3] =
  60                        (unsigned char)((adr & 0x0000FF00) >> 8);
  61                pDataFlash->pDataFlashDesc->command[4] =
  62                        (unsigned char)(adr & 0x000000FF);
  63        } else {
  64                pDataFlash->pDataFlashDesc->command[1] =
  65                        (unsigned char)((adr & 0x00FF0000) >> 16);
  66                pDataFlash->pDataFlashDesc->command[2] =
  67                        (unsigned char)((adr & 0x0000FF00) >> 8);
  68                pDataFlash->pDataFlashDesc->command[3] =
  69                        (unsigned char)(adr & 0x000000FF);
  70                pDataFlash->pDataFlashDesc->command[4] = 0;
  71        }
  72        pDataFlash->pDataFlashDesc->command[5] = 0;
  73        pDataFlash->pDataFlashDesc->command[6] = 0;
  74        pDataFlash->pDataFlashDesc->command[7] = 0;
  75
  76        /* Initialize the SpiData structure for the spi write fuction */
  77        pDataFlash->pDataFlashDesc->tx_cmd_pt =
  78                pDataFlash->pDataFlashDesc->command;
  79        pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize;
  80        pDataFlash->pDataFlashDesc->rx_cmd_pt =
  81                pDataFlash->pDataFlashDesc->command;
  82        pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize;
  83
  84        /* send the command and read the data */
  85        return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
  86}
  87
  88/*----------------------------------------------------------------------*/
  89/* \fn    AT91F_DataFlashGetStatus                                      */
  90/* \brief Read the status register of the dataflash                     */
  91/*----------------------------------------------------------------------*/
  92AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
  93{
  94        AT91S_DataFlashStatus status;
  95
  96        /* if a transfert is in progress ==> return 0 */
  97        if ((pDesc->state) != IDLE)
  98                return DATAFLASH_BUSY;
  99
 100        /* first send the read status command (D7H) */
 101        pDesc->command[0] = DB_STATUS;
 102        pDesc->command[1] = 0;
 103
 104        pDesc->DataFlash_state = GET_STATUS;
 105        pDesc->tx_data_size = 0;        /* Transmit the command */
 106        /* and receive response */
 107        pDesc->tx_cmd_pt = pDesc->command;
 108        pDesc->rx_cmd_pt = pDesc->command;
 109        pDesc->rx_cmd_size = 2;
 110        pDesc->tx_cmd_size = 2;
 111        status = AT91F_SpiWrite(pDesc);
 112
 113        pDesc->DataFlash_state = *((unsigned char *)(pDesc->rx_cmd_pt) + 1);
 114
 115        return status;
 116}
 117
 118/*----------------------------------------------------------------------*/
 119/* \fn    AT91F_DataFlashWaitReady                                      */
 120/* \brief wait for dataflash ready (bit7 of the status register == 1)   */
 121/*----------------------------------------------------------------------*/
 122AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc
 123                                                pDataFlashDesc,
 124                                                unsigned int timeout)
 125{
 126        pDataFlashDesc->DataFlash_state = IDLE;
 127
 128        do {
 129                AT91F_DataFlashGetStatus(pDataFlashDesc);
 130                timeout--;
 131        } while (((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) &&
 132                 (timeout > 0));
 133
 134        if ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
 135                return DATAFLASH_ERROR;
 136
 137        return DATAFLASH_OK;
 138}
 139
 140/*--------------------------------------------------------------------------*/
 141/* Function Name       : AT91F_DataFlashContinuousRead                      */
 142/* Object              : Continuous stream Read                     */
 143/* Input Parameters    : DataFlash Service                                  */
 144/*                                              : <src> = dataflash address */
 145/*                     : <*dataBuffer> = data buffer pointer                */
 146/*                     : <sizeToRead> = data buffer size                    */
 147/* Return value         : State of the dataflash                            */
 148/*--------------------------------------------------------------------------*/
 149AT91S_DataFlashStatus AT91F_DataFlashContinuousRead(
 150                                AT91PS_DataFlash pDataFlash,
 151                                int src,
 152                                unsigned char *dataBuffer,
 153                                int sizeToRead)
 154{
 155        AT91S_DataFlashStatus status;
 156        /* Test the size to read in the device */
 157        if ((src + sizeToRead) >
 158                        (pDataFlash->pDevice->pages_size *
 159                                (pDataFlash->pDevice->pages_number)))
 160                return DATAFLASH_MEMORY_OVERFLOW;
 161
 162        pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
 163        pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
 164        pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
 165        pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
 166
 167        status = AT91F_DataFlashSendCommand(
 168                        pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
 169        /* Send the command to the dataflash */
 170        return (status);
 171}
 172
 173/*---------------------------------------------------------------------------*/
 174/* Function Name       : AT91F_DataFlashPagePgmBuf                           */
 175/* Object              : Main memory page program thru buffer 1 or buffer 2  */
 176/* Input Parameters    : DataFlash Service                                   */
 177/*                                              : <*src> = Source buffer     */
 178/*                     : <dest> = dataflash destination address              */
 179/*                     : <SizeToWrite> = data buffer size                    */
 180/* Return value         : State of the dataflash                             */
 181/*---------------------------------------------------------------------------*/
 182AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(AT91PS_DataFlash pDataFlash,
 183                                                unsigned char *src,
 184                                                unsigned int dest,
 185                                                unsigned int SizeToWrite)
 186{
 187        int cmdsize;
 188        pDataFlash->pDataFlashDesc->tx_data_pt = src;
 189        pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
 190        pDataFlash->pDataFlashDesc->rx_data_pt = src;
 191        pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
 192
 193        cmdsize = 4;
 194        /* Send the command to the dataflash */
 195        if (pDataFlash->pDevice->pages_number >= 16384)
 196                cmdsize = 5;
 197        return (AT91F_DataFlashSendCommand(
 198                        pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
 199}
 200
 201/*---------------------------------------------------------------------------*/
 202/* Function Name       : AT91F_MainMemoryToBufferTransfert                   */
 203/* Object              : Read a page in the SRAM Buffer 1 or 2               */
 204/* Input Parameters    : DataFlash Service                                   */
 205/*                     : Page concerned                                      */
 206/*                     :                                                     */
 207/* Return value         : State of the dataflash                             */
 208/*---------------------------------------------------------------------------*/
 209AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
 210                                        AT91PS_DataFlash
 211                                        pDataFlash,
 212                                        unsigned char
 213                                        BufferCommand,
 214                                        unsigned int page)
 215{
 216        int cmdsize;
 217        /* Test if the buffer command is legal */
 218        if ((BufferCommand != DB_PAGE_2_BUF1_TRF) &&
 219                        (BufferCommand != DB_PAGE_2_BUF2_TRF)) {
 220                return DATAFLASH_BAD_COMMAND;
 221        }
 222
 223        /* no data to transmit or receive */
 224        pDataFlash->pDataFlashDesc->tx_data_size = 0;
 225        cmdsize = 4;
 226        if (pDataFlash->pDevice->pages_number >= 16384)
 227                cmdsize = 5;
 228        return (AT91F_DataFlashSendCommand(
 229                        pDataFlash, BufferCommand, cmdsize,
 230                        page * pDataFlash->pDevice->pages_size));
 231}
 232
 233/*-------------------------------------------------------------------------- */
 234/* Function Name       : AT91F_DataFlashWriteBuffer                          */
 235/* Object              : Write data to the internal sram buffer 1 or 2       */
 236/* Input Parameters    : DataFlash Service                                   */
 237/*                      : <BufferCommand> = command to write buffer1 or 2    */
 238/*                     : <*dataBuffer> = data buffer to write                */
 239/*                     : <bufferAddress> = address in the internal buffer    */
 240/*                     : <SizeToWrite> = data buffer size                    */
 241/* Return value         : State of the dataflash                             */
 242/*---------------------------------------------------------------------------*/
 243AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer(
 244                                        AT91PS_DataFlash pDataFlash,
 245                                        unsigned char BufferCommand,
 246                                        unsigned char *dataBuffer,
 247                                        unsigned int bufferAddress,
 248                                        int SizeToWrite)
 249{
 250        int cmdsize;
 251        /* Test if the buffer command is legal */
 252        if ((BufferCommand != DB_BUF1_WRITE) &&
 253                        (BufferCommand != DB_BUF2_WRITE)) {
 254                return DATAFLASH_BAD_COMMAND;
 255        }
 256
 257        /* buffer address must be lower than page size */
 258        if (bufferAddress > pDataFlash->pDevice->pages_size)
 259                return DATAFLASH_BAD_ADDRESS;
 260
 261        if ((pDataFlash->pDataFlashDesc->state) != IDLE)
 262                return DATAFLASH_BUSY;
 263
 264        /* Send first Write Command */
 265        pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
 266        pDataFlash->pDataFlashDesc->command[1] = 0;
 267        if (pDataFlash->pDevice->pages_number >= 16384) {
 268                pDataFlash->pDataFlashDesc->command[2] = 0;
 269                pDataFlash->pDataFlashDesc->command[3] =
 270                        (unsigned char)(((unsigned int)(bufferAddress &
 271                                                        pDataFlash->pDevice->
 272                                                        byte_mask)) >> 8);
 273                pDataFlash->pDataFlashDesc->command[4] =
 274                        (unsigned char)((unsigned int)bufferAddress & 0x00FF);
 275                cmdsize = 5;
 276        } else {
 277                pDataFlash->pDataFlashDesc->command[2] =
 278                        (unsigned char)(((unsigned int)(bufferAddress &
 279                                                        pDataFlash->pDevice->
 280                                                        byte_mask)) >> 8);
 281                pDataFlash->pDataFlashDesc->command[3] =
 282                        (unsigned char)((unsigned int)bufferAddress & 0x00FF);
 283                pDataFlash->pDataFlashDesc->command[4] = 0;
 284                cmdsize = 4;
 285        }
 286
 287        pDataFlash->pDataFlashDesc->tx_cmd_pt =
 288                pDataFlash->pDataFlashDesc->command;
 289        pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize;
 290        pDataFlash->pDataFlashDesc->rx_cmd_pt =
 291                pDataFlash->pDataFlashDesc->command;
 292        pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize;
 293
 294        pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
 295        pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
 296        pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
 297        pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
 298
 299        return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
 300}
 301
 302/*---------------------------------------------------------------------------*/
 303/* Function Name       : AT91F_PageErase                                     */
 304/* Object              : Erase a page                                        */
 305/* Input Parameters    : DataFlash Service                                   */
 306/*                     : Page concerned                                      */
 307/*                     :                                                     */
 308/* Return value         : State of the dataflash                             */
 309/*---------------------------------------------------------------------------*/
 310AT91S_DataFlashStatus AT91F_PageErase(
 311                                        AT91PS_DataFlash pDataFlash,
 312                                        unsigned int page)
 313{
 314        int cmdsize;
 315        /* Test if the buffer command is legal */
 316        /* no data to transmit or receive */
 317        pDataFlash->pDataFlashDesc->tx_data_size = 0;
 318
 319        cmdsize = 4;
 320        if (pDataFlash->pDevice->pages_number >= 16384)
 321                cmdsize = 5;
 322        return (AT91F_DataFlashSendCommand(pDataFlash,
 323                                DB_PAGE_ERASE, cmdsize,
 324                                page * pDataFlash->pDevice->pages_size));
 325}
 326
 327/*---------------------------------------------------------------------------*/
 328/* Function Name       : AT91F_BlockErase                                    */
 329/* Object              : Erase a Block                                       */
 330/* Input Parameters    : DataFlash Service                                   */
 331/*                     : Page concerned                                      */
 332/*                     :                                                     */
 333/* Return value         : State of the dataflash                             */
 334/*---------------------------------------------------------------------------*/
 335AT91S_DataFlashStatus AT91F_BlockErase(
 336                                AT91PS_DataFlash pDataFlash,
 337                                unsigned int block)
 338{
 339        int cmdsize;
 340        /* Test if the buffer command is legal */
 341        /* no data to transmit or receive */
 342        pDataFlash->pDataFlashDesc->tx_data_size = 0;
 343        cmdsize = 4;
 344        if (pDataFlash->pDevice->pages_number >= 16384)
 345                cmdsize = 5;
 346        return (AT91F_DataFlashSendCommand(pDataFlash, DB_BLOCK_ERASE, cmdsize,
 347                                        block * 8 *
 348                                        pDataFlash->pDevice->pages_size));
 349}
 350
 351/*---------------------------------------------------------------------------*/
 352/* Function Name       : AT91F_WriteBufferToMain                             */
 353/* Object              : Write buffer to the main memory                     */
 354/* Input Parameters    : DataFlash Service                                   */
 355/*              : <BufferCommand> = command to send to buffer1 or buffer2    */
 356/*                     : <dest> = main memory address                        */
 357/* Return value         : State of the dataflash                             */
 358/*---------------------------------------------------------------------------*/
 359AT91S_DataFlashStatus AT91F_WriteBufferToMain(AT91PS_DataFlash pDataFlash,
 360                                        unsigned char BufferCommand,
 361                                        unsigned int dest)
 362{
 363        int cmdsize;
 364        /* Test if the buffer command is correct */
 365        if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
 366                        (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
 367                        (BufferCommand != DB_BUF2_PAGE_PGM) &&
 368                        (BufferCommand != DB_BUF2_PAGE_ERASE_PGM))
 369                return DATAFLASH_BAD_COMMAND;
 370
 371        /* no data to transmit or receive */
 372        pDataFlash->pDataFlashDesc->tx_data_size = 0;
 373
 374        cmdsize = 4;
 375        if (pDataFlash->pDevice->pages_number >= 16384)
 376                cmdsize = 5;
 377        /* Send the command to the dataflash */
 378        return (AT91F_DataFlashSendCommand(pDataFlash, BufferCommand,
 379                                                cmdsize, dest));
 380}
 381
 382/*---------------------------------------------------------------------------*/
 383/* Function Name       : AT91F_PartialPageWrite                              */
 384/* Object              : Erase partielly a page                              */
 385/* Input Parameters    : <page> = page number                                */
 386/*                      : <AdrInpage> = adr to begin the fading              */
 387/*                     : <length> = Number of bytes to erase                 */
 388/*---------------------------------------------------------------------------*/
 389AT91S_DataFlashStatus AT91F_PartialPageWrite(AT91PS_DataFlash pDataFlash,
 390                                        unsigned char *src,
 391                                        unsigned int dest,
 392                                        unsigned int size)
 393{
 394        unsigned int page;
 395        unsigned int AdrInPage;
 396
 397        page = dest / (pDataFlash->pDevice->pages_size);
 398        AdrInPage = dest % (pDataFlash->pDevice->pages_size);
 399
 400        /* Read the contents of the page in the Sram Buffer */
 401        AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
 402        AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 403                                 AT91C_TIMEOUT_WRDY);
 404        /*Update the SRAM buffer */
 405        AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src,
 406                                        AdrInPage, size);
 407
 408        AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 409                                        AT91C_TIMEOUT_WRDY);
 410
 411        /* Erase page if a 128 Mbits device */
 412        if (pDataFlash->pDevice->pages_number >= 16384) {
 413                AT91F_PageErase(pDataFlash, page);
 414                /* Rewrite the modified Sram Buffer in the main memory */
 415                AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 416                                         AT91C_TIMEOUT_WRDY);
 417        }
 418
 419        /* Rewrite the modified Sram Buffer in the main memory */
 420        return (AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM,
 421                                        (page *
 422                                         pDataFlash->pDevice->pages_size)));
 423}
 424
 425/*---------------------------------------------------------------------------*/
 426/* Function Name       : AT91F_DataFlashWrite                                */
 427/* Object              :                                                     */
 428/* Input Parameters    : <*src> = Source buffer                              */
 429/*                     : <dest> = dataflash adress                           */
 430/*                     : <size> = data buffer size                           */
 431/*---------------------------------------------------------------------------*/
 432AT91S_DataFlashStatus AT91F_DataFlashWrite(AT91PS_DataFlash pDataFlash,
 433                                                unsigned char *src,
 434                                                int dest, int size)
 435{
 436        unsigned int length;
 437        unsigned int page;
 438        unsigned int status;
 439
 440        AT91F_SpiEnable(pDataFlash->pDevice->cs);
 441
 442        if ((dest + size) > (pDataFlash->pDevice->pages_size *
 443                        (pDataFlash->pDevice->pages_number)))
 444                return DATAFLASH_MEMORY_OVERFLOW;
 445
 446        /* If destination does not fit a page start address */
 447        if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0) {
 448                length =
 449                        pDataFlash->pDevice->pages_size -
 450                        (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
 451
 452                if (size < length)
 453                        length = size;
 454
 455                if (!AT91F_PartialPageWrite(pDataFlash, src, dest, length))
 456                        return DATAFLASH_ERROR;
 457
 458                AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 459                                         AT91C_TIMEOUT_WRDY);
 460
 461                /* Update size, source and destination pointers */
 462                size -= length;
 463                dest += length;
 464                src += length;
 465        }
 466
 467        while ((size - pDataFlash->pDevice->pages_size) >= 0) {
 468                /* program dataflash page */
 469                page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
 470
 471                status = AT91F_DataFlashWriteBuffer(pDataFlash,
 472                                        DB_BUF1_WRITE, src, 0,
 473                                        pDataFlash->pDevice->
 474                                        pages_size);
 475                AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 476                                         AT91C_TIMEOUT_WRDY);
 477
 478                status = AT91F_PageErase(pDataFlash, page);
 479                AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 480                                         AT91C_TIMEOUT_WRDY);
 481                if (!status)
 482                        return DATAFLASH_ERROR;
 483
 484                status = AT91F_WriteBufferToMain(pDataFlash,
 485                                         DB_BUF1_PAGE_PGM, dest);
 486                if (!status)
 487                        return DATAFLASH_ERROR;
 488
 489                AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 490                                         AT91C_TIMEOUT_WRDY);
 491
 492                /* Update size, source and destination pointers */
 493                size -= pDataFlash->pDevice->pages_size;
 494                dest += pDataFlash->pDevice->pages_size;
 495                src += pDataFlash->pDevice->pages_size;
 496        }
 497
 498        /* If still some bytes to read */
 499        if (size > 0) {
 500                /* program dataflash page */
 501                if (!AT91F_PartialPageWrite(pDataFlash, src, dest, size))
 502                        return DATAFLASH_ERROR;
 503
 504                AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 505                                         AT91C_TIMEOUT_WRDY);
 506        }
 507        return DATAFLASH_OK;
 508}
 509
 510/*---------------------------------------------------------------------------*/
 511/* Function Name       : AT91F_DataFlashRead                                 */
 512/* Object              : Read a block in dataflash                           */
 513/* Input Parameters    :                                                     */
 514/* Return value         :                                                    */
 515/*---------------------------------------------------------------------------*/
 516int AT91F_DataFlashRead(AT91PS_DataFlash pDataFlash,
 517                        unsigned long addr, unsigned long size, char *buffer)
 518{
 519        unsigned long SizeToRead;
 520
 521        AT91F_SpiEnable(pDataFlash->pDevice->cs);
 522
 523        if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 524                                        AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
 525                return -1;
 526
 527        while (size) {
 528                SizeToRead = (size < 0x8000) ? size : 0x8000;
 529
 530                if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
 531                                        AT91C_TIMEOUT_WRDY) !=
 532                                                DATAFLASH_OK)
 533                        return -1;
 534
 535                if (AT91F_DataFlashContinuousRead(pDataFlash, addr,
 536                                                (uchar *) buffer,
 537                                                SizeToRead) != DATAFLASH_OK)
 538                        return -1;
 539
 540                size -= SizeToRead;
 541                addr += SizeToRead;
 542                buffer += SizeToRead;
 543        }
 544
 545        return DATAFLASH_OK;
 546}
 547
 548/*---------------------------------------------------------------------------*/
 549/* Function Name       : AT91F_DataflashProbe                                */
 550/* Object              :                                                     */
 551/* Input Parameters    :                                                     */
 552/* Return value        : Dataflash status register                           */
 553/*---------------------------------------------------------------------------*/
 554int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
 555{
 556        AT91F_SpiEnable(cs);
 557        AT91F_DataFlashGetStatus(pDesc);
 558        return ((pDesc->command[1] == 0xFF) ? 0 : pDesc->command[1] & 0x3C);
 559}
 560