?? s3c6410_fil.c
字號(hào):
{
NF_SETREG_8BITECC();
Write_Spare_Separate(nBank, nPpn, pSpareCxt);
NF_SETREG_4BITECC();
}
else
{
Write_Spare(nBank, nPpn, pSpareCxt);
}
// Write Confirm
if(TWO_PLANE_PROGRAM == TRUE32 && !bSecondWrite && bLoopNeed)
{
bSecondWrite = TRUE32;
NF_CMD(CMD_2PLANE_PROGRAM_DUMMY);
_TRDelay2(0);
goto _B_SecondWrite;
}
NF_CMD(CMD_PROGRAM_CONFIRM);
// Chip Unselect
NF_CE_H(nBank);
#ifdef USE_SETKMODE
SetKMode(bLastMode);
#endif
NAND_MSG((_T("[FIL]--NAND_Write()\r\n")));
return;
}
/*****************************************************************************/
/* */
/* NAME */
/* NAND_Write_Steploader */
/* DESCRIPTION */
/* This function writes NAND page area */
/* PARAMETERS */
/* nBank [IN] Physical device number */
/* nPpn [IN] Physical page number */
/* nSctBitmap [IN] The indicator for the sector to write */
/* nPlaneBitmap[IN] The indicator of the plane */
/* pDBuf [IN] Buffer pointer of main area to write */
/* pSBuf [IN] Buffer pointer of spare area to write */
/* */
/* RETURN VALUES */
/* None */
/* NOTES */
/* */
/*****************************************************************************/
VOID
NAND_Steploader_Write(UINT32 nBank, UINT32 nPpn, UINT32 nSctBitmap,
UINT32 nPlaneBitmap, UINT8* pDBuf, UINT8* pSBuf)
{
UINT32 nCnt;
UINT32 nPbn;
UINT32 nPOffset;
UINT32 i;
//BOOL32 bFirstWrite = TRUE32;
BOOL32 bSecondWrite = FALSE32;
BOOL32 bLoopNeed = FALSE32;
SECCInfo tSECCInfo;
#ifdef USE_SETKMODE
BOOL bLastMode;
#endif
NAND_MSG((_T("[FIL] ++NAND_Write(%d, %d, 0x%02x, 0x%02x)\r\n"), nBank, nPpn, nSctBitmap, nPlaneBitmap));
if (nBank >= BANKS_TOTAL || nPpn >= PAGES_PER_BANK || (pDBuf == NULL && pSBuf == NULL))
{
NAND_ERR((_T("[FIL:ERR]--NAND_Write() : Parameter Overflow\r\n")));
WMR_ASSERT(FALSE32);
return;
}
#if (WMR_STDLIB_SUPPORT)
nPbn = nPpn / PAGES_PER_BLOCK;
nPOffset = nPpn % PAGES_PER_BLOCK;
#else
nPbn = DIV(nPpn, PAGES_PER_BLOCK_SHIFT);
nPOffset = REM(nPpn, PAGES_PER_BLOCK_SHIFT);
#endif
// In case of 2-Plane Program, re-calculate the page address
if(TWO_PLANE_PROGRAM == TRUE32)
{
nPpn = nPbn * 2 * PAGES_PER_BLOCK + nPOffset;
if (nPlaneBitmap == enuBOTH_PLANE_BITMAP)
{
bLoopNeed = TRUE32;
}
else if (nPlaneBitmap == enuRIGHT_PLANE_BITMAP)
{
nPpn += PAGES_PER_BLOCK;
//nSctBitmap = nSctBitmap>>4;
}
}
nSctBitmap &= FULL_SECTOR_BITMAP_PAGE;
#ifdef USE_SETKMODE
bLastMode = SetKMode(TRUE);
#endif
pNANDFConReg->NFCONF = (pNANDFConReg->NFCONF & ~((1<<30)|(3<<23))) | (1<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1); // System Clock is more than 66Mhz, ECC type is MLC.
pNANDFConReg->NFCONT |= (1<<18)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9); //ECC for programming.// Enable RnB Interrupt
pNANDFConReg->NFSTAT |= ((1<<6)|(1<<5)|(1<<4));
// CE Select
NF_CE_L(nBank);
NF_CMD(CMD_PROGRAM);
NF_SET_ADDR(nPpn, 0);
WMR_MEMSET(&tSECCInfo, 0xFF, 53); // Initialize the spare buffer
// Write Main Sector
if (pDBuf != NULL)
{
for (nCnt=0; nCnt<SECTORS_PER_PAGE; nCnt++)
{
NF_MECC_UnLock();
NF_MECC_Reset();
if ((UINT32)pDBuf&0x3)
{
_Write_512Byte_Unaligned(pDBuf+NAND_SECTOR_SIZE*nCnt);
}
else
{
_Write_512Byte(pDBuf+NAND_SECTOR_SIZE*nCnt);
}
NF_MECC_Lock();
while(!(pNANDFConReg->NFSTAT&(1<<7))) ;
pNANDFConReg->NFSTAT|=(1<<7);
tSECCInfo.t8MECC[nCnt].n8MECC0 = NF_8MECC0();
tSECCInfo.t8MECC[nCnt].n8MECC1 = NF_8MECC1();
tSECCInfo.t8MECC[nCnt].n8MECC2 = NF_8MECC2();
tSECCInfo.t8MECC[nCnt].n8MECC3 = (NF_8MECC3() & 0xff);
}
}
// NF_DATA_W(tSECCInfo.nBadBlock); // 1 byte n8MECC3 ==> bad block marker
for(i = 0; i < SECTORS_PER_PAGE; i++) {
NF_DATA_W4(tSECCInfo.t8MECC[i].n8MECC0); // 4 byte n8MECC0
NF_DATA_W4(tSECCInfo.t8MECC[i].n8MECC1); // 4 byte n8MECC1
NF_DATA_W4(tSECCInfo.t8MECC[i].n8MECC2); // 4 byte n8MECC2
NF_DATA_W((tSECCInfo.t8MECC[i].n8MECC3) & 0xff); // 1 byte n8MECC3
}
pNANDFConReg->NFSTAT |= (1<<4); //NF_CLEAR_RB
NF_CMD(CMD_PROGRAM_CONFIRM);
// NF_DETECT_RB();
NF_WAIT_RnB(nBank);
NF_CMD(CMD_READ_STATUS); // Read status command
for(i=0;i<3;i++); //twhr=60ns
if (NF_DATA_R()&NAND_STATUS_ERROR)
{// Page write error
NF_CE_H(nBank);
RETAILMSG(1,(TEXT("##### Error write operation #####\r\n")));
pNANDFConReg->NFCONF = NF_4BIT_ECC | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
return;
}
else
{
NF_CE_H(nBank);
pNANDFConReg->NFCONF = NF_4BIT_ECC | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
return;
}
}
/*****************************************************************************/
/* */
/* NAME */
/* NAND_Erase */
/* DESCRIPTION */
/* This function erases NAND block area */
/* PARAMETERS */
/* nBank [IN] Physical device number */
/* nPpn [IN] Physical page number */
/* nPlaneBitmap[IN] The indicator of the plane */
/* */
/* RETURN VALUES */
/* None */
/* NOTES */
/* */
/*****************************************************************************/
VOID
NAND_Erase (UINT32 nBank, UINT32 nPbn, UINT32 nPlaneBitmap)
{
UINT32 nVBank;
UINT32 nPageAddr;
UINT32 nPairBank;
UINT32 nSyncRet;
BOOL32 bSecondErase = FALSE32;
BOOL32 bLoopNeed = FALSE32;
#ifdef USE_SETKMODE
BOOL bLastMode;
#endif
NAND_MSG((_T("[FIL]++NAND_Erase(%d, %d, 0x%02x)\r\n"), nBank, nPbn, nPlaneBitmap));
// NAND_ERR((_T("[FIL]++NAND_Erase(%d, %d, 0x%02x)\r\n"), nBank, nPbn, nPlaneBitmap));
if (nBank >= BANKS_TOTAL || nPbn >= BLOCKS_PER_BANK)
{
NAND_ERR((_T("[FIL]++NAND_Erase(%d, %d, 0x%02x)\r\n"), nBank, nPbn, nPlaneBitmap));
NAND_ERR((_T("[FIL:ERR]--NAND_Erase() : Parameter overflow\r\n")));
WMR_ASSERT(FALSE32);
return;
}
nVBank = nBank;
// avoid r/b check error with internal interleaving
if (bInternalInterleaving == TRUE32)
{
nPairBank = ((nBank & 0x1) == 1) ? (nBank - 1) : (nBank + 1);
}
/*
In case of Internal Interleaving, the first address of the second bank should be
the half of toal block number of NAND.
For example, In 4Gbit DDP NAND, its total block number is 4096.
So, the bank 0 has 2048 blocks (Physical number : 0 ~ 2047),
the bank 1 has another 2048 blocks (Physical number : 2048 ~ 4095).
therefore, first block address of Bank 1 could be the physically 2048th block.
*/
if (bInternalInterleaving == TRUE32)
{
if ((nBank & 0x1) == 1)
{
nPbn += BLOCKS_PER_BANK;
}
nBank /= 2;
}
if (TWO_PLANE_PROGRAM == TRUE32)
{
if (nPlaneBitmap == enuBOTH_PLANE_BITMAP)
{
bLoopNeed = TRUE32;
}
else if (nPlaneBitmap == enuRIGHT_PLANE_BITMAP)
{
bSecondErase = TRUE32;
}
}
nPbn = nPbn*(1+(TWO_PLANE_PROGRAM == TRUE32));
/*
In the Internal Interleaving, it's forbidden NAND to do Write operation & the other operation
at the same time. When Write is going on in Bank 1, Bank 0 has to wait to finish
the operation of Bank 1 if the next operation is not Write.
While Bank 1 is erased, Bank 0 do not start Write operation. (But, Erase or Read is allowed)
Internal Interleaving concept is only existed between Write and Write.
*/
if (bInternalInterleaving == TRUE32)
{
NAND_Sync(nVBank, &nSyncRet);
// TODO: what does this means???
#if 1
NF_CE_L(nBank);
NF_CMD(CMD_READ);
NF_CE_H(nBank);
#endif
NAND_Sync(nPairBank, &nSyncRet);
aNeedSync[nVBank] = TRUE32;
}
#ifdef USE_SETKMODE
bLastMode = SetKMode(TRUE);
#endif
// Chip Select
NF_CE_L(nBank);
_B_SecondErase:
if(bSecondErase)
{
nPbn++;
}
// Calculate Row Address of the Block (128 page/block)
nPageAddr = (nPbn << (6 + IS_MLC));
// Erase Command
NF_CMD(CMD_ERASE);
// Write Row Address
NF_ADDR(nPageAddr&0xff);
NF_ADDR((nPageAddr>>8)&0xff);
NF_ADDR((nPageAddr>>16)&0xff);
if (TWO_PLANE_PROGRAM == TRUE32 && !bSecondErase && bLoopNeed)
{
bSecondErase = TRUE32;
goto _B_SecondErase;
}
// Erase confirm command
NF_CMD( CMD_ERASE_CONFIRM);
// Chip Unselect
NF_CE_H(nBank);
#ifdef USE_SETKMODE
SetKMode(bLastMode);
#endif
/* In the Internal Interleaving, it's forbidden NAND to do Write operation & the other operation
at the same time. When Write is going on in Bank 1, Bank 0 has to wait to finish
the operation of Bank 1 if the next operation is not Write.
While Bank 1 is erased, Bank 0 do not start Write operation. (But, Erase or Read is allowed)
Internal Interleaving concept is only existed between Write and Write.
*/
if (bInternalInterleaving == TRUE32)
{
NAND_Sync(nVBank, &nSyncRet);
}
NAND_MSG((_T("[FIL]--NAND_Erase()\r\n")));
return;
}
/*****************************************************************************/
/* */
/* NAME */
/* NAND_Sync */
/* DESCRIPTION */
/* This function checks the R/B signal of NAND */
/* When it's busy, it means NAND is under operation. */
/* When it's ready, it means NAND is ready for the next operation. */
/* PARAMETERS */
/* nBank [IN] Physical device number */
/* */
/* RETURN VALUES */
/* FIL_CRITICAL_ERROR */
/* When the input value is more than its range */
/* or it has erase fail */
/* FIL_SUCCESS */
/* When the erase operation has done clearly */
/* NOTES */
/* */
/*****************************************************************************/
INT32
NAND_Sync(UINT32 nBank, UINT32 *nPlaneBitmap)
{
UINT32 nData;
UINT32 nPairBank;
UINT32 nVBank;
INT32 nRet = FIL_SUCCESS;
BOOL32 bInternalBank = FALSE32;
#ifdef USE_SETKMODE
BOOL bLastMode;
#endif
NAND_MSG((_T("[FIL]++NAND_Sync(%d, %d)\r\n"), nBank, nPlaneBitmap));
if (nBank >= BANKS_TOTAL)
{
NAND_ERR((_T("[FIL:ERR]--NAND_Sync() : Parameter overflow\r\n")));
WMR_ASSERT(FALSE32);
return FIL_CRITICAL_ERROR;
}
WMR_ASSERT(nPlaneBitmap != NULL);
nVBank = nBank;
// avoid r/b check error with internal interleaving
if (bInternalInterleaving == TRUE32)
{
nPairBank = ((nBank & 0x1) == 1) ? (nBank - 1) : (nBank + 1);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -