⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 davincihd_nandflash.c

📁 用于dm6467 开发平台的uboot源码
💻 C
字号:
/*
 *  Copyright 2007 by Spectrum Digital Incorporated.
 *  All rights reserved. Property of Spectrum Digital Incorporated.
 */

/*
 *  NAND Flash interface
 *
 */

#include "davincihd_nandflash.h"

/*
 *  NAND Organization - Only 1 instance needed
 */
NAND_ORGANIZATION nand_org;

/*
 *  NAND Flash timeout
 */
Int32 nand_rw_timeout    = ( 0x00100000 );
Int32 nand_erase_timeout = ( 0x00100000 );
Int32 nand_reset_timeout = ( 0x00100000 );

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _NAND_busywait( timeout )                                               *
 *      Poll the external RDY/BSY pin                                       *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 _NAND_busywait( Int32 timeout )
{
    /* Wait while the device is busy */
    while( ( NAND_READ_RB == 0 ) && ( timeout-- > 0 ) );

    _waitusec( 250 );

    if ( timeout == 0 )
        return NAND_ERR_TIMEOUT;

    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _NAND_readECC( )                                                        *
 *      Read ECC calcualtions                                               *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Uint32 _NAND_readECC( )
{
    return EMIFA_NANDF1ECC;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _NAND_startECC( )                                                       *
 *      Start ECC calcualtions                                              *
 *                                                                          *
 * ------------------------------------------------------------------------ */
void _NAND_startECC( )
{
    _NAND_readECC( );
    EMIFA_NANDFCR |= 0x0100;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _NAND_CMD( command )                                                    *
 *      Issue command                                                       *
 *                                                                          *
 * ------------------------------------------------------------------------ */
void _NAND_CMD( Uint32 command )
{
    NAND_CLE_PTR = command;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _NAND_PAGE_ADDR( page_addr )                                            *
 *      Issue page address                                                  *
 *                                                                          *
 * ------------------------------------------------------------------------ */
void _NAND_PAGE_ADDR( Uint32 page_addr )
{
    switch( nand_org.page_addressing )
    {
        case PAGE_ADDR_07_916_1724_2526:
            /* [1st]7:0 -> [2nd]16:9 -> [3rd]24:17 -> [4th]26:25 */
            NAND_ALE_PTR = ( page_addr >> 0 );
            NAND_ALE_PTR = ( page_addr >> 9 );
            NAND_ALE_PTR = ( page_addr >> 17 );
            NAND_ALE_PTR = ( page_addr >> 25 ) & 0x03;
            break;
        case PAGE_ADDR_07_811_1219_2027:
            /* [1st]7:0 -> [2nd]11:8 -> [3rd]19:12 -> [4th]27:20 */
            NAND_ALE_PTR = ( page_addr >> 0 );
            NAND_ALE_PTR = ( page_addr >> 8 ) & 0x0f;
            NAND_ALE_PTR = ( page_addr >> 12 );
            NAND_ALE_PTR = ( page_addr >> 20 );
            break;
    }
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _NAND_BLOCK_ADDR( block_addr )                                          *
 *      Issue block address                                                 *
 *                                                                          *
 * ------------------------------------------------------------------------ */
void _NAND_BLOCK_ADDR( Uint32 block_addr )
{
    switch ( nand_org.block_addressing )
    {
        case BLK_ADDR_9_1724_2526:
            /* [1st]16:9 -> [2nd]24:17 -> [3rd]26:25 */
            NAND_ALE_PTR = ( block_addr >> 9 );
            NAND_ALE_PTR = ( block_addr >> 17 );
            NAND_ALE_PTR = ( block_addr >> 25 );
            break;
        case BLK_ADDR_1819_2027:
            /* [1st]19:18-> [2nd]27:20 */
            NAND_ALE_PTR = ((block_addr >> 18) << 6);
            NAND_ALE_PTR = ( block_addr >> 20 );
            break;
    }
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _NAND_reset( )                                                          *
 *      Reset NAND Flash                                                    *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 _NAND_reset( )
{
    _NAND_CMD( CMD_RESET );

    if ( _NAND_busywait( nand_reset_timeout ) )
        return NAND_ERR_TIMEOUT;

    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _NAND_unlockBlocks( start_block, block_count )                          *
 *      Unlock blocks                                                       *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 _NAND_unlockBlocks( Uint32 start_block, Uint32 block_count )
{
    /* Block Unlock */
    _NAND_CMD( CMD_BLOCK_UNLOCK );
    _NAND_BLOCK_ADDR( start_block * nand_org.block_addr_incr );

    /* Block Unlock Confirm */
    _NAND_CMD( CMD_BLOCK_UNLOCK_CONFIRM );
    _NAND_BLOCK_ADDR( ( start_block + block_count ) * nand_org.block_addr_incr );
    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _NAND_init( )                                                           *
 *      Initialize the NAND Flash                                           *
 *                                                                          *
 *  Note:                                                                   *
 *      The Write Protect on the NAND Flash is disabled.  This allows the   *
 *      erase & write NAND flash to work.                                   *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 _NAND_init( )
{
    Uint32 acfg2;
    Uint8 bus_width;
    Uint8 read_strobe;

    /* Reset EMIFA CS2 */
    DAVINCIHD_resetEMIF( EMIF_CS2 );
    DAVINCIHD_setupEMIF( EMIF_CS2, EMIFA_MAX_TIMEOUT_8BIT, EMIF_MODE );

    /* Extract NAND Flash ID and info */
    if ( _NAND_getId( ) != 0 )
        return -1;

    /* Setup EMIFA timings */
    bus_width   = ( nand_org.bus_width == 8 ) ? 0 : 1;
    read_strobe = ( nand_org.access_time ) / 10;
/*
    acfg2 = 0
        | ( 0 << 31 )           // selectStrobe
        | ( 0 << 30 )           // extWait
        | ( 0 << 26 )           // writeSetup      //   0 ns
        | ( 8 << 20 )           // writeStrobe     //  40 ns
        | ( 2 << 17 )           // writeHold       //  10 ns
        | ( 0 << 13 )           // readSetup       //   0 ns
        | ( read_strobe << 7 )  // readStrobe      //  25 ns
        | ( 2 << 4 )            // readHold        //  10 ns
        | ( 2 << 2 )            // turnAround      //  10 ns
        | ( bus_width << 0 );   // asyncSize       //  8/16-bit bus
*/
    acfg2 = 0
        | ( 0 << 31 )           // selectStrobe
        | ( 0 << 30 )           // extWait
        | ( 2 << 26 )           // writeSetup      //   0 ns
        | ( 8 << 20 )           // writeStrobe     //  40 ns
        | ( 2 << 17 )           // writeHold       //  10 ns
        | ( 2 << 13 )           // readSetup       //   0 ns
        | ( read_strobe << 7 )  // readStrobe      //  25 ns
        | ( 2 << 4 )            // readHold        //  10 ns
        | ( 2 << 2 )            // turnAround      //  10 ns
        | ( bus_width << 0 );   // asyncSize       //  8/16-bit bus

    DAVINCIHD_setupEMIF( EMIF_CS2, acfg2, EMIF_MODE );

    /* Reset NAND */
    if ( _NAND_reset( ) )
        return 1;

    /* Unlock all blocks */
    if ( nand_org.use_block_unlock )
        _NAND_unlockBlocks( 0, nand_org.blocks );

    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -