📄 nand_mtd.c
字号:
{ 0x75EC, 32, 16, 512, 3, 8, NAND_PLANE_BLOCK_BIT0/*0x01*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* K9K1208X0C */
{ 0x76EC, 64, 16, 512, 4, 8, NAND_PLANE_BLOCK_BIT0|NAND_PLANE_BLOCK_BIT1|NAND_PLANE_BLOCK_BIT11/*0x803*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* K9K1G08X0A */
{ 0x79EC, 128, 16, 512, 4, 8, NAND_PLANE_BLOCK_BIT0|NAND_PLANE_BLOCK_BIT1|NAND_PLANE_BLOCK_BIT12/*0x1003*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* K9F1G08X0M */
{ 0xF1EC, 128, 128, 2048, 4, 8, 0, &NANDFlashMtd_2K_hw_enhanced},
/* K9F1G16X0M */
{ 0xC1EC, 128, 128, 2048, 4, 16, 0, &NANDFlashMtd_2K_hw_enhanced},
/* K9F2G08X0M */
{ 0xDAEC, 256, 128, 2048, 5, 8, 0, &NANDFlashMtd_2K_hw_enhanced},
/* K9K8G08U0M */
{ 0xD3EC, 1024, 128, 2048, 5, 8, NAND_PLANE_BLOCK_BIT0|NAND_PLANE_BLOCK_BIT12/*0x1001*/, &NANDFlashMtd_2K_hw_enhanced},
/* K9K4G08U0M */
{ 0xDCEC, 512, 128, 2048, 5, 8, NAND_PLANE_BLOCK_BIT11/*0x800*/, &NANDFlashMtd_2K_hw_enhanced},
/* Toshiba series: manufacture ID - 98 */
/* TC58DVM82A1FT*/
{ 0x7598, 32, 16, 512, 3, 8, 0, &NANDFlashMtd_512_default},
/* TC58DVM92A1FT */
{ 0x7698, 64, 16, 512, 4, 8, 0, &NANDFlashMtd_512_default},
/* TC58DVG02A1FT */
{ 0x7998, 128, 16, 512, 4, 8, 0, &NANDFlashMtd_512_default},
/* TC58NVG0S3AFT */
{ 0xF198, 128, 128, 2048, 4, 8, 0, &NANDFlashMtd_Toshiba_2K_hw_enhanced},
/* TC58NVG0S8BFTI0 */
{ 0xC198, 128, 128, 2048, 5, 16, 0, &NANDFlashMtd_2K_default},
/* TC58NVG1S8BFTI0 */
{ 0xCA98, 256, 128, 2048, 5, 16, 0, &NANDFlashMtd_2K_default},
/* TH58NVG1S3AFT */
{ 0xDA98, 256, 128, 2048, 5, 16, 0, &NANDFlashMtd_2K_default},
/* TH58NVG2S3BT */
{ 0xDC98, 512, 128, 2048, 5, 8, NAND_PLANE_BLOCK_BIT10|NAND_PLANE_BLOCK_BIT11/*0xC00*/, &NANDFlashMtd_Toshiba_2K_hw_enhanced}, // Dual NAND test
/* Hynix series: manufacture ID - AD */
/* HY27XS08561M */
{ 0x75AD, 32, 16, 512, 3, 8, NAND_PLANE_BLOCK_BIT11/*0x800*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* HY27XS08121M */
{ 0x76AD, 64, 16, 512, 4, 8, NAND_PLANE_BLOCK_BIT12/*0x1000*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* HY27XA081G1M */
{ 0x79AD, 128, 16, 512, 4, 8, NAND_PLANE_BLOCK_BIT12|NAND_PLANE_BLOCK_BIT13/*0x3000*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* HY27UF081G2M */
{ 0xF1AD, 128, 128, 2048, 4, 8, 0, &NANDFlashMtd_2K_default/*&NANDFlashMtd_Samsung_512_hw_enhanced*/},
/* ST series: manufacture ID - 20 */
/* ST128W3A */
{ 0x7320, 16, 16, 512, 3, 8, NAND_PLANE_BLOCK_BIT9/*0x200*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* ST128W4A */
{ 0x5320, 16, 16, 512, 3, 16, NAND_PLANE_BLOCK_BIT9/*0x200*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* ST256W3A */
{ 0x7520, 32, 16, 512, 3, 8, NAND_PLANE_BLOCK_BIT10/*0x400*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* ST256W4A */
{ 0x5520, 32, 16, 512, 3, 16, NAND_PLANE_BLOCK_BIT10/*0x400*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* ST512W3A */
{ 0x7620, 64, 16, 512, 4, 8, NAND_PLANE_BLOCK_BIT11/*0x800*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* ST512W4A */
{ 0x5620, 64, 16, 512, 4, 16, NAND_PLANE_BLOCK_BIT11/*0x800*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* ST01GW3A */
{ 0x7920, 128, 16, 512, 4, 8, NAND_PLANE_BLOCK_BIT11|NAND_PLANE_BLOCK_BIT12/*0x1800*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* ST01GW4A */
{ 0x5920, 128, 16, 512, 4, 16, NAND_PLANE_BLOCK_BIT11|NAND_PLANE_BLOCK_BIT12/*0x1800*/, &NANDFlashMtd_Samsung_512_hw_enhanced},
/* ST01GW3B */
{ 0xF120, 128, 128, 2048, 4, 8, 0, &NANDFlashMtd_2K_hw_enhanced},
/* Micron series: manufacture ID - 2C */
/* MT29F2G08AAC */
{ 0xDA2C, 256, 128, 2048, 5, 8, NAND_PLANE_BLOCK_BIT12/*0x1000*/, &NANDFlashMtd_2K_hw_enhanced},
/* MT29F4G08BAB */
{ 0xDC2C, 512, 128, 2048, 5, 8, NAND_PLANE_BLOCK_BIT12/*0x1000*/, &NANDFlashMtd_2K_hw_enhanced},
/* Infineon series: manufacture ID - C1 */
/* HYF33DS51280 */
{ 0x66C1, 64, 16, 512, 4, 8, 0, &NANDFlashMtd_512_default},
/* HYF33DS1G80 */
{ 0xF1C1, 128, 128, 2048, 4, 8, 0, &NANDFlashMtd_2K_hw_enhanced},
{ 0xFFFF, 0, 0, 0, 0, 0, 0} // End of ID Table
};
const DWORD CUSTOMIZED_RESERVED_POOL_SIZE = 12;
/*******************************************************************************
* NFI bus semaphore
*******************************************************************************/
static kal_semid nfi_bus;
void init_NFI_bus_semaphore(void)
{
if(nfi_bus == NULL)
nfi_bus = kal_create_sem("NFI_BUS", 1);
}
void get_NFI_bus(void)
{
if(nfi_bus != NULL)
kal_take_sem(nfi_bus, KAL_INFINITE_WAIT);
}
void free_NFI_bus(void)
{
if(nfi_bus != NULL)
kal_give_sem(nfi_bus);
}
#if(! ( (defined(MT6205)) || (defined(MT6205B)) || (defined(MT6208)) || (defined(FPGA)) ) )
static DMA_FULLSIZE_HWMENU nfi_menu;
static kal_uint8 nfi_dmaport;
static DMA_INPUT nfi_input;
//static kal_hisrid nfi_hisr_id;
static kal_eventgrpid nfi_egid = NULL;
static kal_bool is_initialized;
/* for copy back support */
kal_uint32 mtd_copy_counts = 0;
static kal_uint32 mtd_buffer[MAX_PAGE_BUFFER_SIZE/sizeof(kal_uint32)];
static kal_uint32 mtd_spare[MAX_SPARE_BUFFER_SIZE/sizeof(kal_uint32)];
/* for copy back support */
/*******************************************************************************
* Declaration for NAND flash booting
*******************************************************************************/
#ifdef _NAND_FLASH_BOOTING_
typedef int (*NFBReadFunc_T)(void *, DWORD, BYTE *, BYTE *, BYTE);
DWORD NFB_FLASH_BASE_PAGE;
NFBReadFunc_T NFBReadFunc;
int NFBPageSize;
extern const DWORD NFB_BASE_ADDRESS;
extern const DWORD NFB_ALLOCATED_FAT_SPACE;
int NFB_ReadPage_2K_default(void *, DWORD, BYTE *, BYTE *, BYTE);
int NFB_ReadPage_512_default(void *, DWORD, BYTE *, BYTE *, BYTE);
#endif
// For NAND flash booting
extern kal_bool use_interrupt; // KAL_TRUE for using interrupt; KAL_FALSE for using polling
const DWORD NFI_DEBUG_VERSION = 532; // SW ver.05.30
/*******************************************************************************
* MTD functions
*******************************************************************************/
int MTD_MountDevice(void * DriveData)
{
NAND_FLASH_DRV_DATA * D = DriveData;
kal_int32 check_value = 0;
init_NFI_bus_semaphore();
if(SuperAND_MTD_MountDevice(DriveData) == FS_NO_ERROR)
{
SuperAND_MTD_Init();
return SUPERAND_MOUNTED;
}
if(is_initialized)
{
pdn_nfi(1);
/* In case that NFI is performing an operation */
while (*NFI_PSTA & STATUS_BUSY);
*NFI_FIFOCON = RESET;
*NFI_OPCON = 0;
*NFI_CON = 0;
/* use 512-byte page and 8-bit IO format for read ID */
*NFI_PAGEFMT = PAGEFMT_512_8BIT;
check_value = InitializeMTD(D);
*NFI_OPCON = 0;
pdn_nfi(0);
if(check_value == MTD_STATUS_NO_ERROR)
return FS_NO_ERROR;
else if( check_value == MTD_STATUS_ID_NOT_SUPPORT )
return FS_NAND_DEVICE_NOT_SUPPORTED;
else
return FS_FLASH_MOUNT_ERROR;
}
pdn_nfi(1);
// set NFI conrol bin in GPIO
#if ((defined(MT6228)) || (defined(MT6229) ))
*NFI_GPIO_CON &= 0x000F;
#elif defined MT6217
*NFI_GPIO_CON &= 0xC003;
*NFI_GPIO_CON |= 0x1554;
#else
*NFI_GPIO_CON &= 0xC003;
*NFI_GPIO_CON |= 0x1554;
#endif
*NFI_ACCCON = ACCCON | (((NFI_W2R<<6)|(NFI_WH<<4)) | ((NFI_WST<<2)|NFI_RLC));
/* initialize DMA and interrupt*/
*PDN_CON0 &= ~0x0001; // enable DMA
*NFI_INTR_EN = 0x0; // disable interrupt
if ( stack_query_boot_mode() != USBMS_BOOT )
{
nfi_egid = kal_create_event_group("NFI_EG");
//nfi_hisr_id = kal_create_hisr("NFI_HISR",1,512,nfi_hisr,NULL);
DRV_Register_HISR(DRV_NFI_HISR_ID, nfi_hisr);
IRQ_Register_LISR(IRQ_NFI_CODE, nfi_lisr, "NFI_LISR");
IRQSensitivity(IRQ_NFI_CODE, EDGE_SENSITIVE);
IRQUnmask(IRQ_NFI_CODE);
}
nfi_menu.TMOD.burst_mode = 0;
nfi_menu.master = DMA_NFI;
nfi_menu.source = NULL;
nfi_menu.destination = NULL;
nfi_input.type = DMA_HWTX;
nfi_input.size = DMA_BYTE;
nfi_input.menu = &nfi_menu;
nfi_input.count = 0;
if (nfi_egid == 0)
nfi_input.callback = NULL;
else
nfi_input.callback = NFI_DMA_Callback;
// initially set NFI chip select dir and out data
INITIALIZE_NFI_DIR_DOUT;
/* use 512-byte page and 8-bit IO format for read ID */
*NFI_PAGEFMT = PAGEFMT_512_8BIT;
check_value = InitializeMTD(D);
*NFI_OPCON = 0;
pdn_nfi(0);
is_initialized = KAL_TRUE;
if (check_value == MTD_STATUS_NO_ERROR)
return FS_NO_ERROR;
else if( check_value == MTD_STATUS_ID_NOT_SUPPORT )
return FS_NAND_DEVICE_NOT_SUPPORTED;
else
return FS_FLASH_MOUNT_ERROR;
} /* End of MountDevice */
/*******************************************************************************/
int MTD_ShutDown(void * DriveData)
{
#ifdef _NAND_FLASH_BOOTING_
while (IS_NFI_DMA_RUN);
while (*NFI_PSTA & STATUS_BUSY);
#endif
return FS_NO_ERROR;
} /* End of ShutDown */
/*******************************************************************************/
#ifdef _NAND_FLASH_BOOTING_
int NFB_ReadPhysicalPage(DWORD PhyBlock, DWORD PhyPage, void * Data)
{
extern NAND_FLASH_DRV_DATA NANDFlashDriveData;
NAND_FLASH_DRV_DATA * D = &NANDFlashDriveData;
int NFBStatus=-1;
if ( PhyBlock==0xFFFFFFFF && PhyPage==0xFFFFFFFF )
{
if ( D->MTD==NULL )
{
NFBStatus = MTD_MountDevice((void *)D);
EXT_ASSERT(NFBStatus==FS_NO_ERROR, NFBStatus, 0, 0);
D->MTD = &NANDFlashMtd;
if ( D->flash_info.page_type==PAGE_2K )
{
NFBReadFunc = (NFBReadFunc_T)NFB_ReadPage_2K_default;
NFBPageSize = 2048;
}
else
{
NFBReadFunc = (NFBReadFunc_T)NFB_ReadPage_512_default;
NFBPageSize = 512;
}
return (D->flash_info.io_width);
}
else
return -1;
}
NFB_FLASH_BASE_PAGE = 0;
// Bad block checking
D->MTD->ReadSpare(D, PhyBlock*B_PAGES, (BYTE*)D->spare0);
D->MTD->ReadSpare(D, PhyBlock*B_PAGES+1, (BYTE*)D->spare1);
if ( (!IsGoodBlock(D,D->spare0)) || (!IsGoodBlock(D,D->spare1)) )
return -1;
else
{
pdn_nfi(1);
NFBStatus = NFBReadFunc(D,PhyBlock*B_PAGES+PhyPage,(BYTE*)Data,NULL,0);
pdn_nfi(0);
if ( NFBStatus != FS_NO_ERROR )
return -1;
return NFBPageSize;
}
return FS_NO_ERROR;
} /* End of NFB_ReadPhysicalPage */
#endif
/*******************************************************************************/
int MTD_EraseBlock(void * DriveData, DWORD BlockIndex)
{
NAND_FLASH_DRV_DATA * D = DriveData;
kal_uint32 addr;
kal_uint16 block_add_num;
kal_uint8 status, cs;
kal_uint32 event_group;
pdn_nfi(1);
#ifdef _NAND_FLASH_BOOTING_
BlockIndex += NFB_FLASH_BASE_PAGE/B_PAGES;
#endif
if((BlockIndex<(NANDSUBDriveData[1].base_page/B_PAGES)) || (NANDSUBDriveData[1].base_page==0) ) // chip select 0
{
cs = 0;
SET_NFI_CS0;
}
else // chip select 1
{
cs = 1;
SET_NFI_CS1;
}
//switch (B_PAGES)
switch(NANDSUBDriveData[cs].page_size)
{
//case 64: // 2K page-size
case 2048:
if (NANDSUBDriveData[cs].io_width == IO_ACCESS_8BIT)
{
*NFI_PAGEFMT = PAGEFMT_2K_8BIT;
}
else
{
*NFI_PAGEFMT = PAGEFMT_2K_16BIT;
#if ((defined(MT6228)) || (defined(MT6229) ))
*NFI_GPIO_DATA1 &= 0x0FFF;
*NFI_GPIO_DATA2 &= 0xF000;
#endif
}
addr = (BlockIndex - (NANDSUBDriveData[cs].base_page/B_PAGES) ) << 6;
block_add_num = (kal_uint16)(NANDSUBDriveData[cs].address_cycle - 2);
break;
//case 32: // 512 page-siae
case 512:
if (NANDSUBDriveData[cs].io_width == IO_ACCESS_8BIT)
{
*NFI_PAGEFMT = PAGEFMT_512_8BIT;
}
else
{
*NFI_PAGEFMT = PAGEFMT_512_16BIT;
#if ((defined(MT6228)) || (defined(MT6229) ))
*NFI_GPIO_DATA1 &= 0x0FFF;
*NFI_GPIO_DATA2 &= 0xF000;
#endif
}
addr = (BlockIndex - (NANDSUBDriveData[cs].base_page/B_PAGES) ) << 5;
block_add_num = (kal_uint16)(NANDSUBDriveData[cs].address_cycle - 1);
break;
default: // avoid unassignment warning
addr = 0;
block_add_num = 0;
EXT_ASSERT(0, NANDSUBDriveData[cs].page_size, cs, NANDSUBDriveData[cs].base_page);
}
*NFI_CON = 0x0;
*NFI_OPCON = 0x0;
if (nfi_egid && use_interrupt == KAL_TRUE)
*NFI_INTR_EN = ERASE_COMPLETE_EN;
*NFI_CMD = BLOCK_ERASE1_CMD; // erase command phase 1
while (*NFI_PSTA & STATUS_CMD);
*NFI_ADDRL = addr; // erase block address
*NFI_ADDNOB = block_add_num; // no. of block address
while (*NFI_PSTA & STATUS_ADDR);
*NFI_CMD = BLOCK_ERASE2_CMD; // erase command phase 2
while (*NFI_PSTA & STATUS_CMD);
if (nfi_egid && use_interrupt == KAL_TRUE)
{
kal_retrieve_eg_events(nfi_egid, NFI_EVENT, KAL_OR_CONSUME,
&event_group, KAL_SUSPEND);
}
else
{
// using interrupt instead of polling after system initialization and before exception in normal mode
if(nfi_egid && (kal_query_systemInit() == KAL_FALSE && INT_QueryExceptionStatus() == KAL_FALSE))
use_interrupt = KAL_TRUE;
}
while (!((status = read_status())&RDY_BUSY)); // NFI ready
if(cs)
SET_NFI_CS1_END;
*NFI_OPCON = 0;
pdn_nfi(0);
if (status&PASS_FAIL)
{
return FS_DATA_ERROR;
}
return FS_NO_ERROR;
} /* End of EraseBlock */
/*******************************************************************************
* MTD functions for 512 page-size
*******************************************************************************/
int ProgramPage_512 (void * DriveData, DWORD PageIndex, BYTE * Data, BYTE * Spare, BYTE ECCFlag)
{
NAND_FLASH_DRV_DATA * D = DriveData;
kal_uint8 status, cs;
pdn_nfi(1);
#ifdef _NAND_FLASH_BOOTING_
PageIndex += NFB_FLASH_BASE_PAGE;
#endif
if((PageIndex<NANDSUBDriveData[1].base_page) || (NANDSUBDriveData[1].base_page==0) ) // chip select 0
{
cs = 0;
SET_NFI_CS0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -