?? s3c6410_fil.c
字號:
}
NF_CMD(CMD_READ_CONFIRM);
if (bInternalInterleaving == TRUE32)
{
#if 1
_TRDelay(nPpn);
#else
if (nVBank%2)
{
NF_CMD(CMD_READ_STATUS_CHIP1);
}
else
{
NF_CMD(CMD_READ_STATUS_CHIP0);
}
while(!(NF_DATA_R()&0x40));
// Dummy Command to Set Proper Pointer to Read Position after NF_WAIT_RnB()
NF_CMD(CMD_READ);
#endif
}
else
{
NF_WAIT_RnB(nBank);
// Dummy Command to Set Proper Pointer to Read Position after NF_WAIT_RnB()
NF_CMD(CMD_READ);
}
// Read Spare Area
if (ECC_8BIT_SPPORT == TRUE32)
{
NF_SETREG_8BITECC();
nRet = Read_Spare_8BitECC(nBank, nPpn, (UINT32*)pSBuf);
}
else if (SECTORS_PER_PAGE == 8)
{
NF_SETREG_8BITECC();
nRet = Read_Spare_Separate(nBank, nPpn, (UINT32*)pSBuf);
NF_SETREG_4BITECC();
}
else
{
nRet = Read_Spare(nBank, nPpn, (UINT32*)pSBuf);
}
if ((nRet & ECC_UNCORRECTABLE_ERROR) == 0)
{
nPageReadStatus = (nRet<<16);
if (WMR_GetChkSum(&pSBuf[1], 1) >= 4)
{
// Not Clean Page
bPageClean = FALSE32;
}
// Read Main Area
if(pDBuf != NULL)
{
for (nCnt=0; nCnt<nLoopCount; nCnt++)
{
if (nSctBitmap&(0x1<<nCnt))
{
if (ECC_8BIT_SPPORT == TRUE32)
{
NF_SETREG_8BITECC();
nRet = Read_Sector_8BitECC(nBank, nPpn, nCnt, pDBuf, (UINT32*)pSBuf, bPageClean);
}
else
{
nRet = Read_Sector(nBank, nPpn, nCnt, pDBuf, (UINT32*)pSBuf, bPageClean);
}
//nPageReadStatus |= (nRet<<(nCnt*4)); // if 2KByte/Page
nPageReadStatus |= (nRet<<(nCnt*2)); // if both non-case for all-ff and 4KByte/Page
}
}
}
}
else
{
nPageReadStatus |= (nRet<<(8*2)); // The spare area position.
}
// Chip Unselect
NF_CE_H(nBank);
#ifdef USE_SETKMODE
SetKMode(bLastMode);
#endif
if(bSecondRead)
{
nPageReadStatus2nd = nPageReadStatus;
}
else
{
nPageReadStatus1st = nPageReadStatus;
}
if(bLoopNeed && !bSecondRead)
{
bSecondRead = TRUE32;
goto _B_SecondRead;
}
if(nPageReadStatus1st&PAGE_UNCORRECTABLE_ERROR_MASK || nPageReadStatus2nd&PAGE_UNCORRECTABLE_ERROR_MASK)
{
// Uncorrectable ECC Error
NAND_ERR((_T("[FIL:ERR]--NAND_Read() : Uncorrectable Error in Bank %d, Page %d [0x%08x] [0x%08x]\r\n"), nBank, nPpn, nPageReadStatus1st, nPageReadStatus));
return FIL_U_ECC_ERROR;
}
else
{
// MLC_Print_Page_Data(pDBuf, pSBuf);
#if (WMR_READ_RECLAIM)
if (nPageReadStatus1st&PAGE_CORRECTABLE_ERROR_MASK || nPageReadStatus2nd&PAGE_CORRECTABLE_ERROR_MASK)
{
READ_ERR_FLAG = TRUE32;
NAND_ERR((_T("[FIL:INF] NAND_Read() : Correctable Error in Bank %d, Page %d [0x%08x] [0x%08x]\r\n"), nBank, nPpn, nPageReadStatus1st, nPageReadStatus2nd));
}
#endif
if (bCleanCheck&&bPageClean)
{
if (bIsSBufNull == FALSE32)
{
BOOL32 bClean;
// Check 32 bytes is all 0xFF & don't care about ECC Value
if ((pDBuf == NULL) && (bECCIn))
{
// When the pMBuf is NULL, read 128 bytes(twice read) in the spare area
if (bSecondRead)
{
pSBuf -= BYTES_PER_SPARE_PAGE;
}
bClean = _IsAllFF(pSBuf, BYTES_PER_SPARE_SUPAGE);
}
else
{
// TODO: to be changed all FF check Size
bClean = _IsAllFF(pSBuf, ((SECTORS_PER_PAGE == 8) ? NAND_MECC_OFFSET_4K : NAND_MECC_OFFSET));
}
if (bClean)
{
NAND_MSG((_T("[FIL]--NAND_Read() : FIL_SUCCESS_CLEAN\r\n")));
return FIL_SUCCESS_CLEAN;
}
else
{
NAND_MSG((_T("[FIL]--NAND_Read()[bClean==FASLE32]\r\n")));
return FIL_SUCCESS;
}
}
else
{
NAND_MSG((_T("[FIL]--NAND_Read()[bIsSBufNull != FALSE32] : FIL_SUCCESS_CLEAN\r\n")));
return FIL_SUCCESS_CLEAN;
}
}
else
{
NAND_MSG((_T("[FIL]--NAND_Read()[bCleanCheck&&bPageClean == FASLE32]\r\n")));
return FIL_SUCCESS;
}
}
}
/*****************************************************************************/
/* */
/* NAME */
/* NAND_Write */
/* 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_Write(UINT32 nBank, UINT32 nPpn, UINT32 nSctBitmap,
UINT32 nPlaneBitmap, UINT8* pDBuf, UINT8* pSBuf)
{
UINT32 nCnt;
UINT32 nPbn;
UINT32 nPOffset;
//BOOL32 bFirstWrite = TRUE32;
BOOL32 bSecondWrite = FALSE32;
BOOL32 bLoopNeed = FALSE32;
pSECCCxt pSpareCxt = NULL;
#ifdef USE_SETKMODE
BOOL bLastMode;
#endif
NAND_MSG((_T("[FIL] ++NAND_Write(%d, %d, 0x%02x, 0x%02x)\r\n"), nBank, nPpn, nSctBitmap, nPlaneBitmap));
//NAND_ERR((_T("[FIL] ++NAND_Write(%d, %d, 0x%02x, 0x%02x)\r\n"), nBank, nPpn, nSctBitmap, nPlaneBitmap)); // ksk dbg
// MLC_Print_Page_Data(pDBuf, pSBuf);
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;
}
// avoid r/b check error with internal interleaving
if (bInternalInterleaving == TRUE32)
{
aNeedSync[nBank] = TRUE32;
}
/*
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)
{
nPpn += PAGES_PER_BANK;
}
nBank /= 2;
}
#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
// CE Select
NF_CE_L(nBank);
_B_SecondWrite:
// 2-Plane Program, page address is changed
if (bSecondWrite)
{
nPpn += PAGES_PER_BLOCK;
nSctBitmap = nSctBitmap >> SECTORS_PER_PAGE;
}
if(pSBuf == NULL)
{
pSBuf = aTempSBuf;
WMR_MEMSET(pSBuf, 0xFF, BYTES_PER_SPARE_PAGE); // Initialize the spare buffer
}
else
{
// Set 0xFF to ECC Area
if (IS_CHECK_SPARE_ECC == TRUE32)
{
pSBuf[2] = 0xff; // Reserved
pSBuf[3] = 0xff;
//WMR_MEMSET(pSBuf+2, 0xFF, 2); // Clear Reserved area in Spare Buffer
WMR_MEMSET(pSBuf+((SECTORS_PER_PAGE == 8) ? NAND_MECC_OFFSET_4K : NAND_MECC_OFFSET),
0xFF,
BYTES_PER_SPARE_PAGE-((SECTORS_PER_PAGE == 8) ? NAND_MECC_OFFSET_4K : NAND_MECC_OFFSET)); // Clear ECC area in Spare Buffer
}
}
pSpareCxt = (pSECCCxt)pSBuf;
pSpareCxt->cCleanMark = 0x0; // Clean mark to 0. It means that page is written
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))
{
if (ECC_8BIT_SPPORT == TRUE32)
{
NF_SETREG_8BITECC();
Write_Sector_8BitECC(nPpn, nCnt, pDBuf);
}
else
{
Write_Sector(nPpn, nCnt, pDBuf);
}
if (IS_CHECK_SPARE_ECC == TRUE32)
{
if ( ECC_8BIT_SPPORT != TRUE32 )
{
pSpareCxt->aMECC[nCnt*2] = NF_MECC0();
pSpareCxt->aMECC[nCnt*2+1] = NF_MECC1();
}
else
{
pSpareCxt->aMECC[nCnt*4] = NF_8MECC0();
pSpareCxt->aMECC[nCnt*4+1] = NF_8MECC1();
pSpareCxt->aMECC[nCnt*4+2] = NF_8MECC2();
pSpareCxt->aMECC[nCnt*4+3] = NF_8MECC3() & 0xff;
}
}
}
else
{
if (ECC_8BIT_SPPORT == TRUE32)
{
pSpareCxt->aMECC[nCnt*4] = ECCVAL_ALLFF0;
pSpareCxt->aMECC[nCnt*4+1] = ECCVAL_ALLFF1;
pSpareCxt->aMECC[nCnt*4+2] = ECCVAL_ALLFF2;
pSpareCxt->aMECC[nCnt*4+3] = ECCVAL_ALLFF3 & 0xff;
}
else
{
pSpareCxt->aMECC[nCnt*2] = ECCVAL_ALLFF0; // All 0xFF ECC
pSpareCxt->aMECC[nCnt*2+1] = ECCVAL_ALLFF1;
}
}
}
}
else if (IS_CHECK_SPARE_ECC == TRUE32)
{
if (ECC_8BIT_SPPORT == TRUE32)
{
for (nCnt=0; nCnt<SECTORS_PER_PAGE; nCnt++)
{
pSpareCxt->aMECC[nCnt*4] = ECCVAL_ALLFF0;
pSpareCxt->aMECC[nCnt*4+1] = ECCVAL_ALLFF1;
pSpareCxt->aMECC[nCnt*4+2] = ECCVAL_ALLFF2;
pSpareCxt->aMECC[nCnt*4+3] = ECCVAL_ALLFF3 & 0xff;
}
}
else
{
for (nCnt=0; nCnt<SECTORS_PER_PAGE; nCnt++)
{
pSpareCxt->aMECC[nCnt*2] = ECCVAL_ALLFF0; // All 0xFF ECC
pSpareCxt->aMECC[nCnt*2+1] = ECCVAL_ALLFF1;
}
}
}
// Write Spare
if (ECC_8BIT_SPPORT == TRUE32)
{
NF_SETREG_8BITECC();
Write_Spare_8BitECC(nBank, nPpn, pSpareCxt);
}
else if (SECTORS_PER_PAGE == 8)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -