mirror of
https://github.com/hno/allwinner-boot.git
synced 2025-05-09 03:41:18 +08:00
change nand source to lib with crosstalk
This commit is contained in:
parent
8ac8607979
commit
fe32579929
@ -149,9 +149,9 @@ void set_pll( void )
|
||||
{
|
||||
__u32 reg_val, i;
|
||||
|
||||
//切换到24M
|
||||
//CPU切换到24M,AXI_CLK=CPU_CLK,AXI到AHB不分频,这点和23不一样,23 DIV=2
|
||||
CCMU_REG_AXI_MOD = 0x00010000;
|
||||
//设置PLL1到408M
|
||||
//设置PLL1到384M
|
||||
reg_val = (0x00001000) | (0x80000000);
|
||||
CCMU_REG_PLL1_CTRL = reg_val;
|
||||
//延时
|
||||
|
@ -270,7 +270,7 @@ __s32 card_sprite(void *mbr_i, int flash_erase, int disp_type)
|
||||
*
|
||||
*****************************************************************************/
|
||||
update_flash_init();
|
||||
flash_sector = NAND_GetDiskSize();
|
||||
flash_sector = NAND_GetDiskSize();
|
||||
if(dl_info->download_count > 0)
|
||||
{
|
||||
aver_rage = ((CARD_SPRITE_DOWN_PART - CARD_SPRITE_GET_MAP)/dl_info->download_count);
|
||||
|
@ -247,10 +247,10 @@ int private_fetch_from_flash(void)
|
||||
update_flash_env_err:
|
||||
sprite_flash_exit(0);
|
||||
#endif
|
||||
if(!env_exist) //如果在旧的环境变量中没有找到动态数据,则去boot1中寻找
|
||||
{
|
||||
ret = env_fetch_from_boot1();
|
||||
}
|
||||
// if(!env_exist) //如果在旧的环境变量中没有找到动态数据,则去boot1中寻找
|
||||
// {
|
||||
// ret = env_fetch_from_boot1();
|
||||
// }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -255,6 +255,7 @@ int sprite_flash_hardware_scan(void *mbr_i,void *flash_info, int erase_flash)
|
||||
int speed_mode;
|
||||
int type;
|
||||
MBR* mbr_info=(MBR*)mbr_i;
|
||||
int good_block_ratio = 0;
|
||||
//ɨÃèNAND
|
||||
|
||||
type = 0;
|
||||
@ -282,6 +283,18 @@ int sprite_flash_hardware_scan(void *mbr_i,void *flash_info, int erase_flash)
|
||||
goto __hardware_scan__;
|
||||
}
|
||||
}
|
||||
good_block_ratio = NAND_BadBlockScan((const boot_nand_para_t*)&nand_para);
|
||||
if((good_block_ratio == -1)| (good_block_ratio == 0))
|
||||
{
|
||||
__inf("sprite update error: nand bad block scan failed\n");
|
||||
ret = -2;
|
||||
|
||||
goto __hardware_scan__;
|
||||
}
|
||||
nand_para.good_block_ratio = good_block_ratio;
|
||||
NAND_SetValidBlkRatio(good_block_ratio);
|
||||
__inf("****************************************************************************************** \n");
|
||||
__inf("get the good blk ratio from hwscan : %d \n", good_block_ratio);
|
||||
//ɨÃè½áÊø
|
||||
if(NAND_HWScanStop())
|
||||
{
|
||||
|
@ -34,7 +34,8 @@ INCLUDES = -I$(ROOT) \
|
||||
|
||||
#库文件列表
|
||||
LIBS = $(LIBSPATH)/eGon2_libc.lib \
|
||||
$(LIBSPATH)/eGon2_ui.lib
|
||||
$(LIBSPATH)/eGon2_ui.lib \
|
||||
$(SDKROOT)/boot1/driver/drv_nand/bsp_nfc_boot1_for_card.lib
|
||||
|
||||
#定义生成的目标文件(输出/本地)
|
||||
TARGET = $(WORKSPACEPATH)/wboot/bootfs/sprite.axf
|
||||
@ -45,6 +46,7 @@ SRCDIRS := $(shell find . -maxdepth 3 -type d) \
|
||||
$(shell find $(ROOT)/../../driver/drv_sd -maxdepth 3 -type d) \
|
||||
$(ROOT)/../../driver/drv_nand \
|
||||
$(ROOT)/../../driver/drv_nand/osal-burn \
|
||||
$(ROOT)/../../driver/drv_nand/nand_for_boot1_card \
|
||||
$(shell find $(ROOT)/../../driver/drv_nand/nand_bsp -maxdepth 3 -type d) \
|
||||
$(shell find $(ROOT)/../../driver/drv_nand/nand_boot_operation -maxdepth 3 -type d)
|
||||
|
||||
|
@ -385,12 +385,12 @@ void eGon2_watchdog_enable(void)
|
||||
************************************************************************************************************
|
||||
*/
|
||||
void eGon2_timer_init(void)
|
||||
{
|
||||
*(volatile unsigned int *)(0x01c20000 + 0x144) |= (1U << 31);
|
||||
*(volatile unsigned int *)(0x01c20C00 + 0x80 ) = 1;
|
||||
*(volatile unsigned int *)(0x01c20C00 + 0x8C ) = 0x0C;
|
||||
*(volatile unsigned int *)(0x01c20C00 + 0x84 ) = 0;
|
||||
CFG_SW_TIMER_INT_STATS |= 0x03;
|
||||
{ //avs timer clk=24M OSC
|
||||
// *(volatile unsigned int *)(0x01c20000 + 0x144) |= (1U << 31);
|
||||
// *(volatile unsigned int *)(0x01c20C00 + 0x80 ) = 1;//enable avs cnt0, source is 24M OSC
|
||||
// *(volatile unsigned int *)(0x01c20C00 + 0x8C ) = 0x0C; //avs cnt0 clk div 12
|
||||
// *(volatile unsigned int *)(0x01c20C00 + 0x84 ) = 0;//clear avs count value
|
||||
CFG_SW_TIMER_INT_STATS |= 0x03;//timer0 and timer1 irq clear
|
||||
}
|
||||
/*
|
||||
************************************************************************************************************
|
||||
|
@ -36,11 +36,12 @@ LINK_SCT = config.lds
|
||||
|
||||
#库文件列表
|
||||
ifeq ($(STORAGE_MEDIA_TYPE), STORAGE_NAND)
|
||||
LIBS = $(SDKROOT)/boot1/libs/eGon2_libc.lib
|
||||
LIBS = $(SDKROOT)/boot1/libs/eGon2_libc.lib \
|
||||
$(ROOT)/../driver/drv_nand/bsp_nfc_boot1_for_boot.lib
|
||||
STORAGE_TYPE = -I$(SDKROOT)/config/storage_media_cfg/nand
|
||||
SRCDIRS = $(ROOT)/../driver/drv_nand \
|
||||
$(ROOT)/../driver/drv_nand/osal-boot \
|
||||
$(shell find $(ROOT)/../driver/drv_nand/nand_bsp -maxdepth 3 -type d)
|
||||
$(ROOT)/../driver/drv_nand/nand_for_boot1_boot \
|
||||
$(ROOT)/../driver/drv_nand/osal-boot
|
||||
TARGET0 = $(WORKSPACEPATH)/egon/boot1_nand.bin
|
||||
TARGET1 = $(LICHEEPATH)/eGon/boot1_nand.bin
|
||||
LOCALTARGET = boot1_nand
|
||||
|
@ -35,7 +35,7 @@
|
||||
// nand driver 版本号
|
||||
//---------------------------------------------------------------
|
||||
#define NAND_VERSION_0 0x02
|
||||
#define NAND_VERSION_1 0x10
|
||||
#define NAND_VERSION_1 0x11
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// 结构体 定义
|
||||
|
BIN
boot1/driver/drv_nand/bsp_nfc_boot1_for_boot.lib
Normal file
BIN
boot1/driver/drv_nand/bsp_nfc_boot1_for_boot.lib
Normal file
Binary file not shown.
BIN
boot1/driver/drv_nand/bsp_nfc_boot1_for_card.lib
Normal file
BIN
boot1/driver/drv_nand/bsp_nfc_boot1_for_card.lib
Normal file
Binary file not shown.
@ -220,7 +220,8 @@ static __s32 burn_boot0_lsb_mode( __u32 read_retry_type, __u32 Boot0_buf )
|
||||
|
||||
/* ¼ì²é page count */
|
||||
page_size = info.pagesize*512;
|
||||
|
||||
if(page_size == 8192*2) //change for h27ucg8t2btr 16k pagesize
|
||||
page_size = 8192;
|
||||
for( i = BOOT0_START_BLK_NUM; i <= BOOT0_LAST_BLK_NUM; i++ )
|
||||
{
|
||||
struct boot_physical_param para;
|
||||
|
@ -182,8 +182,11 @@ __s32 Nand_Burn_Boot1(__u32 Boot1_buf, __u32 length )
|
||||
__s32 status;
|
||||
__s32 ret = -1;
|
||||
|
||||
NF_open( ); // ´ò¿ªnand flash
|
||||
|
||||
if(NF_ERROR==NF_open( )) // ´ò¿ªnand flash
|
||||
{
|
||||
__inf("%s: NF_open fail !\n",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
if( length <= NF_BLOCK_SIZE )
|
||||
{
|
||||
for( i = BOOT1_START_BLK_NUM; i <= BOOT1_LAST_BLK_NUM; i++ )
|
||||
|
@ -74,7 +74,7 @@ enum
|
||||
};
|
||||
|
||||
|
||||
#define MAX_PAGE_SIZE SZ_8K
|
||||
#define MAX_PAGE_SIZE SZ_16K
|
||||
#define BAD_BLK_FLAG 0
|
||||
|
||||
|
||||
|
@ -106,6 +106,10 @@ __s32 NF_open( void )
|
||||
NF_BLK_SZ_WIDTH = 21;
|
||||
blk_for_boot1 = BLKS_FOR_BOOT1_IN_2M_BLK_NF;
|
||||
break;
|
||||
case SZ_4M :
|
||||
NF_BLK_SZ_WIDTH = 22;
|
||||
blk_for_boot1 = BLKS_FOR_BOOT1_IN_4M_BLK_NF;
|
||||
break;
|
||||
default :
|
||||
goto error;
|
||||
}
|
||||
@ -126,6 +130,9 @@ __s32 NF_open( void )
|
||||
case SZ_8K :
|
||||
NF_PG_SZ_WIDTH = 13;
|
||||
break;
|
||||
case SZ_16K :
|
||||
NF_PG_SZ_WIDTH = 14;
|
||||
break;
|
||||
default :
|
||||
goto error;
|
||||
}
|
||||
@ -228,24 +235,31 @@ __s32 NF_read( __u32 sector_num, void *buffer, __u32 N )
|
||||
* NF_ERROR ²Ù×÷ʧ°Ü
|
||||
*±¸ ×¢:
|
||||
*******************************************************************************/
|
||||
static __u8 page_buf[MAX_PAGE_SIZE];
|
||||
__s32 NF_read_status( __u32 blk_num )
|
||||
{
|
||||
struct boot_physical_param para;
|
||||
__u8 oob_buf[MAX_PAGE_SIZE/NF_SECTOR_SIZE * OOB_BUF_SIZE_PER_SECTOR];
|
||||
__u8 page_buf[MAX_PAGE_SIZE];
|
||||
|
||||
|
||||
para.chip = 0;
|
||||
para.block = blk_num;
|
||||
para.page = page_with_bad_block;
|
||||
para.mainbuf = page_buf;
|
||||
para.oobbuf = oob_buf;
|
||||
|
||||
|
||||
if( NAND_PhyRead( ¶ ) == FAIL )
|
||||
return NF_ERROR;
|
||||
if( oob_buf[0] != (__u8)0xFF )
|
||||
{
|
||||
|
||||
return NF_BAD_BLOCK;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return NF_GOOD_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,58 +0,0 @@
|
||||
#ifndef __NAND_OSAL_H__
|
||||
#define __NAND_OSAL_H__
|
||||
|
||||
#include <string.h>
|
||||
#include "egon2.h"
|
||||
|
||||
#define __OS_LINUX_SYSTEM__
|
||||
#define __OS_NAND_DBG__
|
||||
|
||||
#define NAND_IO_BASE_ADDR 0x01c03000
|
||||
|
||||
extern void *NAND_IORemap(unsigned int base_addr, unsigned int size);
|
||||
|
||||
//USE_SYS_CLK
|
||||
extern int NAND_ClkRequest(void);
|
||||
extern void NAND_ClkRelease(void);
|
||||
extern int NAND_AHBEnable(void);
|
||||
extern void NAND_AHBDisable(void);
|
||||
extern int NAND_ClkEnable(void);
|
||||
extern void NAND_ClkDisable(void);
|
||||
extern int NAND_SetClk(unsigned int nand_clk);
|
||||
extern int NAND_GetClk(void);
|
||||
|
||||
extern int NAND_RequestDMA(void);
|
||||
extern int NAND_ReleaseDMA(void);
|
||||
extern void NAND_DMAConfigStart(int rw, unsigned int buff_addr, int len);
|
||||
extern int NAND_QueryDmaStat(void);
|
||||
extern int NAND_WaitDmaFinish(void);
|
||||
|
||||
extern void NAND_PIORequest(void);
|
||||
extern void NAND_PIORelease(void);
|
||||
|
||||
extern void NAND_EnRbInt(void);
|
||||
extern void NAND_ClearRbInt(void);
|
||||
extern int NAND_WaitRbReady(void);
|
||||
extern void NAND_RbInterrupt(void);
|
||||
|
||||
extern void* NAND_Malloc(unsigned int Size);
|
||||
extern void NAND_Free(void *pAddr, unsigned int Size);
|
||||
extern int NAND_Print(const char * str, ...);
|
||||
|
||||
//define the memory set interface
|
||||
#define MEMSET(x,y,z) memset((x),(y),(z))
|
||||
|
||||
//define the memory copy interface
|
||||
#define MEMCPY(x,y,z) memcpy((x),(y),(z))
|
||||
|
||||
//define the memory alocate interface
|
||||
#define MALLOC(x) NAND_Malloc((x))
|
||||
|
||||
//define the memory release interface
|
||||
#define FREE(x,size) NAND_Free((x),(size))
|
||||
|
||||
//define the message print interface
|
||||
#define PRINT(...) NAND_Print(__VA_ARGS__)
|
||||
|
||||
|
||||
#endif //__NAND_OSAL_H__
|
File diff suppressed because it is too large
Load Diff
@ -1,234 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver module config define
|
||||
*
|
||||
* Copyright(C), 2006-2008, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : nand_drv_cfg.h
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.03.19
|
||||
*
|
||||
* Description : This file define the module config for nand flash driver.
|
||||
* if need support some module /
|
||||
* if need support some operation type /
|
||||
* config limit for some parameter. ex.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.03.19 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#ifndef __NAND_DRV_CFG_H
|
||||
#define __NAND_DRV_CFG_H
|
||||
|
||||
#include "../../osal/nand_osal.h"
|
||||
|
||||
//==============================================================================
|
||||
// define the value of some variable for
|
||||
//==============================================================================
|
||||
|
||||
#define NAND_VERSION_0 0x02
|
||||
#define NAND_VERSION_1 0x11
|
||||
#define NAND_DRV_DATE 0x20121207
|
||||
|
||||
|
||||
|
||||
|
||||
//define the max value of the count of chip select
|
||||
#define MAX_CHIP_SELECT_CNT (8)
|
||||
|
||||
//define the max value the count of the zone
|
||||
#define MAX_ZONE_CNT (32)
|
||||
|
||||
//define the value of the count of the block mapping table cache
|
||||
#define BLOCK_MAP_TBL_CACHE_CNT (4)
|
||||
#if (BLOCK_MAP_TBL_CACHE_CNT < 1)
|
||||
#error BLOCK_MAP_TBL_CACHE_CNT config error, the value must be larger than 0!!!
|
||||
#endif
|
||||
|
||||
//define the max value of the count of the page mapping table cache
|
||||
#define PAGE_MAP_TBL_CACHE_CNT (4)
|
||||
#if (PAGE_MAP_TBL_CACHE_CNT < 1)
|
||||
#error PAGE_MAP_TBL_CACHE_CNT config error, the value must be larger than 0!!!
|
||||
#endif
|
||||
|
||||
//define the max value of the count of the log block in a zone, the recommended value is 8
|
||||
#define MAX_LOG_BLK_CNT (16)
|
||||
|
||||
//define the frequency of the doing wear-levelling
|
||||
#define WEAR_LEVELLING_FREQUENCY (10)
|
||||
|
||||
//define the number of the chip select which connecting the boot chip
|
||||
#define BOOT_CHIP_SELECT_NUM (0)
|
||||
|
||||
//define the default value the count of the data block in one zone
|
||||
#define DEFAUL_DATA_BLK_CNT_PER_ZONE (1000)
|
||||
#if (DEFAUL_DATA_BLK_CNT_PER_ZONE > 1000)
|
||||
#error DEFAUL_DATA_BLK_CNT_PER_ZONE config error, the value must not be larger than 1000!!!
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// define some sitch to decide if need support some operation
|
||||
//==============================================================================
|
||||
|
||||
//define the switch that if need support multi-plane program
|
||||
#define CFG_SUPPORT_MULTI_PLANE_PROGRAM (1)
|
||||
|
||||
//define the switch that if need support multi-plane read
|
||||
#define CFG_SUPPORT_MULTI_PLANE_READ (0)
|
||||
|
||||
//define the switch that if need support internal inter-leave
|
||||
#define CFG_SUPPORT_INT_INTERLEAVE (0)
|
||||
|
||||
//define the switch that if need support external inter-leave
|
||||
#define CFG_SUPPORT_EXT_INTERLEAVE (1)
|
||||
|
||||
//define the switch that if need support cache program
|
||||
#define CFG_SUPPORT_CACHE_PROGRAM (0)
|
||||
|
||||
//define the switch that if need support doing page copyback by send command
|
||||
#define CFG_SUPPORT_PAGE_COPYBACK (1)
|
||||
|
||||
//define the switch that if need support wear-levelling
|
||||
#define CFG_SUPPORT_WEAR_LEVELLING (0)
|
||||
|
||||
//define the switch that if need support read-reclaim
|
||||
#define CFG_SUPPORT_READ_RECLAIM (1)
|
||||
|
||||
//define if need check the page program status after page program immediately
|
||||
#define CFG_SUPPORT_CHECK_WRITE_SYNCH (0)
|
||||
|
||||
//define if need support align bank when allocating the log page
|
||||
#define CFG_SUPPORT_ALIGN_NAND_BNK (1)
|
||||
|
||||
//define if need support Randomizer
|
||||
#define CFG_SUPPORT_RANDOM (1)
|
||||
|
||||
//define if need support ReadRetry
|
||||
#define CFG_SUPPORT_READ_RETRY (1)
|
||||
|
||||
|
||||
#define SUPPORT_DMA_IRQ (0)
|
||||
#define SUPPORT_RB_IRQ (0)
|
||||
|
||||
//==============================================================================
|
||||
// define some pr__s32 switch
|
||||
//==============================================================================
|
||||
//define if need pr__s32 the physic operation module debug message
|
||||
#ifndef __OS_NAND_DBG__
|
||||
#define PHY_DBG_MESSAGE_ON (0)
|
||||
#else
|
||||
#define PHY_DBG_MESSAGE_ON (1)
|
||||
#endif
|
||||
|
||||
//define if need pr__s32 the physic operation module error message
|
||||
#define PHY_ERR_MESSAGE_ON (1)
|
||||
|
||||
//define if need pr__s32 the nand hardware scan module debug message
|
||||
#ifndef __OS_NAND_DBG__
|
||||
#define SCAN_DBG_MESSAGE_ON (0)
|
||||
#else
|
||||
#define SCAN_DBG_MESSAGE_ON (1)
|
||||
#endif
|
||||
|
||||
//define if need pr__s32 the nand hardware scan module error message
|
||||
#define SCAN_ERR_MESSAGE_ON (1)
|
||||
|
||||
//define if need pr__s32 the nand disk format module debug message
|
||||
#define FORMAT_DBG_MESSAGE_ON (0)
|
||||
|
||||
//define if need pr__s32 the nand disk format module error message
|
||||
#define FORMAT_ERR_MESSAGE_ON (1)
|
||||
|
||||
//define if need pr__s32 the mapping manage module debug message
|
||||
#define MAPPING_DBG_MESSAGE_ON (0)
|
||||
|
||||
//define if need pr__s32 the mapping manage module error message
|
||||
#define MAPPING_ERR_MESSAGE_ON (1)
|
||||
|
||||
//define if need pr__s32 the logic control layer debug message
|
||||
#define LOGICCTL_DBG_MESSAGE_ON (0)
|
||||
|
||||
//define if need pr__s32 the logic control layer error message
|
||||
#define LOGICCTL_ERR_MESSAGE_ON (1)
|
||||
|
||||
|
||||
#if PHY_DBG_MESSAGE_ON
|
||||
#define PHY_DBG(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PHY_DBG(...)
|
||||
#endif
|
||||
|
||||
#if PHY_ERR_MESSAGE_ON
|
||||
#define PHY_ERR(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PHY_ERR(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if SCAN_DBG_MESSAGE_ON
|
||||
#define SCAN_DBG(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define SCAN_DBG(...)
|
||||
#endif
|
||||
|
||||
#if SCAN_ERR_MESSAGE_ON
|
||||
#define SCAN_ERR(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define SCAN_ERR(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if FORMAT_DBG_MESSAGE_ON
|
||||
#define FORMAT_DBG(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define FORMAT_DBG(...)
|
||||
#endif
|
||||
|
||||
#if FORMAT_ERR_MESSAGE_ON
|
||||
#define FORMAT_ERR(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define FORMAT_ERR(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if MAPPING_DBG_MESSAGE_ON
|
||||
#define MAPPING_DBG(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define MAPPING_DBG(...)
|
||||
#endif
|
||||
|
||||
#if MAPPING_ERR_MESSAGE_ON
|
||||
#define MAPPING_ERR(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define MAPPING_ERR(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if LOGICCTL_DBG_MESSAGE_ON
|
||||
#define LOGICCTL_DBG(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define LOGICCTL_DBG(...)
|
||||
#endif
|
||||
|
||||
#if LOGICCTL_ERR_MESSAGE_ON
|
||||
#define LOGICCTL_ERR(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define LOGICCTL_ERR(...)
|
||||
#endif
|
||||
|
||||
|
||||
#endif //ifndef __NAND_DRV_CFG_H
|
||||
|
@ -1,181 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver format module define
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : nand_format.h
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.03.25
|
||||
*
|
||||
* Description : This file define the function interface and some data structure export
|
||||
* for the format module.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.03.25 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#ifndef __NAND_FORMAT_H__
|
||||
#define __NAND_FORMAT_H__
|
||||
|
||||
#include "nand_type.h"
|
||||
#include "nand_physic.h"
|
||||
|
||||
|
||||
//define the structure for a zone detail information
|
||||
struct __ScanZoneInfo_t
|
||||
{
|
||||
__u16 nDataBlkCnt; //the count of data blocks in a zone
|
||||
__u16 nFreeBlkCnt; //the count of free blocks in a zone
|
||||
__u16 nFreeBlkIndex; //the index of the free blocks in a zone
|
||||
__u16 Reserved; //reserved for 32bit aligned
|
||||
struct __SuperPhyBlkType_t ZoneTbl[BLOCK_CNT_OF_ZONE]; //the zone table buffer
|
||||
struct __LogBlkType_t LogBlkTbl[MAX_LOG_BLK_CNT]; //the log block mapping table buffer
|
||||
};
|
||||
|
||||
|
||||
//define the structure for a nand flash die detail information
|
||||
struct __ScanDieInfo_t
|
||||
{
|
||||
__u8 nDie; //the number of the die in the nand flash storage system
|
||||
__u8 TblBitmap; //the bitmap that mark the block mapping table status in a die
|
||||
__u16 nBadCnt; //the count of the bad block in a nand die
|
||||
__u16 nFreeCnt; //the count of the free block in a nand die
|
||||
__u16 nFreeIndex; //the free block allocate index
|
||||
__u16 *pPhyBlk; //the pointer to the physical block information buffer of a whole die
|
||||
struct __ScanZoneInfo_t *ZoneInfo; //the pointer to the zone table detail information of the whole die
|
||||
};
|
||||
|
||||
//define the first super block used for block mapping, the front used for boot
|
||||
typedef struct _blk_for_boot1_t
|
||||
{
|
||||
__u32 blk_size; //unit by k
|
||||
__u32 blks_boot0;
|
||||
__u32 blks_boot1;
|
||||
}blk_for_boot1_t;
|
||||
|
||||
//define the max value of the default position of the block mapping table
|
||||
#define TBL_AREA_BLK_NUM 32
|
||||
|
||||
//define the sector bitmap in a super page to get the user data
|
||||
#if (0)
|
||||
#define SPARE_DATA_BITMAP (SUPPORT_MULTI_PROGRAM ? (0x3 | (0x3 << SECTOR_CNT_OF_SINGLE_PAGE)) : 0x1)
|
||||
#elif (1)
|
||||
#define SPARE_DATA_BITMAP FULL_BITMAP_OF_SUPER_PAGE
|
||||
#endif
|
||||
//define the sector bitmap in a super page to get the logical information in the spare area
|
||||
#if (0)
|
||||
#define LOGIC_INFO_BITMAP (SUPPORT_MULTI_PROGRAM ? (0x1 | (0x1 << SECTOR_CNT_OF_SINGLE_PAGE)) : 0x1)
|
||||
#elif (1)
|
||||
#define LOGIC_INFO_BITMAP FULL_BITMAP_OF_SUPER_PAGE
|
||||
#endif
|
||||
//define the sector bitmap in a super page for table data operation
|
||||
#define DATA_TABLE_BITMAP 0xf //the bitmap for check data block table of block mapping table
|
||||
#define LOG_TABLE_BITMAP 0xf //the bitmap for check log block table of block mapping table
|
||||
#define DIRTY_FLAG_BITMAP 0x1 //the bitmap for check dirty flag of block mapping table
|
||||
|
||||
//define the offset of tables in one table group
|
||||
#define DATA_TBL_OFFSET 0 //page0 and page1 of a table group are used for data & free block table
|
||||
#define LOG_TBL_OFFSET 2 //page2 of a table group is used for log block table
|
||||
#define DIRTY_FLAG_OFFSET 3 //page3 of a table group is used for dirty flag
|
||||
#define PAGE_CNT_OF_TBL_GROUP 4 //one table group contain 4 pages
|
||||
|
||||
//define the page buffer for cache the super page data for read or write
|
||||
#define FORMAT_PAGE_BUF (PageCachePool.PageCache0)
|
||||
|
||||
#define FORMAT_SPARE_BUF (PageCachePool.SpareCache)
|
||||
|
||||
//define the empty item in the logical information buffer
|
||||
#define NULL_BLOCK_INFO 0xfffd
|
||||
//define the bad block information in the logcial information buffer
|
||||
#define BAD_BLOCK_INFO 0xfffe
|
||||
//define the free block infomation in the logical information buffer
|
||||
#define FREE_BLOCK_INFO 0xffff
|
||||
|
||||
//define the mark for allocate the free block
|
||||
#define ALLOC_BLK_MARK ((0x1<<14) | 0xff)
|
||||
|
||||
|
||||
//define the macro for compare the log age of the blocks
|
||||
#define COMPARE_AGE(a, b) ((signed char)((signed char)(a) - (signed char)(b)))
|
||||
|
||||
//define the macro for get the zone number in the logical information of physical block
|
||||
#define GET_LOGIC_INFO_ZONE(a) ((((unsigned int)(a))>>10) & 0x0f)
|
||||
//define the macro for get the block used type in the logical information of physical block
|
||||
#define GET_LOGIC_INFO_TYPE(a) ((((unsigned int)(a))>>14) & 0x01)
|
||||
//define the macro for get the logical block number in the logical information of physical block
|
||||
#define GET_LOGIC_INFO_BLK(a) (((unsigned int)(a)) & 0x03ff)
|
||||
|
||||
//define the return value of format error when we should try format again
|
||||
#define RET_FORMAT_TRY_AGAIN (-2)
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* FORMAT NAND FLASH DISK MODULE INIT
|
||||
*
|
||||
*Description: Init the nand disk format module, initiate some variables and request resource.
|
||||
*
|
||||
*Arguments : none
|
||||
*
|
||||
*Return : init result;
|
||||
* = 0 format module init successful;
|
||||
* < 0 format module init failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 FMT_Init(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* FORMAT NAND FLASH DISK MODULE EXIT
|
||||
*
|
||||
*Description: Exit the nand disk format module, release some resource.
|
||||
*
|
||||
*Arguments : none
|
||||
*
|
||||
*Return : exit result;
|
||||
* = 0 format module exit successful;
|
||||
* < 0 format module exit failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 FMT_Exit(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* FORMAT NAND FLASH DISK
|
||||
*
|
||||
*Description: Format the nand flash disk, create a logical disk area.
|
||||
*
|
||||
*Arguments : none
|
||||
*
|
||||
*Return : format result;
|
||||
* = 0 format nand successful;
|
||||
* < 0 format nand failed.
|
||||
*
|
||||
*Note : This function look for the mapping information on the nand flash first, if the find all
|
||||
* mapping information and check successful, format nand disk successful; if the mapping
|
||||
* information has some error, need repair it. If find none mapping information, create it!
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 FMT_FormatNand(void);
|
||||
|
||||
void ClearNandStruct( void );
|
||||
|
||||
|
||||
#endif //ifndef __NAND_FORMAT_H__
|
||||
|
||||
|
@ -1,582 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver logic control module define
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : nand_logic.h
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.03.25
|
||||
*
|
||||
* Description : This file define the function interface and some data structure export
|
||||
* for the logical control module.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.03.25 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#ifndef __NAND_LOGIC_H__
|
||||
#define __NAND_LOGIC_H__
|
||||
|
||||
#include "nand_type.h"
|
||||
#include "nand_physic.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// define the logical architecture export parameter
|
||||
//==============================================================================
|
||||
|
||||
//define the count of the sectors in the logical page
|
||||
#define SECTOR_CNT_OF_LOGIC_PAGE SECTOR_CNT_OF_SUPER_PAGE
|
||||
|
||||
//define the full bitmap of sector in the logical page
|
||||
#define FULL_BITMAP_OF_LOGIC_PAGE FULL_BITMAP_OF_SUPER_PAGE
|
||||
|
||||
//define the count of the pages in a logical block
|
||||
#define PAGE_CNT_OF_LOGIC_BLK (NandDriverInfo.LogicalArchitecture->PageCntPerLogicBlk)
|
||||
|
||||
//define the count of the pages in a super physical block, size is same as the logical block
|
||||
#define PAGE_CNT_OF_SUPER_BLK PAGE_CNT_OF_LOGIC_BLK
|
||||
|
||||
//define the count of the data block in a zone, the value is based on the ration of the invalid blocks
|
||||
#define DATA_BLK_CNT_OF_ZONE (NandDriverInfo.LogicalArchitecture->LogicBlkCntPerZone)
|
||||
|
||||
//define the count of the free block item in a free block table of a zone
|
||||
#define FREE_BLK_CNT_OF_ZONE (BLOCK_CNT_OF_ZONE - DATA_BLK_CNT_OF_ZONE - 1)
|
||||
|
||||
|
||||
//define the count of the log block in a zone, the value is configurable, recommended value is 8
|
||||
#define LOG_BLK_CNT_OF_ZONE MAX_LOG_BLK_CNT
|
||||
|
||||
//define the count of the free block in a zone
|
||||
#define FREE_BLK_CNT_OF_ZONE (BLOCK_CNT_OF_ZONE - DATA_BLK_CNT_OF_ZONE - 1)
|
||||
|
||||
//define the count of the zone in a die
|
||||
#define ZONE_CNT_OF_DIE (NandDriverInfo.LogicalArchitecture->ZoneCntPerDie)
|
||||
|
||||
//define the total count of inter-leave banks
|
||||
#define INTERLEAVE_BANK_CNT (PAGE_CNT_OF_LOGIC_BLK / NandDriverInfo.NandStorageInfo->PageCntPerPhyBlk)
|
||||
|
||||
//define the buffer for cache data when write loigcal sector
|
||||
|
||||
//define the buffer for processing the data of mapping table
|
||||
#define LML_PROCESS_TBL_BUF (NandDriverInfo.PageCachePool->PageCache2)
|
||||
|
||||
//define the buffer for copy page data or process other data
|
||||
#define LML_TEMP_BUF (NandDriverInfo.PageCachePool->PageCache0)
|
||||
#define LML_WRITE_PAGE_CACHE (NandDriverInfo.PageCachePool->PageCache1)
|
||||
|
||||
#define LML_SPARE_BUF (NandDriverInfo.PageCachePool->SpareCache)
|
||||
|
||||
//==============================================================================
|
||||
// define the mapping table access export parameter
|
||||
//==============================================================================
|
||||
|
||||
//define the pointer for block mapping table cache pool accessing
|
||||
#define BLK_MAP_CACHE_POOL (NandDriverInfo.BlkMapTblCachePool)
|
||||
|
||||
//define the counter of the super block erase, for do wear-levelling
|
||||
#define BLK_ERASE_CNTER (BLK_MAP_CACHE_POOL->SuperBlkEraseCnt)
|
||||
|
||||
//define the log block access timer for set log block access age
|
||||
#define LOG_ACCESS_TIMER (BLK_MAP_CACHE_POOL->LogBlkAccessTimer)
|
||||
|
||||
//define the log block access age array
|
||||
#define LOG_ACCESS_AGE (BLK_MAP_CACHE_POOL->LogBlkAccessAge)
|
||||
|
||||
//define the pointer for active block mapping table accessing
|
||||
#define BLK_MAP_CACHE (BLK_MAP_CACHE_POOL->ActBlkMapTbl)
|
||||
|
||||
//define the free block position that get free block last time
|
||||
#define LAST_FREE_BLK_PST (BLK_MAP_CACHE->LastFreeBlkPst)
|
||||
|
||||
//define the pointer for active data block table accessing
|
||||
#define DATA_BLK_TBL (BLK_MAP_CACHE->DataBlkTbl)
|
||||
|
||||
//define the pointer for active log block table accessing
|
||||
#define LOG_BLK_TBL (BLK_MAP_CACHE->LogBlkTbl)
|
||||
|
||||
//define the pointer for active free block table accessing
|
||||
#define FREE_BLK_TBL (BLK_MAP_CACHE->FreeBlkTbl)
|
||||
|
||||
//define the zone number of the active block mapping table
|
||||
#define CUR_MAP_ZONE (BLK_MAP_CACHE->ZoneNum)
|
||||
|
||||
//define the pointer for page mapping table cahce pool accessing
|
||||
#define PAGE_MAP_CACHE_POOL (NandDriverInfo.PageMapTblCachePool)
|
||||
|
||||
//define the pointer for active page mapping table cache accessing
|
||||
#define PAGE_MAP_CACHE (NandDriverInfo.PageMapTblCachePool->ActPageMapTbl)
|
||||
|
||||
//define the pointer for active page mapping table accessing
|
||||
#define PAGE_MAP_TBL (PAGE_MAP_CACHE->PageMapTbl)
|
||||
|
||||
//define the type of merger operation
|
||||
#define NORMAL_MERGE_MODE 0x00 //normal merge mode, there is not enough log item
|
||||
#define SPECIAL_MERGE_MODE 0x01 //special merge mode, there is not enough log page
|
||||
|
||||
//define the invalid page number
|
||||
#define INVALID_PAGE_NUM 0xffff
|
||||
|
||||
//define the type for get free block from free block table
|
||||
#define LOWEST_EC_TYPE 0x00
|
||||
#define HIGHEST_EC_TYPE 0x01
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// define the function interface for logic manage module
|
||||
//==============================================================================
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* INITIATE NAND FLASH LOGIC MANAGE LAYER
|
||||
*
|
||||
*Description: initiate the logic manage layer for nand flash driver.
|
||||
*
|
||||
*Arguments : none;
|
||||
*
|
||||
*Return : intiate result;
|
||||
* = 0 init successful;
|
||||
* = -1 init failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_Init(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER EXIT
|
||||
*
|
||||
*Description: exit nand flash logic manage layer.
|
||||
*
|
||||
*Arguments : none;
|
||||
*
|
||||
*Return : exit result;
|
||||
* = 0 exit successfu;
|
||||
* = -1 exit failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_Exit(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER READ
|
||||
*
|
||||
*Description: Read data from logic disk area to buffer.
|
||||
*
|
||||
*Arguments : nLba the logic block address on the logic area from where to read;
|
||||
* nLength the size of the data need be read, based on sector;
|
||||
* pBuf the pointer to the buffer where will store the data readout of nand.
|
||||
*
|
||||
*Return : read result;
|
||||
* = 0 read successful;
|
||||
* = -1 read failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_Read(__u32 nLba, __u32 nLength, void* pBuf);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER WRITE
|
||||
*
|
||||
*Description: Write data from buffer to logic disk area.
|
||||
*
|
||||
*Arguments : nLba the logic block address on the logic area from where to write;
|
||||
* nLength the size of the data need to be write, based on sector;
|
||||
* pBuf the pointer to the buffer where stored the data write to nand flash.
|
||||
*
|
||||
*Return : write result;
|
||||
* = 0 write successful;
|
||||
* = -1 write failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_Write(__u32 nLba, __u32 nLength, void* pBuf);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER FLUSH PAGE CACHE
|
||||
*
|
||||
*Description: Flush the data in the cache buffer to nand flash.
|
||||
*
|
||||
*Arguments : none
|
||||
|
||||
*Return : flush result;
|
||||
* = 0 flush successful;
|
||||
* = -1 flush failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_FlushPageCache(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER PAGE READ
|
||||
*
|
||||
*Description: Read data from logic disk to buffer based page.
|
||||
*
|
||||
*Arguments : nPage the page address which need be read;
|
||||
* nBitmap the bitmap of the sectors in the page which need be read data;
|
||||
* pBuf the pointer to the buffer where will store the data read out.
|
||||
*
|
||||
*Return : page read result;
|
||||
* = 0 read successful;
|
||||
* > 0 read successful, but need do some process;
|
||||
* < 0 read failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_PageRead(__u32 nPage, __u64 nBitmap, void* pBuf);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER PAGE WRITE
|
||||
*
|
||||
*Description: Write data from buffer to logic area based on page.
|
||||
*
|
||||
*Arguments : nPage the page address which need be write;
|
||||
* nBitmap the bitmap of sectors in the page which need be write, it is always full;
|
||||
* pBuf the pointer to the buffer where is storing the data.
|
||||
*
|
||||
*Return : write result;
|
||||
* = 0 write successful;
|
||||
* > 0 write successful, but need do some process;
|
||||
* < 0 write failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_PageWrite(__u32 nPage, __u64 nBitmap, void* pBuf);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER READ-RECLAIM
|
||||
*
|
||||
*Description: Repair the logic block whose data has reach the limit of the ability of
|
||||
* the HW ECC module correct.
|
||||
*
|
||||
*Arguments : nPage the page address where need be repaired.
|
||||
*
|
||||
*Return : read-reclaim result;
|
||||
* = 0 do read-reclaim successful;
|
||||
* = -1 do read-reclaim failed.
|
||||
*
|
||||
*Notes : if read a physical page millions of times, there may be some bit error in
|
||||
* the page, and the error bit number will increase along with the read times,
|
||||
* so, if the number of the error bit reachs the ECC limit, the data should be
|
||||
* read out and write to another physical blcok.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_ReadReclaim(__u32 nPage);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER WEAR-LEVELLING
|
||||
*
|
||||
*Description: Equate the erase cycles among all physical blocks.
|
||||
*
|
||||
*Arguments : none
|
||||
*
|
||||
*Return : do wear-levelling result;
|
||||
* = 0 do wear-levelling successful;
|
||||
* = -1 do wear-levelling failed.
|
||||
*
|
||||
*Notes : The erase cycle of a physical block is limited, if the erase cycle overun this
|
||||
* limit, the physical block may be invalid. so a policy is needed to equate the
|
||||
* millions of erase cycles to ervery physical block.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_WearLevelling(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER CALCULATE PHYSICAL ADDRESS
|
||||
*
|
||||
*Description: Calculate the physical address parameter.
|
||||
*
|
||||
*Arguments : pPhyPar the pointer to the physical address parameter;
|
||||
* nZone the zone number which the superblock belonged to;
|
||||
* nBlock the number of the super block in a DIE;
|
||||
* nPage the page number in the super block.
|
||||
*
|
||||
*Return : calculate result;
|
||||
* = 0 calculate successful;
|
||||
* = -1 calculate failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_CalPhyPar(struct __PhysicOpPara_t *pPhyPar, __u32 nZone, __u32 nBlock, __u32 nPage);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER BAD BLOCK MANAGE
|
||||
*
|
||||
*Description: Nand flash bad block manage.
|
||||
*
|
||||
*Arguments : pBadBlk the pointer to the bad physical block parameter;
|
||||
* nZoneNum the number of the zone which the bad block belonged to;
|
||||
* nErrPage the number of the error page;
|
||||
* pNewBlk the pointer to the new valid block parameter.
|
||||
*
|
||||
*Return : bad block manage result;
|
||||
* = 0 do bad block manage successful;
|
||||
* = -1 do bad block manage failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_BadBlkManage(struct __SuperPhyBlkType_t *pBadBlk, __u32 nZoneNum, __u32 nErrPage, struct __SuperPhyBlkType_t *pNewBlk);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER MERGE LOG BLOCK
|
||||
*
|
||||
*Description: Merge the log block whoes mapping table is active.
|
||||
*
|
||||
*Arguments : nMode the type of the merge;
|
||||
* = 0 normal merge, the log block table is not full;
|
||||
* = 1 special merge, the log block table is full;
|
||||
* nLogicBlk the number of the logical block, which need be merged.
|
||||
*
|
||||
*Return : merge result;
|
||||
* = 0 merge log successful;
|
||||
* = -1 do bad block manage failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_MergeLogBlk(__u32 nMode, __u32 nLogicBlk);
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER ERASE SUPER BLOCK
|
||||
*
|
||||
*Description: Erase the given super block.
|
||||
*
|
||||
*Arguments : nZone the number of the zone which the super block belonged to;
|
||||
* nSuperBlk the number of the super block which need be erased.
|
||||
*
|
||||
*Return : erase result
|
||||
* = 0 super block erase successful;
|
||||
* =-1 super block erase failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_SuperBlkErase(__u32 nZone, __u32 nSuperBlk);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CALCULATE PHYSICAL OPERATION PARAMETER
|
||||
*
|
||||
*Description: Calculate the paramter for physical operation with the number of zone, number of
|
||||
* super block and number of page in the super block.
|
||||
*
|
||||
*Arguments : pPhyPar the pointer to the physical operation parameter;
|
||||
* nZone the number of the zone which the super block blonged to;
|
||||
* nBlock the number of the super block;
|
||||
* nPage the number of the super page in the super block.
|
||||
*
|
||||
*Return : calculate parameter result;
|
||||
* = 0 calculate parameter successful;
|
||||
* < 0 calcualte parameter failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_CalculatePhyOpPar(struct __PhysicOpPara_t *pPhyPar, __u32 nZone, __u32 nBlock, __u32 nPage);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* INIT BLOCK MAPPING TABLE CACHE
|
||||
*
|
||||
*Description: Initiate block mapping talbe cache.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : init result;
|
||||
* = 0 init successful;
|
||||
* = -1 init failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_InitMapTblCache(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* BLOCK MAPPING TABLE CACHE EXIT
|
||||
*
|
||||
*Description: exit block mapping table cache.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : exit result;
|
||||
* = 0 exit successful;
|
||||
* = -1 exit failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_ExitMapTblCache(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SWITCH BLOCK MAPPING TABLE
|
||||
*
|
||||
*Description: Switch block mapping table.
|
||||
*
|
||||
*Arguments : nZone zone number which block mapping table need be accessed.
|
||||
*
|
||||
*Return : switch result;
|
||||
* = 0 switch successful;
|
||||
* = -1 switch failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_SwitchMapTbl(__u32 nZone);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* WRITE BACK ALL MAPPING TABLE
|
||||
*
|
||||
*Description: Write back all mapping table.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : write table result;
|
||||
* = 0 write successful;
|
||||
* = -1 write failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_WriteBackAllMapTbl(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SET DIRTY FLAG FOR BLOCK MAPPING TABLE
|
||||
*
|
||||
*Description: Set dirty flag for block mapping table.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : set dirty flag result;
|
||||
* = 0 set dirty flag successful;
|
||||
* = -1 set dirty flag failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_SetDirtyFlag(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CALCULATE BLOCK MAPPING TABLE ACCESS COUNT
|
||||
*
|
||||
*Description: Calculate block mapping table access count for cache switch.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : none;
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
void BMM_CalAccessCount(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* INIT PAGE MAPPING TABLE CACHE
|
||||
*
|
||||
*Description: Init page mapping table cache.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : init result;
|
||||
* = 0 init page mapping table cache successful;
|
||||
* = -1 init page mapping table cache failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PMM_InitMapTblCache(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* EXIT PAGE MAPPING TABLE CACHE
|
||||
*
|
||||
*Description: Exit page mapping table cache.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : exit result;
|
||||
* = 0 exit page mapping table cache successful;
|
||||
* = -1 exit page mapping table cache failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PMM_ExitMapTblCache(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SWITCH PAGE MAPPING TABLE
|
||||
*
|
||||
*Description: Switch page mapping table cache.
|
||||
*
|
||||
*Arguments : nLogBlkPst the position of the log block in the log block table.
|
||||
*
|
||||
*Return : switch result;
|
||||
* = 0 switch table successful;
|
||||
* = -1 switch table failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PMM_SwitchMapTbl(__u32 nLogBlkPst);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CALCUALTE PAGE MAPPING TABLE ACCESS COUNT
|
||||
*
|
||||
*Description: Calculate page mapping table access count for table cache switch.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : none.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
void PMM_CalAccessCount(void);
|
||||
|
||||
__s32 BMM_GetDataBlk(__u32 nBlk, struct __SuperPhyBlkType_t *pDataBlk);
|
||||
__s32 BMM_SetDataBlk(__u32 nBlk, struct __SuperPhyBlkType_t *pDataBlk);
|
||||
__s32 BMM_GetFreeBlk(__u32 nType, struct __SuperPhyBlkType_t *pFreeBlk);
|
||||
__s32 BMM_SetFreeBlk(struct __SuperPhyBlkType_t *pFreeBlk);
|
||||
__s32 BMM_GetLogBlk(__u32 nLogicBlk, struct __LogBlkType_t *pLogBlk);
|
||||
__s32 BMM_SetLogBlk(__u32 nLogicBlk, struct __LogBlkType_t *pLogBlk);
|
||||
__u32 PMM_GetLogPage(__u32 nBlk, __u32 nPage, __u8 nMode);
|
||||
void PMM_ClearCurMapTbl(void);
|
||||
__u32 PMM_GetCurMapPage(__u16 nLogicalPage);
|
||||
void PMM_SetCurMapPage(__u16 nLogicalPage,__u16 nPhysicPage);
|
||||
__s32 LML_VirtualBlkErase(__u32 nZone, __u32 nSuperBlk);
|
||||
__s32 LML_VirtualPageWrite( struct __PhysicOpPara_t *pVirtualPage);
|
||||
__s32 LML_VirtualPageRead(struct __PhysicOpPara_t *pVirtualPage);
|
||||
|
||||
__s32 NAND_CacheFlush(void);
|
||||
__s32 NAND_CacheFlushDev(__u32 dev_num);
|
||||
__s32 NAND_CacheRead(__u32 blk, __u32 nblk, void *buf);
|
||||
__s32 NAND_CacheWrite(__u32 blk, __u32 nblk, void *buf);
|
||||
__s32 NAND_CacheOpen(void);
|
||||
__s32 NAND_CacheClose(void);
|
||||
|
||||
|
||||
// 2010-12-04 modified
|
||||
__u32 NAND_GetDiskSize(void);
|
||||
|
||||
|
||||
#endif //ifndef __NAND_LOGIC_H__
|
||||
|
@ -1,348 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver physical module define
|
||||
*
|
||||
* Copyright(C), 2006-2008, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : nand_physic.h
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.03.25
|
||||
*
|
||||
* Description : This file define the function __s32erface and some data structure export for
|
||||
* the physical module.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.03.25 0.1 build the file
|
||||
* penggang 2009.09.09 0.2 modify the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#ifndef __NAND_PHYSIC_H__
|
||||
#define __NAND_PHYSIC_H__
|
||||
|
||||
#include "nand_type.h"
|
||||
|
||||
//===========================================
|
||||
extern struct __NandStorageInfo_t NandStorageInfo;
|
||||
extern struct __NandPageCachePool_t PageCachePool;
|
||||
//===========================================
|
||||
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// define the physical archictecture export parameter
|
||||
//==============================================================================
|
||||
|
||||
//define the Ecc Mode
|
||||
#define ECC_MODE (NandStorageInfo.EccMode)
|
||||
|
||||
//define the DDR tyep
|
||||
#define DDR_TYPE (NandStorageInfo.DDRType)
|
||||
|
||||
//define the sector count of a single physical page
|
||||
#define SECTOR_CNT_OF_SINGLE_PAGE (NandStorageInfo.SectorCntPerPage)
|
||||
|
||||
//define the sector count of a super physical page, the super page may be based on multi-plane
|
||||
#define SECTOR_CNT_OF_SUPER_PAGE (NandStorageInfo.SectorCntPerPage * NandStorageInfo.PlaneCntPerDie)
|
||||
|
||||
//define the sector bitmap for a single page
|
||||
#define FULL_BITMAP_OF_SINGLE_PAGE ((__u64)(((__u64)1<<(SECTOR_CNT_OF_SINGLE_PAGE - 1)) | (((__u64)1<<(SECTOR_CNT_OF_SINGLE_PAGE - 1)) - 1)))
|
||||
|
||||
//define the sector bitmap for a super page, the sector count of a super page may be equal to 32
|
||||
#define FULL_BITMAP_OF_SUPER_PAGE ((__u64)(((__u64)1<<(SECTOR_CNT_OF_SUPER_PAGE - 1)) | (((__u64)1<<(SECTOR_CNT_OF_SUPER_PAGE - 1)) - 1)))
|
||||
|
||||
//define the block number offset for the multi-plane operation
|
||||
#define MULTI_PLANE_BLOCK_OFFSET (NandStorageInfo.OptPhyOpPar.MultiPlaneBlockOffset)
|
||||
|
||||
//define the position of the bad block flag in a physical block
|
||||
#define BAD_BLOCK_FLAG_PST (NandStorageInfo.OptPhyOpPar.BadBlockFlagPosition)
|
||||
|
||||
//define if the nand flash can support cache read operation
|
||||
#define SUPPORT_CACHE_READ (NAND_CACHE_READ & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash can support cache program operation
|
||||
#define SUPPORT_CACHE_PROGRAM (NAND_CACHE_PROGRAM & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash can support multi-plane read operation
|
||||
#define SUPPORT_MULTI_READ (NAND_MULTI_READ & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash can support multi-plane program operation
|
||||
#define SUPPORT_MULTI_PROGRAM (NAND_MULTI_PROGRAM & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash can support page copy-back with command operation
|
||||
#define SUPPORT_PAGE_COPYBACK (NAND_PAGE_COPYBACK & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash can support __s32ernal __s32er-leave operation
|
||||
#define SUPPORT_INT_INTERLEAVE (NAND_INT_INTERLEAVE & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash system can support external __s32er-leave operation
|
||||
#define SUPPORT_EXT_INTERLEAVE (NAND_EXT_INTERLEAVE & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash system can support randomizer
|
||||
#define SUPPORT_RANDOM (NAND_RANDOM & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash system can support read retry
|
||||
#define SUPPORT_READ_RETRY (NAND_READ_RETRY & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash system can support read unique id
|
||||
#define SUPPORT_READ_UNIQUE_ID (NAND_READ_UNIQUE_ID & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define if the nand flash system can support bank align
|
||||
#define SUPPORT_ALIGN_NAND_BNK (!(NAND_PAGE_ADR_NO_SKIP & NandStorageInfo.OperationOpt))
|
||||
|
||||
//define if the nand flash require to skip die addr
|
||||
#define SUPPORT_DIE_SKIP (NAND_DIE_SKIP & NandStorageInfo.OperationOpt)
|
||||
|
||||
//define the count of the nand flash DIE in a nand flash chip
|
||||
#define DIE_CNT_OF_CHIP (NandStorageInfo.DieCntPerChip)
|
||||
|
||||
//define the count of the nand flash bank in a nand flas hchip
|
||||
#define BNK_CNT_OF_CHIP (NandStorageInfo.BankCntPerChip)
|
||||
|
||||
//define the Rb connect Mode
|
||||
#define RB_CONNECT_MODE (NandStorageInfo.RbConnectMode)
|
||||
|
||||
//define the count of the total nand flash bank in the nand flash storage system
|
||||
#define TOTAL_BANK_CNT (NandStorageInfo.BankCntPerChip * NandStorageInfo.ChipCnt)
|
||||
|
||||
//define the count of the physical block in a nand flash DIE
|
||||
#define BLOCK_CNT_OF_DIE (NandStorageInfo.BlkCntPerDie)
|
||||
|
||||
//define the count of the nand flash plane in a nand flash DIE
|
||||
#define PLANE_CNT_OF_DIE (NandStorageInfo.PlaneCntPerDie)
|
||||
|
||||
//define the count of the physical page in a physical block
|
||||
#define PAGE_CNT_OF_PHY_BLK (NandStorageInfo.PageCntPerPhyBlk)
|
||||
|
||||
//define the information of the nand chip connect in the nand storage system
|
||||
#define CHIP_CONNECT_INFO (NandStorageInfo.ChipConnectInfo)
|
||||
|
||||
//define the ReadRetryType of the nand chip connect in the nand storage system
|
||||
#define READ_RETRY_TYPE (NandStorageInfo.ReadRetryType)
|
||||
|
||||
//define the ReadRetryType of the nand chip connect in the nand storage system
|
||||
#define READ_RETRY_MODE ((READ_RETRY_TYPE>>16)&0xff)
|
||||
|
||||
//define the ReadRetryType of the nand chip connect in the nand storage system
|
||||
#define READ_RETRY_CYCLE ((READ_RETRY_TYPE>>8)&0xff)
|
||||
|
||||
//define the ReadRetryType of the nand chip connect in the nand storage system
|
||||
#define READ_RETRY_REG_CNT ((READ_RETRY_TYPE>>0)&0xff)
|
||||
|
||||
//define the nand flash access frequence parameter
|
||||
#define NAND_ACCESS_FREQUENCE (NandStorageInfo.FrequencePar)
|
||||
|
||||
#define BAD_BLK_FLAG_PST (NandStorageInfo.OptPhyOpPar.BadBlockFlagPosition)
|
||||
|
||||
//sync bank with chip mode, need wait whole chip true ready
|
||||
#define SYNC_CHIP_MODE 0x00
|
||||
|
||||
//sync bank with bank mode, only check the status of the bank to wait bank ready
|
||||
#define SYNC_BANK_MODE 0x01
|
||||
|
||||
//define the page cache for physical module processing page data
|
||||
#define PHY_TMP_PAGE_CACHE (PageCachePool.PageCache0)
|
||||
|
||||
//define the spare data cache for physical module processing spare area data
|
||||
#define PHY_TMP_SPARE_CACHE (PageCachePool.SpareCache)
|
||||
//==============================================================================
|
||||
// define the functions __s32erface for the physic operation module
|
||||
//==============================================================================
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* INIT NAND FLASH DRIVER PHYSICAL MODULE
|
||||
*
|
||||
* Description: init nand flash driver physical module.
|
||||
*
|
||||
* Aguments : none
|
||||
*
|
||||
* Returns : the resutl of initial.
|
||||
* = 0 initiate successful;
|
||||
* = -1 initiate failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_Init(void);
|
||||
__s32 PHY_ChangeMode(__u8 serial_mode);
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH DRIVER PHYSICAL MODULE EXIT
|
||||
*
|
||||
* Description: nand flash driver physical module exit.
|
||||
*
|
||||
* Aguments : none
|
||||
*
|
||||
* Returns : the resutl of exit.
|
||||
* = 0 exit successful;
|
||||
* = -1 exit failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_Exit(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* RESET ONE NAND FLASH CHIP
|
||||
*
|
||||
*Description: Reset the given nand chip;
|
||||
*
|
||||
*Arguments : nChip the chip select number, which need be reset.
|
||||
*
|
||||
*Return : the result of chip reset;
|
||||
* = 0 reset nand chip successful;
|
||||
* = -1 reset nand chip failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_ResetChip(__u32 nChip);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* READ NAND FLASH ID
|
||||
*
|
||||
*Description: Read nand flash ID from the given nand chip.
|
||||
*
|
||||
*Arguments : nChip the chip number whoes ID need be read;
|
||||
* pChipID the po__s32er to the chip ID buffer.
|
||||
*
|
||||
*Return : read nand chip ID result;
|
||||
* = 0 read chip ID successful, the chip ID has been stored in given buffer;
|
||||
* = -1 read chip ID failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_ReadNandId(__s32 nChip, void *pChipID);
|
||||
__s32 PHY_ReadNandUniqueId(__s32 bank, void *pChipID);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CHECK WRITE PROTECT STATUS
|
||||
*
|
||||
*Description: check the status of write protect.
|
||||
*
|
||||
*Arguments : nChip the number of chip, which nand chip need be checked.
|
||||
*
|
||||
*Return : the result of status check;
|
||||
* = 0 the nand flash is not write proteced;
|
||||
* = 1 the nand flash is write proteced;
|
||||
* = -1 check status failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_CheckWp(__u32 nChip);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* PHYSICAL BLOCK ERASE
|
||||
*
|
||||
*Description: Erase one nand flash physical block.
|
||||
*
|
||||
*Arguments : pBlkAdr the parameter of the physical block which need be erased.
|
||||
*
|
||||
*Return : the result of the block erase;
|
||||
* = 0 erase physical block successful;
|
||||
* = -1 erase physical block failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_BlockErase(struct __PhysicOpPara_t *pBlkAdr);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* READ NAND FLASH PHYSICAL PAGE DATA
|
||||
*
|
||||
*Description: Read a page from a nand flash physical page to buffer.
|
||||
*
|
||||
*Arguments : pPageAdr the po__s32er to the accessed page parameter.
|
||||
*
|
||||
*Return : the result of physical page read;
|
||||
* = 0 read physical page successful;
|
||||
* > 0 read physical page successful, but need do some process;
|
||||
* < 0 read physical page failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_PageRead(struct __PhysicOpPara_t *pPageAdr);
|
||||
|
||||
|
||||
__s32 PHY_PageReadSpare(struct __PhysicOpPara_t *pPageAdr);
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* WRITE NAND FLASH PHYSICAL PAGE DATA
|
||||
*
|
||||
*Description: Write a page from buffer to a nand flash physical page.
|
||||
*
|
||||
*Arguments : pPageAdr the po__s32er to the accessed page parameter.
|
||||
*
|
||||
*Return : The result of the page write;
|
||||
* = 0 page write successful;
|
||||
* > 0 page write successful, but need do some process;
|
||||
* < 0 page write failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_PageWrite(struct __PhysicOpPara_t *pPageAdr);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* PHYSIC PAGE COPY-BACK
|
||||
*
|
||||
*Description: copy one physical page from one physical block to another physical block.
|
||||
*
|
||||
*Arguments : pSrcPage the parameter of the source page which need be copied;
|
||||
* pDstPage the parameter of the destination page which copied to.
|
||||
*
|
||||
*Return : the result of the page copy-back;
|
||||
* = 0 page copy-back successful;
|
||||
* = -1 page copy-back failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_PageCopyback(struct __PhysicOpPara_t *pSrcPage, struct __PhysicOpPara_t *pDstPage);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SYNCH NAND FLASH PHYSIC OPERATION
|
||||
*
|
||||
*Description: Synch nand flash operation, check nand flash program/erase operation status.
|
||||
*
|
||||
*Arguments : nBank the number of the bank which need be synchronized;
|
||||
* bMode the type of synch,
|
||||
* = 0 synch the chip which the bank belonged to, wait the whole chip
|
||||
* to be ready, and report status. if the chip support cacheprogram,
|
||||
* need check if the chip is true ready;
|
||||
* = 1 only synch the the bank, wait the bank ready and report the status,
|
||||
* if the chip support cache program, need not check if the cache is
|
||||
* true ready.
|
||||
*
|
||||
*Return : the result of synch;
|
||||
* = 0 synch nand flash successful, nand operation ok;
|
||||
* = -1 synch nand flash failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PHY_SynchBank(__u32 nBank, __u32 bMode);
|
||||
|
||||
|
||||
__s32 PHY_GetDefaultParam(__u32 bank);
|
||||
__s32 PHY_SetDefaultParam(__u32 bank);
|
||||
|
||||
__s32 PHY_ScanDDRParam(void);
|
||||
|
||||
#endif //ifnedf __NAND_PHYSIC_H__
|
||||
|
||||
|
||||
|
||||
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver scan module define
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : nand_scan.h
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.03.25
|
||||
*
|
||||
* Description : This file define the function __s32erface and some data structure export
|
||||
* for the nand flash scan module.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.03.25 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#ifndef __NAND_SCAN_H__
|
||||
#define __NAND_SCAN_H__
|
||||
|
||||
#include "nand_type.h"
|
||||
#include "nand_physic.h"
|
||||
|
||||
//==============================================================================
|
||||
// define nand flash manufacture ID number
|
||||
//==============================================================================
|
||||
|
||||
#define TOSHIBA_NAND 0x98 //Toshiba nand flash manufacture number
|
||||
#define SAMSUNG_NAND 0xec //Samsunt nand flash manufacture number
|
||||
#define HYNIX_NAND 0xad //Hynix nand flash manufacture number
|
||||
#define MICRON_NAND 0x2c //Micron nand flash manufacture number
|
||||
#define ST_NAND 0x20 //ST nand flash manufacture number
|
||||
#define INTEL_NAND 0x89 //Intel nand flash manufacture number
|
||||
#define SPANSION_NAND 0x01 //spansion nand flash manufacture number
|
||||
#define POWER_NAND 0x92 //power nand flash manufacture number
|
||||
#define SANDISK 0x45 //sandisk nand flash manufacture number
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// define the function __s32erface for nand storage scan module
|
||||
//==============================================================================
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* ANALYZE NAND FLASH STORAGE SYSTEM
|
||||
*
|
||||
*Description: Analyze nand flash storage system, generate the nand flash physical
|
||||
* architecture parameter and connect information.
|
||||
*
|
||||
*Arguments : none
|
||||
*
|
||||
*Return : analyze result;
|
||||
* = 0 analyze successful;
|
||||
* < 0 analyze failed, can't recognize or some other error.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 SCN_AnalyzeNandSystem(void);
|
||||
|
||||
__u32 NAND_GetValidBlkRatio(void);
|
||||
__s32 NAND_SetValidBlkRatio(__u32 ValidBlkRatio);
|
||||
__u32 NAND_GetFrequencePar(void);
|
||||
__s32 NAND_SetFrequencePar(__u32 FrequencePar);
|
||||
__u32 NAND_GetNandVersion(void);
|
||||
__s32 NAND_GetParam(boot_nand_para_t * nand_param);
|
||||
|
||||
#endif //ifndef __NAND_SCAN_H__
|
@ -1,22 +0,0 @@
|
||||
#ifndef __PHY_BOOT__
|
||||
#define __PHY_BOOT__
|
||||
|
||||
#include "nand_drv_cfg.h"
|
||||
|
||||
struct boot_physical_param{
|
||||
__u32 chip; //chip no
|
||||
__u32 block; // block no within chip
|
||||
__u32 page; // apge no within block
|
||||
__u64 sectorbitmap; //done't care
|
||||
void *mainbuf; //data buf
|
||||
void *oobbuf; //oob buf
|
||||
};
|
||||
|
||||
extern __s32 PHY_SimpleErase(struct boot_physical_param * eraseop);
|
||||
extern __s32 PHY_SimpleRead(struct boot_physical_param * readop);
|
||||
extern __s32 PHY_SimpleWrite(struct boot_physical_param * writeop);
|
||||
extern __s32 PHY_SimpleWrite_1K(struct boot_physical_param * writeop);
|
||||
extern __s32 PHY_SimpleWrite_Seq(struct boot_physical_param * writeop);
|
||||
extern __s32 PHY_SimpleRead_Seq(struct boot_physical_param * readop);
|
||||
extern __s32 PHY_SimpleRead_1K(struct boot_physical_param * readop);
|
||||
#endif
|
@ -1,373 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver data struct type define
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : nand_type.h
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.03.19
|
||||
*
|
||||
* Description : This file defines the data struct type and return value type for nand flash driver.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.03.19 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#ifndef __NAND_TYPE_H
|
||||
#define __NAND_TYPE_H
|
||||
|
||||
#include "nand_drv_cfg.h"
|
||||
|
||||
//==============================================================================
|
||||
// define the data structure for physic layer module
|
||||
//==============================================================================
|
||||
|
||||
//define the optional physical operation parameter
|
||||
struct __OptionalPhyOpPar_t
|
||||
{
|
||||
__u8 MultiPlaneReadCmd[2]; //the command for multi-plane read, the sequence is [0] -ADDR- [0] -ADDR- [1] - DATA
|
||||
__u8 MultiPlaneWriteCmd[2]; //the command for multi-plane program, the sequence is 80 -ADDR- DATA - [0] - [1] -ADDR- DATA - 10/15
|
||||
__u8 MultiPlaneCopyReadCmd[3]; //the command for multi-plane page copy-back read, the sequence is [0] -ADDR- [1] -ADDR- [2]
|
||||
__u8 MultiPlaneCopyWriteCmd[3]; //the command for multi-plane page copy-back program, the sequence is [0] -ADDR- [1] - [2] -ADDR- 10
|
||||
__u8 MultiPlaneStatusCmd; //the command for multi-plane operation status read, the command may be 0x70/0x71/0x78/...
|
||||
__u8 InterBnk0StatusCmd; //the command for inter-leave bank0 operation status read, the command may be 0xf1/0x78/...
|
||||
__u8 InterBnk1StatusCmd; //the command for inter-leave bank1 operation status read, the command may be 0xf2/0x78/...
|
||||
__u8 BadBlockFlagPosition; //the flag that marks the position of the bad block flag,0x00-1stpage/ 0x01-1st&2nd page/ 0x02-last page/ 0x03-last 2 page
|
||||
__u16 MultiPlaneBlockOffset; //the value of the block number offset between the left-plane block and the right pane block
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__u32 ChipCnt; //the count of the total nand flash chips are currently connecting on the CE pin
|
||||
__u32 ChipConnectInfo; //chip connect information, bit == 1 means there is a chip connecting on the CE pin
|
||||
__u32 RbCnt;
|
||||
__u32 RbConnectInfo; //the connect information of the all rb chips are connected
|
||||
__u32 RbConnectMode; //the rb connect mode
|
||||
__u32 BankCntPerChip; //the count of the banks in one nand chip, multiple banks can support Inter-Leave
|
||||
__u32 DieCntPerChip; //the count of the dies in one nand chip, block management is based on Die
|
||||
__u32 PlaneCntPerDie; //the count of planes in one die, multiple planes can support multi-plane operation
|
||||
__u32 SectorCntPerPage; //the count of sectors in one single physic page, one sector is 0.5k
|
||||
__u32 PageCntPerPhyBlk; //the count of physic pages in one physic block
|
||||
__u32 BlkCntPerDie; //the count of the physic blocks in one die, include valid block and invalid block
|
||||
__u32 OperationOpt; //the mask of the operation types which current nand flash can support support
|
||||
__u32 FrequencePar; //the parameter of the hardware access clock, based on 'MHz'
|
||||
__u32 EccMode; //the Ecc Mode for the nand flash chip, 0: bch-16, 1:bch-28, 2:bch_32
|
||||
__u8 NandChipId[8]; //the nand chip id of current connecting nand chip
|
||||
__u32 ValidBlkRatio; //the ratio of the valid physical blocks, based on 1024
|
||||
__u32 good_block_ratio; //good block ratio get from hwscan
|
||||
__u32 ReadRetryType; //the read retry type
|
||||
__u32 DDRType;
|
||||
__u32 Reserved[23];
|
||||
}boot_nand_para_t;
|
||||
|
||||
typedef struct boot_flash_info{
|
||||
__u32 chip_cnt;
|
||||
__u32 blk_cnt_per_chip;
|
||||
__u32 blocksize;
|
||||
__u32 pagesize;
|
||||
__u32 pagewithbadflag; /*bad block flag was written at the first byte of spare area of this page*/
|
||||
}boot_flash_info_t;
|
||||
|
||||
//define the nand flash storage system information
|
||||
struct __NandStorageInfo_t
|
||||
{
|
||||
__u32 ChipCnt; //the count of the total nand flash chips are currently connecting on the CE pin
|
||||
__u32 ChipConnectInfo; //chip connect information, bit == 1 means there is a chip connecting on the CE pin
|
||||
__u32 RbCnt;
|
||||
__u32 RbConnectInfo; //the connect information of the all rb chips are connected
|
||||
__u32 RbConnectMode; //the rb connect mode
|
||||
__u32 BankCntPerChip; //the count of the banks in one nand chip, multiple banks can support Inter-Leave
|
||||
__u32 DieCntPerChip; //the count of the dies in one nand chip, block management is based on Die
|
||||
__u32 PlaneCntPerDie; //the count of planes in one die, multiple planes can support multi-plane operation
|
||||
__u32 SectorCntPerPage; //the count of sectors in one single physic page, one sector is 0.5k
|
||||
__u32 PageCntPerPhyBlk; //the count of physic pages in one physic block
|
||||
__u32 BlkCntPerDie; //the count of the physic blocks in one die, include valid block and invalid block
|
||||
__u32 OperationOpt; //the mask of the operation types which current nand flash can support support
|
||||
__u32 FrequencePar; //the parameter of the hardware access clock, based on 'MHz'
|
||||
__u32 EccMode; //the Ecc Mode for the nand flash chip, 0: bch-16, 1:bch-28, 2:bch_32
|
||||
__u32 NandChipId[8]; //the nand chip id of current connecting nand chip
|
||||
__u32 ValidBlkRatio; //the ratio of the valid physical blocks, based on 1024
|
||||
__u32 ReadRetryType; //the read retry type
|
||||
__u32 DDRType;
|
||||
struct __OptionalPhyOpPar_t OptPhyOpPar; //the parameters for some optional operation
|
||||
};
|
||||
|
||||
|
||||
//define the page buffer pool for nand flash driver
|
||||
struct __NandPageCachePool_t
|
||||
{
|
||||
__u8 *PageCache0; //the pointer to the first page size ram buffer
|
||||
__u8 *PageCache1; //the pointer to the second page size ram buffer
|
||||
__u8 *PageCache2; //the pointer to the third page size ram buffer
|
||||
__u8 *SpareCache;
|
||||
|
||||
__u8 *TmpPageCache;
|
||||
};
|
||||
|
||||
#ifdef __OS_LINUX_SYSTEM__
|
||||
//define the User Data structure for nand flash driver
|
||||
struct __NandUserData_t
|
||||
{
|
||||
__u8 BadBlkFlag; //the flag that marks if a physic block is a valid block or a invalid block
|
||||
__u16 LogicInfo; //the logical information of the physical block
|
||||
__u8 Reserved0; //reserved for 32bit align
|
||||
__u16 LogicPageNum; //the value of the logic page number, which the physic page is mapping to
|
||||
__u8 PageStatus; //the logical information of the physical page
|
||||
__u8 Reserved1; //reserved for 32bit align
|
||||
} __attribute__ ((packed));
|
||||
#else
|
||||
__packed struct __NandUserData_t
|
||||
{
|
||||
__u8 BadBlkFlag; //the flag that marks if a physic block is a valid block or a invalid block
|
||||
__u16 LogicInfo; //the logical information of the physical block
|
||||
__u8 Reserved0; //reserved for 32bit align
|
||||
__u16 LogicPageNum; //the value of the logic page number, which the physic page is mapping to
|
||||
__u8 PageStatus; //the logical information of the physical page
|
||||
__u8 Reserved1; //reserved for 32bit align
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//define the paramter structure for physic operation function
|
||||
struct __PhysicOpPara_t
|
||||
{
|
||||
__u8 BankNum; //the number of the bank current accessed, bank NO. is different of chip NO.
|
||||
__u8 PageNum; //the number of the page current accessed, the page is based on single-plane or multi-plane
|
||||
__u16 BlkNum; //the number of the physic block, the block is based on single-plane or multi-plane
|
||||
__u64 SectBitmap; //the bitmap of the sector in the page which need access data
|
||||
void *MDataPtr; //the pointer to main data buffer, it is the start address of a page size based buffer
|
||||
void *SDataPtr; //the pointer to spare data buffer, it will be set to NULL if needn't access spare data
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// define the data structure for logic management module
|
||||
//==============================================================================
|
||||
|
||||
//define the logical architecture parameter structure
|
||||
struct __LogicArchitecture_t
|
||||
{
|
||||
__u16 LogicBlkCntPerZone; //the counter that marks how many logic blocks in one zone
|
||||
__u16 PageCntPerLogicBlk; //the counter that marks how many pages in one logical block
|
||||
__u8 SectCntPerLogicPage; //the counter that marks how many sectors in one logical page
|
||||
__u8 ZoneCntPerDie; //the counter that marks how many zones in one die
|
||||
__u16 Reserved; //reserved for 32bit align
|
||||
};
|
||||
|
||||
//define the super block type
|
||||
struct __SuperPhyBlkType_t
|
||||
{
|
||||
__u16 PhyBlkNum; //the super physic block offset number in a die,the first block of the die is 0
|
||||
__u16 BlkEraseCnt; //the erase count of the super physic block,record how many times it has been erased
|
||||
};
|
||||
|
||||
|
||||
//define the log block table item type
|
||||
struct __LogBlkType_t
|
||||
{
|
||||
__u16 LogicBlkNum; //the logic block number which the log block is belonged to
|
||||
__u16 LastUsedPage; //the number of the page which is the last used in the super physic block
|
||||
struct __SuperPhyBlkType_t PhyBlk; //the super physic block number which the log block is mapping to
|
||||
};
|
||||
|
||||
|
||||
//define the zone table position information type
|
||||
struct __ZoneTblPstInfo_t
|
||||
{
|
||||
__u16 PhyBlkNum; //the physic block number in the chip which stored the block mapping table
|
||||
__u16 TablePst; //the page number in the physic block which stored the valid block mapping table
|
||||
};
|
||||
|
||||
|
||||
//define the block mapping table cache access type
|
||||
struct __BlkMapTblCache_t
|
||||
{
|
||||
__u8 ZoneNum; //the number of the zone which is the block mapping table belonged to
|
||||
__u8 DirtyFlag; //the flag that marks the status of the table in the nand, notes if the table need write back
|
||||
__u16 AccessCnt; //the counter that record how many times the block mapping table has been accessed
|
||||
struct __SuperPhyBlkType_t *DataBlkTbl; //the pointer to the data block table of the block mapping table
|
||||
struct __LogBlkType_t *LogBlkTbl; //the pointer to the log block table of the block mapping table
|
||||
struct __SuperPhyBlkType_t *FreeBlkTbl; //the pointer to the free block table of the block mapping table
|
||||
__u16 LastFreeBlkPst; //the pointer to the free block position which is got last time
|
||||
__u16 Reserved; //reserved for 32bit align
|
||||
};
|
||||
|
||||
//define the block mapping table cache management parameter type
|
||||
struct __BlkMapTblCachePool_t
|
||||
{
|
||||
struct __BlkMapTblCache_t *ActBlkMapTbl; //the pointer to the active block mapping table
|
||||
struct __BlkMapTblCache_t BlkMapTblCachePool[BLOCK_MAP_TBL_CACHE_CNT]; //the pool of the block mapping table cache
|
||||
__u16 LogBlkAccessAge[MAX_LOG_BLK_CNT]; //the time of accessing log block for the log block
|
||||
__u16 LogBlkAccessTimer; //the timer of the access time for recording the log block accessing time
|
||||
__u16 SuperBlkEraseCnt; //the counter of the super block erase, for do wear-levelling
|
||||
};
|
||||
|
||||
|
||||
//define the page mapping table item type
|
||||
struct __PageMapTblItem_t
|
||||
{
|
||||
__u16 PhyPageNum; //the physic page number which the logic page mapping to
|
||||
};
|
||||
|
||||
//define the page mapping table access type
|
||||
struct __PageMapTblCache_t
|
||||
{
|
||||
__u8 ZoneNum; //the zone number which the page mapping table is belonged to
|
||||
__u8 LogBlkPst; //the position of the log block in the log block table
|
||||
__u16 AccessCnt; //the counter that the page mapping table has been accessed
|
||||
struct __PageMapTblItem_t *PageMapTbl; //the pointer to the page mapping table
|
||||
__u8 DirtyFlag; //the flag that marks if the page mapping table need be writen back to nand flash
|
||||
__u8 Reserved[3]; //reserved for 32bit align
|
||||
};
|
||||
|
||||
//define the page mapping table cache management parameter type
|
||||
struct __PageMapTblCachePool_t
|
||||
{
|
||||
struct __PageMapTblCache_t *ActPageMapTbl; //the poninter to the active page mapping table
|
||||
struct __PageMapTblCache_t PageMapTblCachePool[PAGE_MAP_TBL_CACHE_CNT]; //the pool of the page mapping table cache
|
||||
};
|
||||
|
||||
|
||||
//define the global logical page parameter type
|
||||
struct __GlobalLogicPageType_t
|
||||
{
|
||||
__u32 LogicPageNum; //the global page number of the logic page, it is based on super page size
|
||||
__u64 SectorBitmap; //the bitmap of the sector in the logic page which data need access
|
||||
};
|
||||
|
||||
|
||||
//define the global logcial page based on zone and block parameter type
|
||||
struct __LogicPageType_t
|
||||
{
|
||||
__u64 SectBitmap; //the bitmap marks which sectors' data in the logical page need access
|
||||
__u16 BlockNum; //the value of the number of the logical block which the page is belonged to
|
||||
__u16 PageNum; //the value of the number of the page in the logical block
|
||||
__u8 ZoneNum; //the value of the number of the zone, which the page is belonged to
|
||||
__u8 Reserved[3]; //reserved for 32bit align
|
||||
};
|
||||
|
||||
|
||||
//define the logical control layer management parameter type
|
||||
struct __LogicCtlPar_t
|
||||
{
|
||||
__u8 OpMode; //record nand flash driver last operation, may be read, write, or none.
|
||||
__u8 ZoneNum; //the number of the zone which is accessed last time
|
||||
__u16 LogicBlkNum; //the number of the logic block which is accessed last time
|
||||
__u16 LogicPageNum; //the number of the logic page which is accessed last time
|
||||
__u16 LogPageNum; //the number of the log page, which is accessed last time
|
||||
struct __SuperPhyBlkType_t DataBlkNum; //the number of the data block, which is accessed last time
|
||||
struct __SuperPhyBlkType_t LogBlkNum; //the number of the log block, which is accessed last time
|
||||
__u32 DiskCap; //the capacity of the logical disk
|
||||
};
|
||||
|
||||
|
||||
//define the nand flash physical information parameter type
|
||||
struct __NandPhyInfoPar_t
|
||||
{
|
||||
__u8 NandID[8]; //the ID number of the nand flash chip
|
||||
__u8 DieCntPerChip; //the count of the Die in one nand flash chip
|
||||
__u8 SectCntPerPage; //the count of the sectors in one single physical page
|
||||
__u16 PageCntPerBlk; //the count of the pages in one single physical block
|
||||
__u16 BlkCntPerDie; //the count fo the physical blocks in one nand flash Die
|
||||
__u16 OperationOpt; //the bitmap that marks which optional operation that the nand flash can support
|
||||
__u16 ValidBlkRatio; //the valid block ratio, based on 1024 blocks
|
||||
__u16 AccessFreq; //the highest access frequence of the nand flash chip, based on MHz
|
||||
__u16 EccMode; //the Ecc Mode for the nand flash chip, 0: bch-16, 1:bch-28, 2:bch_32
|
||||
__u32 ReadRetryType;
|
||||
__u32 DDRType;
|
||||
struct __OptionalPhyOpPar_t *OptionOp; //the pointer point to the optional operation parameter
|
||||
};
|
||||
|
||||
|
||||
//define the global paramter for nand flash driver to access all parameter
|
||||
struct __NandDriverGlobal_t
|
||||
{
|
||||
struct __NandStorageInfo_t *NandStorageInfo; //the pointer to the nand flash hardware information parameter
|
||||
struct __ZoneTblPstInfo_t *ZoneTblPstInfo; //the pointer to the block mapping table information parameter
|
||||
struct __BlkMapTblCachePool_t *BlkMapTblCachePool; //the pointer to the block mapping thable cache pool management parameter
|
||||
struct __PageMapTblCachePool_t *PageMapTblCachePool; //the pointer to the page mapping table cache pool management parameter
|
||||
struct __LogicArchitecture_t *LogicalArchitecture; //the pointer to the logical archtecture parameter
|
||||
struct __NandPageCachePool_t *PageCachePool; //the pointer to the page cache pool parameter
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// define some constant variable for the nand flash driver used
|
||||
//==============================================================================
|
||||
|
||||
//define the mask for the nand flash optional operation
|
||||
#define NAND_CACHE_READ (1<<0) //nand flash support cache read operation
|
||||
#define NAND_CACHE_PROGRAM (1<<1) //nand flash support page cache program operation
|
||||
#define NAND_MULTI_READ (1<<2) //nand flash support multi-plane page read operation
|
||||
#define NAND_MULTI_PROGRAM (1<<3) //nand flash support multi-plane page program operation
|
||||
#define NAND_PAGE_COPYBACK (1<<4) //nand flash support page copy-back command mode operation
|
||||
#define NAND_INT_INTERLEAVE (1<<5) //nand flash support internal inter-leave operation, it based multi-bank
|
||||
#define NAND_EXT_INTERLEAVE (1<<6) //nand flash support external inter-leave operation, it based multi-chip
|
||||
#define NAND_RANDOM (1<<7) //nand flash support RANDOMIZER
|
||||
#define NAND_READ_RETRY (1<<8) //nand falsh support READ RETRY
|
||||
#define NAND_READ_UNIQUE_ID (1<<9) //nand falsh support READ UNIQUE_ID
|
||||
#define NAND_PAGE_ADR_NO_SKIP (1<<10) //nand falsh page adr no skip is requiered
|
||||
#define NAND_DIE_SKIP (1<<11) //nand flash die adr skip
|
||||
|
||||
|
||||
//define the mask for the nand flash operation status
|
||||
#define NAND_OPERATE_FAIL (1<<0) //nand flash program/erase failed mask
|
||||
#define NAND_CACHE_READY (1<<5) //nand flash cache program true ready mask
|
||||
#define NAND_STATUS_READY (1<<6) //nand flash ready/busy status mask
|
||||
#define NAND_WRITE_PROTECT (1<<7) //nand flash write protected mask
|
||||
|
||||
|
||||
//define the mark for physical page status
|
||||
#define FREE_PAGE_MARK 0xff //the page is storing no data, is not used
|
||||
#define DATA_PAGE_MARK 0x55 //the physical page is used for storing the update data
|
||||
#define TABLE_PAGE_MARK 0xaa //the physical page is used for storing page mapping table
|
||||
|
||||
#define TABLE_BLK_MARK 0xaa //the mark for the block mapping table block which is a special type block
|
||||
#define BOOT_BLK_MARK 0xbb //the mark for the boot block which is a special type block
|
||||
|
||||
//define the count of the physical blocks managed by one zone
|
||||
#define BLOCK_CNT_OF_ZONE 1024 //one zone is organized based on 1024 blocks
|
||||
|
||||
//define the size of the sector
|
||||
#define SECTOR_SIZE 512 //the size of a sector, based on byte
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// define the function return value for different modules
|
||||
//==============================================================================
|
||||
|
||||
#define NAND_OP_TRUE (0) //define the successful return value
|
||||
#define NAND_OP_FALSE (-1) //define the failed return value
|
||||
|
||||
|
||||
//define the return value
|
||||
#define ECC_LIMIT 10 //reach the limit of the ability of ECC
|
||||
#define ERR_MALLOC 11 //request buffer failed
|
||||
#define ERR_ECC 12 //too much ecc error
|
||||
#define ERR_NANDFAIL 13 //nand flash program or erase fail
|
||||
#define ERR_TIMEOUT 14 //hardware timeout
|
||||
#define ERR_PHYSIC 15 //physical operation module error
|
||||
#define ERR_SCAN 16 //scan module error
|
||||
#define ERR_FORMAT 17 //format module error
|
||||
#define ERR_MAPPING 18 //mapping module error
|
||||
#define ERR_LOGICCTL 19 //logic control module error
|
||||
#define ERR_ADDRBEYOND 20 //the logical sectors need be accessed is beyond the logical disk
|
||||
#define ERR_INVALIDPHYADDR 21
|
||||
|
||||
#endif //ifndef __NAND_TYPE_H
|
||||
|
@ -1,273 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND BSP for sun
|
||||
* NAND hardware registers definition and BSP interfaces
|
||||
*
|
||||
* Copyright(C), 2006-2008, uLIVE
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : nfc.h
|
||||
*
|
||||
* Author : Gary.Wang
|
||||
*
|
||||
* Version : 1.1.0
|
||||
*
|
||||
* Date : 2008.03.25
|
||||
*
|
||||
* Description : This file provides some definition of NAND's hardware registers and BSP interfaces.
|
||||
* This file is very similar to file "nand.inc"; the two files should be modified at the
|
||||
* same time to keep coherence of information.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Gary.Wang 2008.03.25 1.1.0 build the file
|
||||
* penggang 2009.09.09 1.1.1 modify the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#ifndef _NFC_H_
|
||||
#define _NFC_H_
|
||||
|
||||
#include "nand_drv_cfg.h"
|
||||
|
||||
extern __u32 nand_io_base;
|
||||
#define NAND_IO_BASE (nand_io_base)
|
||||
#define __NFC_REG(x) (*(volatile unsigned int *)(NAND_IO_BASE + x))
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* Nand Flash Controller define < maintained by Richard >
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
/* offset */
|
||||
#define NFC_REG_o_CTL 0x0000
|
||||
#define NFC_REG_o_ST 0x0004
|
||||
#define NFC_REG_o_INT 0x0008
|
||||
#define NFC_REG_o_TIMING_CTL 0x000C
|
||||
#define NFC_REG_o_TIMING_CFG 0x0010
|
||||
#define NFC_REG_o_ADDR_LOW 0x0014
|
||||
#define NFC_REG_o_ADDR_HIGH 0x0018
|
||||
#define NFC_REG_o_SECTOR_NUM 0x001C
|
||||
#define NFC_REG_o_CNT 0x0020
|
||||
#define NFC_REG_o_CMD 0x0024
|
||||
#define NFC_REG_o_RCMD_SET 0x0028
|
||||
#define NFC_REG_o_WCMD_SET 0x002C
|
||||
#define NFC_REG_o_IO_DATA 0x0030
|
||||
#define NFC_REG_o_ECC_CTL 0x0034
|
||||
#define NFC_REG_o_ECC_ST 0x0038
|
||||
#define NFC_REG_o_DEBUG 0x003C
|
||||
#define NFC_REG_o_ECC_CNT0 0x0040
|
||||
#define NFC_REG_o_ECC_CNT1 0x0044
|
||||
#define NFC_REG_o_ECC_CNT2 0x0048
|
||||
#define NFC_REG_o_ECC_CNT3 0x004c
|
||||
#define NFC_REG_o_USER_DATA_BASE 0x0050
|
||||
#define NFC_REG_o_SPARE_AREA 0x00A0
|
||||
#define NFC_o_RAM0_BASE 0x0400
|
||||
#define NFC_o_RAM1_BASE 0x0800
|
||||
/* registers */
|
||||
#define NFC_REG_CTL __NFC_REG( NFC_REG_o_CTL )
|
||||
#define NFC_REG_ST __NFC_REG( NFC_REG_o_ST )
|
||||
#define NFC_REG_INT __NFC_REG( NFC_REG_o_INT )
|
||||
#define NFC_REG_TIMING_CTL __NFC_REG( NFC_REG_o_TIMING_CTL )
|
||||
#define NFC_REG_TIMING_CFG __NFC_REG( NFC_REG_o_TIMING_CFG )
|
||||
#define NFC_REG_ADDR_LOW __NFC_REG( NFC_REG_o_ADDR_LOW )
|
||||
#define NFC_REG_ADDR_HIGH __NFC_REG( NFC_REG_o_ADDR_HIGH )
|
||||
#define NFC_REG_SECTOR_NUM __NFC_REG( NFC_REG_o_SECTOR_NUM )
|
||||
#define NFC_REG_CNT __NFC_REG( NFC_REG_o_CNT )
|
||||
#define NFC_REG_CMD __NFC_REG( NFC_REG_o_CMD )
|
||||
#define NFC_REG_RCMD_SET __NFC_REG( NFC_REG_o_RCMD_SET )
|
||||
#define NFC_REG_WCMD_SET __NFC_REG( NFC_REG_o_WCMD_SET )
|
||||
#define NFC_REG_IO_DATA __NFC_REG( NFC_REG_o_IO_DATA )
|
||||
#define NFC_REG_ECC_CTL __NFC_REG( NFC_REG_o_ECC_CTL )
|
||||
#define NFC_REG_ECC_ST __NFC_REG( NFC_REG_o_ECC_ST )
|
||||
#define NFC_REG_ECC_CNT0 __NFC_REG( NFC_REG_o_ECC_CNT0 )
|
||||
#define NFC_REG_ECC_CNT1 __NFC_REG( NFC_REG_o_ECC_CNT1 )
|
||||
#define NFC_REG_ECC_CNT2 __NFC_REG( NFC_REG_o_ECC_CNT2 )
|
||||
#define NFC_REG_ECC_CNT3 __NFC_REG( NFC_REG_o_ECC_CNT3 )
|
||||
#define NFC_REG_DEBUG __NFC_REG( NFC_REG_o_DEBUG )
|
||||
#define NFC_REG_USER_DATA(sct_num) __NFC_REG( NFC_REG_o_USER_DATA_BASE + 4 * sct_num )
|
||||
#define NFC_REG_SPARE_AREA __NFC_REG( NFC_REG_o_SPARE_AREA )
|
||||
#define NFC_RAM0_BASE ( NFC_o_RAM0_BASE )
|
||||
#define NFC_RAM1_BASE ( NFC_o_RAM1_BASE )
|
||||
|
||||
/*define bit use in NFC_CTL*/
|
||||
#define NFC_EN (1 << 0)
|
||||
#define NFC_RESET (1 << 1)
|
||||
#define NFC_BUS_WIDYH (1 << 2)
|
||||
#define NFC_RB_SEL (1 << 3)
|
||||
#define NFC_CE_SEL (7 << 24)
|
||||
#define NFC_CE_CTL (1 << 6)
|
||||
#define NFC_CE_CTL1 (1 << 7)
|
||||
#define NFC_PAGE_SIZE (0xf << 8)
|
||||
#define NFC_SAM (1 << 12)
|
||||
#define NFC_RAM_METHOD (1 << 14)
|
||||
#define NFC_DEBUG_CTL (1 << 31)
|
||||
|
||||
/*define bit use in NFC_ST*/
|
||||
#define NFC_RB_B2R (1 << 0)
|
||||
#define NFC_CMD_INT_FLAG (1 << 1)
|
||||
#define NFC_DMA_INT_FLAG (1 << 2)
|
||||
#define NFC_CMD_FIFO_STATUS (1 << 3)
|
||||
#define NFC_STA (1 << 4)
|
||||
#define NFC_NATCH_INT_FLAG (1 << 5)
|
||||
#define NFC_RB_STATE0 (1 << 8)
|
||||
#define NFC_RB_STATE1 (1 << 9)
|
||||
#define NFC_RB_STATE2 (1 << 10)
|
||||
#define NFC_RB_STATE3 (1 << 11)
|
||||
|
||||
/*define bit use in NFC_INT*/
|
||||
#define NFC_B2R_INT_ENABLE (1 << 0)
|
||||
#define NFC_CMD_INT_ENABLE (1 << 1)
|
||||
#define NFC_DMA_INT_ENABLE (1 << 2)
|
||||
|
||||
|
||||
/*define bit use in NFC_CMD*/
|
||||
#define NFC_CMD_LOW_BYTE (0xff << 0)
|
||||
#define NFC_CMD_HIGH_BYTE (0xff << 8)
|
||||
#define NFC_ADR_NUM (0x7 << 16)
|
||||
#define NFC_SEND_ADR (1 << 19)
|
||||
#define NFC_ACCESS_DIR (1 << 20)
|
||||
#define NFC_DATA_TRANS (1 << 21)
|
||||
#define NFC_SEND_CMD1 (1 << 22)
|
||||
#define NFC_WAIT_FLAG (1 << 23)
|
||||
#define NFC_SEND_CMD2 (1 << 24)
|
||||
#define NFC_SEQ (1 << 25)
|
||||
#define NFC_DATA_SWAP_METHOD (1 << 26)
|
||||
#define NFC_ROW_AUTO_INC (1 << 27)
|
||||
#define NFC_SEND_CMD3 (1 << 28)
|
||||
#define NFC_SEND_CMD4 (1 << 29)
|
||||
#define NFC_CMD_TYPE (3 << 30)
|
||||
|
||||
/* define bit use in NFC_RCMD_SET*/
|
||||
#define NFC_READ_CMD (0xff<< 0)
|
||||
#define NFC_RANDOM_READ_CMD0 (0xff << 8)
|
||||
#define NFC_RANDOM_READ_CMD1 (0xff << 16)
|
||||
|
||||
/*define bit use in NFC_WCMD_SET*/
|
||||
#define NFC_PROGRAM_CMD (0xff << 0)
|
||||
#define NFC_RANDOM_WRITE_CMD (0xff << 8)
|
||||
#define NFC_READ_CMD0 (0xff << 16)
|
||||
#define NFC_READ_CMD1 (0xff << 24)
|
||||
|
||||
/*define bit use in NFC_ECC_CTL*/
|
||||
#define NFC_ECC_EN (1 << 0)
|
||||
#define NFC_ECC_PIPELINE (1 << 3)
|
||||
#define NFC_ECC_EXCEPTION (1 << 4)
|
||||
#define NFC_ECC_BLOCK_SIZE (1 << 5)
|
||||
#define NFC_RANDOM_EN (1 << 9 )
|
||||
#define NFC_RANDOM_DIRECTION (1 << 10 )
|
||||
#define NFC_ECC_MODE (0xf << 12)
|
||||
#define NFC_RANDOM_SEED (0x7fff << 16))
|
||||
|
||||
#define NFC_IRQ_MAJOR 13
|
||||
/*cmd flag bit*/
|
||||
#define NFC_PAGE_MODE 0x1
|
||||
#define NFC_NORMAL_MODE 0x0
|
||||
|
||||
#define NFC_DATA_FETCH 0x1
|
||||
#define NFC_NO_DATA_FETCH 0x0
|
||||
#define NFC_MAIN_DATA_FETCH 0x1
|
||||
#define NFC_SPARE_DATA_FETCH 0X0
|
||||
#define NFC_WAIT_RB 0x1
|
||||
#define NFC_NO_WAIT_RB 0x0
|
||||
#define NFC_IGNORE 0x0
|
||||
|
||||
#define NFC_INT_RB 0
|
||||
#define NFC_INT_CMD 1
|
||||
#define NFC_INT_DMA 2
|
||||
#define NFC_INT_BATCh 5
|
||||
|
||||
typedef struct cmd_list{
|
||||
struct cmd_list *next;
|
||||
__u8 *addr;
|
||||
__u8 addr_cycle;
|
||||
__u8 data_fetch_flag;
|
||||
__u8 main_data_fetch;
|
||||
__u8 wait_rb_flag;
|
||||
__u32 bytecnt;
|
||||
__u32 value;
|
||||
}NFC_CMD_LIST;
|
||||
|
||||
typedef struct NFC_init_info{
|
||||
__u8 bus_width;// bus width 8 bit
|
||||
__u8 rb_sel; // ready busy
|
||||
__u8 ce_ctl; // chip select
|
||||
__u8 ce_ctl1;
|
||||
__u8 pagesize; // 1024 ,2048 ,
|
||||
__u8 serial_access_mode; // SAM0 SAM1
|
||||
__u8 ddr_type;
|
||||
__u8 debug;
|
||||
}NFC_INIT_INFO;
|
||||
|
||||
__s32 NFC_ReadRetryInit(__u32 read_retry_type);
|
||||
__s32 NFC_ReadRetryExit(__u32 read_retry_type);
|
||||
__s32 NFC_GetDefaultParam(__u32 chip, __u8 *defautl_value, __u32 read_retry_type);
|
||||
void NFC_GetOTPValue(__u32 chip, __u8* otp_value, __u32 read_retry_type);
|
||||
__s32 NFC_SetDefaultParam(__u32 chip, __u8 *defautl_value, __u32 read_retry_type);
|
||||
__s32 NFC_ReadRetry(__u32 chip, __u32 retry_count, __u32 read_retry_type);
|
||||
__s32 NFC_LSBEnable(__u32 chip, __u32 read_retry_type);
|
||||
__s32 NFC_LSBDisable(__u32 chip, __u32 read_retry_type);
|
||||
__s32 NFC_LSBInit(__u32 read_retry_type);
|
||||
__s32 NFC_LSBExit(__u32 read_retry_type);
|
||||
__s32 NFC_SetRandomSeed(__u32 random_seed);
|
||||
__s32 NFC_RandomEnable(void);
|
||||
__s32 NFC_RandomDisable(void);
|
||||
__s32 NFC_Init(NFC_INIT_INFO * nand_info);
|
||||
void NFC_Exit(void);
|
||||
__s32 NFC_Read(NFC_CMD_LIST * rcmd, void * mainbuf, void * sparebuf, __u8 dma_wait_mode, __u8 page_mode);
|
||||
__s32 NFC_Read_1K(NFC_CMD_LIST * rcmd, void * mainbuf, void * sparebuf, __u8 dma_wait_mode, __u8 page_mode);
|
||||
__s32 NFC_Read_Seq(NFC_CMD_LIST * rcmd, void * mainbuf, void * sparebuf, __u8 dma_wait_mode, __u8 page_mode);
|
||||
__s32 NFC_Read_Spare(NFC_CMD_LIST * rcmd, void * mainbuf, void * sparebuf, __u8 dma_wait_mode, __u8 page_mode);
|
||||
__s32 NFC_Write(NFC_CMD_LIST * wcmd, void * mainbuf, void * sparebuf, __u8 dma_wait_mode, __u8 rb_wait_mode, __u8 page_mode);
|
||||
__s32 NFC_Write_Seq(NFC_CMD_LIST * wcmd, void * mainbuf, void * sparebuf, __u8 dma_wait_mode, __u8 rb_wait_mode, __u8 page_mode);
|
||||
__s32 NFC_Write_1K(NFC_CMD_LIST * wcmd, void * mainbuf, void * sparebuf, __u8 dma_wait_mode, __u8 rb_wait_mode, __u8 page_mode);
|
||||
__s32 NFC_Erase(NFC_CMD_LIST * ecmd, __u8 rb_wait_mode);
|
||||
__s32 NFC_CopyBackRead(NFC_CMD_LIST * crcmd);
|
||||
__s32 NFC_CopyBackWrite(NFC_CMD_LIST * cwcmd, __u8 rb_wait_mode);
|
||||
__s32 NFC_GetId(NFC_CMD_LIST * idcmd, __u8 * idbuf);
|
||||
__s32 NFC_GetUniqueId(NFC_CMD_LIST * idcmd, __u8 * idbuf);
|
||||
__s32 NFC_SelectChip(__u32 chip);
|
||||
__s32 NFC_DeSelectChip(__u32 chip);
|
||||
__s32 NFC_SelectRb(__u32 rb);
|
||||
__s32 NFC_DeSelectRb(__u32 rb);
|
||||
__s32 NFC_GetStatus(NFC_CMD_LIST * scmd);
|
||||
__s32 NFC_CheckRbReady(__u32 rb);
|
||||
__s32 NFC_ChangMode(NFC_INIT_INFO * nand_info);
|
||||
__s32 NFC_SetEccMode(__u8 ecc_mode);
|
||||
__s32 NFC_ResetChip(NFC_CMD_LIST * reset_cmd);
|
||||
__s32 NFC_ReadRetry_off(__u32 chip); //sandisk readretry exit
|
||||
__u32 NFC_QueryINT(void);
|
||||
void NFC_EnableInt(__u8 minor_int);
|
||||
void NFC_DisableInt(__u8 minor_int);
|
||||
void NFC_InitDDRParam(__u32 chip, __u32 param);
|
||||
|
||||
#define NFC_READ_REG(reg) (reg)
|
||||
#define NFC_WRITE_REG(reg,data) (reg) = (data)
|
||||
|
||||
#define ERR_ECC 12
|
||||
#define ECC_LIMIT 10
|
||||
#define ERR_TIMEOUT 14
|
||||
#define READ_RETRY_MAX_TYPE_NUM 5
|
||||
#define READ_RETRY_MAX_REG_NUM 16
|
||||
#define READ_RETRY_MAX_CYCLE 20
|
||||
#define LSB_MODE_MAX_REG_NUM 8
|
||||
|
||||
/* define various unit data input or output*/
|
||||
#define NFC_READ_RAM_B(ram) (*((volatile __u8 *)(NAND_IO_BASE + ram)))
|
||||
#define NFC_WRITE_RAM_B(ram,data) (*((volatile __u8 *)(NAND_IO_BASE + ram)) = (data))
|
||||
#define NFC_READ_RAM_HW(ram) (*((volatile __u16 *)(NAND_IO_BASE + ram)))
|
||||
#define NFC_WRITE_RAM_HW(ram,data) (*((volatile __u16 *)(NAND_IO_BASE + ram)) = (data))
|
||||
#define NFC_READ_RAM_W(ram) (*((volatile __u32 *)(NAND_IO_BASE + ram)))
|
||||
#define NFC_WRITE_RAM_W(ram,data) (*((volatile __u32 *)(NAND_IO_BASE + ram)) = (data))
|
||||
|
||||
#ifdef USE_PHYSICAL_ADDRESS
|
||||
#define NFC_IS_SDRAM(addr) ((addr >= DRAM_BASE)?1:0)
|
||||
#else
|
||||
#define NFC_IS_SDRAM(addr) ( ((addr >= DRAM_BASE))&&(addr < SRAM_BASE)?1:0)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef _NFC_H_
|
@ -1,194 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver logic manage module
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : bad_manage.c
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.04.07
|
||||
*
|
||||
* Description : This file is the bad block processing module, process bad block in different
|
||||
* cases of bad block produced.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.04.07 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#include "../include/nand_logic.h"
|
||||
|
||||
extern struct __NandDriverGlobal_t NandDriverInfo;
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* RESTORE VALID PAGE DATA FROM BAD BLOCK
|
||||
*
|
||||
*Description: Restore the valid page data from the bad block.
|
||||
*
|
||||
*Arguments : pBadBlk the pointer to the bad physical block parameter;
|
||||
* nErrPage the number of the error page;
|
||||
* pNewBlk the pointer to the new valid block parameter.
|
||||
*
|
||||
*Return : restore page data result;
|
||||
* = 0 restore data successful;
|
||||
* = -1 restore data failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
static __s32 _RestorePageData(struct __SuperPhyBlkType_t *pBadBlk, __u32 nZoneNum, __u32 nErrPage, struct __SuperPhyBlkType_t *pNewBlk)
|
||||
{
|
||||
__s32 i, result;
|
||||
struct __PhysicOpPara_t tmpSrcPage, tmpDstPage;
|
||||
|
||||
//set sector bitmap and buffer pointer for copy nand flash page
|
||||
tmpSrcPage.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
tmpDstPage.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
tmpSrcPage.MDataPtr = NULL;
|
||||
tmpSrcPage.SDataPtr = NULL;
|
||||
|
||||
for(i=0; i<nErrPage; i++)
|
||||
{
|
||||
//calculate source page and destination page parameter for copy nand page
|
||||
LML_CalculatePhyOpPar(&tmpSrcPage, nZoneNum, pBadBlk->PhyBlkNum, i);
|
||||
LML_CalculatePhyOpPar(&tmpDstPage, nZoneNum, pNewBlk->PhyBlkNum, i);
|
||||
|
||||
PHY_PageCopyback(&tmpSrcPage, &tmpDstPage);
|
||||
//check page copy result
|
||||
result = PHY_SynchBank(tmpDstPage.BankNum, SYNC_CHIP_MODE);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_DBG("[LOGICCTL_DBG] Copy page failed when restore bad block data!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* WRITE BAD FLAG TO BAD BLOCK
|
||||
*
|
||||
*Description: Write bad block flag to bad block.
|
||||
*
|
||||
*Arguments : pBadBlk the pointer to the bad physical block parameter.
|
||||
*
|
||||
*Return : mark bad block result;
|
||||
* = 0 mark bad block successful;
|
||||
* = -1 mark bad block failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
static __s32 _MarkBadBlk(struct __SuperPhyBlkType_t *pBadBlk, __u32 nZoneNum)
|
||||
{
|
||||
__s32 i;
|
||||
__s32 ret;
|
||||
struct __PhysicOpPara_t tmpPage;
|
||||
struct __NandUserData_t tmpSpare[2];
|
||||
|
||||
//add by neil 20101201
|
||||
/* erase bad blcok */
|
||||
ret = LML_VirtualBlkErase(nZoneNum, pBadBlk->PhyBlkNum);
|
||||
if(ret)
|
||||
{
|
||||
LOGICCTL_DBG("[LOGICCTL_DBG] erase bad block fail!\n");
|
||||
}
|
||||
|
||||
|
||||
//set the spare area data for write
|
||||
MEMSET((void *)tmpSpare, 0x00, 2*sizeof(struct __NandUserData_t));
|
||||
|
||||
tmpPage.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
tmpPage.MDataPtr = LML_TEMP_BUF;
|
||||
tmpPage.SDataPtr = (void *)tmpSpare;
|
||||
|
||||
//write the bad flag in ervery single physical block of the super block
|
||||
for(i=0; i<INTERLEAVE_BANK_CNT; i++)
|
||||
{
|
||||
//write the bad flag in the first page of the physical block
|
||||
LML_CalculatePhyOpPar(&tmpPage, nZoneNum, pBadBlk->PhyBlkNum, i);
|
||||
LML_VirtualPageWrite(&tmpPage);
|
||||
PHY_SynchBank(tmpPage.BankNum, SYNC_CHIP_MODE);
|
||||
|
||||
//write the bad flag in the last page of the physical block
|
||||
LML_CalculatePhyOpPar(&tmpPage, nZoneNum, pBadBlk->PhyBlkNum, PAGE_CNT_OF_SUPER_BLK - INTERLEAVE_BANK_CNT + i);
|
||||
LML_VirtualPageWrite(&tmpPage);
|
||||
PHY_SynchBank(tmpPage.BankNum, SYNC_CHIP_MODE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER BAD BLOCK MANAGE
|
||||
*
|
||||
*Description: Nand flash bad block manage.
|
||||
*
|
||||
*Arguments : pBadBlk the pointer to the bad physical block parameter;
|
||||
* nZoneNum the number of the zone which the bad block belonged to;
|
||||
* nErrPage the number of the error page;
|
||||
* pNewBlk the pointer to the new valid block parameter.
|
||||
*
|
||||
*Return : bad block manage result;
|
||||
* = 0 do bad block manage successful;
|
||||
* = -1 do bad block manage failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_BadBlkManage(struct __SuperPhyBlkType_t *pBadBlk, __u32 nZoneNum, __u32 nErrPage, struct __SuperPhyBlkType_t *pNewBlk)
|
||||
{
|
||||
__s32 result;
|
||||
struct __SuperPhyBlkType_t tmpFreeBlk;
|
||||
struct __SuperPhyBlkType_t tmpBadBlk;
|
||||
|
||||
tmpBadBlk = *pBadBlk;
|
||||
|
||||
LOGICCTL_ERR("%s : %d : bad block manage go\n",__FUNCTION__,__LINE__);
|
||||
|
||||
__PROCESS_BAD_BLOCK:
|
||||
|
||||
if(pNewBlk)
|
||||
{
|
||||
//get a new free block to replace the bad block
|
||||
BMM_GetFreeBlk(LOWEST_EC_TYPE, &tmpFreeBlk);
|
||||
if(tmpFreeBlk.PhyBlkNum == 0xffff)
|
||||
{
|
||||
LOGICCTL_ERR("[LOGICCTL_ERR] Look for free block failed when replace bad block\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//restore the valid page data from the bad block
|
||||
if(nErrPage)
|
||||
{
|
||||
result = _RestorePageData(&tmpBadBlk, nZoneNum, nErrPage, &tmpFreeBlk);
|
||||
if(result < 0)
|
||||
{
|
||||
//restore data failed, mark bad flag to the new free block
|
||||
_MarkBadBlk(&tmpFreeBlk, nZoneNum);
|
||||
|
||||
goto __PROCESS_BAD_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
*pNewBlk = tmpFreeBlk;
|
||||
}
|
||||
|
||||
//write bad flag to the bad block
|
||||
_MarkBadBlk(&tmpBadBlk, nZoneNum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,499 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver logic manage module
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : logic_cache.c
|
||||
*
|
||||
* Author : Richard.x
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.03.29
|
||||
*
|
||||
* Description : This file descripe the cache read / cache write nand interface.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Richard.x 2008.03.29 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#include "../include/nand_logic.h"
|
||||
|
||||
//#define CACHE_DBG
|
||||
|
||||
#define NAND_W_CACHE_EN
|
||||
#define N_NAND_W_CACHE 8
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__u8 *data;
|
||||
__u32 size;
|
||||
|
||||
__u32 hit_page;
|
||||
__u64 secbitmap;
|
||||
|
||||
__u32 access_count;
|
||||
__u32 dev_num;
|
||||
}__nand_cache_t;
|
||||
|
||||
__u32 g_w_access_cnt;
|
||||
|
||||
__nand_cache_t nand_w_cache[N_NAND_W_CACHE];
|
||||
__nand_cache_t nand_r_cache;
|
||||
__u32 nand_current_dev_num;
|
||||
|
||||
__u32 _get_valid_bits(__u64 secbitmap)
|
||||
{
|
||||
__u32 validbit = 0;
|
||||
|
||||
while(secbitmap)
|
||||
{
|
||||
if(secbitmap & (__u64)0x1)
|
||||
validbit++;
|
||||
secbitmap >>= 1;
|
||||
}
|
||||
|
||||
return validbit;
|
||||
}
|
||||
|
||||
__u32 _get_first_valid_bit(__u64 secbitmap)
|
||||
{
|
||||
__u32 firstbit = 0;
|
||||
|
||||
while(!(secbitmap & (__u64)0x1))
|
||||
{
|
||||
secbitmap >>= 1;
|
||||
firstbit++;
|
||||
}
|
||||
|
||||
return firstbit;
|
||||
}
|
||||
|
||||
__s32 _flush_w_cache(void)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
for(i = 0; i < N_NAND_W_CACHE; i++)
|
||||
{
|
||||
if(nand_w_cache[i].hit_page != 0xffffffff)
|
||||
{
|
||||
if(nand_w_cache[i].secbitmap != FULL_BITMAP_OF_LOGIC_PAGE)
|
||||
LML_PageRead(nand_w_cache[i].hit_page,(nand_w_cache[i].secbitmap ^ FULL_BITMAP_OF_LOGIC_PAGE)&FULL_BITMAP_OF_LOGIC_PAGE,nand_w_cache[i].data);
|
||||
|
||||
LML_PageWrite(nand_w_cache[i].hit_page,FULL_BITMAP_OF_LOGIC_PAGE,nand_w_cache[i].data);
|
||||
|
||||
|
||||
/*disable read cache with current page*/
|
||||
if (nand_r_cache.hit_page == nand_w_cache[i].hit_page){
|
||||
nand_r_cache.hit_page = 0xffffffff;
|
||||
nand_r_cache.secbitmap = 0;
|
||||
}
|
||||
|
||||
|
||||
nand_w_cache[i].hit_page = 0xffffffff;
|
||||
nand_w_cache[i].secbitmap = 0;
|
||||
nand_w_cache[i].access_count = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
__s32 _flush_w_cache_simple(__u32 i)
|
||||
{
|
||||
if(nand_w_cache[i].hit_page != 0xffffffff)
|
||||
{
|
||||
if(nand_w_cache[i].secbitmap != FULL_BITMAP_OF_LOGIC_PAGE)
|
||||
LML_PageRead(nand_w_cache[i].hit_page,(nand_w_cache[i].secbitmap ^ FULL_BITMAP_OF_LOGIC_PAGE)&FULL_BITMAP_OF_LOGIC_PAGE,nand_w_cache[i].data);
|
||||
|
||||
LML_PageWrite(nand_w_cache[i].hit_page,FULL_BITMAP_OF_LOGIC_PAGE,nand_w_cache[i].data);
|
||||
|
||||
|
||||
/*disable read cache with current page*/
|
||||
if (nand_r_cache.hit_page == nand_w_cache[i].hit_page){
|
||||
nand_r_cache.hit_page = 0xffffffff;
|
||||
nand_r_cache.secbitmap = 0;
|
||||
}
|
||||
|
||||
nand_w_cache[i].hit_page = 0xffffffff;
|
||||
nand_w_cache[i].secbitmap = 0;
|
||||
nand_w_cache[i].access_count = 0;
|
||||
nand_w_cache[i].dev_num= 0xffffffff;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
__s32 NAND_CacheFlush(void)
|
||||
{
|
||||
//__u32 i;
|
||||
|
||||
_flush_w_cache();
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
__s32 NAND_CacheFlushDev(__u32 dev_num)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
//printk("Nand Flush Dev: 0x%x\n", dev_num);
|
||||
for(i = 0; i < N_NAND_W_CACHE; i++)
|
||||
{
|
||||
if(nand_w_cache[i].dev_num == dev_num)
|
||||
{
|
||||
//printk("nand flush cache 0x%x\n", i);
|
||||
_flush_w_cache_simple(i);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void _get_data_from_cache(__u32 blk, __u32 nblk, void *buf)
|
||||
{
|
||||
__u32 i;
|
||||
__u32 sec;
|
||||
__u32 page,SecWithinPage;
|
||||
__u64 SecBitmap;
|
||||
|
||||
for(sec = blk; sec < blk + nblk; sec++)
|
||||
{
|
||||
SecWithinPage = sec % SECTOR_CNT_OF_LOGIC_PAGE;
|
||||
SecBitmap = ((__u64)1 << SecWithinPage);
|
||||
page = sec / SECTOR_CNT_OF_LOGIC_PAGE;
|
||||
for (i = 0; i < N_NAND_W_CACHE; i++)
|
||||
{
|
||||
if ((nand_w_cache[i].hit_page == page) && (nand_w_cache[i].secbitmap & SecBitmap))
|
||||
{
|
||||
MEMCPY((__u8 *)buf + (sec - blk) * 512, nand_w_cache[i].data + SecWithinPage * 512,512);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _get_one_page(__u32 page,__u64 SecBitmap,__u8 *data)
|
||||
{
|
||||
__u32 i;
|
||||
__u8 *tmp = data;
|
||||
|
||||
|
||||
if(page == nand_r_cache.hit_page)
|
||||
{
|
||||
for(i = 0;i < SECTOR_CNT_OF_LOGIC_PAGE; i++)
|
||||
{
|
||||
if(SecBitmap & ((__u64)1<<i))
|
||||
{
|
||||
MEMCPY(tmp + (i<<9),nand_r_cache.data + (i<<9),512);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if(SecBitmap == FULL_BITMAP_OF_LOGIC_PAGE)
|
||||
{
|
||||
LML_PageRead(page,FULL_BITMAP_OF_LOGIC_PAGE,tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
LML_PageRead(page,FULL_BITMAP_OF_LOGIC_PAGE,nand_r_cache.data);
|
||||
nand_r_cache.hit_page = page;
|
||||
nand_r_cache.secbitmap = FULL_BITMAP_OF_LOGIC_PAGE;
|
||||
|
||||
for(i = 0;i < SECTOR_CNT_OF_LOGIC_PAGE; i++)
|
||||
{
|
||||
if(SecBitmap & ((__u64)1<<i))
|
||||
{
|
||||
MEMCPY(tmp + (i<<9),nand_r_cache.data + (i<<9),512);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SecBitmap = 0;
|
||||
}
|
||||
|
||||
__s32 NAND_CacheRead(__u32 blk, __u32 nblk, void *buf)
|
||||
{
|
||||
__u32 nSector,StartSec;
|
||||
__u32 page;
|
||||
__u32 SecWithinPage;
|
||||
__u64 SecBitmap;
|
||||
__u8 *pdata;
|
||||
|
||||
nSector = nblk;
|
||||
StartSec = blk;
|
||||
SecBitmap = 0;
|
||||
page = 0xffffffff;
|
||||
pdata = (__u8 *)buf;
|
||||
|
||||
/*combind sectors to pages*/
|
||||
while(nSector)
|
||||
{
|
||||
SecWithinPage = StartSec % SECTOR_CNT_OF_LOGIC_PAGE;
|
||||
SecBitmap |= ((__u64)1 << SecWithinPage);
|
||||
page = StartSec / SECTOR_CNT_OF_LOGIC_PAGE;
|
||||
|
||||
/*close page if last sector*/
|
||||
if (SecWithinPage == (SECTOR_CNT_OF_LOGIC_PAGE - 1))
|
||||
{
|
||||
|
||||
__u8 *tmp = pdata + 512 - 512*_get_valid_bits(SecBitmap) - 512 * _get_first_valid_bit(SecBitmap);
|
||||
_get_one_page(page, SecBitmap, tmp);
|
||||
SecBitmap = 0;
|
||||
}
|
||||
|
||||
/*reset variable*/
|
||||
nSector--;
|
||||
StartSec++;
|
||||
pdata += 512;
|
||||
}
|
||||
|
||||
/*fill opened page*/
|
||||
if (SecBitmap)
|
||||
{
|
||||
__u8 *tmp = pdata - 512*_get_valid_bits(SecBitmap) - 512 * _get_first_valid_bit(SecBitmap);
|
||||
_get_one_page(page, SecBitmap, tmp);
|
||||
}
|
||||
|
||||
/*renew data from cache*/
|
||||
_get_data_from_cache(blk,nblk,buf);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
__s32 _fill_nand_cache(__u32 page, __u64 secbitmap, __u8 *pdata)
|
||||
{
|
||||
__u8 hit;
|
||||
__u8 i;
|
||||
__u8 pos = 0xff;
|
||||
|
||||
g_w_access_cnt++;
|
||||
|
||||
hit = 0;
|
||||
|
||||
for (i = 0; i < N_NAND_W_CACHE; i++)
|
||||
{
|
||||
/*merge data if cache hit*/
|
||||
if (nand_w_cache[i].hit_page == page){
|
||||
hit = 1;
|
||||
MEMCPY(nand_w_cache[i].data + 512 * _get_first_valid_bit(secbitmap),pdata, 512 * _get_valid_bits(secbitmap));
|
||||
nand_w_cache[i].secbitmap |= secbitmap;
|
||||
nand_w_cache[i].access_count = g_w_access_cnt;
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*post data if cache miss*/
|
||||
if (!hit)
|
||||
{
|
||||
/*find cache to post*/
|
||||
for (i = 0; i < N_NAND_W_CACHE; i++)
|
||||
{
|
||||
if (nand_w_cache[i].hit_page == 0xffffffff)
|
||||
{
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == 0xff)
|
||||
{
|
||||
__u32 access_cnt = nand_w_cache[0].access_count;
|
||||
pos = 0;
|
||||
|
||||
for (i = 1; i < N_NAND_W_CACHE; i++)
|
||||
{
|
||||
if (access_cnt > nand_w_cache[i].access_count)
|
||||
{
|
||||
pos = i;
|
||||
access_cnt = nand_w_cache[i].access_count;
|
||||
}
|
||||
|
||||
if((nand_w_cache[i].hit_page == page-1)&&(page>0))
|
||||
{
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(nand_w_cache[pos].secbitmap != FULL_BITMAP_OF_LOGIC_PAGE)
|
||||
LML_PageRead(nand_w_cache[pos].hit_page,nand_w_cache[pos].secbitmap ^ FULL_BITMAP_OF_LOGIC_PAGE,nand_w_cache[pos].data);
|
||||
|
||||
LML_PageWrite(nand_w_cache[pos].hit_page, FULL_BITMAP_OF_LOGIC_PAGE, nand_w_cache[pos].data);
|
||||
nand_w_cache[pos].access_count = 0;
|
||||
|
||||
//add by penggang
|
||||
/*disable read cache with current page*/
|
||||
if (nand_r_cache.hit_page == nand_w_cache[pos].hit_page){
|
||||
nand_r_cache.hit_page = 0xffffffff;
|
||||
nand_r_cache.secbitmap = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*merge data*/
|
||||
MEMCPY(nand_w_cache[pos].data + 512 * _get_first_valid_bit(secbitmap),pdata, 512 * _get_valid_bits(secbitmap));
|
||||
nand_w_cache[pos].hit_page = page;
|
||||
nand_w_cache[pos].secbitmap = secbitmap;
|
||||
nand_w_cache[pos].access_count = g_w_access_cnt;
|
||||
nand_w_cache[i].dev_num= nand_current_dev_num;
|
||||
|
||||
}
|
||||
|
||||
if (g_w_access_cnt == 0)
|
||||
{
|
||||
for (i = 0; i < N_NAND_W_CACHE; i++)
|
||||
nand_w_cache[i].access_count = 0;
|
||||
g_w_access_cnt = 1;
|
||||
nand_w_cache[pos].access_count = g_w_access_cnt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__s32 NAND_CacheWrite(__u32 blk, __u32 nblk, void *buf)
|
||||
{
|
||||
__u32 nSector,StartSec;
|
||||
__u32 page;
|
||||
__u32 SecWithinPage;
|
||||
__u64 SecBitmap;
|
||||
__u32 i;
|
||||
__u8 *pdata;
|
||||
//__u32 hit = 0;
|
||||
|
||||
nSector = nblk;
|
||||
StartSec = blk;
|
||||
SecBitmap = 0;
|
||||
page = 0xffffffff;
|
||||
pdata = (__u8 *)buf;
|
||||
|
||||
/*combind sectors to pages*/
|
||||
while(nSector)
|
||||
{
|
||||
SecWithinPage = StartSec % SECTOR_CNT_OF_LOGIC_PAGE;
|
||||
SecBitmap |= ((__u64)1 << SecWithinPage);
|
||||
page = StartSec / SECTOR_CNT_OF_LOGIC_PAGE;
|
||||
|
||||
|
||||
/*close page if last sector*/
|
||||
if (SecWithinPage == (SECTOR_CNT_OF_LOGIC_PAGE - 1))
|
||||
{
|
||||
/*write to nand flash if align one logic page*/
|
||||
if(SecBitmap == FULL_BITMAP_OF_LOGIC_PAGE)
|
||||
{
|
||||
/*disable write cache with current page*/
|
||||
for (i = 0; i < N_NAND_W_CACHE; i++)
|
||||
{
|
||||
if(nand_w_cache[i].hit_page == page)
|
||||
{
|
||||
nand_w_cache[i].hit_page = 0xffffffff;
|
||||
nand_w_cache[i].secbitmap = 0;
|
||||
nand_w_cache[i].dev_num= 0xffffffff;
|
||||
//hit=1;
|
||||
}
|
||||
else if((nand_w_cache[i].hit_page == page-1)&&(page>0))
|
||||
{
|
||||
_flush_w_cache_simple(i);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*disable read cache with current page*/
|
||||
if (nand_r_cache.hit_page == page){
|
||||
nand_r_cache.hit_page = 0xffffffff;
|
||||
nand_r_cache.secbitmap = 0;
|
||||
}
|
||||
|
||||
//if(!hit)
|
||||
// _flush_w_cache();
|
||||
|
||||
LML_PageWrite(page,FULL_BITMAP_OF_LOGIC_PAGE,pdata + 512 - 512*SECTOR_CNT_OF_LOGIC_PAGE);
|
||||
}
|
||||
|
||||
/*fill to cache if unalign one logic page*/
|
||||
else
|
||||
_fill_nand_cache(page, SecBitmap, pdata + 512 - 512*_get_valid_bits(SecBitmap));
|
||||
|
||||
SecBitmap = 0;
|
||||
}
|
||||
|
||||
|
||||
/*reset variable*/
|
||||
nSector--;
|
||||
StartSec++;
|
||||
pdata += 512;
|
||||
}
|
||||
|
||||
/*fill opened page*/
|
||||
if (SecBitmap)
|
||||
_fill_nand_cache(page,SecBitmap,pdata - 512*_get_valid_bits(SecBitmap));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
__s32 NAND_CacheOpen(void)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
g_w_access_cnt = 0;
|
||||
|
||||
for(i = 0; i < N_NAND_W_CACHE; i++)
|
||||
{
|
||||
nand_w_cache[i].size = 512 * SECTOR_CNT_OF_LOGIC_PAGE;
|
||||
nand_w_cache[i].data = MALLOC(nand_w_cache[i].size);
|
||||
nand_w_cache[i].hit_page = 0xffffffff;
|
||||
nand_w_cache[i].secbitmap = 0;
|
||||
nand_w_cache[i].access_count = 0;
|
||||
nand_w_cache[i].dev_num= 0xffffffff;
|
||||
}
|
||||
|
||||
nand_r_cache.size = 512 * SECTOR_CNT_OF_LOGIC_PAGE;
|
||||
nand_r_cache.data = MALLOC(nand_r_cache.size);
|
||||
nand_r_cache.hit_page = 0xffffffff;
|
||||
nand_r_cache.secbitmap = 0;
|
||||
nand_r_cache.access_count = 0;
|
||||
nand_r_cache.dev_num= 0xffffffff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__s32 NAND_CacheClose(void)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
NAND_CacheFlush();
|
||||
|
||||
#ifdef NAND_W_CACHE_EN
|
||||
for(i = 0; i < N_NAND_W_CACHE; i++)
|
||||
FREE(nand_w_cache[i].data,nand_w_cache[i].size);
|
||||
#endif
|
||||
FREE(nand_r_cache.data,nand_r_cache.size);
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,996 +0,0 @@
|
||||
/*********************************************************************************
|
||||
* NAND FLASH DRIVER
|
||||
* (c) Copyright 2008, SoftWinners Co,Ld.
|
||||
* All Right Reserved
|
||||
*file : mapping.c
|
||||
*description : this file create a interface to mange map table:
|
||||
*history :
|
||||
* v0.1 2008-04-09 Richard
|
||||
* support all kinds of access way of block map and page map.
|
||||
**********************************************************************************/
|
||||
|
||||
#include "../include/nand_logic.h"
|
||||
|
||||
extern struct __NandDriverGlobal_t NandDriverInfo;
|
||||
|
||||
struct __BlkMapTblCachePool_t BlkMapTblCachePool;
|
||||
struct __PageMapTblCachePool_t PageMapTblCachePool;
|
||||
|
||||
void dump(void *buf, __u32 len , __u8 nbyte,__u8 linelen)
|
||||
{
|
||||
__u32 i;
|
||||
__u32 tmplen = len/nbyte;
|
||||
|
||||
PRINT("/********************************************/\n");
|
||||
|
||||
for (i = 0; i < tmplen; i++)
|
||||
{
|
||||
if (nbyte == 1)
|
||||
PRINT("%x ",((__u8 *)buf)[i]);
|
||||
else if (nbyte == 2)
|
||||
PRINT("%x ",((__u16 *)buf)[i]);
|
||||
else if (nbyte == 4)
|
||||
PRINT("%x ",((__u32 *)buf)[i]);
|
||||
else
|
||||
break;
|
||||
|
||||
if(i%linelen == (linelen - 1))
|
||||
PRINT("\n");
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CALCULATE THE CHECKSUM FOR A MAPPING TABLE
|
||||
*
|
||||
*Description: Calculate the checksum for a mapping table, based on word.
|
||||
*
|
||||
*Arguments : pTblBuf the pointer to the table data buffer;
|
||||
* nLength the size of the table data, based on word.
|
||||
*
|
||||
*Return : table checksum;
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
static __u32 _GetTblCheckSum(__u32 *pTblBuf, __u32 nLength)
|
||||
{
|
||||
__u32 i;
|
||||
__u32 tmpCheckSum = 0;
|
||||
|
||||
for(i= 0; i<nLength; i++)
|
||||
{
|
||||
tmpCheckSum += pTblBuf[i];
|
||||
}
|
||||
|
||||
return tmpCheckSum;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* INIT PAGE MAPPING TABLE CACHE
|
||||
*
|
||||
*Description: Init page mapping table cache.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : init result;
|
||||
* = 0 init page mapping table cache successful;
|
||||
* = -1 init page mapping table cache failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PMM_InitMapTblCache(void)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
PAGE_MAP_CACHE_POOL = &PageMapTblCachePool;
|
||||
|
||||
for(i = 0; i<PAGE_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].AccessCnt = 0;
|
||||
PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].DirtyFlag = 0;
|
||||
PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].LogBlkPst = 0xff;
|
||||
PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].ZoneNum = 0xff;
|
||||
PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].PageMapTbl = \
|
||||
(void *)MALLOC(PAGE_CNT_OF_SUPER_BLK * sizeof(struct __PageMapTblItem_t));
|
||||
if (!PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].PageMapTbl)
|
||||
{
|
||||
return -ERR_MAPPING;
|
||||
}
|
||||
}
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CALCUALTE PAGE MAPPING TABLE ACCESS COUNT
|
||||
*
|
||||
*Description: Calculate page mapping table access count for table cache switch.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : none.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
static void _CalPageTblAccessCount(void)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
for(i=0; i<PAGE_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].AccessCnt++;
|
||||
}
|
||||
|
||||
PAGE_MAP_CACHE->AccessCnt = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* EXIT PAGE MAPPING TABLE CACHE
|
||||
*
|
||||
*Description: Exit page mapping table cache.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : exit result;
|
||||
* = 0 exit page mapping table cache successful;
|
||||
* = -1 exit page mapping table cache failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PMM_ExitMapTblCache(void)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
for (i = 0; i<PAGE_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
FREE(PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].PageMapTbl,PAGE_CNT_OF_SUPER_BLK * sizeof(struct __PageMapTblItem_t));
|
||||
}
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*the page map table in the cahce pool? cahce hit?*/
|
||||
static __s32 _page_map_tbl_cache_hit(__u32 nLogBlkPst)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
for(i=0; i<PAGE_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
if((PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].ZoneNum == CUR_MAP_ZONE)\
|
||||
&& (PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].LogBlkPst == nLogBlkPst))
|
||||
{
|
||||
|
||||
PAGE_MAP_CACHE = &(PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i]);
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return NAND_OP_FALSE;
|
||||
|
||||
}
|
||||
|
||||
/*find post cache, clear cache or LRU cache */
|
||||
static __u32 _find_page_tbl_post_location(void)
|
||||
{
|
||||
__u32 i, location = 0;
|
||||
__u16 access_cnt;
|
||||
|
||||
/*try to find clear cache*/
|
||||
for(i=0; i<PAGE_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
if(PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].ZoneNum == 0xff)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/*try to find least used cache recently*/
|
||||
access_cnt = PAGE_MAP_CACHE_POOL->PageMapTblCachePool[0].AccessCnt;
|
||||
|
||||
for (i = 1; i < PAGE_MAP_TBL_CACHE_CNT; i++){
|
||||
if (access_cnt < PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].AccessCnt){
|
||||
location = i;
|
||||
access_cnt = PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].AccessCnt;
|
||||
}
|
||||
}
|
||||
|
||||
/*clear access counter*/
|
||||
for (i = 0; i < PAGE_MAP_TBL_CACHE_CNT; i++)
|
||||
PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].AccessCnt = 0;
|
||||
|
||||
return location;
|
||||
|
||||
}
|
||||
|
||||
static __s32 _write_back_page_map_tbl(__u32 nLogBlkPst)
|
||||
{
|
||||
__u16 TablePage;
|
||||
__u32 TableBlk;
|
||||
struct __NandUserData_t UserData[2];
|
||||
struct __PhysicOpPara_t param;
|
||||
struct __SuperPhyBlkType_t BadBlk,NewBlk;
|
||||
|
||||
|
||||
/*check page poisition, merge if no free page*/
|
||||
TablePage = LOG_BLK_TBL[nLogBlkPst].LastUsedPage + 1;
|
||||
TableBlk = LOG_BLK_TBL[nLogBlkPst].PhyBlk.PhyBlkNum;
|
||||
if (TablePage == PAGE_CNT_OF_SUPER_BLK){
|
||||
/*block id full,need merge*/
|
||||
if (LML_MergeLogBlk(SPECIAL_MERGE_MODE,LOG_BLK_TBL[nLogBlkPst].LogicBlkNum)){
|
||||
MAPPING_ERR("write back page tbl : merge err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
if (PAGE_MAP_CACHE->ZoneNum != 0xff){
|
||||
/*move merge*/
|
||||
TablePage = LOG_BLK_TBL[nLogBlkPst].LastUsedPage + 1;
|
||||
TableBlk = LOG_BLK_TBL[nLogBlkPst].PhyBlk.PhyBlkNum;
|
||||
}
|
||||
else
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
rewrite:
|
||||
//PRINT("-------------------write back page tbl for blk %x\n",TableBlk);
|
||||
/*write page map table*/
|
||||
MEMSET((void *)&UserData,0xff,sizeof(struct __NandUserData_t) * 2);
|
||||
UserData[0].PageStatus = 0xaa;
|
||||
MEMSET(LML_PROCESS_TBL_BUF,0xff,SECTOR_CNT_OF_SUPER_PAGE * SECTOR_SIZE);
|
||||
|
||||
if(PAGE_CNT_OF_SUPER_BLK >= 512)
|
||||
{
|
||||
__u32 page;
|
||||
|
||||
for(page = 0; page < PAGE_CNT_OF_SUPER_BLK; page++)
|
||||
*((__u16 *)LML_PROCESS_TBL_BUF + page) = PAGE_MAP_TBL[page].PhyPageNum;
|
||||
|
||||
((__u32 *)LML_PROCESS_TBL_BUF)[511] = \
|
||||
_GetTblCheckSum((__u32 *)LML_PROCESS_TBL_BUF, PAGE_CNT_OF_SUPER_BLK*2/(sizeof (__u32)));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
MEMCPY(LML_PROCESS_TBL_BUF, PAGE_MAP_TBL,PAGE_CNT_OF_SUPER_BLK*sizeof(struct __PageMapTblItem_t));
|
||||
((__u32 *)LML_PROCESS_TBL_BUF)[511] = \
|
||||
_GetTblCheckSum((__u32 *)LML_PROCESS_TBL_BUF, PAGE_CNT_OF_SUPER_BLK*sizeof(struct __PageMapTblItem_t)/(sizeof (__u32)));
|
||||
}
|
||||
|
||||
param.MDataPtr = LML_PROCESS_TBL_BUF;
|
||||
param.SDataPtr = (void *)&UserData;
|
||||
param.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
|
||||
//rewrite:
|
||||
LML_CalculatePhyOpPar(¶m, CUR_MAP_ZONE, TableBlk, TablePage);
|
||||
LML_VirtualPageWrite(¶m);
|
||||
if (NAND_OP_TRUE != PHY_SynchBank(param.BankNum, SYNC_CHIP_MODE)){
|
||||
BadBlk.PhyBlkNum = TableBlk;
|
||||
if (NAND_OP_TRUE != LML_BadBlkManage(&BadBlk,CUR_MAP_ZONE,TablePage,&NewBlk)){
|
||||
MAPPING_ERR("write page map table : bad block mange err after write\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
TableBlk = NewBlk.PhyBlkNum;
|
||||
LOG_BLK_TBL[nLogBlkPst].PhyBlk = NewBlk;
|
||||
goto rewrite;
|
||||
}
|
||||
|
||||
LOG_BLK_TBL[nLogBlkPst].LastUsedPage = TablePage;
|
||||
PAGE_MAP_CACHE->ZoneNum = 0xff;
|
||||
PAGE_MAP_CACHE->LogBlkPst = 0xff;
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
|
||||
}
|
||||
|
||||
static __s32 _rebuild_page_map_tbl(__u32 nLogBlkPst)
|
||||
{
|
||||
__s32 ret;
|
||||
__u16 TablePage;
|
||||
__u32 TableBlk;
|
||||
__u16 logicpagenum;
|
||||
//__u8 status;
|
||||
struct __NandUserData_t UserData[2];
|
||||
struct __PhysicOpPara_t param;
|
||||
|
||||
MEMSET(PAGE_MAP_TBL,0xff, PAGE_CNT_OF_SUPER_BLK*sizeof(struct __PageMapTblItem_t));
|
||||
TableBlk = LOG_BLK_TBL[nLogBlkPst].PhyBlk.PhyBlkNum;
|
||||
|
||||
param.MDataPtr = LML_PROCESS_TBL_BUF;
|
||||
param.SDataPtr = (void *)&UserData;
|
||||
param.SectBitmap = 0x3;
|
||||
|
||||
//PRINT("-----------------------rebuild page table for blk %x\n",TableBlk);
|
||||
|
||||
for(TablePage = 0; TablePage < PAGE_CNT_OF_SUPER_BLK; TablePage++){
|
||||
LML_CalculatePhyOpPar(¶m, CUR_MAP_ZONE, TableBlk, TablePage);
|
||||
ret = LML_VirtualPageRead(¶m);
|
||||
if (ret < 0){
|
||||
MAPPING_ERR("rebuild logic block %x page map table : read err\n",LOG_BLK_TBL[nLogBlkPst].LogicBlkNum);
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
//status = UserData[0].PageStatus;
|
||||
logicpagenum = UserData[0].LogicPageNum;
|
||||
|
||||
//if(((!TablePage || (status == 0x55))) && (logicpagenum != 0xffff) && (logicpagenum < PAGE_CNT_OF_SUPER_BLK)) /*legal page*/
|
||||
if((logicpagenum != 0xffff) && (logicpagenum < PAGE_CNT_OF_SUPER_BLK)) /*legal page*/
|
||||
{
|
||||
PAGE_MAP_TBL[logicpagenum].PhyPageNum = TablePage; /*l2p:logical to physical*/
|
||||
}
|
||||
}
|
||||
|
||||
PAGE_MAP_CACHE->DirtyFlag = 1;
|
||||
BMM_SetDirtyFlag();
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
static __s32 _read_page_map_tbl(__u32 nLogBlkPst)
|
||||
{
|
||||
__s32 ret;
|
||||
__u16 TablePage;
|
||||
__u32 TableBlk, checksum;
|
||||
__u16 logicpagenum;
|
||||
__u8 status;
|
||||
struct __NandUserData_t UserData[2];
|
||||
struct __PhysicOpPara_t param;
|
||||
|
||||
|
||||
/*check page poisition, merge if no free page*/
|
||||
TablePage = LOG_BLK_TBL[nLogBlkPst].LastUsedPage;
|
||||
TableBlk = LOG_BLK_TBL[nLogBlkPst].PhyBlk.PhyBlkNum;
|
||||
|
||||
if (TablePage == 0xffff){
|
||||
/*log block is empty*/
|
||||
MEMSET(PAGE_MAP_TBL, 0xff,PAGE_CNT_OF_SUPER_BLK*sizeof(struct __PageMapTblItem_t) );
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
/*read page map table*/
|
||||
param.MDataPtr = LML_PROCESS_TBL_BUF;
|
||||
param.SDataPtr = (void *)&UserData;
|
||||
param.SectBitmap = 0xf;
|
||||
|
||||
LML_CalculatePhyOpPar(¶m, CUR_MAP_ZONE, TableBlk, TablePage);
|
||||
ret = LML_VirtualPageRead(¶m);
|
||||
|
||||
if(PAGE_CNT_OF_SUPER_BLK >= 512)
|
||||
{
|
||||
checksum = _GetTblCheckSum((__u32 *)LML_PROCESS_TBL_BUF, \
|
||||
PAGE_CNT_OF_SUPER_BLK*2/sizeof(__u32));
|
||||
}
|
||||
else
|
||||
{
|
||||
checksum = _GetTblCheckSum((__u32 *)LML_PROCESS_TBL_BUF, \
|
||||
PAGE_CNT_OF_SUPER_BLK*sizeof(struct __PageMapTblItem_t)/sizeof(__u32));
|
||||
}
|
||||
|
||||
status = UserData[0].PageStatus;
|
||||
logicpagenum = UserData[0].LogicPageNum;
|
||||
|
||||
if((ret < 0) || (status != 0xaa) || (logicpagenum != 0xffff) || (checksum != ((__u32 *)LML_PROCESS_TBL_BUF)[511]))
|
||||
{
|
||||
if(NAND_OP_TRUE != _rebuild_page_map_tbl(nLogBlkPst))
|
||||
{
|
||||
MAPPING_ERR("rebuild page map table err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(PAGE_CNT_OF_SUPER_BLK >= 512)
|
||||
{
|
||||
__u32 page;
|
||||
|
||||
for(page = 0; page < PAGE_CNT_OF_SUPER_BLK; page++)
|
||||
PAGE_MAP_TBL[page].PhyPageNum = *((__u16 *)LML_PROCESS_TBL_BUF + page);
|
||||
}
|
||||
else
|
||||
MEMCPY(PAGE_MAP_TBL,LML_PROCESS_TBL_BUF, PAGE_CNT_OF_SUPER_BLK*sizeof(struct __PageMapTblItem_t));
|
||||
}
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*post current zone map table in cache*/
|
||||
static __s32 _page_map_tbl_cache_post(__u32 nLogBlkPst)
|
||||
{
|
||||
__u8 poisition;
|
||||
__u8 i;
|
||||
|
||||
struct __BlkMapTblCache_t *TmpBmt = BLK_MAP_CACHE;
|
||||
|
||||
/*find the cache to be post*/
|
||||
poisition = _find_page_tbl_post_location();
|
||||
PAGE_MAP_CACHE = &(PAGE_MAP_CACHE_POOL->PageMapTblCachePool[poisition]);
|
||||
|
||||
if (PAGE_MAP_CACHE->DirtyFlag && (PAGE_MAP_CACHE->ZoneNum != 0xff)){
|
||||
/*write back page map table*/
|
||||
if (PAGE_MAP_CACHE->ZoneNum != TmpBmt->ZoneNum){
|
||||
for (i = 0; i < BLOCK_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
if (BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].ZoneNum == PAGE_MAP_CACHE->ZoneNum){
|
||||
BLK_MAP_CACHE = &(BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == BLOCK_MAP_TBL_CACHE_CNT){
|
||||
MAPPING_ERR("_page_map_tbl_cache_post : position %d ,page map zone %d,blk map zone %d\n",
|
||||
poisition,PAGE_MAP_CACHE->ZoneNum,BLK_MAP_CACHE->ZoneNum);
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
/* write back new table in flash if dirty*/
|
||||
BMM_SetDirtyFlag();
|
||||
if (NAND_OP_TRUE != _write_back_page_map_tbl(PAGE_MAP_CACHE->LogBlkPst)){
|
||||
MAPPING_ERR("write back page tbl err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
BLK_MAP_CACHE = TmpBmt;
|
||||
|
||||
}
|
||||
|
||||
PAGE_MAP_CACHE->DirtyFlag = 0;
|
||||
|
||||
/*fetch current page map table*/
|
||||
if (NAND_OP_TRUE != _read_page_map_tbl(nLogBlkPst)){
|
||||
MAPPING_ERR("read page map tbl err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
PAGE_MAP_CACHE->ZoneNum = CUR_MAP_ZONE;
|
||||
PAGE_MAP_CACHE->LogBlkPst = nLogBlkPst;
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SWITCH PAGE MAPPING TABLE
|
||||
*
|
||||
*Description: Switch page mapping table cache.
|
||||
*
|
||||
*Arguments : nLogBlkPst the position of the log block in the log block table.
|
||||
*
|
||||
*Return : switch result;
|
||||
* = 0 switch table successful;
|
||||
* = -1 switch table failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 PMM_SwitchMapTbl(__u32 nLogBlkPst)
|
||||
{
|
||||
__s32 result = NAND_OP_TRUE;
|
||||
if (NAND_OP_TRUE !=_page_map_tbl_cache_hit(nLogBlkPst))
|
||||
{
|
||||
result = (_page_map_tbl_cache_post(nLogBlkPst));
|
||||
}
|
||||
|
||||
_CalPageTblAccessCount();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* INIT BLOCK MAPPING TABLE CACHE
|
||||
*
|
||||
*Description: Initiate block mapping talbe cache.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : init result;
|
||||
* = 0 init successful;
|
||||
* = -1 init failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_InitMapTblCache(void)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
BLK_MAP_CACHE_POOL = &BlkMapTblCachePool;
|
||||
|
||||
BLK_MAP_CACHE_POOL->LogBlkAccessTimer = 0x0;
|
||||
BLK_MAP_CACHE_POOL->SuperBlkEraseCnt = 0x0;
|
||||
|
||||
/*init block map table cache*/
|
||||
for(i=0; i<BLOCK_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
//init the parmater for block mapping table cache management
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].ZoneNum = 0xff;
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].DirtyFlag = 0x0;
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].AccessCnt = 0x0;
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].LastFreeBlkPst = 0xff;
|
||||
|
||||
//request buffer for data block table and free block table
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].DataBlkTbl = \
|
||||
(struct __SuperPhyBlkType_t *)MALLOC(sizeof(struct __SuperPhyBlkType_t)*BLOCK_CNT_OF_ZONE);
|
||||
if(NULL == BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].DataBlkTbl)
|
||||
{
|
||||
MAPPING_ERR("BMM_InitMapTblCache : allocate memory err\n");
|
||||
return -ERR_MALLOC;
|
||||
}
|
||||
//set free block table pointer
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].FreeBlkTbl = \
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].DataBlkTbl + DATA_BLK_CNT_OF_ZONE;
|
||||
|
||||
//request buffer for log block table
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].LogBlkTbl = \
|
||||
(struct __LogBlkType_t *)MALLOC(sizeof(struct __LogBlkType_t)*LOG_BLK_CNT_OF_ZONE);
|
||||
if(NULL == BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].LogBlkTbl)
|
||||
{
|
||||
MAPPING_ERR("BMM_InitMapTblCache : allocate memory err\n");
|
||||
FREE(BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].DataBlkTbl,sizeof(struct __SuperPhyBlkType_t)*BLOCK_CNT_OF_ZONE);
|
||||
return -ERR_MALLOC;
|
||||
}
|
||||
}
|
||||
|
||||
/*init log block access time*/
|
||||
MEMSET(BLK_MAP_CACHE_POOL->LogBlkAccessAge, 0x0, MAX_LOG_BLK_CNT);
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CALCULATE BLOCK MAPPING TABLE ACCESS COUNT
|
||||
*
|
||||
*Description: Calculate block mapping table access count for cache switch.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : none;
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
static void _CalBlkTblAccessCount(void)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
for (i=0; i<BLOCK_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].AccessCnt++;
|
||||
}
|
||||
|
||||
BLK_MAP_CACHE->AccessCnt = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* BLOCK MAPPING TABLE CACHE EXIT
|
||||
*
|
||||
*Description: exit block mapping table cache.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : exit result;
|
||||
* = 0 exit successful;
|
||||
* = -1 exit failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_ExitMapTblCache(void)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
for (i=0; i<BLOCK_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
|
||||
FREE(BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].DataBlkTbl,sizeof(struct __SuperPhyBlkType_t)*BLOCK_CNT_OF_ZONE);
|
||||
FREE(BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].LogBlkTbl,sizeof(struct __LogBlkType_t)*LOG_BLK_CNT_OF_ZONE);
|
||||
}
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
/*the zone table in the cahce pool? cahce hit?*/
|
||||
static __s32 _blk_map_tbl_cache_hit(__u32 nZone)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
for (i = 0; i < BLOCK_MAP_TBL_CACHE_CNT; i++){
|
||||
if (BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].ZoneNum == nZone){
|
||||
BLK_MAP_CACHE = &(BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i]);
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return NAND_OP_FALSE;
|
||||
|
||||
}
|
||||
|
||||
/*find post cache, clear cache or LRU cache */
|
||||
static __u32 _find_blk_tbl_post_location(void)
|
||||
{
|
||||
__u32 i;
|
||||
__u8 location;
|
||||
__u16 access_cnt ;
|
||||
|
||||
/*try to find clear cache*/
|
||||
for (i = 0; i < BLOCK_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
if (BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].ZoneNum == 0xff)
|
||||
return i;
|
||||
}
|
||||
/*try to find least used cache recently*/
|
||||
location = 0;
|
||||
access_cnt = BLK_MAP_CACHE_POOL->BlkMapTblCachePool[0].AccessCnt;
|
||||
|
||||
for (i = 1; i < BLOCK_MAP_TBL_CACHE_CNT; i++){
|
||||
if (access_cnt < BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].AccessCnt){
|
||||
location = i;
|
||||
access_cnt = BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].AccessCnt;
|
||||
}
|
||||
}
|
||||
|
||||
/*clear access counter*/
|
||||
for (i = 0; i < BLOCK_MAP_TBL_CACHE_CNT; i++)
|
||||
BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].AccessCnt = 0;
|
||||
|
||||
return location;
|
||||
|
||||
}
|
||||
|
||||
static __s32 _write_back_all_page_map_tbl(__u8 nZone)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
for(i=0; i<PAGE_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
if((PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].ZoneNum == nZone)\
|
||||
&& (PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i].DirtyFlag == 1))
|
||||
{
|
||||
PAGE_MAP_CACHE = &(PAGE_MAP_CACHE_POOL->PageMapTblCachePool[i]);
|
||||
if (NAND_OP_TRUE != _write_back_page_map_tbl(PAGE_MAP_CACHE->LogBlkPst))
|
||||
{
|
||||
MAPPING_ERR("write back all page tbl : write page map table err \n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
PAGE_MAP_CACHE->DirtyFlag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*write block map table to flash*/
|
||||
static __s32 _write_back_block_map_tbl(__u8 nZone)
|
||||
{
|
||||
__s32 TablePage;
|
||||
__u32 TableBlk;
|
||||
struct __NandUserData_t UserData[2];
|
||||
struct __PhysicOpPara_t param;
|
||||
struct __SuperPhyBlkType_t BadBlk,NewBlk;
|
||||
|
||||
/*write back all page map table within this zone*/
|
||||
if (NAND_OP_TRUE != _write_back_all_page_map_tbl(nZone)){
|
||||
MAPPING_ERR("write back all page map tbl err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
/*set table block number and table page number*/
|
||||
TableBlk = NandDriverInfo.ZoneTblPstInfo[nZone].PhyBlkNum;
|
||||
TablePage = NandDriverInfo.ZoneTblPstInfo[nZone].TablePst;
|
||||
if(TablePage >= PAGE_CNT_OF_SUPER_BLK - 4)
|
||||
{
|
||||
if(NAND_OP_TRUE != LML_VirtualBlkErase(nZone, TableBlk))
|
||||
{
|
||||
BadBlk.PhyBlkNum = TableBlk;
|
||||
|
||||
if(NAND_OP_TRUE != LML_BadBlkManage(&BadBlk,CUR_MAP_ZONE,0,&NewBlk))
|
||||
{
|
||||
MAPPING_ERR("write back block tbl : bad block manage err erase data block\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
TableBlk = NewBlk.PhyBlkNum;
|
||||
}
|
||||
TablePage = -4;
|
||||
}
|
||||
|
||||
TablePage += 4;
|
||||
|
||||
//calculate checksum for data block table and free block table
|
||||
((__u32 *)DATA_BLK_TBL)[1023] = \
|
||||
_GetTblCheckSum((__u32 *)DATA_BLK_TBL, (DATA_BLK_CNT_OF_ZONE + FREE_BLK_CNT_OF_ZONE));
|
||||
//clear full page data
|
||||
MEMSET(LML_PROCESS_TBL_BUF, 0xff, SECTOR_CNT_OF_SUPER_PAGE * SECTOR_SIZE);
|
||||
|
||||
rewrite:
|
||||
/*write back data block and free block map table*/
|
||||
MEMSET((void *)&UserData,0xff,sizeof(struct __NandUserData_t) * 2);
|
||||
MEMCPY(LML_PROCESS_TBL_BUF,DATA_BLK_TBL,2048);
|
||||
/*write page 0, need set spare info*/
|
||||
if (TablePage == 0)
|
||||
{
|
||||
UserData[0].LogicInfo = (1<<14) | ((nZone % ZONE_CNT_OF_DIE) << 10) | 0xaa ;
|
||||
}
|
||||
UserData[0].PageStatus = 0x55;
|
||||
param.MDataPtr = LML_PROCESS_TBL_BUF;
|
||||
param.SDataPtr = (void *)&UserData;
|
||||
param.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
LML_CalculatePhyOpPar(¶m, nZone, TableBlk, TablePage);
|
||||
LML_VirtualPageWrite(¶m);
|
||||
if (NAND_OP_TRUE != PHY_SynchBank(param.BankNum, SYNC_CHIP_MODE)){
|
||||
BadBlk.PhyBlkNum = TableBlk;
|
||||
if (NAND_OP_TRUE != LML_BadBlkManage(&BadBlk,nZone,0,&NewBlk)){
|
||||
MAPPING_ERR("write blk map table : bad block mange err after write\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
TableBlk = NewBlk.PhyBlkNum;
|
||||
TablePage = 0;
|
||||
goto rewrite;
|
||||
}
|
||||
|
||||
MEMCPY(LML_PROCESS_TBL_BUF, &DATA_BLK_TBL[512], 2048);
|
||||
TablePage ++;
|
||||
param.MDataPtr = LML_PROCESS_TBL_BUF;
|
||||
MEMSET((void *)&UserData,0xff,sizeof(struct __NandUserData_t) * 2);
|
||||
UserData[0].PageStatus = 0x55;
|
||||
LML_CalculatePhyOpPar(¶m, nZone, TableBlk, TablePage);
|
||||
LML_VirtualPageWrite(¶m);
|
||||
if(NAND_OP_TRUE != PHY_SynchBank(param.BankNum, SYNC_CHIP_MODE))
|
||||
{
|
||||
BadBlk.PhyBlkNum = TableBlk;
|
||||
if(NAND_OP_TRUE != LML_BadBlkManage(&BadBlk,nZone,0,&NewBlk))
|
||||
{
|
||||
MAPPING_ERR("write blk map table : bad block mange err after write\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
TableBlk = NewBlk.PhyBlkNum;
|
||||
TablePage = 0;
|
||||
goto rewrite;
|
||||
}
|
||||
|
||||
|
||||
/*write back log block map table*/
|
||||
TablePage++;
|
||||
MEMSET(LML_PROCESS_TBL_BUF, 0xff, SECTOR_CNT_OF_SUPER_PAGE * SECTOR_SIZE);
|
||||
MEMCPY(LML_PROCESS_TBL_BUF,LOG_BLK_TBL,LOG_BLK_CNT_OF_ZONE*sizeof(struct __LogBlkType_t));
|
||||
/*cal checksum*/
|
||||
((__u32 *)LML_PROCESS_TBL_BUF)[511] = \
|
||||
_GetTblCheckSum((__u32 *)LML_PROCESS_TBL_BUF, LOG_BLK_CNT_OF_ZONE*sizeof(struct __LogBlkType_t)/sizeof(__u32));
|
||||
LML_CalculatePhyOpPar(¶m, nZone, TableBlk, TablePage);
|
||||
LML_VirtualPageWrite(¶m);
|
||||
if(NAND_OP_TRUE != PHY_SynchBank(param.BankNum, SYNC_CHIP_MODE))
|
||||
{
|
||||
BadBlk.PhyBlkNum = TableBlk;
|
||||
if(NAND_OP_TRUE != LML_BadBlkManage(&BadBlk,nZone,0,&NewBlk))
|
||||
{
|
||||
MAPPING_ERR("write blk map table : bad block mange err after write\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
TableBlk = NewBlk.PhyBlkNum;
|
||||
TablePage = 0;
|
||||
goto rewrite;
|
||||
}
|
||||
|
||||
/*reset zone info*/
|
||||
NandDriverInfo.ZoneTblPstInfo[nZone].PhyBlkNum = TableBlk;
|
||||
NandDriverInfo.ZoneTblPstInfo[nZone].TablePst = TablePage - 2;
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
/* fetch block map table from flash */
|
||||
static __s32 _read_block_map_tbl(__u8 nZone)
|
||||
{
|
||||
__s32 TablePage;
|
||||
__u32 TableBlk;
|
||||
struct __PhysicOpPara_t param;
|
||||
|
||||
/*set table block number and table page number*/
|
||||
TableBlk = NandDriverInfo.ZoneTblPstInfo[nZone].PhyBlkNum;
|
||||
TablePage = NandDriverInfo.ZoneTblPstInfo[nZone].TablePst;
|
||||
|
||||
/*read data block and free block map tbl*/
|
||||
|
||||
param.MDataPtr = LML_PROCESS_TBL_BUF;
|
||||
param.SDataPtr = NULL;
|
||||
param.SectBitmap = 0xf;
|
||||
LML_CalculatePhyOpPar(¶m, nZone, TableBlk, TablePage);
|
||||
if(LML_VirtualPageRead(¶m) < 0)
|
||||
{
|
||||
MAPPING_ERR("_read_block_map_tbl :read block map table0 err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
MEMCPY(DATA_BLK_TBL,LML_PROCESS_TBL_BUF,2048);
|
||||
|
||||
TablePage++;
|
||||
param.MDataPtr = LML_PROCESS_TBL_BUF;
|
||||
LML_CalculatePhyOpPar(¶m, nZone, TableBlk, TablePage);
|
||||
if( LML_VirtualPageRead(¶m) < 0)
|
||||
{
|
||||
MAPPING_ERR("_read_block_map_tbl : read block map table1 err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
MEMCPY(&DATA_BLK_TBL[512],LML_PROCESS_TBL_BUF,2048);
|
||||
if(((__u32 *)DATA_BLK_TBL)[1023] != \
|
||||
_GetTblCheckSum((__u32 *)DATA_BLK_TBL,(DATA_BLK_CNT_OF_ZONE+FREE_BLK_CNT_OF_ZONE)))
|
||||
{
|
||||
MAPPING_ERR("_read_block_map_tbl : read data block map table checksum err\n");
|
||||
dump((void*)DATA_BLK_TBL,1024*4,4,8);
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
/*read log block table*/
|
||||
TablePage++;
|
||||
param.MDataPtr = LML_PROCESS_TBL_BUF;
|
||||
LML_CalculatePhyOpPar(¶m, nZone, TableBlk, TablePage);
|
||||
if ( LML_VirtualPageRead(¶m) < 0){
|
||||
MAPPING_ERR("_read_block_map_tbl : read block map table2 err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
if (((__u32 *)LML_PROCESS_TBL_BUF)[511] != \
|
||||
_GetTblCheckSum((__u32 *)LML_PROCESS_TBL_BUF, LOG_BLK_CNT_OF_ZONE*sizeof(struct __LogBlkType_t)/sizeof(__u32)))
|
||||
{
|
||||
MAPPING_ERR("_read_block_map_tbl : read log block table checksum err\n");
|
||||
dump((void*)LML_PROCESS_TBL_BUF,512*8,2,8);
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
MEMCPY(LOG_BLK_TBL,LML_PROCESS_TBL_BUF,LOG_BLK_CNT_OF_ZONE*sizeof(struct __LogBlkType_t));
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
/*post current zone map table in cache*/
|
||||
static __s32 _blk_map_tbl_cache_post(__u32 nZone)
|
||||
{
|
||||
__u8 poisition;
|
||||
|
||||
/*find the cache to be post*/
|
||||
poisition = _find_blk_tbl_post_location();
|
||||
BLK_MAP_CACHE = &(BLK_MAP_CACHE_POOL->BlkMapTblCachePool[poisition]);
|
||||
|
||||
/* write back new table in flash if dirty*/
|
||||
if (BLK_MAP_CACHE->DirtyFlag){
|
||||
if (NAND_OP_TRUE != _write_back_block_map_tbl(CUR_MAP_ZONE)){
|
||||
MAPPING_ERR("_blk_map_tbl_cache_post : write back zone tbl err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*fetch current zone map table*/
|
||||
if (NAND_OP_TRUE != _read_block_map_tbl(nZone)){
|
||||
MAPPING_ERR("_blk_map_tbl_cache_post : read zone tbl err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
CUR_MAP_ZONE = nZone;
|
||||
BLK_MAP_CACHE->DirtyFlag = 0;
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SWITCH BLOCK MAPPING TABLE
|
||||
*
|
||||
*Description: Switch block mapping table.
|
||||
*
|
||||
*Arguments : nZone zone number which block mapping table need be accessed.
|
||||
*
|
||||
*Return : switch result;
|
||||
* = 0 switch successful;
|
||||
* = -1 switch failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_SwitchMapTbl(__u32 nZone)
|
||||
{
|
||||
__s32 result = NAND_OP_TRUE;
|
||||
|
||||
if(NAND_OP_TRUE != _blk_map_tbl_cache_hit(nZone))
|
||||
{
|
||||
MAPPING_DBG("BMM_SwitchMapTbl : post zone %d cache\n",nZone);
|
||||
result = (_blk_map_tbl_cache_post(nZone));
|
||||
}
|
||||
|
||||
_CalBlkTblAccessCount();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* WRITE BACK ALL MAPPING TABLE
|
||||
*
|
||||
*Description: Write back all mapping table.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : write table result;
|
||||
* = 0 write successful;
|
||||
* = -1 write failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_WriteBackAllMapTbl(void)
|
||||
{
|
||||
__u8 i;
|
||||
|
||||
/*save current scene*/
|
||||
struct __BlkMapTblCache_t *TmpBmt = BLK_MAP_CACHE;
|
||||
struct __PageMapTblCache_t *TmpPmt = PAGE_MAP_CACHE;
|
||||
|
||||
for (i = 0; i < BLOCK_MAP_TBL_CACHE_CNT; i++)
|
||||
{
|
||||
if (BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i].DirtyFlag){
|
||||
BLK_MAP_CACHE = &(BLK_MAP_CACHE_POOL->BlkMapTblCachePool[i]);
|
||||
if (NAND_OP_TRUE != _write_back_block_map_tbl(CUR_MAP_ZONE))
|
||||
return NAND_OP_FALSE;
|
||||
BLK_MAP_CACHE->DirtyFlag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*resore current scene*/
|
||||
BLK_MAP_CACHE = TmpBmt;
|
||||
PAGE_MAP_CACHE = TmpPmt;
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
static __s32 _write_dirty_flag(__u8 nZone)
|
||||
{
|
||||
__s32 TablePage;
|
||||
__u32 TableBlk;
|
||||
struct __PhysicOpPara_t param;
|
||||
struct __NandUserData_t UserData[2];
|
||||
|
||||
/*set table block number and table page number*/
|
||||
TableBlk = NandDriverInfo.ZoneTblPstInfo[nZone].PhyBlkNum;
|
||||
TablePage = NandDriverInfo.ZoneTblPstInfo[nZone].TablePst;
|
||||
|
||||
TablePage += 3;
|
||||
MEMSET((void *)&UserData,0xff,sizeof(struct __NandUserData_t) * 2);
|
||||
UserData[0].PageStatus = 0x55;
|
||||
MEMSET(LML_PROCESS_TBL_BUF,0x55,512);
|
||||
param.MDataPtr = LML_PROCESS_TBL_BUF;
|
||||
param.SDataPtr = (void *)&UserData;
|
||||
|
||||
LML_CalculatePhyOpPar(¶m, nZone, TableBlk, TablePage);
|
||||
LML_VirtualPageWrite(¶m);
|
||||
PHY_SynchBank(param.BankNum, SYNC_CHIP_MODE);
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SET DIRTY FLAG FOR BLOCK MAPPING TABLE
|
||||
*
|
||||
*Description: Set dirty flag for block mapping table.
|
||||
*
|
||||
*Arguments : none.
|
||||
*
|
||||
*Return : set dirty flag result;
|
||||
* = 0 set dirty flag successful;
|
||||
* = -1 set dirty flag failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_SetDirtyFlag(void)
|
||||
{
|
||||
if (0 == BLK_MAP_CACHE->DirtyFlag){
|
||||
_write_dirty_flag(CUR_MAP_ZONE);
|
||||
BLK_MAP_CACHE->DirtyFlag = 1;
|
||||
}
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,766 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver logic manage module
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : logic_ctl.c
|
||||
*
|
||||
* Author :
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.04.03
|
||||
*
|
||||
* Description : This file is the mapping manage module of nand flash driver.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#include "../include/nand_logic.h"
|
||||
|
||||
extern struct __NandDriverGlobal_t NandDriverInfo;
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CALCULATE THE ACCESS COUNT OF THE LOG BLOCK
|
||||
*
|
||||
*Description: Calculate the access count of the log block for make a rule to choose
|
||||
* the log for merge.
|
||||
*
|
||||
*Arguments : nLogPst the position of the log block in the log block table.
|
||||
*
|
||||
*Return : none.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
static void _CalLogAccessCnt(__u32 nLogPst)
|
||||
{
|
||||
__s32 i;
|
||||
|
||||
if(LOG_ACCESS_TIMER == 0xffff)
|
||||
{
|
||||
LOG_ACCESS_TIMER = 0;
|
||||
|
||||
//the timer of the log block access is overflow, need clear all
|
||||
for(i=0; i<LOG_BLK_CNT_OF_ZONE; i++)
|
||||
{
|
||||
LOG_ACCESS_AGE[i] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//increase the log access timer
|
||||
LOG_ACCESS_TIMER++;
|
||||
|
||||
LOG_ACCESS_AGE[nLogPst] = LOG_ACCESS_TIMER;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* GET THE PARAMETER OF DATA BLOCK
|
||||
*
|
||||
*Description: Get the parameter of the data block from the data block mapping table.
|
||||
*
|
||||
*Arguments : nBlk the number of the logical block whose data block need be got;
|
||||
* pDataBlk the pointer to the super block parameter.
|
||||
*
|
||||
*Return : get data block result;
|
||||
* = 0 get data block successful;
|
||||
* =-1 get data block failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_GetDataBlk(__u32 nBlk, struct __SuperPhyBlkType_t *pDataBlk)
|
||||
{
|
||||
if(nBlk > DATA_BLK_CNT_OF_ZONE)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] Logical block number(0x%x) is invalid when get data block!\n", nBlk);
|
||||
pDataBlk->BlkEraseCnt = 0xffff;
|
||||
pDataBlk->PhyBlkNum = 0xffff;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDataBlk->BlkEraseCnt = DATA_BLK_TBL[nBlk].BlkEraseCnt;
|
||||
pDataBlk->PhyBlkNum = DATA_BLK_TBL[nBlk].PhyBlkNum;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SET THE PARAMETER OF DATA BLOCK
|
||||
*
|
||||
*Description: set the parameter of the data block to the data block mapping table.
|
||||
*
|
||||
*Arguments : nBlk the number of the logical block whose data block need be set;
|
||||
* pDataBlk the pointer to the usper block parameter.
|
||||
*
|
||||
*Return : set data block result;
|
||||
* = 0 set data block successful;
|
||||
* =-1 set data block failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_SetDataBlk(__u32 nBlk, struct __SuperPhyBlkType_t *pDataBlk)
|
||||
{
|
||||
if(nBlk > DATA_BLK_CNT_OF_ZONE)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] Logical block number(0x%x) is invalid when set data block!\n", nBlk);
|
||||
DATA_BLK_TBL[nBlk].BlkEraseCnt = 0xffff;
|
||||
DATA_BLK_TBL[nBlk].PhyBlkNum = 0xffff;
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DATA_BLK_TBL[nBlk].BlkEraseCnt = pDataBlk->BlkEraseCnt;
|
||||
DATA_BLK_TBL[nBlk].PhyBlkNum = pDataBlk->PhyBlkNum;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* GET FREE BLOCK FROM FREE BLOCK TABLE
|
||||
*
|
||||
*Description: Get a free block from the free block table with highest erase counter or lowest
|
||||
* erase counter.
|
||||
*
|
||||
*Arguments : nType the type of the free block which need be got;
|
||||
* pFreeBlk the pointer to the free block pointer for return.
|
||||
*
|
||||
*Return : get free block result;
|
||||
* = 0 get free block successful;
|
||||
* =-1 get free block failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_GetFreeBlk(__u32 nType, struct __SuperPhyBlkType_t *pFreeBlk)
|
||||
{
|
||||
__s32 i, tmpFreePst = -1;
|
||||
__u16 tmpItem = LAST_FREE_BLK_PST + 1;
|
||||
__u32 tmpEraseCnt;
|
||||
|
||||
if(nType == LOWEST_EC_TYPE)
|
||||
{
|
||||
//need look for the free block with the lowest erase count
|
||||
tmpEraseCnt = 0xffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
//need look for the free block with the highest erase count
|
||||
tmpEraseCnt = 0x0000;
|
||||
}
|
||||
|
||||
for(i=0; i<FREE_BLK_CNT_OF_ZONE; i++, tmpItem++)
|
||||
{
|
||||
if(tmpItem >= FREE_BLK_CNT_OF_ZONE)
|
||||
{
|
||||
tmpItem = 0;
|
||||
}
|
||||
|
||||
if(FREE_BLK_TBL[tmpItem].PhyBlkNum != 0xffff)
|
||||
{
|
||||
//current free block item is valid
|
||||
if(((nType == LOWEST_EC_TYPE) && (FREE_BLK_TBL[tmpItem].BlkEraseCnt <= tmpEraseCnt))
|
||||
|| ((nType != LOWEST_EC_TYPE) && (FREE_BLK_TBL[tmpItem].BlkEraseCnt >= tmpEraseCnt)))
|
||||
{
|
||||
tmpEraseCnt = FREE_BLK_TBL[tmpItem].BlkEraseCnt;
|
||||
|
||||
tmpFreePst = tmpItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(tmpFreePst < 0)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] There is none free block in the free block table!\n");
|
||||
pFreeBlk->PhyBlkNum = 0xffff;
|
||||
pFreeBlk->BlkEraseCnt = 0xffff;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
pFreeBlk->PhyBlkNum = FREE_BLK_TBL[tmpFreePst].PhyBlkNum;
|
||||
pFreeBlk->BlkEraseCnt = FREE_BLK_TBL[tmpFreePst].BlkEraseCnt;
|
||||
LAST_FREE_BLK_PST = tmpFreePst;
|
||||
|
||||
//delete the free block item from the free block table
|
||||
FREE_BLK_TBL[tmpFreePst].PhyBlkNum = 0xffff;
|
||||
FREE_BLK_TBL[tmpFreePst].BlkEraseCnt = 0xffff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SET FREE BLOCK TO FREE BLOCK TABLE
|
||||
*
|
||||
*Description: Fill a free block to the free block table.
|
||||
*
|
||||
*Arguments : pFreeBlk the pointer to the free block which need be fill free block table.
|
||||
*
|
||||
*Return : set free block result;
|
||||
* = 0 set free block successful;
|
||||
* =-1 set free block failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_SetFreeBlk(struct __SuperPhyBlkType_t *pFreeBlk)
|
||||
{
|
||||
__s32 i;
|
||||
|
||||
for(i=0; i<FREE_BLK_CNT_OF_ZONE; i++)
|
||||
{
|
||||
//look for a empty free block item in the free block table to fill the free block
|
||||
if(FREE_BLK_TBL[i].PhyBlkNum == 0xffff)
|
||||
{
|
||||
FREE_BLK_TBL[i].PhyBlkNum = pFreeBlk->PhyBlkNum;
|
||||
FREE_BLK_TBL[i].BlkEraseCnt = pFreeBlk->BlkEraseCnt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* GET POSITION OF LOG BLOCK IN LOG BLOCK TABLE
|
||||
*
|
||||
*Description: Get the position of the log block in the log block table.
|
||||
*
|
||||
*Arguments : nBlk the logical block number which the log block is belonged to;
|
||||
*
|
||||
*Return : Log block position;
|
||||
* >= 0 the position of the log block in log block table.
|
||||
* = -1 there is no such log block;
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
static __s32 _GetLogBlkPst(__u32 nBlk)
|
||||
{
|
||||
__s32 i, tmpPst = -1;
|
||||
|
||||
for(i=0; i<LOG_BLK_CNT_OF_ZONE; i++)
|
||||
{
|
||||
if(LOG_BLK_TBL[i].LogicBlkNum == nBlk)
|
||||
{
|
||||
tmpPst = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tmpPst;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* GET PARAMETER OF LOG BLOCK
|
||||
*
|
||||
*Description: Get parameter of log block.
|
||||
*
|
||||
*Arguments : nLogicBlk the logical block number which the log block is belonged to;
|
||||
* pLogBlk the pointer to the log block item for return;
|
||||
*
|
||||
*Return : get log block result;
|
||||
* = 0 get log block successful;
|
||||
* =-1 get log block failed.
|
||||
*
|
||||
*Note : Scan the log block table which is accessing in the buffer currently,
|
||||
* to look for the log block, if the log block is exsit, return 0,
|
||||
* else, return -1
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_GetLogBlk(__u32 nLogicBlk, struct __LogBlkType_t *pLogBlk)
|
||||
{
|
||||
__s32 tmpLogPst;
|
||||
|
||||
tmpLogPst = _GetLogBlkPst(nLogicBlk);
|
||||
if(tmpLogPst < 0)
|
||||
{
|
||||
//if the logic block number is invalid, report error
|
||||
if(nLogicBlk > DATA_BLK_CNT_OF_ZONE)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] Logical block number(0x%x) is invalid when get log block!\n", nLogicBlk);
|
||||
}
|
||||
|
||||
if(pLogBlk != NULL)
|
||||
{
|
||||
pLogBlk->LogicBlkNum = 0xffff;
|
||||
pLogBlk->LastUsedPage = 0xffff;
|
||||
pLogBlk->PhyBlk.PhyBlkNum = 0xffff;
|
||||
pLogBlk->PhyBlk.BlkEraseCnt = 0xffff;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pLogBlk != NULL)
|
||||
{
|
||||
*pLogBlk = LOG_BLK_TBL[tmpLogPst];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SET LOG BLOCK PARAMETER IN THE LOG BLOCK TABLE
|
||||
*
|
||||
*Description: Set the parameter for log block in the log block table.
|
||||
*
|
||||
*Arguments : nLogicBlk the logical block number which the log block is belonged to;
|
||||
* pLogBlk the pointer to log block parameter which need be set to log block table.
|
||||
*
|
||||
*Return : set log block result;
|
||||
* = 0 set log block successful;
|
||||
* < 0 set log block failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 BMM_SetLogBlk(__u32 nLogicBlk, struct __LogBlkType_t *pLogBlk)
|
||||
{
|
||||
__s32 tmpLogPst;
|
||||
|
||||
tmpLogPst = _GetLogBlkPst(nLogicBlk);
|
||||
if(tmpLogPst < 0)
|
||||
{
|
||||
tmpLogPst = _GetLogBlkPst(0xffff);
|
||||
if(tmpLogPst < 0)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] Set log block table item failed!\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//set the log block item in the log block table
|
||||
LOG_BLK_TBL[tmpLogPst] = *pLogBlk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CREATE A NEW LOG BLOCK
|
||||
*
|
||||
*Description: Create a new log block.
|
||||
*
|
||||
*Arguments : nBlk the logical block number of the log block;
|
||||
* pLogPst the pointer to the log block position in the log block table.
|
||||
*
|
||||
*Return : create new log block result.
|
||||
* = 0 create new log block successful;
|
||||
* =-1 create new log block failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
static __s32 _CreateNewLogBlk(__u32 nBlk, __u32 *pLogPst)
|
||||
{
|
||||
__s32 i, result, tmpPst=-1;
|
||||
__u16 tmpLogAccessAge = 0xffff;
|
||||
struct __SuperPhyBlkType_t tmpFreeBlk;
|
||||
struct __PhysicOpPara_t tmpPhyPage;
|
||||
struct __NandUserData_t tmpSpare[2];
|
||||
|
||||
#if CFG_SUPPORT_WEAR_LEVELLING
|
||||
|
||||
//check if need do wear-levelling
|
||||
if(BLK_ERASE_CNTER >= WEAR_LEVELLING_FREQUENCY)
|
||||
{
|
||||
LML_WearLevelling();
|
||||
}
|
||||
|
||||
#endif
|
||||
//try to search an empty item in the log block table
|
||||
for(i=0; i<LOG_BLK_CNT_OF_ZONE; i++)
|
||||
{
|
||||
if(LOG_BLK_TBL[i].LogicBlkNum == 0xffff)
|
||||
{
|
||||
//find a empty item
|
||||
tmpPst = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//there is no empty item in the log block table, need merge a log block
|
||||
if(tmpPst == -1)
|
||||
{
|
||||
//check if there is some full log block
|
||||
for(i=0; i<LOG_BLK_CNT_OF_ZONE; i++)
|
||||
{
|
||||
if(LOG_BLK_TBL[i].LastUsedPage == PAGE_CNT_OF_SUPER_BLK-1)
|
||||
{
|
||||
tmpPst = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(tmpPst == -1)
|
||||
{
|
||||
//there is no full log block, look for an oldest log block to merge
|
||||
for(i=0; i<LOG_BLK_CNT_OF_ZONE; i++)
|
||||
{
|
||||
if(LOG_ACCESS_AGE[i] < tmpLogAccessAge)
|
||||
{
|
||||
tmpLogAccessAge = LOG_ACCESS_AGE[i];
|
||||
tmpPst = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//switch the page mapping table for merge the log block
|
||||
result = PMM_SwitchMapTbl(tmpPst);
|
||||
if(result < 0)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] Switch page mapping table failed when create new log block! Err:0x%x\n", result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//merge the log block with normal type, to make an empty item
|
||||
result = LML_MergeLogBlk(NORMAL_MERGE_MODE, LOG_BLK_TBL[tmpPst].LogicBlkNum);
|
||||
if(result < 0)
|
||||
{
|
||||
//merge log block failed, report error
|
||||
MAPPING_ERR("[MAPPING_ERR] Merge log block failed when create new log block! Err:0x%x\n", result);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//get a free block to create a new log block
|
||||
result = BMM_GetFreeBlk(LOWEST_EC_TYPE, &tmpFreeBlk);
|
||||
if(result < 0)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] Get free block failed when create new log block!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//make a new log item in the log block table
|
||||
LOG_BLK_TBL[tmpPst].LogicBlkNum = nBlk;
|
||||
LOG_BLK_TBL[tmpPst].LastUsedPage = 0xffff;
|
||||
LOG_BLK_TBL[tmpPst].PhyBlk = tmpFreeBlk;
|
||||
//set the return vaule of the log position
|
||||
*pLogPst = tmpPst;
|
||||
|
||||
__CHECK_LOGICAL_INFO_OF_DATA_BLOCK:
|
||||
//check if the data block is an empty block, if so, need update the logic information in the spare area
|
||||
LML_CalculatePhyOpPar(&tmpPhyPage, CUR_MAP_ZONE, DATA_BLK_TBL[nBlk].PhyBlkNum, 0);
|
||||
tmpPhyPage.SectBitmap = 0x03;
|
||||
tmpPhyPage.MDataPtr = LML_TEMP_BUF;
|
||||
tmpPhyPage.SDataPtr = (void *)tmpSpare;
|
||||
LML_VirtualPageRead(&tmpPhyPage);
|
||||
|
||||
if(tmpSpare[0].LogicInfo == 0xffff)
|
||||
{
|
||||
tmpSpare[0].BadBlkFlag = 0xff;
|
||||
tmpSpare[1].BadBlkFlag = 0xff;
|
||||
tmpSpare[0].LogicInfo = ((CUR_MAP_ZONE % ZONE_CNT_OF_DIE)<<10) | nBlk;
|
||||
tmpSpare[1].LogicInfo = ((CUR_MAP_ZONE % ZONE_CNT_OF_DIE)<<10) | nBlk;
|
||||
tmpSpare[0].LogicPageNum = 0xffff;
|
||||
tmpSpare[1].LogicPageNum = 0xffff;
|
||||
tmpSpare[0].PageStatus = 0xff;
|
||||
tmpSpare[1].PageStatus = 0xff;
|
||||
|
||||
//write the logical information to the spare area of the data block
|
||||
tmpPhyPage.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
result = LML_VirtualPageWrite(&tmpPhyPage);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_ERR("[MAPPING_ERR] Physical write module failed when write logical information, Err:0x%x!\n", result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = PHY_SynchBank(tmpPhyPage.BankNum, SYNC_CHIP_MODE);
|
||||
if(result < 0)
|
||||
{
|
||||
//the last write operation on current bank is failed, the block is bad, need proccess it
|
||||
LOGICCTL_DBG("[LOGICCTL_DBG] Find a bad block when write logical page! bank:0x%x, block:0x%x, page:0x%x\n",
|
||||
tmpPhyPage.BankNum, tmpPhyPage.BlkNum, tmpPhyPage.PageNum);
|
||||
|
||||
//process the bad block
|
||||
result = LML_BadBlkManage(&DATA_BLK_TBL[nBlk], CUR_MAP_ZONE, 0, &tmpFreeBlk);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_ERR("[MAPPING_ERR] Bad block process failed when create new log block, Err:0x%x!\n", result);
|
||||
return -1;
|
||||
}
|
||||
DATA_BLK_TBL[nBlk] = tmpFreeBlk;
|
||||
|
||||
goto __CHECK_LOGICAL_INFO_OF_DATA_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* GET LOG PAGE FOR WRITE
|
||||
*
|
||||
*Description: Get a log page for write.
|
||||
*
|
||||
*Arguments : nBlk the logical block number of the log block;
|
||||
* nPage the number of the logical page, which page need log page;
|
||||
* pLogPage the pointer to the log page number, for return value;
|
||||
* pLogPst the pointer to the position of the log block in the log block table.
|
||||
*
|
||||
*Return : get log page result.
|
||||
* = 0 get log page for write successful;
|
||||
* =-1 get log page for write failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
static __s32 _GetLogPageForWrite(__u32 nBlk, __u32 nPage, __u16 *pLogPage, __u32 *pLogPst)
|
||||
{
|
||||
__s32 result, tmpLogPst;
|
||||
__u16 tmpPage;
|
||||
struct __PhysicOpPara_t tmpPhyPage;
|
||||
struct __NandUserData_t tmpSpare[2];
|
||||
|
||||
tmpLogPst = _GetLogBlkPst(nBlk);
|
||||
if(tmpLogPst < 0)
|
||||
{
|
||||
//get log block position failed, there is no such log block, need create a new one
|
||||
result = _CreateNewLogBlk(nBlk, (__u32 *)&tmpLogPst);
|
||||
if(result < 0)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] Create new log block failed!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//need swap the page mapping table to ram which is accessing currently
|
||||
result = PMM_SwitchMapTbl(tmpLogPst);
|
||||
if(result < 0)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] Switch page mapping table failed when get log page! Err:0x%x\n", result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//need get log page by write mode,
|
||||
tmpPage = LOG_BLK_TBL[tmpLogPst].LastUsedPage;
|
||||
|
||||
if(SUPPORT_ALIGN_NAND_BNK)
|
||||
{
|
||||
if(tmpPage == 0xffff)
|
||||
{
|
||||
//the log block is empty, need get log page in the first page line
|
||||
tmpPage = nPage % INTERLEAVE_BANK_CNT;
|
||||
}
|
||||
else
|
||||
{
|
||||
//need bank align, the log page and the data page should be in the same bank
|
||||
if((nPage % INTERLEAVE_BANK_CNT) > (tmpPage % INTERLEAVE_BANK_CNT))
|
||||
{
|
||||
//get the log page in the same page line with last used page
|
||||
tmpPage = tmpPage + ((nPage % INTERLEAVE_BANK_CNT) - (tmpPage % INTERLEAVE_BANK_CNT));
|
||||
}
|
||||
else
|
||||
{
|
||||
//need get the log page in the next page line of the last used page
|
||||
tmpPage = tmpPage + (nPage % INTERLEAVE_BANK_CNT) + (INTERLEAVE_BANK_CNT - (tmpPage % INTERLEAVE_BANK_CNT));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//use the page which is the next of the last used page
|
||||
tmpPage = tmpPage + 1;
|
||||
}
|
||||
|
||||
|
||||
__CHECK_WRITE_LOGICAL_INFO_OF_LOG_BLOCK:
|
||||
//check if need write the logical information in the first page of the log block
|
||||
if((LOG_BLK_TBL[tmpLogPst].LastUsedPage == 0xffff) && (tmpPage != 0))
|
||||
{
|
||||
//get logical information from the data block
|
||||
LML_CalculatePhyOpPar(&tmpPhyPage, CUR_MAP_ZONE, DATA_BLK_TBL[nBlk].PhyBlkNum, 0);
|
||||
tmpPhyPage.SectBitmap = 0x03;
|
||||
tmpPhyPage.MDataPtr = LML_TEMP_BUF;
|
||||
tmpPhyPage.SDataPtr = (void *)tmpSpare;
|
||||
LML_VirtualPageRead(&tmpPhyPage);
|
||||
|
||||
tmpSpare[0].BadBlkFlag = 0xff;
|
||||
tmpSpare[1].BadBlkFlag = 0xff;
|
||||
tmpSpare[0].LogicInfo = ((CUR_MAP_ZONE % ZONE_CNT_OF_DIE)<<10) | nBlk;
|
||||
tmpSpare[1].LogicInfo = ((CUR_MAP_ZONE % ZONE_CNT_OF_DIE)<<10) | nBlk;
|
||||
tmpSpare[0].LogicPageNum = 0xffff;
|
||||
tmpSpare[1].LogicPageNum = 0xffff;
|
||||
tmpSpare[0].PageStatus = tmpSpare[0].PageStatus + 1;
|
||||
tmpSpare[1].PageStatus = tmpSpare[0].PageStatus;
|
||||
|
||||
//write the logical information to the spare area of the data block
|
||||
LML_CalculatePhyOpPar(&tmpPhyPage, CUR_MAP_ZONE, LOG_BLK_TBL[tmpLogPst].PhyBlk.PhyBlkNum, 0);
|
||||
tmpPhyPage.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
result = LML_VirtualPageWrite(&tmpPhyPage);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_ERR("[MAPPING_ERR] Physical write module failed when write logical information, Err:0x%x!\n", result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = PHY_SynchBank(tmpPhyPage.BankNum, SYNC_CHIP_MODE);
|
||||
if(result < 0)
|
||||
{
|
||||
//the last write operation on current bank is failed, the block is bad, need proccess it
|
||||
LOGICCTL_DBG("[LOGICCTL_DBG] Find a bad block when write logical page! bank:0x%x, block:0x%x, page:0x%x\n",
|
||||
tmpPhyPage.BankNum, tmpPhyPage.BlkNum, tmpPhyPage.PageNum);
|
||||
|
||||
//process the bad block
|
||||
result = LML_BadBlkManage(&LOG_BLK_TBL[tmpLogPst].PhyBlk, CUR_MAP_ZONE, 0, &LOG_BLK_TBL[tmpLogPst].PhyBlk);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_ERR("[MAPPING_ERR] Bad block process failed when get log page for write, Err:0x%x!\n", result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
goto __CHECK_WRITE_LOGICAL_INFO_OF_LOG_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
//set the log page number for return
|
||||
*pLogPage = tmpPage;
|
||||
*pLogPst = tmpLogPst;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* GET LOG PAGE PARAMETER
|
||||
*
|
||||
*Description: Get a page from log block for read or write.
|
||||
*
|
||||
*Arguments : nBlk the logical block number of the log block;
|
||||
* nPage the number of the logical page, which page need log page;
|
||||
* nMode the type of get log page, 'r' or 'w', others is invalid.
|
||||
*
|
||||
*Return : the number of the log page;
|
||||
* != 0xffff get log page successful, return page number;
|
||||
* = 0xffff get log page failed.
|
||||
*
|
||||
*Note : Scan the log block table to try to get the log block.
|
||||
* when the get type is 'r', if the log block is exsit and the logical
|
||||
* page contain a log page, return the number of the log page, else,
|
||||
* return 0xffff;
|
||||
* when the get type is 'w', if the log block is not exsit, need create
|
||||
* log block, then, if get log page failed, need merge the log block, and
|
||||
* try to get log page again, this mode should return a value page number
|
||||
* except there is no enough valid blocks.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__u32 PMM_GetLogPage(__u32 nBlk, __u32 nPage, __u8 nMode)
|
||||
{
|
||||
__s32 result, tmpLogPst;
|
||||
__u16 tmpPage;
|
||||
|
||||
if(nMode == 'r')
|
||||
{
|
||||
tmpLogPst = _GetLogBlkPst(nBlk);
|
||||
if(tmpLogPst < 0)
|
||||
{
|
||||
//get log page by read mode, there is no log block, return invalid value
|
||||
return INVALID_PAGE_NUM;
|
||||
}
|
||||
|
||||
//need swap the page mapping table to ram which is accessing currently
|
||||
result = PMM_SwitchMapTbl(tmpLogPst);
|
||||
if(result < 0)
|
||||
{
|
||||
MAPPING_ERR("[MAPPING_ERR] Switch page mapping table failed when get log page! Err:0x%x\n", result);
|
||||
return INVALID_PAGE_NUM;
|
||||
}
|
||||
|
||||
_CalLogAccessCnt(tmpLogPst);
|
||||
|
||||
return PAGE_MAP_TBL[nPage].PhyPageNum;
|
||||
}
|
||||
|
||||
result = _GetLogPageForWrite(nBlk, nPage, &tmpPage, (__u32 *)&tmpLogPst);
|
||||
if(result < 0)
|
||||
{
|
||||
//get log page for write failed
|
||||
MAPPING_ERR("[MAPPING_ERR] Get log page for write failed!\n");
|
||||
return INVALID_PAGE_NUM;
|
||||
}
|
||||
|
||||
//check if the log page is valid
|
||||
if(!(tmpPage < PAGE_CNT_OF_SUPER_BLK))
|
||||
{
|
||||
//the log page is not invalid, need to merge the log block, and get again
|
||||
result = LML_MergeLogBlk(SPECIAL_MERGE_MODE, nBlk);
|
||||
if(result < 0)
|
||||
{
|
||||
//merge log block failed, report error
|
||||
MAPPING_ERR("[MAPPING_ERR] Merge log block failed when get log page! Err:0x%x\n", result);
|
||||
return INVALID_PAGE_NUM;
|
||||
}
|
||||
|
||||
//try to get log page for write again
|
||||
result = _GetLogPageForWrite(nBlk, nPage, &tmpPage, (__u32 *)&tmpLogPst);
|
||||
if(result < 0)
|
||||
{
|
||||
//get log page for write failed
|
||||
MAPPING_ERR("[MAPPING_ERR] Get log page for write failed!\n");
|
||||
return INVALID_PAGE_NUM;
|
||||
}
|
||||
}
|
||||
|
||||
//check if the log page is valid
|
||||
if(!(tmpPage < PAGE_CNT_OF_SUPER_BLK))
|
||||
{
|
||||
//get log page for write failed
|
||||
MAPPING_ERR("[MAPPING_ERR] Get log page for write failed!\n");
|
||||
return INVALID_PAGE_NUM;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_BLK_TBL[tmpLogPst].LastUsedPage = tmpPage;
|
||||
}
|
||||
|
||||
//update the page mapping table item
|
||||
PAGE_MAP_TBL[nPage].PhyPageNum = tmpPage;
|
||||
|
||||
//set the flag that mark need update the page mapping table
|
||||
PAGE_MAP_CACHE->DirtyFlag = 1;
|
||||
|
||||
_CalLogAccessCnt(tmpLogPst);
|
||||
|
||||
return tmpPage;
|
||||
}
|
||||
|
||||
|
||||
void PMM_ClearCurMapTbl(void)
|
||||
{
|
||||
PAGE_MAP_CACHE->ZoneNum = 0xff;
|
||||
PAGE_MAP_CACHE->LogBlkPst = 0xff;
|
||||
PAGE_MAP_CACHE->DirtyFlag = 0x0;
|
||||
}
|
||||
|
||||
__u32 PMM_GetCurMapPage(__u16 nLogicalPage)
|
||||
{
|
||||
return PAGE_MAP_TBL[nLogicalPage].PhyPageNum;
|
||||
}
|
||||
|
||||
void PMM_SetCurMapPage(__u16 nLogicalPage,__u16 nPhysicPage)
|
||||
{
|
||||
PAGE_MAP_TBL[nLogicalPage].PhyPageNum = nPhysicPage;
|
||||
}
|
||||
|
@ -1,485 +0,0 @@
|
||||
/*********************************************************************************
|
||||
* NAND FLASH DRIVER
|
||||
* (c) Copyright 2008, SoftWinners Co,Ld.
|
||||
* All Right Reserved
|
||||
*file : merge.c
|
||||
*description : this file create a interface to make room for new data writing. three block type:
|
||||
* data block - data was arrange must be in page order;
|
||||
* log block - data was arranged is not necessary in page order.
|
||||
* free block - totally clear physical block.
|
||||
* only log block can be programmed.so if log block is used up, merge is necessary.
|
||||
*history :
|
||||
* v0.1 2008-04-07 Richard
|
||||
* support three methods to make free physic block or free physic page.
|
||||
**********************************************************************************/
|
||||
|
||||
#include "../include/nand_logic.h"
|
||||
|
||||
extern struct __NandDriverGlobal_t NandDriverInfo;
|
||||
|
||||
__s32 _copy_page0(__u32 SrcBlk,__u16 SrcDataPage,__u32 DstBlk,__u8 SeqPlus)
|
||||
{
|
||||
__u8 seq;
|
||||
__u16 LogicInfo;
|
||||
struct __NandUserData_t UserData[2];
|
||||
struct __PhysicOpPara_t SrcParam,DstParam;
|
||||
|
||||
SrcParam.MDataPtr = DstParam.MDataPtr = LML_TEMP_BUF;
|
||||
SrcParam.SDataPtr = DstParam.SDataPtr = (void *)&UserData;
|
||||
MEMSET((void *)&UserData,0xff,sizeof(struct __NandUserData_t) * 2);
|
||||
|
||||
/*get seq and logicinfo*/
|
||||
SrcParam.SectBitmap = 0x3;
|
||||
LML_CalculatePhyOpPar(&SrcParam,CUR_MAP_ZONE, SrcBlk, 0);
|
||||
if (LML_VirtualPageRead(&SrcParam) < 0){
|
||||
LOGICCTL_ERR("_copy_page0 : read user data err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
seq = UserData[0].PageStatus;
|
||||
LogicInfo = UserData[0].LogicInfo;
|
||||
|
||||
/*copy main data */
|
||||
SrcParam.SectBitmap = DstParam.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
LML_CalculatePhyOpPar(&SrcParam, CUR_MAP_ZONE, SrcBlk, SrcDataPage);
|
||||
LML_CalculatePhyOpPar(&DstParam, CUR_MAP_ZONE, DstBlk, 0);
|
||||
|
||||
if (LML_VirtualPageRead(&SrcParam) < 0){
|
||||
LOGICCTL_ERR("_copy_page0 : read main data err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
UserData[0].LogicInfo = LogicInfo;
|
||||
UserData[0].PageStatus = seq + SeqPlus;
|
||||
if (NAND_OP_TRUE != LML_VirtualPageWrite(&DstParam)){
|
||||
LOGICCTL_ERR("_copy_page0 : write err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \par Description:
|
||||
* This function copy valuable data from datablk to logblk,then change datablk to freeblk ,change logblk to datablk.
|
||||
*
|
||||
* \param [in] LogNum,serial number within log block space
|
||||
* \return sucess or failed.
|
||||
* \note this function was called when log block is in order,that is to say physical
|
||||
* page number is same with logical page number.
|
||||
**/
|
||||
__s32 _log2data_swap_merge(__u32 nlogical)
|
||||
{
|
||||
__u16 LastUsedPage,SuperPage;
|
||||
struct __SuperPhyBlkType_t DataBlk;
|
||||
struct __LogBlkType_t LogBlk;
|
||||
struct __PhysicOpPara_t SrcParam,DstParam;
|
||||
|
||||
/* init info of data block and log block*/
|
||||
BMM_GetDataBlk(nlogical, &DataBlk);
|
||||
BMM_GetLogBlk(nlogical, &LogBlk);
|
||||
LastUsedPage = LogBlk.LastUsedPage;
|
||||
|
||||
/*copy data from data block to log block*/
|
||||
for (SuperPage = LastUsedPage + 1; SuperPage < PAGE_CNT_OF_SUPER_BLK; SuperPage++){
|
||||
/*set source and destinate address*/
|
||||
LML_CalculatePhyOpPar(&SrcParam,CUR_MAP_ZONE, DataBlk.PhyBlkNum, SuperPage);
|
||||
LML_CalculatePhyOpPar(&DstParam,CUR_MAP_ZONE, LogBlk.PhyBlk.PhyBlkNum, SuperPage);
|
||||
if (NAND_OP_TRUE != PHY_PageCopyback(&SrcParam,&DstParam)){
|
||||
LOGICCTL_ERR("swap merge : copy back err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
if (NAND_OP_TRUE != PHY_SynchBank(DstParam.BankNum, SYNC_BANK_MODE)){
|
||||
struct __SuperPhyBlkType_t SubBlk;
|
||||
if (NAND_OP_TRUE != LML_BadBlkManage(&LogBlk.PhyBlk,CUR_MAP_ZONE,SuperPage,&SubBlk)){
|
||||
LOGICCTL_ERR("swap merge : bad block manage err after copy back\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
LogBlk.PhyBlk = SubBlk;
|
||||
SuperPage -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*move log block to data block*/
|
||||
BMM_SetDataBlk(nlogical, &LogBlk.PhyBlk);
|
||||
/*clear log block item*/
|
||||
MEMSET(&LogBlk, 0xff, sizeof(struct __LogBlkType_t));
|
||||
BMM_SetLogBlk(nlogical, &LogBlk);
|
||||
|
||||
/*erase data block*/
|
||||
if ( NAND_OP_TRUE != LML_VirtualBlkErase(CUR_MAP_ZONE, DataBlk.PhyBlkNum)){
|
||||
if (NAND_OP_TRUE != LML_BadBlkManage(&DataBlk,CUR_MAP_ZONE,0,&DataBlk)){
|
||||
LOGICCTL_ERR("swap merge : bad block manage err erase data block\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
/*move erased data block to free block*/
|
||||
if (DataBlk.BlkEraseCnt < 0xffff)
|
||||
DataBlk.BlkEraseCnt ++;
|
||||
BMM_SetFreeBlk(&DataBlk);
|
||||
|
||||
/*clear page map table*/
|
||||
PMM_ClearCurMapTbl();
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \par Description:
|
||||
* This function move valuable data from log block to free block,then replace them.
|
||||
*
|
||||
* \param [in] LogNum,serial number within log block space
|
||||
* \return sucess or failed.
|
||||
* \note this function was called when log block is full, and valid pages is less than half of one block.
|
||||
**/
|
||||
__s32 _free2log_move_merge(__u32 nlogical)
|
||||
{
|
||||
__u8 bank;
|
||||
__u16 LastUsedPage,SuperPage;
|
||||
__u16 SrcPage,DstPage;
|
||||
struct __SuperPhyBlkType_t FreeBlk;
|
||||
struct __LogBlkType_t LogBlk;
|
||||
struct __PhysicOpPara_t SrcParam,DstParam;
|
||||
struct __NandUserData_t UserData[2];
|
||||
|
||||
|
||||
/*init info of log block , and get one free block */
|
||||
BMM_GetLogBlk(nlogical, &LogBlk);
|
||||
if (NAND_OP_TRUE != BMM_GetFreeBlk(LOWEST_EC_TYPE, &FreeBlk))
|
||||
return NAND_OP_FALSE;
|
||||
|
||||
SrcParam.MDataPtr = DstParam.MDataPtr = NULL;
|
||||
SrcParam.SDataPtr = DstParam.SDataPtr = NULL;
|
||||
SrcParam.SectBitmap = DstParam.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
|
||||
if(SUPPORT_ALIGN_NAND_BNK)
|
||||
{
|
||||
redo:
|
||||
/*copy data bank by bank, for copy-back using*/
|
||||
LastUsedPage = 0;
|
||||
for (bank = 0; bank < INTERLEAVE_BANK_CNT; bank++)
|
||||
{
|
||||
DstPage = bank;
|
||||
for (SuperPage = bank; SuperPage < PAGE_CNT_OF_SUPER_BLK; SuperPage+= INTERLEAVE_BANK_CNT)
|
||||
{
|
||||
SrcPage = PMM_GetCurMapPage(SuperPage);
|
||||
if (SrcPage != 0xffff)
|
||||
{
|
||||
/*set source and destinate address*/
|
||||
LML_CalculatePhyOpPar(&SrcParam,CUR_MAP_ZONE, LogBlk.PhyBlk.PhyBlkNum, SrcPage);
|
||||
LML_CalculatePhyOpPar(&DstParam,CUR_MAP_ZONE, FreeBlk.PhyBlkNum, DstPage);
|
||||
if (DstPage == 0)
|
||||
{
|
||||
if ( NAND_OP_FALSE == _copy_page0(LogBlk.PhyBlk.PhyBlkNum,SrcPage,FreeBlk.PhyBlkNum,0))
|
||||
{
|
||||
LOGICCTL_ERR("move merge : copy page 0 err1\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NAND_OP_TRUE != PHY_PageCopyback(&SrcParam,&DstParam))
|
||||
{
|
||||
LOGICCTL_ERR("move merge : copy back err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (NAND_OP_TRUE != PHY_SynchBank(DstParam.BankNum, SYNC_BANK_MODE))
|
||||
{
|
||||
struct __SuperPhyBlkType_t SubBlk;
|
||||
if (NAND_OP_TRUE != LML_BadBlkManage(&FreeBlk,CUR_MAP_ZONE,0,&SubBlk))
|
||||
{
|
||||
LOGICCTL_ERR("move merge : bad block manage err after copy back\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
FreeBlk = SubBlk;
|
||||
goto redo;
|
||||
}
|
||||
|
||||
PMM_SetCurMapPage(SuperPage,DstPage);
|
||||
DstPage += INTERLEAVE_BANK_CNT;
|
||||
}
|
||||
}
|
||||
|
||||
/*if bank 0 is empty, need write mange info in page 0*/
|
||||
if ((bank == 0) && (DstPage == 0))
|
||||
{
|
||||
if ( NAND_OP_FALSE == _copy_page0(LogBlk.PhyBlk.PhyBlkNum,0,FreeBlk.PhyBlkNum,0))
|
||||
{
|
||||
LOGICCTL_ERR("move merge : copy page 0 err2\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
LML_CalculatePhyOpPar(&DstParam, CUR_MAP_ZONE, FreeBlk.PhyBlkNum, 0);
|
||||
if (NAND_OP_TRUE != PHY_SynchBank(DstParam.BankNum, SYNC_BANK_MODE))
|
||||
{
|
||||
struct __SuperPhyBlkType_t SubBlk;
|
||||
if (NAND_OP_TRUE != LML_BadBlkManage(&FreeBlk,CUR_MAP_ZONE,0,&SubBlk))
|
||||
{
|
||||
LOGICCTL_ERR("move merge : bad block manage err after copy back\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
FreeBlk = SubBlk;
|
||||
goto redo;
|
||||
}
|
||||
}
|
||||
|
||||
/*reset LastUsedPage*/
|
||||
if ((DstPage - INTERLEAVE_BANK_CNT) > LastUsedPage)
|
||||
{
|
||||
LastUsedPage = DstPage - INTERLEAVE_BANK_CNT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*copy data page by page*/
|
||||
DstPage = 0;
|
||||
LastUsedPage = 0;
|
||||
for (SuperPage = 0; SuperPage < PAGE_CNT_OF_LOGIC_BLK; SuperPage++)
|
||||
{
|
||||
SrcPage = PMM_GetCurMapPage(SuperPage);
|
||||
if (SrcPage != 0xffff)
|
||||
{
|
||||
/*set source and destinate address*/
|
||||
LML_CalculatePhyOpPar(&SrcParam,CUR_MAP_ZONE, LogBlk.PhyBlk.PhyBlkNum, SrcPage);
|
||||
LML_CalculatePhyOpPar(&DstParam,CUR_MAP_ZONE, FreeBlk.PhyBlkNum, DstPage);
|
||||
if (0 == DstPage)
|
||||
{
|
||||
if ( NAND_OP_FALSE == _copy_page0(LogBlk.PhyBlk.PhyBlkNum,SrcPage,FreeBlk.PhyBlkNum,0))
|
||||
{
|
||||
LOGICCTL_ERR("move merge : copy page 0 err1\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SrcParam.MDataPtr = DstParam.MDataPtr = LML_TEMP_BUF;
|
||||
SrcParam.SDataPtr = DstParam.SDataPtr = (void *)&UserData;
|
||||
MEMSET((void *)&UserData,0xff,sizeof(struct __NandUserData_t) * 2);
|
||||
SrcParam.SectBitmap = DstParam.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
if (LML_VirtualPageRead(&SrcParam) < 0){
|
||||
LOGICCTL_ERR("move merge : read main data err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
|
||||
if (NAND_OP_TRUE != LML_VirtualPageWrite(&DstParam)){
|
||||
LOGICCTL_ERR("move merge : write err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
if (NAND_OP_TRUE != PHY_SynchBank(DstParam.BankNum, SYNC_BANK_MODE))
|
||||
{
|
||||
struct __SuperPhyBlkType_t SubBlk;
|
||||
if (NAND_OP_TRUE != LML_BadBlkManage(&FreeBlk,CUR_MAP_ZONE,LastUsedPage,&SubBlk))
|
||||
{
|
||||
LOGICCTL_ERR("move merge : bad block manage err after copy back\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
FreeBlk = SubBlk;
|
||||
SuperPage -= 1;
|
||||
}
|
||||
PMM_SetCurMapPage(SuperPage,DstPage);
|
||||
LastUsedPage = DstPage;
|
||||
DstPage++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*erase log block*/
|
||||
if(NAND_OP_TRUE != LML_VirtualBlkErase(CUR_MAP_ZONE, LogBlk.PhyBlk.PhyBlkNum))
|
||||
{
|
||||
if(NAND_OP_TRUE != LML_BadBlkManage(&LogBlk.PhyBlk,CUR_MAP_ZONE,0,&LogBlk.PhyBlk))
|
||||
{
|
||||
LOGICCTL_ERR("move merge : bad block manage err after erase log block\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
/*move erased log block to free block*/
|
||||
if(LogBlk.PhyBlk.BlkEraseCnt < 0xffff)
|
||||
{
|
||||
LogBlk.PhyBlk.BlkEraseCnt ++;
|
||||
}
|
||||
BMM_SetFreeBlk(&LogBlk.PhyBlk);
|
||||
|
||||
/*move free block to log block*/
|
||||
LogBlk.PhyBlk = FreeBlk;
|
||||
LogBlk.LastUsedPage = LastUsedPage;
|
||||
BMM_SetLogBlk(nlogical, &LogBlk);
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \par Description:
|
||||
* This function copy valuable data from log block or dat block to free block, change free to data ,change
|
||||
* data and log to free.
|
||||
*
|
||||
* \param [in] LogNum,serial number within log block space
|
||||
* \return sucess or failed.
|
||||
* \note this function was called when log block is not suit for swap or move.
|
||||
**/
|
||||
__s32 _free2data_simple_merge(__u32 nlogical)
|
||||
{
|
||||
__u8 InData;
|
||||
__u16 SuperPage;
|
||||
__u16 SrcPage,DstPage;
|
||||
__u32 SrcBlk,DstBlk;
|
||||
struct __SuperPhyBlkType_t DataBlk;
|
||||
struct __SuperPhyBlkType_t FreeBlk;
|
||||
struct __LogBlkType_t LogBlk;
|
||||
struct __PhysicOpPara_t SrcParam,DstParam;
|
||||
|
||||
/*init block info*/
|
||||
BMM_GetDataBlk(nlogical,&DataBlk);
|
||||
if (NAND_OP_TRUE != BMM_GetFreeBlk(LOWEST_EC_TYPE, &FreeBlk))
|
||||
return NAND_OP_FALSE;
|
||||
BMM_GetLogBlk(nlogical,&LogBlk);
|
||||
|
||||
/*copy data from data block or log block to free block*/
|
||||
for (SuperPage = 0; SuperPage < PAGE_CNT_OF_LOGIC_BLK; SuperPage++)
|
||||
{
|
||||
/*set source address and destination address*/
|
||||
DstPage = SuperPage;
|
||||
DstBlk = FreeBlk.PhyBlkNum;
|
||||
SrcPage = PMM_GetCurMapPage(SuperPage);
|
||||
InData = (SrcPage == 0xffff)?1 : 0;
|
||||
SrcBlk = InData?DataBlk.PhyBlkNum : LogBlk.PhyBlk.PhyBlkNum;
|
||||
SrcPage = InData?SuperPage:SrcPage;
|
||||
LML_CalculatePhyOpPar(&SrcParam, CUR_MAP_ZONE,SrcBlk, SrcPage);
|
||||
LML_CalculatePhyOpPar(&DstParam, CUR_MAP_ZONE,DstBlk, DstPage);
|
||||
|
||||
if (DstPage == 0)
|
||||
{
|
||||
__u8 SeqPlus;
|
||||
//SeqPlus = InData?1:0;
|
||||
SeqPlus = InData?2:1;
|
||||
if(NAND_OP_FALSE == _copy_page0(SrcBlk, SrcPage, DstBlk,SeqPlus))
|
||||
{
|
||||
LOGICCTL_ERR("simple_merge : copy page 0 err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NAND_OP_TRUE != PHY_PageCopyback(&SrcParam,&DstParam))
|
||||
{
|
||||
LOGICCTL_ERR("simple merge : copy back err\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(NAND_OP_TRUE != PHY_SynchBank(DstParam.BankNum, SYNC_BANK_MODE))
|
||||
{
|
||||
struct __SuperPhyBlkType_t SubBlk;
|
||||
if(NAND_OP_TRUE != LML_BadBlkManage(&FreeBlk,CUR_MAP_ZONE,DstPage, &SubBlk))
|
||||
{
|
||||
LOGICCTL_ERR("simgple merge : bad block manage err after copy back\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
FreeBlk = SubBlk;
|
||||
SuperPage -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*move free block to data block*/
|
||||
BMM_SetDataBlk(nlogical, &FreeBlk);
|
||||
|
||||
|
||||
/*move erased data block to free block*/
|
||||
if ( NAND_OP_TRUE != LML_VirtualBlkErase(CUR_MAP_ZONE, DataBlk.PhyBlkNum)){
|
||||
if (NAND_OP_TRUE != LML_BadBlkManage(&DataBlk,CUR_MAP_ZONE,0,&DataBlk)){
|
||||
LOGICCTL_ERR("swap merge : bad block manage err erase data block\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
/*move erased data block to free block*/
|
||||
if (DataBlk.BlkEraseCnt < 0xffff)
|
||||
DataBlk.BlkEraseCnt ++;
|
||||
BMM_SetFreeBlk(&DataBlk);
|
||||
|
||||
|
||||
/*move erased log block to free block*/
|
||||
if ( NAND_OP_TRUE != LML_VirtualBlkErase(CUR_MAP_ZONE, LogBlk.PhyBlk.PhyBlkNum)){
|
||||
if (NAND_OP_TRUE != LML_BadBlkManage(&LogBlk.PhyBlk,CUR_MAP_ZONE,0,&LogBlk.PhyBlk)){
|
||||
LOGICCTL_ERR("move merge : bad block manage err after erase log block\n");
|
||||
return NAND_OP_FALSE;
|
||||
}
|
||||
}
|
||||
if (LogBlk.PhyBlk.BlkEraseCnt < 0xffff)
|
||||
LogBlk.PhyBlk.BlkEraseCnt ++;
|
||||
BMM_SetFreeBlk(&LogBlk.PhyBlk);
|
||||
MEMSET(&LogBlk, 0xff, sizeof(struct __LogBlkType_t));
|
||||
BMM_SetLogBlk(nlogical, &LogBlk);
|
||||
|
||||
|
||||
|
||||
/*clear page map table*/
|
||||
PMM_ClearCurMapTbl();
|
||||
|
||||
return NAND_OP_TRUE;
|
||||
|
||||
}
|
||||
|
||||
void _get_page_map_tbl_info(__u32 nlogical,__u8 *InOrder, __u16 *nValidPage)
|
||||
{
|
||||
__u16 LastUsedPage,PhysicPage;
|
||||
__u32 i;
|
||||
struct __LogBlkType_t LogBlk;
|
||||
|
||||
*InOrder = 1;
|
||||
*nValidPage = 0;
|
||||
BMM_GetLogBlk(nlogical, &LogBlk);
|
||||
LastUsedPage = LogBlk.LastUsedPage;
|
||||
|
||||
for (i = 0; i < PAGE_CNT_OF_SUPER_BLK; i++)
|
||||
{
|
||||
PhysicPage = PMM_GetCurMapPage(i);
|
||||
if (PhysicPage != 0xffff){
|
||||
*nValidPage = *nValidPage + 1;
|
||||
if (PhysicPage != i)
|
||||
*InOrder = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (*nValidPage < LastUsedPage + 1)
|
||||
*InOrder = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER MERGE LOG BLOCK
|
||||
*
|
||||
*Description: Merge the log block whoes mapping table is active.
|
||||
*
|
||||
*Arguments : nMode the type of the merge;
|
||||
* = 0 normal merge, the log block table is not full;
|
||||
* = 1 special merge, the log block table is full.
|
||||
*
|
||||
*Return : merge result;
|
||||
* = 0 merge log successful;
|
||||
* = -1 do bad block manage failed.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_MergeLogBlk(__u32 nMode, __u32 nlogical)
|
||||
{
|
||||
__u8 InOrder;
|
||||
__u16 nValidPage;
|
||||
|
||||
_get_page_map_tbl_info(nlogical,&InOrder,&nValidPage);
|
||||
|
||||
if (InOrder)
|
||||
return (_log2data_swap_merge(nlogical));
|
||||
else{
|
||||
if ( (nMode == SPECIAL_MERGE_MODE) && (nValidPage < PAGE_CNT_OF_SUPER_BLK/(INTERLEAVE_BANK_CNT+1)))
|
||||
return (_free2log_move_merge(nlogical));
|
||||
else
|
||||
return (_free2data_simple_merge(nlogical));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver logic manage module
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : read_reclaim.c
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.04.07
|
||||
*
|
||||
* Description : This file is the read-reclaim module.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.04.07 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#include "../include/nand_logic.h"
|
||||
|
||||
extern struct __NandDriverGlobal_t NandDriverInfo;
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER READ-RECLAIM
|
||||
*
|
||||
*Description: Repair the logic block whose data has reach the limit of the ability of
|
||||
* the HW ECC module correct.
|
||||
*
|
||||
*Arguments : nPage the page address where need be repaired.
|
||||
*
|
||||
*Return : read-reclaim result;
|
||||
* = 0 do read-reclaim successful;
|
||||
* = -1 do read-reclaim failed.
|
||||
*
|
||||
*Notes : if read a physical page millions of times, there may be some bit error in
|
||||
* the page, and the error bit number will increase along with the read times,
|
||||
* so, if the number of the error bit reachs the ECC limit, the data should be
|
||||
* read out and write to another physical blcok.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_ReadReclaim(__u32 nPage)
|
||||
{
|
||||
__s32 result;
|
||||
|
||||
#if CFG_SUPPORT_READ_RECLAIM
|
||||
|
||||
LOGICCTL_ERR("[LOGICCTL_ERR] read reclaim go\n");
|
||||
|
||||
//flush the page cache to nand flash first, because need use the buffer
|
||||
result = LML_FlushPageCache();
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_ERR("[LOGICCTL_ERR] Flush page cache failed when do read reclaim! Error:0x%x\n", result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//read the full page data to buffer
|
||||
result = LML_PageRead(nPage, FULL_BITMAP_OF_LOGIC_PAGE, LML_WRITE_PAGE_CACHE);
|
||||
if(result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//the data in the page cache is full, write it to nand flash
|
||||
result = LML_PageWrite(nPage, FULL_BITMAP_OF_LOGIC_PAGE, LML_WRITE_PAGE_CACHE);
|
||||
if(result < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,199 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver logic manage module
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : wear_levelling.c
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.04.07
|
||||
*
|
||||
* Description : This file is the wear-levelling module.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.04.07 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#include "../include/nand_logic.h"
|
||||
|
||||
extern struct __NandDriverGlobal_t NandDriverInfo;
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND FLASH LOGIC MANAGE LAYER WEAR-LEVELLING
|
||||
*
|
||||
*Description: Equate the erase cycles among all physical blocks.
|
||||
*
|
||||
*Arguments : none
|
||||
*
|
||||
*Return : do wear-levelling result;
|
||||
* = 0 do wear-levelling successful;
|
||||
* = -1 do wear-levelling failed.
|
||||
*
|
||||
*Notes : The erase cycle of a physical block is limited, if the erase cycle overun this
|
||||
* limit, the physical block may be invalid. so a policy is needed to equate the
|
||||
* millions of erase cycles to ervery physical block.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 LML_WearLevelling(void)
|
||||
{
|
||||
#if CFG_SUPPORT_WEAR_LEVELLING
|
||||
|
||||
__s32 i, result;
|
||||
|
||||
__u32 tmpLogicBlk;
|
||||
__u16 tmpLowEc = 0xffff;
|
||||
struct __SuperPhyBlkType_t tmpFreeBlk, tmpDataBlk;
|
||||
struct __NandUserData_t tmpSpare[2];
|
||||
struct __PhysicOpPara_t tmpSrcPage, tmpDstPage;
|
||||
BLK_ERASE_CNTER = 0;
|
||||
|
||||
//scan the data block table, to look for a physical block with lowest erase count
|
||||
for(i=DATA_BLK_CNT_OF_ZONE-1; i>=0; i--)
|
||||
{
|
||||
if(DATA_BLK_TBL[i].BlkEraseCnt < tmpLowEc)
|
||||
{
|
||||
tmpLowEc = DATA_BLK_TBL[i].BlkEraseCnt;
|
||||
tmpLogicBlk = i;
|
||||
}
|
||||
}
|
||||
|
||||
//get a free block which has the highest erase count
|
||||
result = BMM_GetFreeBlk(HIGHEST_EC_TYPE, &tmpFreeBlk);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_ERR("[LOGICCTL_ERR] Get free block failed when do wear-levelling!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//clear the block erase counter
|
||||
BLK_ERASE_CNTER = 0;
|
||||
|
||||
if(tmpLowEc >= tmpFreeBlk.BlkEraseCnt)
|
||||
{
|
||||
if(tmpLowEc == 0xffff)
|
||||
{
|
||||
//the lowest erase count reach the highest value, clear erase count of all physical block
|
||||
for(i=0; i<DATA_BLK_CNT_OF_ZONE; i++)
|
||||
{
|
||||
//clear the erase count for the data block
|
||||
DATA_BLK_TBL[i].BlkEraseCnt = 0x00;
|
||||
}
|
||||
|
||||
for(i=0; i<FREE_BLK_CNT_OF_ZONE; i++)
|
||||
{
|
||||
//clear the erase count for the free block
|
||||
if(FREE_BLK_TBL[i].PhyBlkNum != 0xffff)
|
||||
{
|
||||
FREE_BLK_TBL[i].BlkEraseCnt = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<MAX_LOG_BLK_CNT; i++)
|
||||
{
|
||||
//clear the erase count for the log block
|
||||
if(LOG_BLK_TBL[i].LogicBlkNum != 0xffff)
|
||||
{
|
||||
LOG_BLK_TBL[i].PhyBlk.BlkEraseCnt = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMM_SetFreeBlk(&tmpFreeBlk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BMM_GetDataBlk(tmpLogicBlk, &tmpDataBlk);
|
||||
result = BMM_GetLogBlk(tmpLogicBlk, NULL);
|
||||
if(result < 0)
|
||||
{
|
||||
//check if the data block is empty
|
||||
LML_CalculatePhyOpPar(&tmpSrcPage, CUR_MAP_ZONE, tmpDataBlk.PhyBlkNum, 0);
|
||||
tmpSrcPage.SectBitmap = 0x03;
|
||||
tmpSrcPage.MDataPtr = LML_TEMP_BUF;
|
||||
tmpSrcPage.SDataPtr = (void *)tmpSpare;
|
||||
LML_VirtualPageRead(&tmpSrcPage);
|
||||
|
||||
if(tmpSpare[0].LogicInfo != 0xffff)
|
||||
{
|
||||
//need copy data from the data block to the free block
|
||||
tmpSrcPage.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
tmpSrcPage.MDataPtr = NULL;
|
||||
tmpSrcPage.SDataPtr = NULL;
|
||||
|
||||
tmpDstPage.SectBitmap = FULL_BITMAP_OF_SUPER_PAGE;
|
||||
tmpDstPage.MDataPtr = NULL;
|
||||
tmpDstPage.SDataPtr = NULL;
|
||||
|
||||
for(i=0; i<PAGE_CNT_OF_SUPER_BLK; i++)
|
||||
{
|
||||
LML_CalculatePhyOpPar(&tmpSrcPage, CUR_MAP_ZONE, tmpDataBlk.PhyBlkNum, i);
|
||||
LML_CalculatePhyOpPar(&tmpDstPage, CUR_MAP_ZONE, tmpFreeBlk.PhyBlkNum, i);
|
||||
|
||||
PHY_PageCopyback(&tmpSrcPage, &tmpDstPage);
|
||||
//check page copy result
|
||||
result = PHY_SynchBank(tmpDstPage.BankNum, SYNC_CHIP_MODE);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_DBG("[LOGICCTL_DBG] Copy page failed when doing wear-levelling!\n");
|
||||
result = LML_BadBlkManage(&tmpFreeBlk, CUR_MAP_ZONE, 0, NULL);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_ERR("[LOGICCTL_ERR] Bad block manage failed when doing wear-levelling!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//set the data block item by the free block
|
||||
BMM_SetDataBlk(tmpLogicBlk, &tmpFreeBlk);
|
||||
|
||||
if(tmpSpare[0].LogicInfo != 0xffff)
|
||||
{
|
||||
//erase the data block to a new free block
|
||||
result = LML_VirtualBlkErase(CUR_MAP_ZONE, tmpDataBlk.PhyBlkNum);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_DBG("[LOGICCTL_DBG] Erase super block failed when doing wear-levelling!\n");
|
||||
result = LML_BadBlkManage(&tmpDataBlk, CUR_MAP_ZONE, 0, NULL);
|
||||
if(result < 0)
|
||||
{
|
||||
LOGICCTL_ERR("[LOGICCTL_ERR] Bad block manage failed when doing wear-levelling!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//set the the data block to free block table
|
||||
tmpDataBlk.BlkEraseCnt++;
|
||||
BMM_SetFreeBlk(&tmpDataBlk);
|
||||
}
|
||||
else
|
||||
{
|
||||
//set the free block back to free table
|
||||
BMM_SetFreeBlk(&tmpFreeBlk);
|
||||
}
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,346 +0,0 @@
|
||||
/*********************************************************************************************************
|
||||
* NAND FLASH DRIVER
|
||||
* (c) Copyright 2008, SoftWinners Co,Ld.
|
||||
* All Right Reserved
|
||||
*file : nand_simple.c
|
||||
*description : this file creates some physic basic access function based on single plane for boot .
|
||||
*history :
|
||||
* v0.1 2008-03-26 Richard
|
||||
* v0.2 2009-9-3 penggang modified for 1615
|
||||
*
|
||||
*********************************************************************************************************/
|
||||
#include "../include/nand_type.h"
|
||||
#include "../include/nand_physic.h"
|
||||
#include "../include/nand_simple.h"
|
||||
#include "../include/nfc.h"
|
||||
|
||||
|
||||
extern __s32 _read_status(__u32 cmd_value, __u32 nBank);
|
||||
extern void _add_cmd_list(NFC_CMD_LIST *cmd,__u32 value,__u32 addr_cycle,__u8 *addr,__u8 data_fetch_flag,
|
||||
__u8 main_data_fetch,__u32 bytecnt,__u8 wait_rb_flag);
|
||||
extern __u8 _cal_real_chip(__u32 global_bank);
|
||||
extern __u8 _cal_real_rb(__u32 chip);
|
||||
extern void _cal_addr_in_chip(__u32 block, __u32 page, __u32 sector,__u8 *addr, __u8 cycle);
|
||||
extern void _pending_dma_irq_sem(void);
|
||||
extern void _pending_rb_irq_sem(void);
|
||||
extern __u32 _cal_random_seed(__u32 page);
|
||||
|
||||
/***************************************************************************
|
||||
*************************write one align single page data**************************
|
||||
****************************************************************************/
|
||||
|
||||
__s32 _write_signle_page (struct boot_physical_param *writeop,__u32 program1,__u32 program2,__u8 dma_wait_mode, __u8 rb_wait_mode )
|
||||
{
|
||||
__s32 ret;
|
||||
__u32 rb;
|
||||
__u32 random_seed;
|
||||
//__u8 *sparebuf;
|
||||
__u8 sparebuf[4*32];
|
||||
__u8 addr[5];
|
||||
NFC_CMD_LIST cmd_list[4];
|
||||
__u32 list_len,i,addr_cycle;
|
||||
|
||||
MEMSET(sparebuf, 0xff, SECTOR_CNT_OF_SINGLE_PAGE * 4);
|
||||
if (writeop->oobbuf){
|
||||
MEMCPY(sparebuf,writeop->oobbuf,SECTOR_CNT_OF_SINGLE_PAGE * 4);
|
||||
}
|
||||
/*create cmd list*/
|
||||
addr_cycle = (SECTOR_CNT_OF_SINGLE_PAGE == 1)?4:5;
|
||||
|
||||
/*the cammand have no corresponding feature if IGNORE was set, */
|
||||
_cal_addr_in_chip(writeop->block,writeop->page,0,addr,addr_cycle);
|
||||
_add_cmd_list(cmd_list,program1,addr_cycle,addr,NFC_DATA_FETCH,NFC_IGNORE,NFC_IGNORE,NFC_NO_WAIT_RB);
|
||||
_add_cmd_list(cmd_list + 1,0x85,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
|
||||
_add_cmd_list(cmd_list + 2,program2,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
|
||||
|
||||
list_len = 3;
|
||||
for(i = 0; i < list_len - 1; i++){
|
||||
cmd_list[i].next = &(cmd_list[i+1]);
|
||||
}
|
||||
rb = _cal_real_rb(writeop->chip);
|
||||
NFC_SelectChip(writeop->chip);
|
||||
NFC_SelectRb(rb);
|
||||
|
||||
if(SUPPORT_RANDOM)
|
||||
{
|
||||
random_seed = _cal_random_seed(writeop->page);
|
||||
NFC_SetRandomSeed(random_seed);
|
||||
NFC_RandomEnable();
|
||||
ret = NFC_Write(cmd_list, writeop->mainbuf, sparebuf, dma_wait_mode, rb_wait_mode, NFC_PAGE_MODE);
|
||||
NFC_RandomDisable();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NFC_Write(cmd_list, writeop->mainbuf, sparebuf, dma_wait_mode, rb_wait_mode, NFC_PAGE_MODE);
|
||||
}
|
||||
|
||||
|
||||
NFC_DeSelectChip(writeop->chip);
|
||||
NFC_DeSelectRb(rb);
|
||||
if (dma_wait_mode)
|
||||
_pending_dma_irq_sem();
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
__s32 _write_signle_page_seq (struct boot_physical_param *writeop,__u32 program1,__u32 program2,__u8 dma_wait_mode, __u8 rb_wait_mode )
|
||||
{
|
||||
__s32 ret;
|
||||
__u32 rb;
|
||||
__u32 random_seed;
|
||||
//__u8 *sparebuf;
|
||||
__u8 sparebuf[4*32];
|
||||
__u8 addr[5];
|
||||
NFC_CMD_LIST cmd_list[4];
|
||||
__u32 list_len,i,addr_cycle;
|
||||
|
||||
MEMSET(sparebuf, 0xff, SECTOR_CNT_OF_SINGLE_PAGE * 4);
|
||||
if (writeop->oobbuf){
|
||||
MEMCPY(sparebuf,writeop->oobbuf,SECTOR_CNT_OF_SINGLE_PAGE * 4);
|
||||
}
|
||||
/*create cmd list*/
|
||||
addr_cycle = (SECTOR_CNT_OF_SINGLE_PAGE == 1)?4:5;
|
||||
|
||||
/*the cammand have no corresponding feature if IGNORE was set, */
|
||||
_cal_addr_in_chip(writeop->block,writeop->page,0,addr,addr_cycle);
|
||||
_add_cmd_list(cmd_list,program1,addr_cycle,addr,NFC_DATA_FETCH,NFC_IGNORE,NFC_IGNORE,NFC_NO_WAIT_RB);
|
||||
_add_cmd_list(cmd_list + 1,0x85,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
|
||||
_add_cmd_list(cmd_list + 2,program2,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
|
||||
|
||||
list_len = 3;
|
||||
for(i = 0; i < list_len - 1; i++){
|
||||
cmd_list[i].next = &(cmd_list[i+1]);
|
||||
}
|
||||
rb = _cal_real_rb(writeop->chip);
|
||||
NFC_SelectChip(writeop->chip);
|
||||
NFC_SelectRb(rb);
|
||||
|
||||
|
||||
if(SUPPORT_RANDOM)
|
||||
{
|
||||
random_seed = 0x4a80;
|
||||
NFC_SetRandomSeed(random_seed);
|
||||
NFC_RandomEnable();
|
||||
ret = NFC_Write_Seq(cmd_list, writeop->mainbuf, sparebuf, dma_wait_mode, rb_wait_mode, NFC_PAGE_MODE);
|
||||
NFC_RandomDisable();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NFC_Write_Seq(cmd_list, writeop->mainbuf, sparebuf, dma_wait_mode, rb_wait_mode, NFC_PAGE_MODE);
|
||||
}
|
||||
|
||||
|
||||
NFC_DeSelectChip(writeop->chip);
|
||||
NFC_DeSelectRb(rb);
|
||||
if (dma_wait_mode)
|
||||
_pending_dma_irq_sem();
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
__s32 _write_signle_page_1K (struct boot_physical_param *writeop,__u32 program1,__u32 program2,__u8 dma_wait_mode, __u8 rb_wait_mode )
|
||||
{
|
||||
__s32 ret;
|
||||
__u32 rb;
|
||||
__u32 random_seed;
|
||||
//__u8 *sparebuf;
|
||||
__u8 sparebuf[4*32];
|
||||
__u8 addr[5];
|
||||
NFC_CMD_LIST cmd_list[4];
|
||||
__u32 list_len,i,addr_cycle;
|
||||
|
||||
MEMSET(sparebuf, 0xff, SECTOR_CNT_OF_SINGLE_PAGE * 4);
|
||||
if (writeop->oobbuf){
|
||||
MEMCPY(sparebuf,writeop->oobbuf,SECTOR_CNT_OF_SINGLE_PAGE * 4);
|
||||
}
|
||||
/*create cmd list*/
|
||||
addr_cycle = (SECTOR_CNT_OF_SINGLE_PAGE == 1)?4:5;
|
||||
|
||||
/*the cammand have no corresponding feature if IGNORE was set, */
|
||||
_cal_addr_in_chip(writeop->block,writeop->page,0,addr,addr_cycle);
|
||||
_add_cmd_list(cmd_list,program1,addr_cycle,addr,NFC_DATA_FETCH,NFC_IGNORE,NFC_IGNORE,NFC_NO_WAIT_RB);
|
||||
_add_cmd_list(cmd_list + 1,0x85,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
|
||||
_add_cmd_list(cmd_list + 2,program2,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
|
||||
|
||||
list_len = 3;
|
||||
for(i = 0; i < list_len - 1; i++){
|
||||
cmd_list[i].next = &(cmd_list[i+1]);
|
||||
}
|
||||
rb = _cal_real_rb(writeop->chip);
|
||||
NFC_SelectChip(writeop->chip);
|
||||
NFC_SelectRb(rb);
|
||||
|
||||
|
||||
if(1)
|
||||
{
|
||||
random_seed = 0x4a80;
|
||||
NFC_SetRandomSeed(random_seed);
|
||||
NFC_RandomEnable();
|
||||
ret = NFC_Write_1K(cmd_list, writeop->mainbuf, sparebuf, dma_wait_mode, rb_wait_mode, NFC_PAGE_MODE);
|
||||
NFC_RandomDisable();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NFC_Write_1K(cmd_list, writeop->mainbuf, sparebuf, dma_wait_mode, rb_wait_mode, NFC_PAGE_MODE);
|
||||
}
|
||||
|
||||
|
||||
NFC_DeSelectChip(writeop->chip);
|
||||
NFC_DeSelectRb(rb);
|
||||
if (dma_wait_mode)
|
||||
_pending_dma_irq_sem();
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
__s32 _erase_single_block(struct boot_physical_param *eraseop)
|
||||
{
|
||||
__s32 ret;
|
||||
__u32 rb;
|
||||
__u8 addr[5];
|
||||
NFC_CMD_LIST cmd_list[4];
|
||||
__u32 list_len,i;
|
||||
|
||||
/*create cmd list*/
|
||||
/*the cammand have no corresponding feature if IGNORE was set, */
|
||||
list_len = 2;
|
||||
_cal_addr_in_chip(eraseop->block,0,0,addr,3);
|
||||
_add_cmd_list(cmd_list,0x60,3,addr,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
|
||||
_add_cmd_list(cmd_list + 1,0xd0,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
|
||||
|
||||
for(i = 0; i < list_len - 1; i++){
|
||||
cmd_list[i].next = &(cmd_list[i+1]);
|
||||
}
|
||||
|
||||
rb = _cal_real_rb(eraseop->chip);
|
||||
NFC_SelectChip(eraseop->chip);
|
||||
NFC_SelectRb(rb);
|
||||
ret = NFC_Erase(cmd_list, 0);
|
||||
NFC_DeSelectChip(eraseop->chip);
|
||||
NFC_DeSelectRb(rb);
|
||||
return ret;
|
||||
}
|
||||
__s32 PHY_SimpleWrite (struct boot_physical_param *writeop)
|
||||
{
|
||||
__s32 status;
|
||||
__u32 rb;
|
||||
|
||||
__s32 ret;
|
||||
|
||||
ret = _write_signle_page(writeop,0x80,0x10,0,0);
|
||||
if (ret)
|
||||
return -1;
|
||||
rb = _cal_real_rb(writeop->chip);
|
||||
NFC_SelectChip(writeop->chip);
|
||||
NFC_SelectRb(rb);
|
||||
/*get status*/
|
||||
while(1){
|
||||
status = _read_status(0x70,writeop->chip);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
if (status & NAND_STATUS_READY)
|
||||
break;
|
||||
}
|
||||
if (status & NAND_OPERATE_FAIL)
|
||||
ret = -2;
|
||||
NFC_DeSelectChip(writeop->chip);
|
||||
NFC_DeSelectRb(rb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
__s32 PHY_SimpleWrite_Seq (struct boot_physical_param *writeop)
|
||||
{
|
||||
__s32 status;
|
||||
__u32 rb;
|
||||
|
||||
__s32 ret;
|
||||
|
||||
ret = _write_signle_page_seq(writeop,0x80,0x10,0,0);
|
||||
if (ret)
|
||||
return -1;
|
||||
rb = _cal_real_rb(writeop->chip);
|
||||
NFC_SelectChip(writeop->chip);
|
||||
NFC_SelectRb(rb);
|
||||
/*get status*/
|
||||
while(1){
|
||||
status = _read_status(0x70,writeop->chip);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
if (status & NAND_STATUS_READY)
|
||||
break;
|
||||
}
|
||||
if (status & NAND_OPERATE_FAIL)
|
||||
ret = -2;
|
||||
NFC_DeSelectChip(writeop->chip);
|
||||
NFC_DeSelectRb(rb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
__s32 PHY_SimpleWrite_1K (struct boot_physical_param *writeop)
|
||||
{
|
||||
__s32 status;
|
||||
__u32 rb;
|
||||
|
||||
__s32 ret;
|
||||
|
||||
ret = _write_signle_page_1K(writeop,0x80,0x10,0,0);
|
||||
if (ret)
|
||||
return -1;
|
||||
rb = _cal_real_rb(writeop->chip);
|
||||
NFC_SelectChip(writeop->chip);
|
||||
NFC_SelectRb(rb);
|
||||
/*get status*/
|
||||
while(1){
|
||||
status = _read_status(0x70,writeop->chip);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
if (status & NAND_STATUS_READY)
|
||||
break;
|
||||
}
|
||||
if (status & NAND_OPERATE_FAIL)
|
||||
ret = -2;
|
||||
NFC_DeSelectChip(writeop->chip);
|
||||
NFC_DeSelectRb(rb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
//#pragma arm section code="PHY_SimpleErase"
|
||||
__s32 PHY_SimpleErase (struct boot_physical_param *eraseop )
|
||||
{
|
||||
__s32 status;
|
||||
__s32 ret;
|
||||
__u32 rb;
|
||||
|
||||
|
||||
ret = _erase_single_block(eraseop);
|
||||
if (ret)
|
||||
return -1;
|
||||
rb = _cal_real_rb(eraseop->chip);
|
||||
NFC_SelectChip(eraseop->chip);
|
||||
NFC_SelectRb(rb);
|
||||
/*get status*/
|
||||
while(1){
|
||||
status = _read_status(0x70,eraseop->chip);
|
||||
if (status & NAND_STATUS_READY)
|
||||
break;
|
||||
}
|
||||
if (status & NAND_OPERATE_FAIL)
|
||||
ret = -2;
|
||||
|
||||
NFC_DeSelectChip(eraseop->chip);
|
||||
NFC_DeSelectRb(rb);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
@ -1,464 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver scan module
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : nand_id.c
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.03.27
|
||||
*
|
||||
* Description : This file is a table, that record the physical architecture parameter for
|
||||
* every kind of nand flash, and indexed by the nand chip ID.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.03.27 0.1 build the file
|
||||
* penggang 2009.09.09 0.2 modify the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
#include "../include/nand_scan.h"
|
||||
|
||||
//==============================================================================
|
||||
// define the optional operation parameter for different kindes of nand flash
|
||||
//==============================================================================
|
||||
|
||||
//the physical architecture parameter for Samsung 2K page SLC nand flash
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara0 =
|
||||
{
|
||||
{0x00, 0x30}, //multi-plane read command
|
||||
{0x11, 0x81}, //multi-plane program command
|
||||
{0x00, 0x00, 0x35}, //multi-plane page copy-back read command
|
||||
{0x85, 0x11, 0x81}, //multi-plane page copy-back program command
|
||||
0x70, //multi-plane operation status read command
|
||||
0xf1, //inter-leave bank0 operation status read command
|
||||
0xf2, //inter-leave bank1 operation status read command
|
||||
0x01, //bad block flag position, in the fist 2 page
|
||||
1 //multi-plane block address offset
|
||||
};
|
||||
|
||||
//the physical architecture parameter for Samsung 4K page SLC nand flash
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara1 =
|
||||
{
|
||||
{0x60, 0x30}, //multi-plane read command
|
||||
{0x11, 0x81}, //multi-plane program command
|
||||
{0x60, 0x60, 0x35}, //multi-plane page copy-back read command
|
||||
{0x85, 0x11, 0x81}, //multi-plane page copy-back program command
|
||||
0x70, //multi-plane operation status read command
|
||||
0xf1, //inter-leave bank0 operation status read command
|
||||
0xf2, //inter-leave bank1 operation status read command
|
||||
0x00, //bad block flag position, in the fist page
|
||||
1 //multi-plane block address offset
|
||||
};
|
||||
|
||||
//the physical architecture parameter for Samsung 2K page MLC nand flash
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara2 =
|
||||
{
|
||||
{0x00, 0x30}, //multi-plane read command
|
||||
{0x11, 0x81}, //multi-plane program command
|
||||
{0x00, 0x00, 0x35}, //multi-plane page copy-back read command
|
||||
{0x85, 0x11, 0x81}, //multi-plane page copy-back program command
|
||||
0x70, //multi-plane operation status read command
|
||||
0xf1, //inter-leave bank0 operation status read command
|
||||
0xf2, //inter-leave bank1 operation status read command
|
||||
0x02, //bad block flag position, in the last page
|
||||
1 //multi-plane block address offset
|
||||
};
|
||||
|
||||
//the physical architecture parameter for Samsung 4K page MLC nand flash
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara3 =
|
||||
{
|
||||
{0x60, 0x60}, //multi-plane read command
|
||||
{0x11, 0x81}, //multi-plane program command
|
||||
{0x60, 0x60, 0x35}, //multi-plane page copy-back read command
|
||||
{0x85, 0x11, 0x81}, //multi-plane page copy-back program command
|
||||
0x70, //multi-plane operation status read command
|
||||
0xf1, //inter-leave bank0 operation status read command
|
||||
0xf2, //inter-leave bank1 operation status read command
|
||||
0x02, //bad block flag position, in the last page
|
||||
1 //multi-plane block address offset
|
||||
};
|
||||
|
||||
//the physical architecture parameter for Micon nand flash
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara4 =
|
||||
{
|
||||
{0x00, 0x30}, //multi-plane read command
|
||||
{0x11, 0x80}, //multi-plane program command
|
||||
{0x00, 0x00, 0x35}, //multi-plane page copy-back read command
|
||||
{0x85, 0x11, 0x80}, //multi-plane page copy-back program command
|
||||
0x70, //multi-plane operation status read command
|
||||
0x78, //inter-leave bank0 operation status read command
|
||||
0x78, //inter-leave bank1 operation status read command
|
||||
0x01, //bad block flag position, in the fist 2 page
|
||||
1 //multi-plane block address offset
|
||||
};
|
||||
|
||||
//the physical architecture parameter for Toshiba SLC nand flash
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara5 =
|
||||
{
|
||||
{0x00, 0x30}, //multi-plane read command
|
||||
{0x11, 0x80}, //multi-plane program command
|
||||
{0x00, 0x00, 0x30}, //multi-plane page copy-back read command
|
||||
{0x8c, 0x11, 0x8c}, //multi-plane page copy-back program command
|
||||
0x71, //multi-plane operation status read command
|
||||
0x70, //inter-leave bank0 operation status read command
|
||||
0x70, //inter-leave bank1 operation status read command
|
||||
0x00, //bad block flag position, in the fist page
|
||||
0 //multi-plane block address offset
|
||||
};
|
||||
|
||||
//the physical architecture parameter for Toshiba MLC nand flash which multi-plane offset is 1024
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara6 =
|
||||
{
|
||||
{0x00, 0x30}, //multi-plane read command
|
||||
{0x11, 0x80}, //multi-plane program command
|
||||
{0x00, 0x00, 0x30}, //multi-plane page copy-back read command
|
||||
{0x8c, 0x11, 0x8c}, //multi-plane page copy-back program command
|
||||
0x71, //multi-plane operation status read command
|
||||
0x70, //inter-leave bank0 operation status read command
|
||||
0x70, //inter-leave bank1 operation status read command
|
||||
0x00, //bad block flag position, in the fist page
|
||||
1024 //multi-plane block address offset
|
||||
};
|
||||
|
||||
//the physical architecture parameter for Toshiba MLC nand flash which multi-plane offset is 2048
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara7 =
|
||||
{
|
||||
{0x00, 0x30}, //multi-plane read command
|
||||
{0x11, 0x80}, //multi-plane program command
|
||||
{0x00, 0x00, 0x30}, //multi-plane page copy-back read command
|
||||
{0x8c, 0x11, 0x8c}, //multi-plane page copy-back program command
|
||||
0x71, //multi-plane operation status read command
|
||||
0x70, //inter-leave bank0 operation status read command
|
||||
0x70, //inter-leave bank1 operation status read command
|
||||
0x00, //bad block flag position, in the fist page
|
||||
2048 //multi-plane block address offset
|
||||
};
|
||||
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara8 =
|
||||
{
|
||||
{0x00, 0x30}, //multi-plane read command
|
||||
{0x11, 0x80}, //multi-plane program command
|
||||
{0x00, 0x00, 0x30}, //multi-plane page copy-back read command
|
||||
{0x8c, 0x11, 0x8c}, //multi-plane page copy-back program command
|
||||
0x71, //multi-plane operation status read command
|
||||
0x70, //inter-leave bank0 operation status read command
|
||||
0x70, //inter-leave bank1 operation status read command
|
||||
0x02, //bad block flag position, in the last page
|
||||
1 //multi-plane block address offset
|
||||
};
|
||||
|
||||
static struct __OptionalPhyOpPar_t PhysicArchiPara9 =
|
||||
{
|
||||
{0x00, 0x30}, //multi-plane read command
|
||||
{0x11, 0x81}, //multi-plane program command
|
||||
{0x00, 0x00, 0x30}, //multi-plane page copy-back read command
|
||||
{0x8c, 0x11, 0x8c}, //multi-plane page copy-back program command
|
||||
0x71, //multi-plane operation status read command
|
||||
0x70, //inter-leave bank0 operation status read command
|
||||
0x70, //inter-leave bank1 operation status read command
|
||||
0x02, //bad block flag position, in the last page
|
||||
1 //multi-plane block address offset
|
||||
};
|
||||
|
||||
static struct __OptionalPhyOpPar_t DefualtPhysicArchiPara =
|
||||
{
|
||||
{0x00, 0x30}, //multi-plane read command
|
||||
{0x11, 0x81}, //multi-plane program command
|
||||
{0x00, 0x00, 0x35}, //multi-plane page copy-back read command
|
||||
{0x85, 0x11, 0x81}, //multi-plane page copy-back program command
|
||||
0x70, //multi-plane operation status read command
|
||||
0xf1, //inter-leave bank0 operation status read command
|
||||
0xf2, //inter-leave bank1 operation status read command
|
||||
0x00, //bad block flag position, in the fist 2 page
|
||||
1 //multi-plane block address offset
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// define the physical architecture parameter for all kinds of nand flash
|
||||
//==============================================================================
|
||||
|
||||
//==============================================================================
|
||||
//============================ SAMSUNG NAND FLASH ==============================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t SamsungNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry DDRType OperationPar
|
||||
//--------------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xec, 0xf1, 0xff, 0x15, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // K9F1G08
|
||||
{ {0xec, 0xf1, 0x00, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // K9F1G08
|
||||
{ {0xec, 0xda, 0xff, 0x15, 0xff, 0xff, 0xff, 0xff }, 2, 4, 64, 1024, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // K9K2G08
|
||||
{ {0xec, 0xda, 0x10, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 2048, 0x0008, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // K9F2G08
|
||||
{ {0xec, 0xdc, 0xc1, 0x15, 0xff, 0xff, 0xff, 0xff }, 2, 4, 64, 2048, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // K9K4G08
|
||||
{ {0xec, 0xdc, 0x10, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 4096, 0x0008, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // K9F4G08
|
||||
{ {0xec, 0xd3, 0x51, 0x95, 0xff, 0xff, 0xff, 0xff }, 2, 4, 64, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara0 }, // K9K8G08
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xec, 0xd3, 0x50, 0xa6, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 4096, 0x0018, 974, 30, 0, 0, 0, &PhysicArchiPara1 }, // K9F8G08
|
||||
{ {0xec, 0xd5, 0x51, 0xa6, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 4096, 0x0038, 974, 30, 0, 0, 0, &PhysicArchiPara1 }, // K9KAG08
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xec, 0xdc, 0x14, 0x25, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 2048, 0x0008, 974, 20, 0, 0, 0, &PhysicArchiPara2 }, // K9G4G08
|
||||
{ {0xec, 0xdc, 0x14, 0xa5, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 2048, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara2 }, // K9G4G08
|
||||
{ {0xec, 0xd3, 0x55, 0x25, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 2048, 0x0008, 974, 20, 0, 0, 0, &PhysicArchiPara2 }, // K9L8G08
|
||||
{ {0xec, 0xd3, 0x55, 0xa5, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 2048, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara2 }, // K9L8G08
|
||||
{ {0xec, 0xd3, 0x14, 0x25, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 4096, 0x0008, 974, 20, 0, 0, 0, &PhysicArchiPara2 }, // K9G8G08
|
||||
{ {0xec, 0xd3, 0x14, 0xa5, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara2 }, // K9G8G08
|
||||
{ {0xec, 0xd5, 0x55, 0x25, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 4096, 0x0028, 974, 30, 0, 0, 0, &PhysicArchiPara2 }, // K9LAG08
|
||||
{ {0xec, 0xd5, 0x55, 0xa5, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 4096, 0x0028, 974, 30, 0, 0, 0, &PhysicArchiPara2 }, // K9LAG08
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xec, 0xd5, 0x14, 0xb6, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara3 }, // K9GAG08
|
||||
{ {0xec, 0xd7, 0x55, 0xb6, 0xff, 0xff, 0xff, 0xff }, 2, 8, 128, 4096, 0x0028, 974, 30, 0, 0, 0, &PhysicArchiPara3 }, // K9LBG08
|
||||
{ {0xec, 0xd7, 0xd5, 0x29, 0xff, 0xff, 0xff, 0xff }, 2, 8, 128, 4096, 0x0028, 974, 30, 0, 0, 0, &PhysicArchiPara3 }, // K9LBG08
|
||||
{ {0xec, 0xd7, 0x94, 0x72, 0xff, 0xff, 0xff, 0xff }, 1, 16, 128, 4096, 0x0008, 974, 30, 2, 0, 0, &PhysicArchiPara3 }, // K9GBG08
|
||||
{ {0xec, 0xd5, 0x98, 0x71, 0xff, 0xff, 0xff, 0xff }, 1, 8, 256, 2048, 0x0008, 950, 30, 3, 0, 0, &PhysicArchiPara3 }, // K9AAG08
|
||||
|
||||
{ {0xec, 0xd5, 0x94, 0x29, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara3 }, // K9GAG08U0D
|
||||
{ {0xec, 0xd5, 0x84, 0x72, 0xff, 0xff, 0xff, 0xff }, 1, 16, 128, 2048, 0x0000, 950, 24, 2, 0, 0, &PhysicArchiPara3 }, // K9GAG08U0E
|
||||
{ {0xec, 0xd5, 0x94, 0x76, 0x54, 0xff, 0xff, 0xff }, 1, 16, 128, 2048, 0x0408, 950, 30, 2, 0, 0, &PhysicArchiPara3 }, // K9GAG08U0E
|
||||
{ {0xec, 0xd3, 0x84, 0x72, 0xff, 0xff, 0xff, 0xff }, 1, 16, 128, 1024, 0x0000, 950, 24, 2, 0, 0, &PhysicArchiPara3 }, // K9G8G08U0C
|
||||
{ {0xec, 0xd7, 0x94, 0x76, 0xff, 0xff, 0xff, 0xff }, 1, 16, 128, 4096, 0x0088, 974, 30, 3, 0, 0, &PhysicArchiPara3 }, // K9GBG08U0A
|
||||
{ {0xec, 0xd7, 0x94, 0x7A, 0xff, 0xff, 0xff, 0xff }, 1, 16, 128, 4096, 0x0088, 974, 30, 3, 0, 0, &PhysicArchiPara3 }, // K9GBG08U0A
|
||||
{ {0xec, 0xde, 0xd5, 0x7A, 0x58, 0xff, 0xff, 0xff }, 2, 16, 128, 4096, 0x0888, 974, 30, 3, 0, 0, &PhysicArchiPara3 }, // K9LCG08U0A
|
||||
|
||||
{ {0xec, 0xd7, 0x94, 0x7A, 0x54, 0xc3, 0xff, 0xff }, 1, 16, 128, 4096, 0x0088, 974, 60, 1, 0, 3, &PhysicArchiPara3 }, // toogle nand 1.0
|
||||
{ {0xec, 0xde, 0xa4, 0x7a, 0x68, 0xc4, 0xff, 0xff }, 1, 16, 128, 8192, 0x0588, 974, 60, 4, 0x200e04, 3, &PhysicArchiPara3 }, // toogle nand 2.0 K9GCGD8U0A
|
||||
{ {0xec, 0xd7, 0x94, 0x7E, 0x64, 0xc4, 0xff, 0xff }, 1, 16, 128, 4096, 0x0588, 974, 60, 4, 0x200e04, 3, &PhysicArchiPara3 }, // toogle nand 2.0 K9GBGD8U0B
|
||||
{ {0xec, 0xd7, 0x94, 0x7e, 0x64, 0x44, 0xff, 0xff }, 1, 16, 128, 4096, 0x0588, 974, 40, 4, 0x200e04, 0, &PhysicArchiPara3 }, // 21nm sdr K9GBG08U0B
|
||||
{ {0xec, 0xde, 0xd5, 0x7e, 0x68, 0x44, 0xff, 0xff }, 2, 16, 128, 4096, 0x0588, 974, 40, 4, 0x200e04, 0, &PhysicArchiPara3 }, // 21nm sdr K9LCG08U0B
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0 }, // NULL
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//============================= HYNIX NAND FLASH ===============================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t HynixNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry OperationPar
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xad, 0xf1, 0x80, 0x15, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // HY27UF081G2M
|
||||
{ {0xad, 0xf1, 0x80, 0x1d, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara0 }, // HY27UF081G2A
|
||||
{ {0xad, 0xf1, 0x00, 0x1d, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara0 }, // H27U1G8F2B
|
||||
{ {0xad, 0xda, 0x80, 0x15, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 2048, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // HY27UF082G2M
|
||||
{ {0xad, 0xda, 0x80, 0x1d, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 2048, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara0 }, // HY27UF082G2A
|
||||
{ {0xad, 0xda, 0x10, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 2048, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara0 }, // HY27UF082G2B
|
||||
{ {0xad, 0xdc, 0x80, 0x15, 0xff, 0xff, 0xff, 0xff }, 4, 4, 64, 1024, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // HY27UH084G2M
|
||||
{ {0xad, 0xdc, 0x80, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 4096, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara0 }, // HY27UF084G2M, HY27UG088G5M
|
||||
{ {0xad, 0xdc, 0x10, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 4096, 0x0008, 974, 20, 0, 0, 0, &PhysicArchiPara0 }, // HY27UF084G2B, HY27UG088G5B
|
||||
{ {0xad, 0xd3, 0x80, 0x15, 0xff, 0xff, 0xff, 0xff }, 4, 4, 64, 2048, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara0 }, // HY27UG084G2M, HY27H088G2M
|
||||
{ {0xad, 0xd3, 0xc1, 0x95, 0xff, 0xff, 0xff, 0xff }, 2, 4, 64, 4096, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara0 }, // HY27UG088G2M, HY27UH08AG5M
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xad, 0xdc, 0x84, 0x25, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 2048, 0x0000, 974, 12, 0, 0, 0, &PhysicArchiPara2 }, // HY27UT084G2M, HY27UU088G5M
|
||||
{ {0xad, 0xdc, 0x14, 0xa5, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 2048, 0x0008, 974, 15, 0, 0, 0, &PhysicArchiPara2 }, // HY27U4G8T2BTR
|
||||
{ {0xad, 0xd3, 0x85, 0x25, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 2048, 0x0000, 974, 10, 0, 0, 0, &PhysicArchiPara2 }, // HY27UV08AG5M, HY27UW08BGFM
|
||||
{ {0xad, 0xd3, 0x14, 0x25, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 4096, 0x0008, 974, 12, 0, 0, 0, &PhysicArchiPara2 }, // HY27UT088G2M, HY27UU08AG5M
|
||||
{ {0xad, 0xd3, 0x14, 0x2d, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 4096, 0x0008, 974, 25, 0, 0, 0, &PhysicArchiPara2 }, // HY27UT088G2M, HY27UU08AG5M
|
||||
{ {0xad, 0xd3, 0x14, 0xa5, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 4096, 0x0008, 974, 15, 0, 0, 0, &PhysicArchiPara2 }, // HY27UT088G2M, HY27UU08AG5M
|
||||
{ {0xad, 0xd5, 0x55, 0x25, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 4096, 0x0008, 974, 15, 0, 0, 0, &PhysicArchiPara2 }, // HY27UV08BG5M, HY27UW08CGFM
|
||||
{ {0xad, 0xd5, 0x55, 0x2d, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 4096, 0x0008, 974, 25, 0, 0, 0, &PhysicArchiPara2 }, // HY27UV08BG5M, HY27UW08CGFM
|
||||
{ {0xad, 0xd5, 0x55, 0xa5, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 8192, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara2 }, // HY27UV08BG5M, HY27UW08CGFM
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xad, 0xd3, 0x14, 0xb6, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 2048, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara3 }, // H27U8G8T2B
|
||||
{ {0xad, 0xd5, 0x14, 0xb6, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara3 }, // H27UAG8T2M, H27UBG8U5M
|
||||
{ {0xad, 0xd7, 0x55, 0xb6, 0xff, 0xff, 0xff, 0xff }, 2, 8, 128, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara3 }, // H27UCG8V5M
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xad, 0xd5, 0x94, 0x25, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 4096, 0x0008, 974, 30, 2, 0, 0, &PhysicArchiPara3 }, // H27UBG8U5A
|
||||
{ {0xad, 0xd7, 0x95, 0x25, 0xff, 0xff, 0xff, 0xff }, 2, 8, 128, 4096, 0x0008, 974, 30, 2, 0, 0, &PhysicArchiPara3 }, // H27UCG8V5A
|
||||
{ {0xad, 0xd5, 0x95, 0x25, 0xff, 0xff, 0xff, 0xff }, 2, 8, 128, 4096, 0x0008, 974, 30, 2, 0, 0, &PhysicArchiPara3 }, // H27UCG8VFA
|
||||
{ {0xad, 0xd5, 0x94, 0x9A, 0xff, 0xff, 0xff, 0xff }, 1, 16, 256, 1024, 0x0000, 950, 30, 2, 0, 0, &PhysicArchiPara3 }, // H27UAG8T2B
|
||||
{ {0xad, 0xd7, 0x94, 0x9A, 0xff, 0xff, 0xff, 0xff }, 1, 16, 256, 2048, 0x0008, 950, 30, 2, 0, 0, &PhysicArchiPara3 }, // H27UBG8T2A H27UCG8U5(D)A H27UDG8VF(D)A
|
||||
{ {0xad, 0xde, 0xd5, 0x9A, 0xff, 0xff, 0xff, 0xff }, 2, 16, 256, 2048, 0x0008, 950, 30, 2, 0, 0, &PhysicArchiPara3 }, // H27UDG8V5A
|
||||
{ {0xad, 0xd7, 0x94, 0x25, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 8192, 0x0008, 974, 30, 2, 0, 0, &PhysicArchiPara3 }, // H27UBG8T2M
|
||||
{ {0xad, 0xde, 0x94, 0xd2, 0xff, 0xff, 0xff, 0xff }, 1, 16, 256, 4096, 0x0188, 950, 30, 2, 0x000604, 0, &PhysicArchiPara3 }, // H27UCG8T2M
|
||||
{ {0xad, 0xd7, 0x18, 0x8d, 0xff, 0xff, 0xff, 0xff }, 1, 8, 256, 4096, 0x0188, 950, 30, 3, 0x000604, 0, &PhysicArchiPara3 }, // H27UBG8M2A
|
||||
{ {0xad, 0xd7, 0x94, 0xda, 0xff, 0xff, 0xff, 0xff }, 1, 16, 256, 2048, 0x0188, 950, 30, 3, 0x010604, 0, &PhysicArchiPara3 }, // H27UBG8M2A
|
||||
{ {0xad, 0xde, 0x94, 0xda, 0x74, 0xff, 0xff, 0xff }, 1, 16, 256, 4096, 0x0188, 928, 40, 4, 0x020708, 0, &PhysicArchiPara3 }, // H27UCG8T2A 20nm 8G
|
||||
{ {0xad, 0xd7, 0x94, 0x91, 0x60, 0xff, 0xff, 0xff }, 1, 16, 256, 2048, 0x0188, 928, 40, 4, 0x030708, 0, &PhysicArchiPara3 }, // H27UBG8T2C 20nm 4G
|
||||
{ {0xad, 0xde, 0x94, 0xeb, 0x74, 0xff, 0xff, 0xff }, 1, 32, 256, 2048, 0x0188, 928, 40, 4, 0x030708, 0, &PhysicArchiPara3 }, // H27UCG8T2B 20nm 8G
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0 }, // NULL
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//============================= TOSHIBA NAND FLASH =============================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t ToshibaNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry OperationPar
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x98, 0xf1, 0x80, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara5 }, // TC58NVG0S3B
|
||||
{ {0x98, 0xda, 0xff, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 2048, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara5 }, // TC58NVG1S3B
|
||||
{ {0x98, 0xdc, 0x81, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 4096, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara5 }, // TC58NVG2S3B
|
||||
{ {0x98, 0xd1, 0x90, 0x15, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara5 }, // TC58NVG0S3E
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x98, 0xda, 0x84, 0xa5, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 1024, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara6 }, // TC58NVG1D4B
|
||||
{ {0x98, 0xdc, 0x84, 0xa5, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 2048, 0x0008, 974, 20, 0, 0, 0, &PhysicArchiPara6 }, // TC58NVG2D4B
|
||||
{ {0x98, 0xd3, 0x84, 0xa5, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 4096, 0x0008, 974, 20, 0, 0, 0, &PhysicArchiPara7 }, // TC58NVG3D4C
|
||||
{ {0x98, 0xd5, 0x85, 0xa5, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 4096, 0x0008, 974, 20, 0, 0, 0, &PhysicArchiPara7 }, // TC58NVG4D4C, TC58NVG5D4C
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x98, 0xd3, 0x94, 0xba, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 2048, 0x0008, 974, 20, 0, 0, 0, &PhysicArchiPara6 }, // TC58NVG3D1DTG00
|
||||
{ {0x98, 0xd7, 0x95, 0xba, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 8192, 0x0008, 918, 30, 2, 0, 0, &PhysicArchiPara7 }, // TC58NVG6D1DTG20
|
||||
{ {0x98, 0xd5, 0x94, 0xba, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 4096, 0x0008, 918, 30, 2, 0, 0, &PhysicArchiPara7}, // TH58NVG5D1DTG20
|
||||
{ {0x98, 0xd5, 0x94, 0x32, 0xff, 0xff, 0xff, 0xff }, 1, 16, 128, 2048, 0x0008, 918, 25, 1, 0, 0, &PhysicArchiPara8}, // TH58NVG4D2ETA20 TH58NVG4D2FTA20 TH58NVG5D2ETA00
|
||||
{ {0x98, 0xd7, 0x94, 0x32, 0xff, 0xff, 0xff, 0xff }, 1, 16, 128, 4096, 0x0008, 918, 25, 2, 0, 0, &PhysicArchiPara8}, // TH58NVG5D2FTA00 TH58NVG6D2FTA20
|
||||
{ {0x98, 0xd7, 0x95, 0x32, 0xff, 0xff, 0xff, 0xff }, 2, 16, 128, 4096, 0x0008, 454, 25, 1, 0, 0, &PhysicArchiPara8}, // TH58NVG6D2ETA20
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x98, 0xde, 0x94, 0x82, 0x76, 0xff, 0xff, 0xff }, 1, 16, 256, 4096, 0x0588, 918, 40, 4, 0x100504, 0, &PhysicArchiPara9}, // TH58NVG6D2ETA20
|
||||
{ {0x98, 0xd7, 0x94, 0x32, 0x76, 0x56, 0xff, 0xff }, 1, 16, 128, 4096, 0x0588, 918, 40, 4, 0x100504, 0, &PhysicArchiPara9}, // TH58NVG5D2HTA20
|
||||
{ {0x98, 0xd5, 0x84, 0x32, 0x72, 0x56, 0xff, 0xff }, 1, 16, 128, 2048, 0x0580, 918, 40, 4, 0x100504, 0, &PhysicArchiPara9}, // TH58NVG4D2HTA20
|
||||
{ {0x98, 0xde, 0x84, 0x93, 0x72, 0x57, 0xff, 0xff }, 1, 32, 256, 2048, 0x0580, 918, 40, 4, 0x100504, 0, &PhysicArchiPara9}, // TC58NVG6DCJTA00
|
||||
{ {0x98, 0xd7, 0x84, 0x93, 0x72, 0x57, 0xff, 0xff }, 1, 32, 256, 1024, 0x0580, 918, 40, 4, 0x100504, 0, &PhysicArchiPara9}, // TC58TEG5DCJTA00
|
||||
{ {0x98, 0xde, 0x84, 0x93, 0x72, 0x57, 0xff, 0xff }, 1, 32, 256, 2048, 0x0580, 918, 40, 4, 0x100504, 0, &PhysicArchiPara9}, // TC58TEG6DCJTA00
|
||||
{ {0x98, 0xde, 0x94, 0x93, 0x76, 0x57, 0xff, 0xff }, 1, 32, 256, 2048, 0x0588, 918, 40, 4, 0x100504, 0, &PhysicArchiPara9}, // TC58TEG6DDJTA00
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0 }, // NULL
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//============================= MICON NAND FLASH ===============================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t MicronNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry OperationPar
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x2c, 0xda, 0xff, 0x15, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 2048, 0x0000, 974, 25, 0, 0, 0, &PhysicArchiPara4 }, // MT29F2G08AAC, JS29F02G08AAN
|
||||
{ {0x2c, 0xdc, 0xff, 0x15, 0xff, 0xff, 0xff, 0xff }, 2, 4, 64, 2048, 0x0000, 974, 25, 0, 0, 0, &PhysicArchiPara4 }, // MT29F4G08BAB, MT29F8G08FAB, JS29F04G08BAN, JS29F08G08FAN
|
||||
{ {0x2c, 0xdc, 0x90, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 4096, 0x0008, 974, 25, 0, 0, 0, &PhysicArchiPara4 }, // MT29F4G08AAA, MT29F8G08DAA, JS29F04G08AAN
|
||||
{ {0x2c, 0xd3, 0xd1, 0x95, 0xff, 0xff, 0xff, 0xff }, 2, 4, 64, 4096, 0x0008, 974, 25, 0, 0, 0, &PhysicArchiPara4 }, // MT29F8G08BAB, MT29F16G08FAB, JS29F08G08BAN, JS29F16G08FAN
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x2c, 0xdc, 0x84, 0x25, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 2048, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara4 }, // MT29F4G08MAA, MT29F8G08QAA
|
||||
{ {0x2c, 0xd3, 0x85, 0x25, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 2048, 0x0000, 974, 20, 0, 0, 0, &PhysicArchiPara4 }, // MT29F16GTAA
|
||||
{ {0x2c, 0xd3, 0x94, 0xa5, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara4 }, // MT29F8G08MAA, MT29F16G08QAA, JS29F08G08AAM, JS29F16G08CAM
|
||||
{ {0x2c, 0xd5, 0x95, 0xa5, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 4096, 0x0008, 974, 20, 0, 0, 0, &PhysicArchiPara4 }, // MT29F32G08TAA, JS29F32G08FAM
|
||||
{ {0x2c, 0xd5, 0xd5, 0xa5, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 4096, 0x0028, 974, 20, 0, 0, 0, &PhysicArchiPara4 }, // MT29F32G08TAA, JS29F32G08FAM
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x2c, 0xd5, 0x94, 0x3e, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara4 }, // MT29F16G08MAA, MT29F32G08QAA, JS29F32G08AAM, JS29F32G08CAM
|
||||
{ {0x2c, 0xd5, 0xd5, 0x3e, 0xff, 0xff, 0xff, 0xff }, 2, 8, 128, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara4 }, // MT29F64G08TAA, JS29F64G08FAM
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x2c, 0xd7, 0x94, 0x3e, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 8192, 0x0208, 950, 30, 2, 0, 0, &PhysicArchiPara4 }, // MT29F32G08CBAAA,MT29F64G08CFAAA
|
||||
{ {0x2c, 0xd7, 0xd5, 0x3e, 0xff, 0xff, 0xff, 0xff }, 2, 8, 128, 4096, 0x0008, 950, 30, 2, 0, 0, &PhysicArchiPara4 }, // MT29F64G08CTAA
|
||||
{ {0x2c, 0xd9, 0xd5, 0x3e, 0xff, 0xff, 0xff, 0xff }, 2, 8, 128, 8192, 0x0008, 950, 30, 2, 0, 0, &PhysicArchiPara4 }, // MT29F128G08,
|
||||
{ {0x2c, 0x68, 0x04, 0x46, 0xff, 0xff, 0xff, 0xff }, 1, 8, 256, 4096, 0x0208, 950, 30, 2, 0, 0, &PhysicArchiPara4 }, // MT29F32G08CBABA
|
||||
{ {0x2c, 0x88, 0x05, 0xC6, 0xff, 0xff, 0xff, 0xff }, 2, 8, 256, 4096, 0x0208, 950, 30, 2, 0, 0, &PhysicArchiPara4 }, // MT29F128G08CJABA
|
||||
{ {0x2c, 0x88, 0x04, 0x4B, 0xff, 0xff, 0xff, 0xff }, 1, 16, 256, 4096, 0x0208, 950, 40, 2, 0, 0, &PhysicArchiPara4 }, // MT29F64G08CBAAA
|
||||
{ {0x2c, 0x68, 0x04, 0x4A, 0xff, 0xff, 0xff, 0xff }, 1, 8, 256, 4096, 0x0208, 950, 40, 2, 0, 0, &PhysicArchiPara4 }, // MT29F32G08CBACA
|
||||
{ {0x2c, 0x48, 0x04, 0x4A, 0xff, 0xff, 0xff, 0xff }, 1, 8, 256, 2048, 0x0208, 950, 40, 2, 0, 0, &PhysicArchiPara4 }, // MT29F16G08CBACA
|
||||
{ {0x2c, 0x48, 0x04, 0x46, 0xff, 0xff, 0xff, 0xff }, 1, 8, 256, 2048, 0x0208, 950, 30, 2, 0, 0, &PhysicArchiPara4 }, // MT29F16G08CBABA
|
||||
{ {0x2c, 0x64, 0x44, 0x4B, 0xff, 0xff, 0xff, 0xff }, 1, 16, 256, 4096, 0x0788, 950, 30, 5, 0x400a01, 0, &PhysicArchiPara4 }, // MT29F64G08CBABA
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0 }, // NULL
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//============================= INTEL NAND FLASH ===============================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t IntelNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry OperationPar
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x89, 0xd3, 0x94, 0xa5, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 4096, 0x0008, 974, 30, 0, 0, 0, &PhysicArchiPara4 }, // 29F08G08AAMB2, 29F16G08CAMB2
|
||||
{ {0x89, 0xd5, 0xd5, 0xa5, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 4096, 0x0028, 974, 20, 0, 0, 0, &PhysicArchiPara4 }, // 29F32G08FAMB2
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x89, 0xd7, 0x94, 0x3e, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 8192, 0x0008, 918, 30, 2, 0, 0, &PhysicArchiPara4 }, // MLC32GW8IMA,MLC64GW8IMA, 29F32G08AAMD2, 29F64G08CAMD2
|
||||
{ {0x89, 0xd5, 0x94, 0x3e, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 4096, 0x0008, 918, 30, 2, 0, 0, &PhysicArchiPara4 }, // 29F32G08CAMC1
|
||||
{ {0x89, 0xd7, 0xd5, 0x3e, 0xff, 0xff, 0xff, 0xff }, 1, 8, 128, 8192, 0x0008, 918, 30, 2, 0, 0, &PhysicArchiPara4 }, // 29F64G08FAMC1
|
||||
{ {0x89, 0x68, 0x04, 0x46, 0xff, 0xff, 0xff, 0xff }, 1, 8, 256, 4096, 0x0208, 918, 30, 2, 0, 0, &PhysicArchiPara4 }, // 29F32G08AAMDB
|
||||
{ {0x89, 0x88, 0x24, 0x4B, 0xff, 0xff, 0xff, 0xff }, 1, 16, 256, 4096, 0x0208, 918, 30, 2, 0, 0, &PhysicArchiPara4 }, // 29F64G08CBAAA 29F64G083AME1
|
||||
{ {0x89, 0xA8, 0x25, 0xCB, 0xff, 0xff, 0xff, 0xff }, 2, 16, 256, 4096, 0x0208, 918, 30, 2, 0, 0, &PhysicArchiPara4 }, // 29F64G08CBAAA 29F64G083AME1
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0 }, // NULL
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//=============================== ST NAND FLASH ================================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t StNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry OperationPar
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x20, 0xf1, 0x80, 0x15, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // NAND01GW3B
|
||||
{ {0x20, 0xf1, 0x00, 0x1d, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // NAND01G001
|
||||
{ {0x20, 0xda, 0x80, 0x15, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 2048, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // NAND02GW3B
|
||||
{ {0x20, 0xda, 0x10, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 2048, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // NAND02GW3B2DN6
|
||||
{ {0x20, 0xdc, 0x80, 0x95, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 4096, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // NAND04GW3B
|
||||
{ {0x20, 0xd3, 0xc1, 0x95, 0xff, 0xff, 0xff, 0xff }, 2, 4, 64, 4096, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara0 }, // NAND08GW3B
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x20, 0xdc, 0x84, 0x25, 0xff, 0xff, 0xff, 0xff }, 1, 4, 128, 2048, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara2 }, // NAND04GW3C
|
||||
{ {0x20, 0xd3, 0x85, 0x25, 0xff, 0xff, 0xff, 0xff }, 2, 4, 128, 2048, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara2 }, // NAND08GW3C
|
||||
{ {0x20, 0xd3, 0x85, 0x25, 0xff, 0xff, 0xff, 0xff }, 4, 4, 128, 2048, 0x0000, 974, 15, 0, 0, 0, &PhysicArchiPara2 }, // NAND16GW3C
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0 }, // NULL
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
//============================ SPANSION NAND FLASH ==============================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t SpansionNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry OperationPar
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x01, 0xaa, 0x10, 0x00, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 2048, 0x0000, 974, 30, 0, 0, 0, &PhysicArchiPara0 }, // S39MS02G
|
||||
{ {0x01, 0xa1, 0x10, 0x00, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 30, 0, 0, 0, &PhysicArchiPara0 }, // S39MS01G
|
||||
{ {0x01, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 30, 0, 0, 0, &PhysicArchiPara0 }, // DFT01GR08P1PM0
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0 }, // NULL
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
//============================ POWER NAND FLASH ==============================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t PowerNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry OperationPar
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x92, 0xf1, 0x80, 0x95, 0x40, 0xff, 0xff, 0xff }, 1, 4, 64, 1024, 0x0000, 974, 30, 0, 0, 0, &PhysicArchiPara0 }, // ASU1GA
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0 }, // NULL
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//============================ SANDDISK NAND FLASH ==============================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t SandiskNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry OperationPar
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0x45, 0xde, 0x94, 0x93, 0xff, 0xff, 0xff, 0xff }, 1, 32, 256, 2048, 0x0188, 950, 40, 4, 0x301409, 0, &PhysicArchiPara0 }, // SDTNQGAMA-008G
|
||||
{ {0x45, 0xd7, 0x84, 0x93, 0xff, 0xff, 0xff, 0xff }, 1, 32, 256, 1024, 0x0180, 950, 40, 4, 0x301409, 0, &PhysicArchiPara0 }, // SDTNQFAMA-004G
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0 }, // NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//============================= DEFAULT NAND FLASH =============================
|
||||
//==============================================================================
|
||||
struct __NandPhyInfoPar_t DefaultNandTbl[] =
|
||||
{
|
||||
// NAND_CHIP_ID DieCnt SecCnt PagCnt BlkCnt OpOpt DatBlk Freq EccMode ReadRetry OperationPar
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, &DefualtPhysicArchiPara }, //default
|
||||
};
|
||||
|
@ -1,549 +0,0 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eNand
|
||||
* Nand flash driver scan module
|
||||
*
|
||||
* Copyright(C), 2008-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : nand_scan.c
|
||||
*
|
||||
* Author : Kevin.z
|
||||
*
|
||||
* Version : v0.1
|
||||
*
|
||||
* Date : 2008.03.27
|
||||
*
|
||||
* Description : This file scan the nand flash storage system, analyze the nand flash type
|
||||
* and initiate the physical architecture parameters.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Kevin.z 2008.03.27 0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
#include "../include/nand_scan.h"
|
||||
#include"../include/nfc.h"
|
||||
|
||||
|
||||
extern struct __NandStorageInfo_t NandStorageInfo;
|
||||
|
||||
extern struct __NandPhyInfoPar_t SamsungNandTbl;
|
||||
extern struct __NandPhyInfoPar_t HynixNandTbl;
|
||||
extern struct __NandPhyInfoPar_t ToshibaNandTbl;
|
||||
extern struct __NandPhyInfoPar_t MicronNandTbl;
|
||||
extern struct __NandPhyInfoPar_t IntelNandTbl;
|
||||
extern struct __NandPhyInfoPar_t StNandTbl;
|
||||
extern struct __NandPhyInfoPar_t DefaultNandTbl;
|
||||
extern struct __NandPhyInfoPar_t SpansionNandTbl;
|
||||
extern struct __NandPhyInfoPar_t PowerNandTbl;
|
||||
extern struct __NandPhyInfoPar_t SandiskNandTbl;
|
||||
|
||||
|
||||
__u32 NAND_GetValidBlkRatio(void)
|
||||
{
|
||||
return NandStorageInfo.ValidBlkRatio;
|
||||
}
|
||||
|
||||
__s32 NAND_SetValidBlkRatio(__u32 ValidBlkRatio)
|
||||
{
|
||||
NandStorageInfo.ValidBlkRatio = (__u16)ValidBlkRatio;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
__u32 NAND_GetFrequencePar(void)
|
||||
{
|
||||
return NandStorageInfo.FrequencePar;
|
||||
}
|
||||
|
||||
__s32 NAND_SetFrequencePar(__u32 FrequencePar)
|
||||
{
|
||||
NandStorageInfo.FrequencePar = (__u8)FrequencePar;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
__u32 NAND_GetNandVersion(void)
|
||||
{
|
||||
__u32 nand_version;
|
||||
|
||||
nand_version = 0;
|
||||
nand_version |= 0xff;
|
||||
nand_version |= 0x00<<8;
|
||||
nand_version |= NAND_VERSION_0<<16;
|
||||
nand_version |= NAND_VERSION_1<<24;
|
||||
|
||||
return nand_version;
|
||||
}
|
||||
|
||||
__s32 NAND_GetParam(boot_nand_para_t * nand_param)
|
||||
{
|
||||
__u32 i;
|
||||
|
||||
nand_param->ChipCnt = NandStorageInfo.ChipCnt ;
|
||||
nand_param->ChipConnectInfo = NandStorageInfo.ChipConnectInfo ;
|
||||
nand_param->RbCnt = NandStorageInfo.RbCnt ;
|
||||
nand_param->RbConnectInfo = NandStorageInfo.RbConnectInfo ;
|
||||
nand_param->RbConnectMode = NandStorageInfo.RbConnectMode ;
|
||||
nand_param->BankCntPerChip = NandStorageInfo.BankCntPerChip ;
|
||||
nand_param->DieCntPerChip = NandStorageInfo.DieCntPerChip ;
|
||||
nand_param->PlaneCntPerDie = NandStorageInfo.PlaneCntPerDie ;
|
||||
nand_param->SectorCntPerPage = NandStorageInfo.SectorCntPerPage ;
|
||||
nand_param->PageCntPerPhyBlk = NandStorageInfo.PageCntPerPhyBlk ;
|
||||
nand_param->BlkCntPerDie = NandStorageInfo.BlkCntPerDie ;
|
||||
nand_param->OperationOpt = NandStorageInfo.OperationOpt ;
|
||||
nand_param->FrequencePar = NandStorageInfo.FrequencePar ;
|
||||
nand_param->EccMode = NandStorageInfo.EccMode ;
|
||||
nand_param->ValidBlkRatio = NandStorageInfo.ValidBlkRatio ;
|
||||
nand_param->good_block_ratio = NandStorageInfo.ValidBlkRatio ;
|
||||
nand_param->ReadRetryType = NandStorageInfo.ReadRetryType ;
|
||||
nand_param->DDRType = NandStorageInfo.DDRType ;
|
||||
|
||||
for(i =0; i<8; i++)
|
||||
nand_param->NandChipId[i] = NandStorageInfo.NandChipId[i];
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__s32 NAND_GetFlashInfo(boot_flash_info_t *param)
|
||||
{
|
||||
param->chip_cnt = NandStorageInfo.ChipCnt;
|
||||
param->blk_cnt_per_chip = NandStorageInfo.BlkCntPerDie * NandStorageInfo.DieCntPerChip;
|
||||
param->blocksize = SECTOR_CNT_OF_SINGLE_PAGE * PAGE_CNT_OF_PHY_BLK;
|
||||
param->pagesize = SECTOR_CNT_OF_SINGLE_PAGE;
|
||||
param->pagewithbadflag = NandStorageInfo.OptPhyOpPar.BadBlockFlagPosition;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SEARCH NAND PHYSICAL ARCHITECTURE PARAMETER
|
||||
*
|
||||
*Description: Search the nand flash physical architecture parameter from the parameter table
|
||||
* by nand chip ID.
|
||||
*
|
||||
*Arguments : pNandID the pointer to nand flash chip ID;
|
||||
* pNandArchiInfo the pointer to nand flash physical architecture parameter.
|
||||
*
|
||||
*Return : search result;
|
||||
* = 0 search successful, find the parameter in the table;
|
||||
* < 0 search failed, can't find the parameter in the table.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 _SearchNandArchi(__u8 *pNandID, struct __NandPhyInfoPar_t *pNandArchInfo)
|
||||
{
|
||||
__s32 i=0, j=0, k=0;
|
||||
__u32 id_match_tbl[3]={0xffff, 0xffff, 0xffff};
|
||||
__u32 id_bcnt;
|
||||
struct __NandPhyInfoPar_t *tmpNandManu;
|
||||
|
||||
//analyze the manufacture of the nand flash
|
||||
switch(pNandID[0])
|
||||
{
|
||||
//manufacture is Samsung, search parameter from Samsung nand table
|
||||
case SAMSUNG_NAND:
|
||||
tmpNandManu = &SamsungNandTbl;
|
||||
break;
|
||||
|
||||
//manufacture is Hynix, search parameter from Hynix nand table
|
||||
case HYNIX_NAND:
|
||||
tmpNandManu = &HynixNandTbl;
|
||||
break;
|
||||
|
||||
//manufacture is Micron, search parameter from Micron nand table
|
||||
case MICRON_NAND:
|
||||
tmpNandManu = &MicronNandTbl;
|
||||
break;
|
||||
|
||||
//manufacture is Intel, search parameter from Intel nand table
|
||||
case INTEL_NAND:
|
||||
tmpNandManu = &IntelNandTbl;
|
||||
break;
|
||||
|
||||
//manufacture is Toshiba, search parameter from Toshiba nand table
|
||||
case TOSHIBA_NAND:
|
||||
tmpNandManu = &ToshibaNandTbl;
|
||||
break;
|
||||
|
||||
//manufacture is St, search parameter from St nand table
|
||||
case ST_NAND:
|
||||
tmpNandManu = &StNandTbl;
|
||||
break;
|
||||
|
||||
//manufacture is Spansion, search parameter from Spansion nand table
|
||||
case SPANSION_NAND:
|
||||
tmpNandManu = &SpansionNandTbl;
|
||||
break;
|
||||
|
||||
//manufacture is power, search parameter from Spansion nand table
|
||||
case POWER_NAND:
|
||||
tmpNandManu = &PowerNandTbl;
|
||||
break;
|
||||
|
||||
//manufacture is sandisk, search parameter from sandisk nand table
|
||||
case SANDISK:
|
||||
tmpNandManu = &SandiskNandTbl;
|
||||
break;
|
||||
|
||||
//manufacture is unknown, search parameter from default nand table
|
||||
default:
|
||||
tmpNandManu = &DefaultNandTbl;
|
||||
break;
|
||||
}
|
||||
|
||||
//search the nand architecture parameter from the given manufacture nand table by nand ID
|
||||
while(tmpNandManu[i].NandID[0] != 0xff)
|
||||
{
|
||||
//compare 6 byte id
|
||||
id_bcnt = 1;
|
||||
for(j=1; j<6; j++)
|
||||
{
|
||||
//0xff is matching all ID value
|
||||
if((pNandID[j] != tmpNandManu[i].NandID[j]) && (tmpNandManu[i].NandID[j] != 0xff))
|
||||
break;
|
||||
|
||||
if(tmpNandManu[i].NandID[j] != 0xff)
|
||||
id_bcnt++;
|
||||
}
|
||||
|
||||
if(j == 6)
|
||||
{
|
||||
/*4 bytes of the nand chip ID are all matching, search parameter successful*/
|
||||
if(id_bcnt == 4)
|
||||
id_match_tbl[0] = i;
|
||||
else if(id_bcnt == 5)
|
||||
id_match_tbl[1] = i;
|
||||
else if(id_bcnt == 6)
|
||||
id_match_tbl[2] = i;
|
||||
}
|
||||
|
||||
//prepare to search the next table item
|
||||
i++;
|
||||
}
|
||||
|
||||
for(k=2; k>=0;k--)
|
||||
{
|
||||
|
||||
if(id_match_tbl[k]!=0xffff)
|
||||
{
|
||||
i= id_match_tbl[k];
|
||||
MEMCPY(pNandArchInfo,tmpNandManu+i,sizeof(struct __NandPhyInfoPar_t));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//search nand architecture parameter failed
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* ANALYZE NAND FLASH STORAGE SYSTEM
|
||||
*
|
||||
*Description: Analyze nand flash storage system, generate the nand flash physical
|
||||
* architecture parameter and connect information.
|
||||
*
|
||||
*Arguments : none
|
||||
*
|
||||
*Return : analyze result;
|
||||
* = 0 analyze successful;
|
||||
* < 0 analyze failed, can't recognize or some other error.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 SCN_AnalyzeNandSystem(void)
|
||||
{
|
||||
__s32 i,result;
|
||||
__u8 tmpChipID[8];
|
||||
__u8 uniqueID[32];
|
||||
struct __NandPhyInfoPar_t tmpNandPhyInfo;
|
||||
|
||||
//init nand flash storage information to default value
|
||||
NandStorageInfo.ChipCnt = 1;
|
||||
NandStorageInfo.ChipConnectInfo = 1;
|
||||
NandStorageInfo.RbConnectMode= 1;
|
||||
NandStorageInfo.RbCnt= 1;
|
||||
NandStorageInfo.RbConnectInfo= 1;
|
||||
NandStorageInfo.BankCntPerChip = 1;
|
||||
NandStorageInfo.DieCntPerChip = 1;
|
||||
NandStorageInfo.PlaneCntPerDie = 1;
|
||||
NandStorageInfo.SectorCntPerPage = 4;
|
||||
NandStorageInfo.PageCntPerPhyBlk = 64;
|
||||
NandStorageInfo.BlkCntPerDie = 1024;
|
||||
NandStorageInfo.OperationOpt = 0;
|
||||
NandStorageInfo.FrequencePar = 10;
|
||||
NandStorageInfo.EccMode = 0;
|
||||
NandStorageInfo.ReadRetryType= 0;
|
||||
|
||||
//reset the nand flash chip on boot chip select
|
||||
result = PHY_ResetChip(BOOT_CHIP_SELECT_NUM);
|
||||
result |= PHY_SynchBank(BOOT_CHIP_SELECT_NUM, SYNC_CHIP_MODE);
|
||||
if(result)
|
||||
{
|
||||
SCAN_ERR("[SCAN_ERR] Reset boot nand flash chip failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//read nand flash chip ID from boot chip
|
||||
result = PHY_ReadNandId(BOOT_CHIP_SELECT_NUM, tmpChipID);
|
||||
if(result)
|
||||
{
|
||||
SCAN_ERR("[SCAN_ERR] Read chip ID from boot chip failed!\n");
|
||||
return -1;
|
||||
}
|
||||
SCAN_DBG("[SCAN_DBG] Nand flash chip id is:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
||||
tmpChipID[0],tmpChipID[1],tmpChipID[2],tmpChipID[3], tmpChipID[4],tmpChipID[5]);
|
||||
|
||||
//search the nand flash physical architecture parameter by nand ID
|
||||
result = _SearchNandArchi(tmpChipID, &tmpNandPhyInfo);
|
||||
if(result)
|
||||
{
|
||||
SCAN_ERR("[SCAN_ERR] search nand physical architecture parameter failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//set the nand flash physical architecture parameter
|
||||
NandStorageInfo.BankCntPerChip = tmpNandPhyInfo.DieCntPerChip;
|
||||
NandStorageInfo.DieCntPerChip = tmpNandPhyInfo.DieCntPerChip;
|
||||
NandStorageInfo.PlaneCntPerDie = 2;
|
||||
NandStorageInfo.SectorCntPerPage = tmpNandPhyInfo.SectCntPerPage;
|
||||
NandStorageInfo.PageCntPerPhyBlk = tmpNandPhyInfo.PageCntPerBlk;
|
||||
NandStorageInfo.BlkCntPerDie = tmpNandPhyInfo.BlkCntPerDie;
|
||||
NandStorageInfo.OperationOpt = tmpNandPhyInfo.OperationOpt;
|
||||
NandStorageInfo.FrequencePar = tmpNandPhyInfo.AccessFreq;
|
||||
NandStorageInfo.EccMode = tmpNandPhyInfo.EccMode;
|
||||
NandStorageInfo.NandChipId[0] = tmpNandPhyInfo.NandID[0];
|
||||
NandStorageInfo.NandChipId[1] = tmpNandPhyInfo.NandID[1];
|
||||
NandStorageInfo.NandChipId[2] = tmpNandPhyInfo.NandID[2];
|
||||
NandStorageInfo.NandChipId[3] = tmpNandPhyInfo.NandID[3];
|
||||
NandStorageInfo.NandChipId[4] = tmpNandPhyInfo.NandID[4];
|
||||
NandStorageInfo.NandChipId[5] = tmpNandPhyInfo.NandID[5];
|
||||
NandStorageInfo.NandChipId[6] = tmpNandPhyInfo.NandID[6];
|
||||
NandStorageInfo.NandChipId[7] = tmpNandPhyInfo.NandID[7];
|
||||
NandStorageInfo.ValidBlkRatio = tmpNandPhyInfo.ValidBlkRatio;
|
||||
NandStorageInfo.ReadRetryType = tmpNandPhyInfo.ReadRetryType;
|
||||
NandStorageInfo.DDRType = tmpNandPhyInfo.DDRType;
|
||||
//set the optional operation parameter
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneReadCmd[0] = tmpNandPhyInfo.OptionOp->MultiPlaneReadCmd[0];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneReadCmd[1] = tmpNandPhyInfo.OptionOp->MultiPlaneReadCmd[1];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneWriteCmd[0] = tmpNandPhyInfo.OptionOp->MultiPlaneWriteCmd[0];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneWriteCmd[1] = tmpNandPhyInfo.OptionOp->MultiPlaneWriteCmd[1];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[0] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyReadCmd[0];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[1] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyReadCmd[1];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[2] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyReadCmd[2];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[0] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyWriteCmd[0];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[1] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyWriteCmd[1];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[2] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyWriteCmd[2];
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneStatusCmd = tmpNandPhyInfo.OptionOp->MultiPlaneStatusCmd;
|
||||
NandStorageInfo.OptPhyOpPar.InterBnk0StatusCmd = tmpNandPhyInfo.OptionOp->InterBnk0StatusCmd;
|
||||
NandStorageInfo.OptPhyOpPar.InterBnk1StatusCmd = tmpNandPhyInfo.OptionOp->InterBnk1StatusCmd;
|
||||
NandStorageInfo.OptPhyOpPar.BadBlockFlagPosition = tmpNandPhyInfo.OptionOp->BadBlockFlagPosition;
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneBlockOffset = tmpNandPhyInfo.OptionOp->MultiPlaneBlockOffset;
|
||||
|
||||
//set some configurable optional operation parameter
|
||||
if(!CFG_SUPPORT_MULTI_PLANE_PROGRAM)
|
||||
{
|
||||
NandStorageInfo.OperationOpt &= ~NAND_MULTI_READ;
|
||||
NandStorageInfo.OperationOpt &= ~NAND_MULTI_PROGRAM;
|
||||
}
|
||||
|
||||
if(!CFG_SUPPORT_INT_INTERLEAVE)
|
||||
{
|
||||
NandStorageInfo.OperationOpt &= ~NAND_INT_INTERLEAVE;
|
||||
}
|
||||
|
||||
if(!CFG_SUPPORT_RANDOM)
|
||||
{
|
||||
NandStorageInfo.OperationOpt &= ~NAND_RANDOM;
|
||||
}
|
||||
|
||||
if(!CFG_SUPPORT_READ_RETRY)
|
||||
{
|
||||
NandStorageInfo.OperationOpt &= ~NAND_READ_RETRY;
|
||||
}
|
||||
|
||||
if(!CFG_SUPPORT_ALIGN_NAND_BNK)
|
||||
{
|
||||
NandStorageInfo.OperationOpt |= NAND_PAGE_ADR_NO_SKIP;
|
||||
}
|
||||
|
||||
//process the plane count of a die and the bank count of a chip
|
||||
if(!SUPPORT_MULTI_PROGRAM)
|
||||
{
|
||||
NandStorageInfo.PlaneCntPerDie = 1;
|
||||
}
|
||||
|
||||
if(!SUPPORT_INT_INTERLEAVE)
|
||||
{
|
||||
NandStorageInfo.BankCntPerChip = 1;
|
||||
}
|
||||
|
||||
//process the rb connect infomation
|
||||
for(i=1; i<MAX_CHIP_SELECT_CNT; i++)
|
||||
{
|
||||
//reset current nand flash chip
|
||||
PHY_ResetChip((__u32)i);
|
||||
|
||||
//read the nand chip ID from current nand flash chip
|
||||
PHY_ReadNandId((__u32)i, tmpChipID);
|
||||
//check if the nand flash id same as the boot chip
|
||||
if((tmpChipID[0] == NandStorageInfo.NandChipId[0]) && (tmpChipID[1] == NandStorageInfo.NandChipId[1])
|
||||
&& (tmpChipID[2] == NandStorageInfo.NandChipId[2]) && (tmpChipID[3] == NandStorageInfo.NandChipId[3])
|
||||
&& ((tmpChipID[4] == NandStorageInfo.NandChipId[4])||(NandStorageInfo.NandChipId[4]==0xff))
|
||||
&& ((tmpChipID[5] == NandStorageInfo.NandChipId[5])||(NandStorageInfo.NandChipId[5]==0xff)))
|
||||
{
|
||||
NandStorageInfo.ChipCnt++;
|
||||
NandStorageInfo.ChipConnectInfo |= (1<<i);
|
||||
}
|
||||
}
|
||||
|
||||
//process the rb connect infomation
|
||||
{
|
||||
NandStorageInfo.RbConnectMode = 0xff;
|
||||
|
||||
if((NandStorageInfo.ChipCnt == 1) && (NandStorageInfo.ChipConnectInfo & (1<<0)))
|
||||
{
|
||||
NandStorageInfo.RbConnectMode =1;
|
||||
}
|
||||
else if(NandStorageInfo.ChipCnt == 2)
|
||||
{
|
||||
if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<1)))
|
||||
NandStorageInfo.RbConnectMode =2;
|
||||
else if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<2)))
|
||||
NandStorageInfo.RbConnectMode =3;
|
||||
else if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<7)))
|
||||
NandStorageInfo.RbConnectMode =0; //special use, only one rb
|
||||
|
||||
}
|
||||
|
||||
else if(NandStorageInfo.ChipCnt == 4)
|
||||
{
|
||||
if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<1))
|
||||
&& (NandStorageInfo.ChipConnectInfo & (1<<2)) && (NandStorageInfo.ChipConnectInfo & (1<<3)) )
|
||||
NandStorageInfo.RbConnectMode =4;
|
||||
else if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<2))
|
||||
&& (NandStorageInfo.ChipConnectInfo & (1<<4)) && (NandStorageInfo.ChipConnectInfo & (1<<6)) )
|
||||
NandStorageInfo.RbConnectMode =5;
|
||||
}
|
||||
else if(NandStorageInfo.ChipCnt == 8)
|
||||
{
|
||||
NandStorageInfo.RbConnectMode =8;
|
||||
}
|
||||
|
||||
if( NandStorageInfo.RbConnectMode == 0xff)
|
||||
{
|
||||
SCAN_ERR("%s : check nand rb connect fail, ChipCnt = %x, ChipConnectInfo = %x \n",__FUNCTION__, NandStorageInfo.ChipCnt, NandStorageInfo.ChipConnectInfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//process the external inter-leave operation
|
||||
if(CFG_SUPPORT_EXT_INTERLEAVE)
|
||||
{
|
||||
if(NandStorageInfo.ChipCnt > 1)
|
||||
{
|
||||
NandStorageInfo.OperationOpt |= NAND_EXT_INTERLEAVE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NandStorageInfo.OperationOpt &= ~NAND_EXT_INTERLEAVE;
|
||||
}
|
||||
|
||||
if(SUPPORT_READ_UNIQUE_ID)
|
||||
{
|
||||
for(i=0; i<NandStorageInfo.ChipCnt; i++)
|
||||
{
|
||||
PHY_ReadNandUniqueId(i, uniqueID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*configure page size*/
|
||||
{
|
||||
NFC_INIT_INFO nand_info;
|
||||
nand_info.bus_width = 0x0;
|
||||
nand_info.ce_ctl = 0x0;
|
||||
nand_info.ce_ctl1 = 0x0;
|
||||
nand_info.debug = 0x0;
|
||||
nand_info.pagesize = SECTOR_CNT_OF_SINGLE_PAGE;
|
||||
nand_info.rb_sel = 1;
|
||||
nand_info.serial_access_mode = 1;
|
||||
nand_info.ddr_type = DDR_TYPE;
|
||||
NFC_ChangMode(&nand_info);
|
||||
}
|
||||
|
||||
PHY_ChangeMode(1);
|
||||
|
||||
if(SUPPORT_READ_RETRY)
|
||||
{
|
||||
PHY_DBG("NFC Read Retry Init. \n");
|
||||
NFC_ReadRetryInit(READ_RETRY_TYPE);
|
||||
|
||||
for(i=0; i<NandStorageInfo.ChipCnt;i++)
|
||||
{
|
||||
PHY_GetDefaultParam(i);
|
||||
}
|
||||
|
||||
}
|
||||
//print nand flash physical architecture parameter
|
||||
SCAN_DBG("\n\n");
|
||||
SCAN_DBG("[SCAN_DBG] ==============Nand Architecture Parameter==============\n");
|
||||
SCAN_DBG("[SCAN_DBG] Nand Chip ID: 0x%x 0x%x\n",
|
||||
(NandStorageInfo.NandChipId[0] << 0) | (NandStorageInfo.NandChipId[1] << 8)
|
||||
| (NandStorageInfo.NandChipId[2] << 16) | (NandStorageInfo.NandChipId[3] << 24),
|
||||
(NandStorageInfo.NandChipId[4] << 0) | (NandStorageInfo.NandChipId[5] << 8)
|
||||
| (NandStorageInfo.NandChipId[6] << 16) | (NandStorageInfo.NandChipId[7] << 24));
|
||||
SCAN_DBG("[SCAN_DBG] Nand Chip Count: 0x%x\n", NandStorageInfo.ChipCnt);
|
||||
SCAN_DBG("[SCAN_DBG] Nand Chip Connect: 0x%x\n", NandStorageInfo.ChipConnectInfo);
|
||||
SCAN_DBG("[SCAN_DBG] Nand Rb Connect Mode: 0x%x\n", NandStorageInfo.RbConnectMode);
|
||||
SCAN_DBG("[SCAN_DBG] Sector Count Of Page: 0x%x\n", NandStorageInfo.SectorCntPerPage);
|
||||
SCAN_DBG("[SCAN_DBG] Page Count Of Block: 0x%x\n", NandStorageInfo.PageCntPerPhyBlk);
|
||||
SCAN_DBG("[SCAN_DBG] Block Count Of Die: 0x%x\n", NandStorageInfo.BlkCntPerDie);
|
||||
SCAN_DBG("[SCAN_DBG] Plane Count Of Die: 0x%x\n", NandStorageInfo.PlaneCntPerDie);
|
||||
SCAN_DBG("[SCAN_DBG] Die Count Of Chip: 0x%x\n", NandStorageInfo.DieCntPerChip);
|
||||
SCAN_DBG("[SCAN_DBG] Bank Count Of Chip: 0x%x\n", NandStorageInfo.BankCntPerChip);
|
||||
SCAN_DBG("[SCAN_DBG] Optional Operation: 0x%x\n", NandStorageInfo.OperationOpt);
|
||||
SCAN_DBG("[SCAN_DBG] Access Frequence: 0x%x\n", NandStorageInfo.FrequencePar);
|
||||
SCAN_DBG("[SCAN_DBG] ECC Mode: 0x%x\n", NandStorageInfo.EccMode);
|
||||
SCAN_DBG("[SCAN_DBG] Read Retry Type: 0x%x\n", NandStorageInfo.ReadRetryType);
|
||||
SCAN_DBG("[SCAN_DBG] DDR Type: 0x%x\n", NandStorageInfo.DDRType);
|
||||
SCAN_DBG("[SCAN_DBG] =======================================================\n\n");
|
||||
|
||||
//print nand flash optional operation parameter
|
||||
SCAN_DBG("[SCAN_DBG] ==============Optional Operaion Parameter==============\n");
|
||||
SCAN_DBG("[SCAN_DBG] MultiPlaneReadCmd: 0x%x, 0x%x\n",
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneReadCmd[0],NandStorageInfo.OptPhyOpPar.MultiPlaneReadCmd[1]);
|
||||
SCAN_DBG("[SCAN_DBG] MultiPlaneWriteCmd: 0x%x, 0x%x\n",
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneWriteCmd[0],NandStorageInfo.OptPhyOpPar.MultiPlaneWriteCmd[1]);
|
||||
SCAN_DBG("[SCAN_DBG] MultiPlaneCopyReadCmd: 0x%x, 0x%x, 0x%x\n",
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[0],NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[1],
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[2]);
|
||||
SCAN_DBG("[SCAN_DBG] MultiPlaneCopyWriteCmd: 0x%x, 0x%x, 0x%x\n",
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[0], NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[1],
|
||||
NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[2]);
|
||||
SCAN_DBG("[SCAN_DBG] MultiPlaneStatusCmd: 0x%x\n", NandStorageInfo.OptPhyOpPar.MultiPlaneStatusCmd);
|
||||
SCAN_DBG("[SCAN_DBG] InterBnk0StatusCmd: 0x%x\n", NandStorageInfo.OptPhyOpPar.InterBnk0StatusCmd);
|
||||
SCAN_DBG("[SCAN_DBG] InterBnk1StatusCmd: 0x%x\n", NandStorageInfo.OptPhyOpPar.InterBnk1StatusCmd);
|
||||
SCAN_DBG("[SCAN_DBG] BadBlockFlagPosition: 0x%x\n", NandStorageInfo.OptPhyOpPar.BadBlockFlagPosition);
|
||||
SCAN_DBG("[SCAN_DBG] MultiPlaneBlockOffset: 0x%x\n", NandStorageInfo.OptPhyOpPar.MultiPlaneBlockOffset);
|
||||
SCAN_DBG("[SCAN_DBG] =======================================================\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
1132
boot1/driver/drv_nand/nand_for_boot1_boot/nand_for_boot1.c
Normal file
1132
boot1/driver/drv_nand/nand_for_boot1_boot/nand_for_boot1.c
Normal file
File diff suppressed because it is too large
Load Diff
2
boot1/driver/drv_nand/nand_for_boot1.h → boot1/driver/drv_nand/nand_for_boot1_boot/nand_for_boot1.h
Executable file → Normal file
2
boot1/driver/drv_nand/nand_for_boot1.h → boot1/driver/drv_nand/nand_for_boot1_boot/nand_for_boot1.h
Executable file → Normal file
@ -37,7 +37,7 @@ typedef struct boot_physical_param
|
||||
{
|
||||
__u32 chip; //chip no
|
||||
__u32 block; // block no within chip
|
||||
__u32 page; // apge no within block
|
||||
__u32 page; // page no within block
|
||||
__u64 sectorbitmap; //done't care
|
||||
void *mainbuf; //data buf
|
||||
void *oobbuf; //oob buf
|
45
boot1/driver/drv_nand/nand_for_boot1.c → boot1/driver/drv_nand/nand_for_boot1_card/nand_for_boot1.c
Executable file → Normal file
45
boot1/driver/drv_nand/nand_for_boot1.c → boot1/driver/drv_nand/nand_for_boot1_card/nand_for_boot1.c
Executable file → Normal file
@ -3,9 +3,12 @@
|
||||
#include "bsp_nand.h"
|
||||
#include "string.h"
|
||||
|
||||
#define NAND_FOR_CARD_PHONIX
|
||||
#define OOB_BUF_SIZE 32
|
||||
|
||||
static __u32 nand_good_block_ratio_flag = 0;
|
||||
static __u32 nand_good_blk_ratio = 0;
|
||||
|
||||
|
||||
extern __s32 NAND_Print(const char * str, ...);
|
||||
/*
|
||||
@ -145,9 +148,39 @@ __s32 NAND_PhyInit(void)
|
||||
NAND_Print("NB1 : nand scan fail\n");
|
||||
return ret;
|
||||
}
|
||||
#ifdef NAND_FOR_CARD_PHONIX
|
||||
if(!nand_good_block_ratio_flag)
|
||||
{
|
||||
NAND_GetParam((void *)¶m);
|
||||
nand_good_blk_ratio = NAND_BadBlockScan((void *)¶m);
|
||||
NAND_SetValidBlkRatio(nand_good_blk_ratio);
|
||||
NAND_Print("get the good blk ratio from bad block scan : %d \n", nand_good_blk_ratio);
|
||||
nand_good_block_ratio_flag = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
NAND_Print(" bad blcok has done before,nand good block ratio is : %d \n", nand_good_blk_ratio);
|
||||
NAND_SetValidBlkRatio(nand_good_blk_ratio);
|
||||
}
|
||||
#else
|
||||
//modify ValidBlkRatio
|
||||
// NAND_SetValidBlkRatio(nand_good_blk_ratio);
|
||||
|
||||
if(wBoot_get_para( WBOOT_PARA_NANDFLASH_INFO, (void *)¶m))
|
||||
{
|
||||
NAND_Print("get good block ratio info failed.\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nand_good_blk_ratio = param.good_block_ratio;
|
||||
if(nand_good_blk_ratio == 0)
|
||||
NAND_Print("get the good blk ratio is 0,use preset value\n");
|
||||
else
|
||||
{
|
||||
NAND_SetValidBlkRatio(nand_good_blk_ratio);
|
||||
NAND_Print("get the good blk ratio from hwscan : %d \n", nand_good_blk_ratio);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
NAND_Print("NB1 : nand phy init ok\n");
|
||||
return(PHY_ChangeMode(1));
|
||||
}
|
||||
@ -800,7 +833,7 @@ __s32 NAND_EraseChip( const boot_nand_para_t *nand_param)
|
||||
if(!die_skip_flag)
|
||||
para_read.block = j;
|
||||
else
|
||||
para_read.block = j%block_cnt_of_die + 2*(j/block_cnt_of_die);
|
||||
para_read.block = j%block_cnt_of_die + 2*block_cnt_of_die*(j/block_cnt_of_die);
|
||||
para_read.mainbuf = page_buf_read;
|
||||
para_read.oobbuf = oob_buf_read;
|
||||
|
||||
@ -967,7 +1000,7 @@ __s32 NAND_BadBlockScan(const boot_nand_para_t *nand_param)
|
||||
if(!die_skip_flag)
|
||||
para.block = j;
|
||||
else
|
||||
para.block = j%block_cnt_of_die + 2*(j/block_cnt_of_die);
|
||||
para.block = j%block_cnt_of_die + 2*block_cnt_of_die*(j/block_cnt_of_die);
|
||||
para.mainbuf = page_buf;
|
||||
para.oobbuf = oob_buf;
|
||||
|
||||
@ -1072,7 +1105,7 @@ __s32 NAND_BadBlockScan(const boot_nand_para_t *nand_param)
|
||||
|
||||
|
||||
//cal good block num required per 1024 blocks
|
||||
good_block_num = (1024*(info.blk_cnt_per_chip - bad_block_num))/info.blk_cnt_per_chip -20;
|
||||
good_block_num = (1024*(info.blk_cnt_per_chip - bad_block_num))/info.blk_cnt_per_chip -50;
|
||||
for(i=0; i<info.chip_cnt; i++)
|
||||
{
|
||||
chip = _cal_real_chip( i, nand_param->ChipConnectInfo );
|
||||
@ -1082,7 +1115,7 @@ __s32 NAND_BadBlockScan(const boot_nand_para_t *nand_param)
|
||||
NAND_Print("cal good block num is %u \n", good_block_num);
|
||||
|
||||
//cal good block ratio
|
||||
for(i=0; i<5; i++)
|
||||
for(i=0; i<10; i++)
|
||||
{
|
||||
if(good_block_num >= (nand_param->good_block_ratio - 32*i))
|
||||
{
|
248
boot1/driver/drv_nand/nand_for_boot1_card/nand_for_boot1.h
Normal file
248
boot1/driver/drv_nand/nand_for_boot1_card/nand_for_boot1.h
Normal file
@ -0,0 +1,248 @@
|
||||
#ifndef __NAND_FOR_HWSCAN__
|
||||
#define __NAND_FOR_HWSCAN__
|
||||
|
||||
|
||||
#define SUCCESS 0
|
||||
#define FAIL -1
|
||||
#define BADBLOCK -2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//__u32 ChannelCnt;
|
||||
__u32 ChipCnt; //the count of the total nand flash chips are currently connecting on the CE pin
|
||||
__u32 ChipConnectInfo; //chip connect information, bit == 1 means there is a chip connecting on the CE pin
|
||||
__u32 RbCnt;
|
||||
__u32 RbConnectInfo; //the connect information of the all rb chips are connected
|
||||
__u32 RbConnectMode; //the rb connect mode
|
||||
__u32 BankCntPerChip; //the count of the banks in one nand chip, multiple banks can support Inter-Leave
|
||||
__u32 DieCntPerChip; //the count of the dies in one nand chip, block management is based on Die
|
||||
__u32 PlaneCntPerDie; //the count of planes in one die, multiple planes can support multi-plane operation
|
||||
__u32 SectorCntPerPage; //the count of sectors in one single physic page, one sector is 0.5k
|
||||
__u32 PageCntPerPhyBlk; //the count of physic pages in one physic block
|
||||
__u32 BlkCntPerDie; //the count of the physic blocks in one die, include valid block and invalid block
|
||||
__u32 OperationOpt; //the mask of the operation types which current nand flash can support support
|
||||
__u32 FrequencePar; //the parameter of the hardware access clock, based on 'MHz'
|
||||
__u32 EccMode; //the Ecc Mode for the nand flash chip, 0: bch-16, 1:bch-28, 2:bch_32
|
||||
__u8 NandChipId[8]; //the nand chip id of current connecting nand chip
|
||||
__u32 ValidBlkRatio; //the ratio of the valid physical blocks, based on 1024
|
||||
__u32 good_block_ratio; //good block ratio get from hwscan
|
||||
__u32 ReadRetryType; //the read retry type
|
||||
__u32 DDRType;
|
||||
__u32 Reserved[23];
|
||||
}boot_nand_para_t;
|
||||
|
||||
|
||||
|
||||
typedef struct boot_physical_param
|
||||
{
|
||||
__u32 chip; //chip no
|
||||
__u32 block; // block no within chip
|
||||
__u32 page; // page no within block
|
||||
__u64 sectorbitmap; //done't care
|
||||
void *mainbuf; //data buf
|
||||
void *oobbuf; //oob buf
|
||||
}
|
||||
boot_physical_param_t;
|
||||
|
||||
typedef struct boot_flash_info
|
||||
{
|
||||
__u32 chip_cnt;
|
||||
__u32 blk_cnt_per_chip;
|
||||
__u32 blocksize; //unit by sector
|
||||
__u32 pagesize; //unit by sector
|
||||
__u32 pagewithbadflag; /*bad block flag was written at the first byte of spare area of this page*/
|
||||
}
|
||||
boot_flash_info_t;
|
||||
|
||||
typedef struct _boot_nand_logical_t
|
||||
{
|
||||
__u32 start_sector; //起始扇区
|
||||
__u32 nsector; //总扇区数
|
||||
void *pbuffer; //数据地址
|
||||
}
|
||||
boot_nand_logical_t;
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* SCAN NAND HW
|
||||
*
|
||||
*Description: initial nand flash,request hardware resources;
|
||||
*
|
||||
*Arguments : void.
|
||||
*
|
||||
*Return : = SUCESS initial ok;
|
||||
* = FAIL initial fail.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_HWScanStart(boot_nand_para_t *nand_connect);
|
||||
|
||||
|
||||
/************************************************************************************************************************
|
||||
* NAND_HWScanStop
|
||||
*
|
||||
*Description: release nand flash and free hardware resources;
|
||||
*
|
||||
*Arguments : void.
|
||||
*
|
||||
*Return : = SUCESS release ok;
|
||||
* = FAIL release fail.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_HWScanStop(void);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* GET FLASH INFO
|
||||
*
|
||||
*Description: get some info about nand flash;
|
||||
*
|
||||
*Arguments : *param the stucture with info.
|
||||
*
|
||||
*Return : = SUCESS get ok;
|
||||
* = FAIL get fail.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_GetFlashInfo(struct boot_flash_info *param);
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* GET NAND VERSION INFO
|
||||
*
|
||||
*Description: get some info about nand flash;
|
||||
*
|
||||
*Arguments : *param the stucture with info.
|
||||
*
|
||||
*Return : >0 get ok;
|
||||
* =0 get fail.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__u32 NAND_GetNandVersion(void);
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* READ ONE SINGLE PAGE
|
||||
*
|
||||
*Description: read one page data from nand based on single plane;
|
||||
*
|
||||
*Arguments : *readop - the structure with physical address in nand and data buffer
|
||||
*
|
||||
*Return : = SUCESS read ok;
|
||||
* = FAIL read fail.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_PhyRead (struct boot_physical_param *readop);
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* READ ONE SINGLE PAGE
|
||||
*
|
||||
*Description: read one page data from nand based on single plane;
|
||||
*
|
||||
*Arguments : *readop - the structure with physical address in nand and data buffer
|
||||
*
|
||||
*Return : = SUCESS read ok;
|
||||
* = FAIL read fail.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_PhyRead_Seq (struct boot_physical_param *readop);
|
||||
|
||||
__s32 NAND_PhyRead_1K (struct boot_physical_param *readop);
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* WRITE ONE SINGLE PAGE
|
||||
*
|
||||
*Description: write one page data to nand based on single plane;
|
||||
*
|
||||
*Arguments : *writeop - the structure with physical address in nand and data buffer
|
||||
*
|
||||
*Return : = SUCESS write ok;
|
||||
* = FAIL write fail.
|
||||
* = BADBLOCK write fail and bad block made by program
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_PhyWrite (struct boot_physical_param *writeop);
|
||||
__s32 NAND_PhyWrite_1K (struct boot_physical_param *writeop);
|
||||
__s32 NAND_PhyWrite_Seq (struct boot_physical_param *writeop);
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* ERASE ONE SINGLE BLOCK
|
||||
*
|
||||
*Description: erase one block in nand based on single plane;
|
||||
*
|
||||
*Arguments : *eraseop - the structure with physical address in nand and data buffer
|
||||
*
|
||||
*Return : = SUCESS erase ok;
|
||||
* = FAIL erase fail.
|
||||
* = BADBLOCK erase fail and bad block made by erase
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_PhyErase(struct boot_physical_param *eraseop);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND_VersionCheck
|
||||
*
|
||||
*Description: Check the nand flash driver is current version
|
||||
*
|
||||
*Arguments : void.
|
||||
*
|
||||
*Return : = 0 nand driver version match;
|
||||
* -1 nand driver version not match
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_VersionCheck(void);
|
||||
__s32 NAND_VersionGet(__u8 *version);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND_EraseBootBlocks
|
||||
*
|
||||
*Description: Check the nand flash driver is current version
|
||||
*
|
||||
*Arguments : connecnt info.
|
||||
*
|
||||
*Return : = 0 OK;
|
||||
* other Fail.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_EraseBootBlocks( const boot_nand_para_t *connect_info_p);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* NAND_EraseChip
|
||||
*
|
||||
*Description: Erase chip, only erase the all 0x0 blocks
|
||||
*
|
||||
*Arguments : connecnt info.
|
||||
*
|
||||
*Return : = 0 OK;
|
||||
* other Fail.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
__s32 NAND_EraseChip( const boot_nand_para_t *connect_info_p);
|
||||
|
||||
/*******************************************************************************
|
||||
*函数名称: NAND_BadBlockScan
|
||||
*函数原型:bad_blcok_scan(const _nand_connect_info_t *connect_info_p)
|
||||
*函数功能: 标记blk_num指定的块为坏块。
|
||||
*入口参数: connect_info_p
|
||||
*返 回 值: >0 编程操作成功
|
||||
* -1 编程操作失败
|
||||
*
|
||||
*备 注:
|
||||
*******************************************************************************/
|
||||
__s32 NAND_BadBlockScan(const boot_nand_para_t *connect_info_p);
|
||||
|
||||
|
||||
__s32 NAND_Init(void);
|
||||
__s32 NAND_Exit(void);
|
||||
|
||||
__s32 NAND_PhyInit(void);
|
||||
__s32 NAND_PhyExit(void);
|
||||
|
||||
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user