📄 s3c2450_fil.c
字号:
if (bSecondWrite)
{
NF_CMD(CMD_2PLANE_PROGRAM);
NF_SET_ADDR(nPpn, 0);
}
else
{
NF_CMD(CMD_PROGRAM);
NF_SET_ADDR(nPpn, 0);
}
// Write Main Sector
if (pDBuf != NULL)
{
// In case of the second write, the position of buffer pointer is moved backward as much as 1 page size
if (bSecondWrite)
{
pDBuf += BYTES_PER_MAIN_PAGE;
}
for (nCnt=0; nCnt<SECTORS_PER_PAGE; nCnt++)
{
if (nSctBitmap&(0x1<<nCnt))
{
Write_Sector(nPpn, nCnt, pDBuf);
if (IS_CHECK_SPARE_ECC == TRUE32)
{
pSpareCxt->aMECC[nCnt] = NF_MECC0();
}
}
else
{
pSpareCxt->aMECC[nCnt] = ECCVAL_ALLFF; // All 0xFF ECC
}
}
}
else if (IS_CHECK_SPARE_ECC == TRUE32)
{
for (nCnt=0; nCnt<SECTORS_PER_PAGE; nCnt++)
{
pSpareCxt->aMECC[nCnt] = ECCVAL_ALLFF; // All 0xFF ECC
}
}
// Write Spare
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_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));
if (nBank >= BANKS_TOTAL || nPbn >= BLOCKS_PER_BANK)
{
NAND_MSG((_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);
}
if (bInternalInterleaving == TRUE32)
{
if ((nBank & 0x1) == 1)
{
bInternalBank = TRUE32;
}
nBank = (nBank >> 1);
}
if ((bInternalInterleaving == TRUE32) && (aNeedSync[nPairBank] == FALSE32))
{
// TODO: what does this means???
#if 1
NF_CE_L(nBank);
NF_ADDR(0x0);
NF_CE_H(nBank);
#else
BLUES_NF_ADDR0(0x0);
rFMCTRL1 = (1 << BLUES_FM_ADDR_SET);
BLUES_NF_CPU_CTRL0(nBank);
#endif
}
#ifdef USE_SETKMODE
bLastMode = SetKMode(TRUE);
#endif
// Chip Select
NF_CE_L(nBank);
if (bInternalInterleaving || TWO_PLANE_READ_STATUS)
{
if (bInternalBank)
{
NF_CMD(CMD_READ_STATUS_CHIP1);
}
else
{
NF_CMD(CMD_READ_STATUS_CHIP0);
}
}
else
{
// Read Status Command is acceptable during Busy
NF_CMD(CMD_READ_STATUS);
}
do
{
nData = NF_DATA_R();
}
while(!(nData&NAND_STATUS_READY));
*nPlaneBitmap = enuNONE_PLANE_BITMAP;
// Read Status
if (nData&NAND_STATUS_ERROR)
{
if (TWO_PLANE_READ_STATUS == TRUE32)
{
if (nData & NAND_STATUS_PLANE0_ERROR)
{
NAND_ERR((_T("[FIL:ERR] NAND_Sync() : Left-plane Sync Error\r\n")));
*nPlaneBitmap = enuLEFT_PLANE_BITMAP;
}
if (nData & NAND_STATUS_PLANE1_ERROR)
{
NAND_ERR((_T("[FIL:ERR] NAND_Sync() : Right-plane Sync Error\r\n")));
*nPlaneBitmap = enuRIGHT_PLANE_BITMAP;
}
}
else
{
NAND_ERR((_T("[FIL:ERR] NAND_Sync() : Status Error\r\n")));
*nPlaneBitmap = enuLEFT_PLANE_BITMAP;
}
nRet = FIL_CRITICAL_ERROR;
}
// Chip Unselect
NF_CE_H(nBank);
#ifdef USE_SETKMODE
SetKMode(bLastMode);
#endif
NAND_MSG((_T("[FIL]--NAND_Sync()\r\n")));
return nRet;
}
VOID
NAND_Reset(UINT32 nBank)
{
#ifdef USE_SETKMODE
BOOL bLastMode;
#endif
NAND_MSG((_T("[FIL]++NAND_Reset(%d)\r\n"), nBank));
#ifdef USE_SETKMODE
bLastMode = SetKMode(TRUE);
#endif
// Chip Select
NF_CE_L(nBank);
// Reset Command is accepted during Busy
NF_CMD(CMD_RESET);
// Chip Unselect
NF_CE_H(nBank);
#ifdef USE_SETKMODE
SetKMode(bLastMode);
#endif
NAND_MSG((_T("[FIL]--NAND_Reset()\r\n")));
return;
}
/*****************************************************************************/
/* */
/* NAME */
/* Read_DeviceID */
/* DESCRIPTION */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -