[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/boot/common/src/loader/drivers/spifc.c b/boot/common/src/loader/drivers/spifc.c
new file mode 100755
index 0000000..5fe3fce
--- /dev/null
+++ b/boot/common/src/loader/drivers/spifc.c
@@ -0,0 +1,869 @@
+/*********************************************************************
+ Copyright 2016 by ZXIC Corporation.
+*
+* FileName:: spifc.c
+* File Mark:
+* Description:
+* Others:
+* Version:
+* Author:
+* Date:
+
+* History 1:
+* Date:
+* Version:
+* Author:
+* Modification:
+* History 2:
+**********************************************************************/
+#include <common.h>
+#include <asm/arch/spifc.h>
+#include <asm/io.h>
+#include <bbt.h>
+
+#include "flash.h"
+
+
+static const struct spi_flash_device_para *spi_flash_info = NULL;
+/* spi flash parameter config */
+static const struct spi_flash_device_para spi_flash_para[] = {
+ /* GIGADEVICE GD5F1GQ4R 128MB 1.8V SPI-NAND */
+ {0xC8, 0xC1, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
+ /* GIGADEVICE GD5F1GQ5RExxG 128MB 1.8V SPI-NAND */
+ {0xC8, 0x41, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* GIGADEVICE GD5F2GQ4R 256MB SPI-NAND */
+ {0xC8, 0xC2, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 1},
+ /* GIGADEVICE GD5F4GQ4U 512MB SPI-NAND */
+ {0xC8, 0xC4, 0x77, 4096, 12, 256, 18, 2048, 0x40000, 1},
+ /* GIGADEVICE GD5F4GQ6REY2G 512MB SPI-NAND*/
+ {0xC8, 0x45, 0x77, 2048, 11, 128, 17, 4096, 0x20000, 1},
+
+ /* PARAGON PN26Q01AWSIUG 128MB SPI-NAND */
+ {0xA1, 0xC1, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
+ /* PN26Q02AWSIUG 1.8V 2G-BIT SPI NAND */
+ {0xA1, 0xC2, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 1},
+
+ /* HYF1GQ4IAACAE SPI-NAND */
+ {0xC9, 0x51, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
+ /* HYF2GQ4IAACAE SPI-NAND */
+ {0xC9, 0x52, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 1},
+ /*winbond W25N01G*/
+ {0xEF, 0xBA, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /*winbond W25N02G*/
+ {0xEF, 0xBB, 0x77, 2048, 11, 64, 17, 2048, 0x20000, 1},
+ /* TOSHIBA TC58CYG0S3HRAIG 128MB SPI-NAND*/
+ {0x98, 0xB2, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* TOSHIBA TC58CYG1S3HRAIG 256MB SPI-NAND*/
+ {0x98, 0xBB, 0x77, 2048, 11, 64, 17, 2048, 0x20000, 1},
+ /* ZETTA ZD35X1GAXXX 128MB SPI-NAND*/
+ {0xBA, 0x21, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* DOSILICON DS35X1GAXXX 128MB SPI-NAND*/
+ {0xE5, 0x21, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* DOSILICON DS35X12BXXX 64MB SPI-NAND*/
+ {0xE5, 0xA5, 0x77, 2048, 11, 128, 17, 512, 0x20000, 1},
+ /* FUDANWEI FM25LS01 128MB SPI-NAND*/
+ {0xA1, 0xA5, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
+ /* hosin HG-SPIXGb-1XAIA 128MB SPI-NAND*/
+ {0xD6, 0x21, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* EMST F50D1G41LB (2M) 128MB SPI-NAND */
+ {0xC8, 0x11, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* FORESEE F35UQA001G 128MB SPI-NAND */
+ {0xCD, 0x61, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* FORESEE F35UQA512M 64MB SPI-NAND */
+ {0xCD, 0x60, 0x77, 2048, 11, 64, 17, 512, 0x20000, 1},
+ /* micron-MT29F2G01ABAGDWB-ITG 256MB SPI-NAND */
+ {0x2C, 0x25, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 2},
+ /* ESMT F50D44G41XB (2X) 512MB SPI-NAND*/
+ {0x2C, 0x35, 0x77, 4096, 12, 256, 18, 2048, 0x40000, 1},
+ {0}
+};
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_enable
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static void spifc_enable(void)
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ if( spi->SFC_EN & FC_EN_BACK )
+ return;
+
+ spi->SFC_EN |= FC_EN;
+ spi->SFC_CTRL0 |= FC_SCLK_PAUSE_EN;
+}
+
+/*
+ ******************************************************************************
+ * Function: spifc_clear_fifo
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+void spifc_clear_fifo( void )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ spi->SFC_CTRL0 |= (FC_RXFIFO_THRES | FC_TXFIFO_THRES |
+ FC_RXFIFO_CLR | FC_TXFIFO_CLR);
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_setup_cmd
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static void spifc_setup_cmd( struct spiflash_cmd_t *cmd,
+ uint32_t addr, uint32_t len )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+ uint32_t wrap = 0;
+ uint32_t tmp = 0;
+
+ /* ÃüÁîÂë */
+ spi->SFC_INS = cmd->cmd;
+
+ /* Êý¾Ý³¤¶È */
+ if( len )
+ spi->SFC_BYTE_NUM = len - 1;
+ else
+ spi->SFC_BYTE_NUM = 0;
+
+ switch( len )
+ {
+ case 2048:
+ wrap = WRAP_SIZE_MAIN;
+ break;
+ case 2112:
+ wrap = WRAP_SIZE_MAIN_OOB;;
+ break;
+ case 64:
+ wrap = WRAP_SIZE_OOB;;
+ break;
+ default:
+ wrap = 0;
+ break;
+ }
+
+ /* µØÖ·Âë */
+ switch( spi->SFC_INS )
+ {
+ case CMD_READ_FROM_CACHE:
+ // case CMD_READ_FROM_CACHE_X2:
+ case CMD_READ_FROM_CACHE_X4:
+ case CMD_READ_FROM_CACHE_QIO:
+ case CMD_PROGRAM_LOAD:
+ case CMD_PROGRAM_LOAD_X4:
+ // case CMD_PROGRAM_LOAD_RANDOM:
+ // case CMD_PROGRAM_LOAD_RANDOM_X4:
+ //case CMD_PROGRAM_LOAD_RANDOM_QIO:
+ addr |= wrap;
+ break;
+
+ default:
+ addr = addr;
+ break;
+ }
+ spi->SFC_ADDR = addr;
+
+ /* µØÖ·Âë¡¢¿ÕÖÜÆÚ¡¢¶Á/д ʹÄÜÉèÖà */
+ spi->SFC_CTRL1 = 0;
+ spi->SFC_CTRL1 = ((cmd->addr_tx_en << FC_ADDR_TX_EN) |
+ (cmd->dumy_tx_en << FC_DUMMY_TX_EN) |
+ (cmd->data_rx_en << FC_READ_DAT_EN) |
+ (cmd->data_tx_en << FC_WRITE_DAT_EN));
+
+
+ /* ¿ÕÖÜÆÚÊý¡¢µØÖ·¿í¶È(1£¬2£¬3£¬4×Ö½Ú)¡¢
+ * µØÖ·/Êý¾ÝÏß¶È¡¢´«Êäģʽ
+ */
+#if 0
+ tmp = spi->SFC_CTRL2;
+ tmp &= 0x1f;
+ tmp |= ((cmd->dumy_bytes << FC_DUMMY_BYTE_NUM) |
+ (cmd->dumy_bits << FC_DUMMY_BIT_NUM) |
+ (cmd->addr_width << FC_ADDR_BYTE_NUM));
+ spi->SFC_CTRL2 = tmp;
+#else
+ spi->SFC_CTRL2 = 0;
+ tmp |= ((cmd->dumy_bytes << FC_DUMMY_BYTE_NUM) |
+ (cmd->dumy_bits << FC_DUMMY_BIT_NUM) |
+ (cmd->addr_width << FC_ADDR_BYTE_NUM));
+ tmp &= ~0x700;
+ spi->SFC_CTRL2 = tmp;
+#endif
+
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_clear_int
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+ void spifc_clear_int( void )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ if(spi->SFC_INT_RAW & 0x2)
+ printf("\n");
+
+ spi->SFC_INT_SW_CLR = 0xFF; //clear int ?
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_wait_cmd_end
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static int spifc_wait_cmd_end( void )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+ uint32_t int_status = 0;
+
+ while(!(spi->SFC_INT_RAW & FC_INT_RAW_MASK));
+
+ int_status = spi->SFC_INT_RAW;
+ spi->SFC_INT_SW_CLR = int_status; /* clear intrrupt */
+
+ if(int_status & FC_INT_RAW_CMD_END)
+ {
+ return 0;
+ }
+ else
+ {
+ printf("intr err.\n");
+ return -1;
+ }
+
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_fifo_one_byte
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ *
+ * Others: only for:
+ [Instruction] |--addr width is 8 bit
+ [addr] |--get feature
+ [data_rx]
+ *******************************************************************************
+ */
+static int spifc_read_fifo_one_byte( uint8_t *value )
+{
+ uint32_t sw = 0;
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ sw = spi->SFC_SW;
+
+ if( ((sw >> FC_RX_FIFO_CNT) & FC_RX_FIFO_CNT_MASK) != 1 )
+ {
+ return -1;
+ }
+
+ *value = (uint8_t)spi->SFC_DATA;
+
+ return 0;
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_fifo
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static uint32_t spifc_read_fifo( uint32_t len, uint8_t *buf )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+ uint32_t *p = (uint32_t *)buf;
+ uint32_t cnt = 0;
+
+ while(cnt < ((len+3)>>2))
+ {
+ if(spi->SFC_SW & (FC_RX_FIFO_CNT_MASK<<FC_RX_FIFO_CNT))//rx fifo not empty
+ {
+ p[cnt++]= spi->SFC_DATA;
+ }
+ }
+
+ return (cnt<<2);
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_start
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static void spifc_start( void )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ spi->SFC_START |= FC_START;
+}
+
+/*
+ ******************************************************************************
+ * Function: spifc_get_feature
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ *
+ * Others: [Instruction] |--addr width is 8 bit
+ [addr] |--get feature
+ [data_rx] |--read id
+
+ *******************************************************************************
+ */
+ static int spifc_get_feature( uint32_t reg_addr, uint8_t *value)
+ {
+ int ret = 0;
+
+ struct spiflash_cmd_t cmd = {CMD_GET_FEATURE,
+ 1,
+ FC_ADDR_BYTE_NUM_8,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0
+ };
+
+ spifc_clear_fifo();
+ spifc_clear_int();
+
+ spifc_setup_cmd(&cmd, reg_addr, 1);
+ spifc_start();
+ ret = spifc_wait_cmd_end();
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ ret = spifc_read_fifo_one_byte(value);
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_id
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ *
+ * Others: [Instruction] |--addr width is 8 bit
+ [addr] |--get feature
+ [data_rx] |--read id
+ *******************************************************************************
+ */
+static int spifc_read_id(uint32_t reg_addr, uint8_t *value, uint8_t len)
+{
+ int ret = 0;
+
+ struct spiflash_cmd_t cmd = { CMD_READ_ID,
+ 1,
+ FC_ADDR_BYTE_NUM_8,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0
+ };
+
+ spifc_clear_fifo();
+ spifc_clear_int();
+ spifc_setup_cmd(&cmd, reg_addr, len);
+ spifc_start();
+ ret = spifc_wait_cmd_end();
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ ret = spifc_read_fifo(len, value);
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_page_to_cache
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others: [Instruction] |--addr width is 24 bit(page/block addr!!!!)
+ [addr] |--page read
+ |--block erase
+ |--program execute
+ *******************************************************************************
+ */
+static int spifc_read_page_to_cache(uint32_t page_addr)
+{
+ int ret = 0;
+ uint8_t status = 0;
+
+ struct spiflash_cmd_t cmd = { CMD_READ_PAGE_TO_CACHE,
+ 1,
+ FC_ADDR_BYTE_NUM_24,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ };
+
+ spifc_clear_fifo();
+ spifc_clear_int();
+ spifc_setup_cmd(&cmd, page_addr, 0);
+ spifc_start();
+ ret = spifc_wait_cmd_end();
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ do
+ {
+ spifc_get_feature(REG_STATUS, &status);
+ }while( status & OIP);
+
+ return 0;
+}
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_from_cache
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others: [Instruction] |--addr width is 16 bit
+ [addr] |--dummy cycel 8/4/2
+ [dummy] |--read form cache(X1,X2,X4)
+ [data_rx] |--read form cache(dual,quad)IO
+ *******************************************************************************
+ */
+static int spifc_read_from_cache(uint32_t column_addr, uint32_t len, uint8_t *buf)
+{
+ int ret = 0;
+
+ uint32_t len_tmp = 0;
+ struct spiflash_cmd_t cmd;
+
+ cmd.cmd = CMD_READ_FROM_CACHE;
+ cmd.dumy_bytes = 1;
+ cmd.dumy_bits = 0;
+ cmd.addr_tx_en = 1;
+ cmd.addr_width = FC_ADDR_BYTE_NUM_16;
+ cmd.data_tx_en = 0;
+ cmd.data_rx_en = 1;
+ cmd.dumy_tx_en = 1;
+
+ spifc_clear_fifo();
+ spifc_clear_int();
+ spifc_setup_cmd(&cmd, column_addr, len);
+ spifc_start();
+
+ len_tmp = spifc_read_fifo(len, buf);
+ if( len_tmp != len )
+ {
+ ret = -2;
+ return ret;
+ }
+
+ ret = spifc_wait_cmd_end();
+ if( ret != 0 )
+ {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/*
+ ******************************************************************************
+ * Function: nand_read_oob
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+void spifc_read_oob(uint8_t *buf, uint32_t offset, uint32_t len)
+{
+ uint32_t column_offset = spi_flash_info->page_size;
+ uint32_t page = offset >> (spi_flash_info->page_size_shift);
+ uint32_t blocks = offset >> (spi_flash_info->block_size_shift);
+
+ spifc_read_page_to_cache(page);
+
+ if((spi_flash_info->planes == 2) && ((blocks%2) != 0))
+ {
+ column_offset |= (0x1 << 12);
+ }
+ spifc_read_from_cache(column_offset, spi_flash_info->oob_size, buf);
+}
+
+
+/*
+ ******************************************************************************
+ * Function: read_page
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int32_t spifc_read_page(uint32_t buf, uint32_t offset)
+{
+ int ret = 0;
+ uint8_t feature = 0x0;
+
+ uint32_t page = offset >> (spi_flash_info->page_size_shift);
+ uint32_t blocks = offset >> (spi_flash_info->block_size_shift);
+ uint32_t column_offset = 0;
+
+ if( (buf & 0x3) != 0 ) /* DMAµØÖ·ÒªÇó4×Ö½Ú¶ÔÆë */
+ {
+ printf("addr err.\n");
+ return -1;
+ }
+
+ ret = spifc_read_page_to_cache(page);
+ if( ret != 0 )
+ return ret;
+
+ ret = spifc_get_feature(REG_STATUS, &feature);
+ if(ret != 0)
+ return ret;
+
+ if((feature>>ECC_ERR_BIT & 0x3) == 0x2)
+ {
+ printf("ecc err.\n");
+ return -1;
+ }
+ if((spi_flash_info->planes == 2) && ((blocks%2) != 0))
+ {
+ column_offset |= (0x1 << 12);
+ }
+ ret = spifc_read_from_cache(column_offset, spi_flash_info->page_size, (uint8_t *)buf);
+ if(ret != 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ ******************************************************************************
+ * Function: read_page
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int32_t spifc_read_page_raw(uint32_t buf, uint32_t offset)
+{
+ int ret = 0;
+ uint8_t feature = 0x0;
+
+ uint32_t page = offset >> (spi_flash_info->page_size_shift);
+
+ if( (buf & 0x3) != 0 ) /* DMAµØÖ·ÒªÇó4×Ö½Ú¶ÔÆë */
+ {
+ printf("addr err.\n");
+ return -1;
+ }
+
+ ret = spifc_read_page_to_cache(page);
+ if( ret != 0 )
+ return ret;
+
+ ret = spifc_read_from_cache(0, spi_flash_info->page_size, (uint8_t *)buf);
+ if(ret != 0)
+ return ret;
+
+ return 0;
+}
+
+
+/*
+ ******************************************************************************
+ * Function: nand_read
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others: from: must page align len: must page align
+ *******************************************************************************
+ */
+int32_t spifc_read(uint32_t from, uint32_t len, uint32_t to)
+{
+ uint32_t offset = from;
+ uint32_t left_to_read = len;
+ uint32_t p_to = to;
+ int32_t ret = 0;
+ int32_t page_size = (spi_flash_info->page_size);
+
+ if((offset & (page_size - 1)) || (len & (page_size - 1)) )
+ {
+ return -1;
+ }
+
+ while( left_to_read > 0 )
+ {
+ ret = spifc_read_page(p_to, offset);
+ if(ret != 0)
+ {
+ return -1;
+ }
+
+ left_to_read -= page_size;
+ offset += page_size;
+ p_to += page_size;
+ }
+ return 0;
+}
+
+
+/*******************************************************************************
+ * Function: nand_read_id
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int32_t read_id (void)
+{
+ uint8_t id[4];
+ const struct spi_flash_device_para *spi_flash = &spi_flash_para[0];
+
+ spifc_read_id(0x0, id, 2);
+
+ while( spi_flash->manuf_id != 0 )
+ {
+ if( ((uint8_t)id[0] == spi_flash->manuf_id) &&
+ ((uint8_t)id[1] == spi_flash->device_id) )
+ {
+ spi_flash_info = spi_flash;
+ return 0;
+ };
+ spi_flash++;
+ }
+
+ return -1;
+}
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int32_t read_data(uint32_t from, uint32_t len, uint32_t to)
+{
+ uint32_t offset = from;
+ uint32_t left_to_read = len;
+ uint32_t p_to = to;
+ int32_t ret = 0;
+ int32_t block_size = (spi_flash_info->block_size);
+
+ while(left_to_read > 0)
+ {
+ uint32_t block_offset = offset & (block_size - 1);
+ uint32_t read_length;
+
+ if( nand_block_isbad(offset) )
+ {
+ offset += block_size;
+ continue;
+ }
+
+ if (left_to_read < (block_size - block_offset))
+ read_length = left_to_read;
+ else
+ read_length = block_size - block_offset;
+
+ ret = spifc_read(offset, read_length, p_to);
+ if(ret != 0)
+ {
+ return -1;
+ }
+
+ left_to_read -= read_length;
+ offset += read_length;
+ p_to += read_length;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Function: nand_init
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int32_t spifc_init (void)
+{
+ int32_t ret = 0;
+ spifc_enable();
+ ret = read_id();
+ if(ret != 0)
+ {
+ printf("id err!\n");
+ return -1;
+ }
+
+ flash.flash_type = SPI_NAND_BOOT;
+ flash.manuf_id = spi_flash_info->manuf_id;
+ flash.device_id = spi_flash_info->device_id;
+ flash.page_size = spi_flash_info->page_size;
+ flash.page_size_shift = spi_flash_info->page_size_shift;
+ flash.oob_size = spi_flash_info->oob_size;
+ flash.block_size = spi_flash_info->block_size;
+ flash.block_size_shift = spi_flash_info->block_size_shift;
+ flash.block_num = spi_flash_info->block_num;
+ flash.read_page_raw = spifc_read_page_raw;
+ flash.read_oob = spifc_read_oob;
+ flash.read = read_data;
+
+ return 0;
+
+}
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int board_flash_init(void)
+{
+ int ret = 0;
+ char boot_mode = 0;
+
+ printf("spi-nand:");
+
+ boot_mode = get_boot_mode();
+ if(boot_mode != SPI_NAND_BOOT)
+ {
+ printf("mode err.\n");
+ return -1;
+ }
+
+ writel(CFG_START_MODE_SPI_NAND, CFG_BOOT_MODE_START_MODE_FOR_UBOOT);
+ ret = spifc_init();
+ if(ret != 0)
+ {
+ printf("init err.\n");
+ return -1;
+ }
+ printf("init ok.\n");
+
+// nand_creat_bbt();
+nand_creat_ram_bbt();
+
+ return 0;
+}
+
+