📄 s3c2450_fil.c
字号:
/* 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, pSECCCxt pSpareCxt, BOOL32 bCheckAllFF)
{
UINT32 nOffSet;
UINT32 nRet = 0;
UINT32 nRetEcc = 0;
int i = 0;
unsigned char bECC[4];
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 1-bit ECC Decoding
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();
if (bCheckAllFF)
{
NF_WRMECCD0(ECCVAL_ALLFF); // All 0xFF ECC
NF_WRMECCD1(ECCVAL_ALLFF);
}
else
{
bECC[0] = (unsigned char)(((pSpareCxt->aMECC[nSctOffset])>>0)&0xffffffff);
bECC[1] = (unsigned char)(((pSpareCxt->aMECC[nSctOffset])>>8)&0xffffffff);
bECC[2] = (unsigned char)(((pSpareCxt->aMECC[nSctOffset])>>16)&0xffffffff);
bECC[3] = (unsigned char)(((pSpareCxt->aMECC[nSctOffset])>>24)&0xffffffff);
NF_WRMECCD0(((bECC[1]&0xff)<<16)|(bECC[0]&0xff));
NF_WRMECCD1(((bECC[3]&0xff)<<16)|(bECC[2]&0xff));
}
nRetEcc = NF_ECC_ERR0();
switch(nRetEcc & 0x3)
{
case 0: // No Error
break;
case 1: // 1-bit Error(Correctable)
(pBuf)[(nRetEcc>>7)&0x7ff] ^= (1<<((nRetEcc>>4)&0x7));
nRet = ECC_CORRECTABLE_ERROR;
break;
case 2: // Multiple Error
case 3: // ECC area Error
nRet = ECC_UNCORRECTABLE_ERROR;
break;
}
NAND_MSG((_T("[FIL]--Read_Sector()\r\n")));
return nRet;
}
PRIVATE UINT32
Read_Spare(UINT32 nBank, UINT32 nPpn, pSECCCxt pSpareCxt)
{
UINT32 nOffset;
UINT32 nRet = 0;
UINT32 nResult = 0;
BOOL32 bCheckAllFF = FALSE32;
NAND_MSG((_T("[FIL]++Read_Spare(%d)\r\n"), nPpn));
// Read Spare Area
pSpareCxt->cBadMark = NF_DATA_R(); // 1 byte Bad Mark
pSpareCxt->cCleanMark = NF_DATA_R(); // 1 byte Clean Mark
pSpareCxt->cReserved[0] = NF_DATA_R(); // 2 byte Reserved
pSpareCxt->cReserved[1] = NF_DATA_R();
if (IS_CHECK_SPARE_ECC == TRUE32)
{
// Initialize 1-bit ECC Decoding
NF_SECC_Reset();
NF_SECC_UnLock();
if (WMR_GetChkSum(&pSpareCxt->cCleanMark, 1) < 4)
{
bCheckAllFF = TRUE32;
}
}
if (SECTORS_PER_PAGE == 4)
{
pSpareCxt->aSpareData[0] = NF_DATA_R4(); // 12 byte Spare Context
pSpareCxt->aSpareData[1] = NF_DATA_R4();
pSpareCxt->aSpareData[2] = NF_DATA_R4();
if (IS_CHECK_SPARE_ECC == TRUE32)
{
NF_SECC_Lock();
}
//CommentPilsun
//Only Use 4Byte for SLC ECC x 4 (Because, there is 4 sector in each page)
pSpareCxt->aMECC[0] = NF_DATA_R4(); // 4 byte Sector0 ECC data
pSpareCxt->aMECC[1] = NF_DATA_R4(); // 4 byte Sector1 ECC data
pSpareCxt->aMECC[2] = NF_DATA_R4(); // 4 byte Sector2 ECC data
pSpareCxt->aMECC[3] = NF_DATA_R4(); // 4 byte Sector3 ECC data
pSpareCxt->aMECC[4] = NF_DATA_R4(); // 4 byte Sector4 ECC data if 4KByte/Page
pSpareCxt->aMECC[5] = NF_DATA_R4(); // 4 byte Sector5 ECC data if 4KByte/Page
pSpareCxt->aMECC[6] = NF_DATA_R4(); // 4 byte Sector6 ECC data if 4KByte/Page
pSpareCxt->aMECC[7] = NF_DATA_R4(); // 4 byte Sector7 ECC data if 4KByte/Page
}
else if (SECTORS_PER_PAGE == 8)
{
pSpareCxt->aSpareData[0] = NF_DATA_R4(); // 20 byte Spare Context for 4KByte/Page
pSpareCxt->aSpareData[1] = NF_DATA_R4();
pSpareCxt->aSpareData[2] = NF_DATA_R4();
pSpareCxt->aSpareData[3] = NF_DATA_R4();
pSpareCxt->aSpareData[4] = NF_DATA_R4();
if (IS_CHECK_SPARE_ECC == TRUE32)
{
NF_SECC_Lock();
}
//CommentPilsun
//Only Use 4Byte for SLC ECC x 4 (Because, there is 4 sector in each page)
pSpareCxt->aMECC[0] = NF_DATA_R4(); // 4 byte Sector0 ECC data
pSpareCxt->aMECC[1] = NF_DATA_R4(); // 4 byte Sector1 ECC data
pSpareCxt->aMECC[2] = NF_DATA_R4(); // 4 byte Sector2 ECC data
pSpareCxt->aMECC[3] = NF_DATA_R4(); // 4 byte Sector3 ECC data
pSpareCxt->aMECC[4] = NF_DATA_R4(); // 4 byte Sector4 ECC data if 4KByte/Page
pSpareCxt->aMECC[5] = NF_DATA_R4(); // 4 byte Sector5 ECC data if 4KByte/Page
pSpareCxt->aMECC[6] = NF_DATA_R4(); // 4 byte Sector6 ECC data if 4KByte/Page
pSpareCxt->aMECC[7] = NF_DATA_R4(); // 4 byte Sector7 ECC data if 4KByte/Page
pSpareCxt->aMECC[8] = NF_DATA_R4(); // 4 byte dummy data
pSpareCxt->aMECC[9] = NF_DATA_R4(); // 4 byte dummy data
pSpareCxt->aMECC[10] = NF_DATA_R4(); // 4 byte dummy data
pSpareCxt->aMECC[11] = NF_DATA_R4(); // 4 byte dummy data
pSpareCxt->aMECC[12] = NF_DATA_R4(); // 4 byte dummy data
pSpareCxt->aMECC[13] = NF_DATA_R4(); // 4 byte dummy data
pSpareCxt->aMECC[14] = NF_DATA_R4(); // 4 byte dummy data
pSpareCxt->aMECC[15] = NF_DATA_R4(); // 4 byte dummy data
}
else
{
WMR_ASSERT(FALSE32);
}
if (IS_CHECK_SPARE_ECC == TRUE32)
{
if (bCheckAllFF)
{
NF_WRSECCD(0x3FF03FF);
}
else
{
pSpareCxt->aSECC[0] = NF_DATA_R4(); // Read 4 byte Spare ECC data
pSpareCxt->aSECC[1] = NF_DATA_R4(); // Read 4 byte dummy ECC data
pSpareCxt->aSECC[2] = NF_DATA_R4(); // Read 4 byte dummy ECC data
pSpareCxt->aSECC[3] = NF_DATA_R4(); // Read 4 byte dummy ECC data
NF_WRSECCD(((pSpareCxt->aSECC[0]&0xff)<<16)|(pSpareCxt->aSECC[0]&0xff));
}
nResult = NF_ECC_ERR0();
if (bCheckAllFF)
{
pSpareCxt->aSECC[0] = NF_DATA_R4(); // Read 4 byte Spare ECC data
pSpareCxt->aSECC[1] = NF_DATA_R4(); // Read 4 byte dummy ECC data
pSpareCxt->aSECC[2] = NF_DATA_R4(); // Read 4 byte dummy ECC data
pSpareCxt->aSECC[3] = NF_DATA_R4(); // Read 4 byte dummy ECC data
}
}
else
{
//CommentPilsun
// just read Spare ECC from NAND for read pointer, NOT decoding ECC
pSpareCxt->aSECC[0] = NF_DATA_R4(); // 4 byte Spare ECC data
pSpareCxt->aSECC[1] = NF_DATA_R4(); // 4 byte dummy ECC data
pSpareCxt->aSECC[2] = NF_DATA_R4(); // 4 byte dummy ECC data
pSpareCxt->aSECC[3] = NF_DATA_R4(); // 4 byte dummy ECC data
NF_WRSECCD(((pSpareCxt->aSECC[0]&0xff)<<16)|(pSpareCxt->aSECC[0]&0xff));
nResult = NF_ECC_ERR0();
}
switch(nResult & 0xc)
{
case 0: // No Error
{
break;
}
case 1: // 1-bit Error(Correctable)
{
NAND_ERR((_T("[FIL:ERR] Read_Spare() : ECC Uncorrectable Error in Spare of Page %d\r\n"), nPpn));
(pSpareCxt->aSpareData)[(nRet>>21)&0x3] ^= (1<<((nRet>>18)&0x7));
break;
}
case 2: // Multiple Error
case 3: // ECC area Error
{
NAND_MSG((_T("[FIL] Read_Spare() : ECC Correctable Error in Spare of Page %d\r\n"), nPpn));
break;
}
}
NAND_MSG((_T("[FIL]--Read_Spare()\r\n")));
return nRet;
}
PRIVATE VOID
Write_Sector(UINT32 nPpn, UINT32 nSctOffset, UINT8* pBuf)
{
UINT32 nOffset;
int i = 0;
NAND_MSG((_T("[FIL]++Write_Sector(%d, %d)\r\n"), nPpn, nSctOffset));
nOffset = NAND_SECTOR_SIZE*nSctOffset;
NF_CMD(CMD_RANDOM_DATA_INPUT);
NF_ADDR(nOffset&0xFF);
NF_ADDR((nOffset>>8)&0xFF);
if (IS_CHECK_SPARE_ECC == TRUE32)
{
NF_MECC_Reset();
NF_MECC_UnLock();
}
#if (NAND_TRANS_MODE == ASM)
if ((UINT32)pBuf&0x3)
{
_Write_512Byte_Unaligned(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
else
{
_Write_512Byte(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
#elif (NAND_TRANS_MODE == DMA)
Write_512Byte_DMA(pBuf+NAND_SECTOR_SIZE*nSctOffset);
#endif
if (IS_CHECK_SPARE_ECC == TRUE32)
{
NF_MECC_Lock();
}
NAND_MSG((_T("[FIL]--Write_Sector()\r\n")));
return;
}
PRIVATE VOID
Write_Spare(UINT32 nBank, UINT32 nPpn, pSECCCxt pSpareCxt)
{
UINT32 nOffset;
NAND_MSG((_T("[FIL]++Write_Spare(%d, %d)\r\n"), nBank, nPpn));
nOffset = BYTES_PER_MAIN_PAGE;
NF_CMD(CMD_RANDOM_DATA_INPUT);
NF_ADDR(nOffset&0xFF);
NF_ADDR((nOffset>>8)&0xFF);
NF_DATA_W(pSpareCxt->cBadMark); // 1 byte Bad Mark
NF_DATA_W(pSpareCxt->cCleanMark); // 1 byte Clean Mark
#if 1
NF_DATA_W(0xff); // 2 byte Reserved
NF_DATA_W(0xff);
#else
NF_DATA_W(pSpareCxt->cReserved[0]); // 2 byte Reserved
NF_DATA_W(pSpareCxt->cReserved[1]);
#endif
if (IS_CHECK_SPARE_ECC == TRUE32)
{
// Initialize 1-bit ECC Encoding
NF_SECC_Reset();
NF_SECC_UnLock();
}
if (SECTORS_PER_PAGE == 4)
{
NF_DATA_W4(pSpareCxt->aSpareData[0]); // 12 byte Spare Context
NF_DATA_W4(pSpareCxt->aSpareData[1]);
NF_DATA_W4(pSpareCxt->aSpareData[2]);
//CommentPilsun
if (IS_CHECK_SPARE_ECC == TRUE32)
{
NF_SECC_Lock();
}
//CommentPilsun
//Only Use 4Byte for SLC ECC
NF_DATA_W4(pSpareCxt->aMECC[0]); // 4 byte Sector0 ECC data
NF_DATA_W4(pSpareCxt->aMECC[1]); // 4 byte Sector1 ECC data
NF_DATA_W4(pSpareCxt->aMECC[2]); // 4 byte Sector2 ECC data
NF_DATA_W4(pSpareCxt->aMECC[3]); // 4 byte Sector3 ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
}
else if (SECTORS_PER_PAGE == 8)
{
NF_DATA_W4(pSpareCxt->aSpareData[0]); // 20 byte Spare Context for 4KByte/Page
NF_DATA_W4(pSpareCxt->aSpareData[1]);
NF_DATA_W4(pSpareCxt->aSpareData[2]);
NF_DATA_W4(pSpareCxt->aSpareData[3]);
NF_DATA_W4(pSpareCxt->aSpareData[4]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -