📄 s3c2450_fil.c
字号:
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 */
/* This function reads manufacturer id, device id and hidden id. */
/* PARAMETERS */
/* nBank [IN] Physical device number */
/* pDID [OUT] NAND flash density id */
/* pHID [OUT] NAND flash hidden id */
/* RETURN VALUES */
/* nScanIdx Device's stDEVInfo[nScanIdx] */
/* NOTES */
/* */
/*****************************************************************************/
PRIVATE INT32
Read_DeviceID(UINT32 nBank, UINT8 *pDID, UINT8 *pHID)
{
UINT8 nMID, nDID, nHID[3];
UINT32 nScanIdx;
UINT32 i;
#ifdef USE_SETKMODE
BOOL bLastMode;
#endif
NAND_MSG((_T("[FIL]++Read_DeviceID(%d)\r\n"), nBank));
#ifdef USE_SETKMODE
bLastMode = SetKMode(TRUE);
#endif
// Chip Select
NF_CE_L(nBank);
NF_WAIT_RnB(nBank);
// Read ID Command
NF_CMD(CMD_READ_ID);
NF_ADDR(0x00);
// Find Maker Code
for (i=0; i<5; i++)
{
nMID = NF_DATA_R(); // Maker Code
if (nMID == 0xEC) break;
}
// Read Device Code
nDID = NF_DATA_R(); // Device Code
nHID[0] = NF_DATA_R(); // Internal Chip Number
nHID[1] = NF_DATA_R(); // Page, Block, Redundant Area Size
nHID[2] = NF_DATA_R(); // Plane Number, Size
// Chip Unselect
NF_CE_H(nBank);
#ifdef USE_SETKMODE
SetKMode(bLastMode);
#endif
for (nScanIdx = 0; nScanIdx < sizeof(stDEVInfo)/sizeof(DEVInfo); nScanIdx++)
{
if ((nMID == (UINT8)0xEC) && (nDID == stDEVInfo[nScanIdx].nDevID) && (nHID[0] == stDEVInfo[nScanIdx].nHidID))
{
*pDID = nDID;
*pHID = nHID[0];
NAND_LOG((_T("[FIL] ################\r\n")));
NAND_LOG((_T("[FIL] MID = 0x%02x\r\n"), nMID));
NAND_LOG((_T("[FIL] DID = 0x%02x\r\n"), nDID));
NAND_LOG((_T("[FIL] HID[0] = 0x%02x\r\n"), nHID[0]));
NAND_LOG((_T("[FIL] HID[1] = 0x%02x\r\n"), nHID[1]));
NAND_LOG((_T("[FIL] HID[2] = 0x%02x\r\n"), nHID[2]));
NAND_LOG((_T("[FIL] ################\r\n")));
NAND_MSG((_T("[FIL] Bank %d Detect\r\n"), nBank));
return nScanIdx;
}
}
*pDID = 0x00;
*pHID = 0x00;
NAND_MSG((_T("[FIL]--Read_DeviceID()\r\n")));
return FIL_CRITICAL_ERROR;
}
PRIVATE UINT32
Read_Sector(UINT32 nBank, UINT32 nPpn, UINT32 nSctOffset, UINT8* pBuf, UINT32* pSpareCxt, BOOL32 bCheckAllFF)
{
UINT32 nOffSet;
UINT32 nRet = 0;
UINT32 nMECC[2];
NAND_MSG((_T("[FIL]++Read_Sector(%d, %d)\r\n"), nPpn, nSctOffset));
// Move pointer to Sector Offset
nOffSet = nSctOffset * NAND_SECTOR_SIZE;
// Random data output command
NF_CMD(CMD_RANDOM_DATA_OUTPUT);
NF_ADDR(nOffSet&0xFF);
NF_ADDR((nOffSet>>8)&0xFF);
NF_CMD(CMD_RANDOM_DATA_OUTPUT_CONFIRM);
// Initialize 4-bit ECC Decoding
NF_SET_ECC_DEC();
NF_MECC_Reset();
NF_MECC_UnLock();
// Read 512 bytes Sector data
#if (NAND_TRANS_MODE == ASM)
if ((UINT32)pBuf&0x3)
{
_Read_512Byte_Unaligned(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
else
{
_Read_512Byte(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
#elif (NAND_TRANS_MODE == DMA)
Read_512Byte_DMA(pBuf+NAND_SECTOR_SIZE*nSctOffset);
#endif
//NF_MECC_Lock(); // Do NOT Lock MECC when using 4-bit ECC Decoding
NF_CLEAR_ECC_DEC_DONE();
NF_CE_H(nBank);
NF_SET_CLK(DUMMY_R_TACLS, DUMMY_R_TWRPH0, DUMMY_R_TWRPH1); // Don't set clk to (0, 0, 0) !!! Decoding error occurs
// Instead of Read Main ECC from NAND, Write Main ECC with CE don't care
if (bCheckAllFF)
{
NF_DATA_W4(ECCVAL_ALLFF0); // All 0xFF ECC
NF_DATA_W4(ECCVAL_ALLFF1);
}
else
{
nMECC[0] = pSpareCxt[(((SECTORS_PER_PAGE==4)?NAND_MECC_OFFSET:NAND_MECC_OFFSET_4K)/4)+nSctOffset*2];
nMECC[1] = pSpareCxt[(((SECTORS_PER_PAGE==4)?NAND_MECC_OFFSET:NAND_MECC_OFFSET_4K)/4)+nSctOffset*2+1];
NF_DATA_W4(nMECC[0]); // pSpareCxt->aMECC[nSctOffset*2]
NF_DATA_W4(nMECC[1]); // pSpareCxt->aMECC[nSctOffset*2+1]
}
NF_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
NF_CE_L(nBank);
// Waiting for Main ECC compare
NF_WAIT_ECC_DEC_DONE();
nRet = Decoding_MainECC(pBuf+NAND_SECTOR_SIZE*nSctOffset);
if (nRet&ECC_MODULE_ERROR)
{
NAND_MSG((_T("[FIL:ERR] Read_Sector() : ECC Module Error in Page %d Sector %d\r\n"), nPpn, nSctOffset));
nRet = Read_Sector2(nBank, pBuf+NAND_SECTOR_SIZE*nSctOffset, bCheckAllFF, nMECC);
if (nRet & ECC_MODULE_ERROR) nRet &= ~ECC_MODULE_ERROR;
}
if (nRet&ECC_UNCORRECTABLE_ERROR)
{
NAND_ERR((_T("[FIL:ERR] Read_Sector() : ECC Uncorrectable Error in Page %d Sector %d\r\n"), nPpn, nSctOffset));
}
else if (nRet&ECC_CORRECTABLE_ERROR)
{
NAND_MSG((_T("[FIL] Read_Sector() : ECC Correctable Error in Page %d Sector %d\r\n"), nPpn, nSctOffset));
}
NAND_MSG((_T("[FIL]--Read_Sector()\r\n")));
return nRet;
}
PRIVATE UINT32
Read_Sector2(UINT32 nBank, UINT8* pBuf, BOOL32 bCheckAllFF, UINT32 nMECC[2])
{
UINT32 nRet = 0;
NAND_MSG((_T("[FIL]++Read_Sector2\r\n")));
// Initialize 4-bit ECC Decoding
NF_SET_ECC_DEC();
NF_MECC_Reset();
NF_MECC_UnLock();
NF_CE_H(nBank);
NF_SET_CLK(DUMMY_R_TACLS, DUMMY_R_TWRPH0, DUMMY_R_TWRPH1);
if ((UINT32)pBuf&0x3)
{
_Write_512Byte_Unaligned(pBuf);
}
else
{
_Write_512Byte(pBuf);
}
// Read Main ECC
NF_CLEAR_ECC_DEC_DONE();
// Instead of Read Main ECC from NAND, Write Main ECC with CE don't care
if (bCheckAllFF)
{
NF_DATA_W4(ECCVAL_ALLFF0); // All 0xFF ECC
NF_DATA_W4(ECCVAL_ALLFF1);
}
else
{
NF_DATA_W4(nMECC[0]);
NF_DATA_W4(nMECC[1]);
}
// Wait Spare ECC Compare Done
NF_WAIT_ECC_DEC_DONE();
NF_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
NF_CE_L(nBank);
nRet = Decoding_MainECC(pBuf);
NAND_MSG((_T("[FIL]--Read_Sector2(), nRet = 0x%x\r\n"), nRet));
return nRet;
}
PRIVATE UINT32
Read_Spare(UINT32 nBank, UINT32 nPpn, UINT32* pSpareCxt)
{
UINT32 nOffset;
UINT32 nRet = 0;
BOOL32 bCheckMore = FALSE32;
BOOL32 bCheckAllFF = FALSE32;
UINT32 nCnt;
UINT32 nPosPtr;
UINT8 cCleanMark;
UINT8* pSBuf;
NAND_MSG((_T("[FIL]++Read_Spare(%d)\r\n"), nPpn));
// Read Spare Area
pSpareCxt[0] = NF_DATA_R4(); // 1 byte Bad Mark(->cBadMark) + 1 byte Clean Mark(->cCleanMark) + 2 byte Reserved(->cReserved)
//NAND_MSG((_T("[FIL]++Read_Spare_MLC_2(%d)\r\n"), nPpn));
if (IS_CHECK_SPARE_ECC == TRUE32)
{
// Initialize 4-bit ECC Decoding
NF_SET_ECC_DEC();
NF_MECC_Reset();
NF_MECC_UnLock();
//NAND_MSG((_T("[FIL]++Read_Spare_MLC_2_1(%d)\r\n"), nPpn));
cCleanMark = (UINT8)((pSpareCxt[0]&0xff00)>>8); // ->cCleanMark
if (WMR_GetChkSum(&cCleanMark, 1) < 4)
{
bCheckAllFF = TRUE32;
}
}
//NAND_MSG((_T("[FIL]++Read_Spare_MLC_3(%d)\r\n"), nPpn));
nPosPtr = NAND_SCXT_OFFSET/4;
if (SECTORS_PER_PAGE == 4)
{
for (nCnt = 0; nCnt < (NAND_SECC_OFFSET-NAND_SCXT_OFFSET)/4; nCnt++)
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // 12 byte Spare Context(->aSpareData) + 32 byte Sector ECC data(->aMECC)
}
else if (SECTORS_PER_PAGE == 8)
{
for (nCnt = 0; nCnt < (NAND_SECC_OFFSET_4K-NAND_SCXT_OFFSET)/4; nCnt++)
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // 20 byte Spare Context(->aSpareData) + 64 byte Sector ECC data(->aMECC)
}
else
{
WMR_ASSERT(FALSE32);
}
// NAND_MSG((_T("[FIL]++Read_Spare_MLC_4(%d)\r\n"), nPpn));
if (IS_CHECK_SPARE_ECC == TRUE32)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -