?? s3c6410_fil.c
字號:
}
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;
}
VOID
NAND_PowerUp(VOID)
{
#if 1
//pSYSConReg->MEM_SYS_CFG &= ~(1<<12); // NAND Flash BUS Width -> 8 bit
//pSYSConReg->MEM_SYS_CFG &= ~(0x1<<1); // Xm0CS2 -> NFCON CS0
pSYSConReg->MEM_SYS_CFG = (pSYSConReg->MEM_SYS_CFG & ~(0x1000)); // 8-bit data width
pSYSConReg->MEM_SYS_CFG = (pSYSConReg->MEM_SYS_CFG & ~(0x3F)) | (0x00); // Xm0CSn[2] = NFCON CS0
/****************************************************************************/
#else
// NAND Chip Selection Signal in the S3C6410
pSYSConReg->MEM_SYS_CFG &= ~(0xA);
#endif
// Initialize NAND Flash Controller for MLC NAND Flash
pNANDFConReg->NFCONF = NF_4BIT_ECC | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
pNANDFConReg->NFCONT = NF_MAIN_ECC_LOCK | NF_SPARE_ECC_LOCK | NF_INIT_MECC | NF_INIT_SECC | NF_NFCE1 | NF_NFCE0 | NF_NFCON_EN;
pNANDFConReg->NFSTAT = NF_RNB_READY; // Clear RnB Transition Detect Bit
}
/*****************************************************************************/
/* */
/* 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];
BOOL32 bECCDecDone = TRUE;
NAND_MSG((_T("[FIL]++Read_Sector(%d, %d)\r\n"), nPpn, nSctOffset));
//NAND_ERR((_T("[FIL]++Read_Sector(%d, %d)\r\n"), nPpn, nSctOffset)); // ksk dbg
gnPpn = nPpn;
// 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 ((UINT32)pBuf&0x3)
{
_Read_512Byte_Unaligned(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
else
{
_Read_512Byte(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
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]
}
if ( bReadSafeMode == TRUE32 )
{
NF_SET_CLK(MAX_RW_TACLS, MAX_RW_TWRPH0, MAX_RW_TWRPH1); // Don't set clk to (0, 0, 0) !!! Decoding error occurs
}
else
{
NF_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
}
NF_CE_L(nBank);
// Waiting for Main ECC compare
bECCDecDone = NF_WAIT_ECC_DEC_DONE(pNANDFConReg);
if ( bECCDecDone == TRUE32 )
{
nRet = Decoding_MainECC(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
else
{
nRet = ECC_UNCORRECTABLE_ERROR;
NAND_ERR((_T("Read_Sector: ECC Decoding Timeout Error\r\n")));
}
#if (PROVE_ECC_ALGORITHM)
if ( nRet&ECC_NEED_DECODING_AGAIN )
{
// 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); // Don't set clk to (0, 0, 0) !!! Decoding error occurs
if ((UINT32)pBuf&0x3)
{
_Write_512Byte_Unaligned(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
else
{
_Write_512Byte(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
NF_CLEAR_ECC_DEC_DONE();
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]);
}
if ( bReadSafeMode == TRUE32 )
{
NF_SET_CLK(MAX_RW_TACLS, MAX_RW_TWRPH0, MAX_RW_TWRPH1); // Don't set clk to (0, 0, 0) !!! Decoding error occurs
}
else
{
NF_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
}
NF_CE_L(nBank);
// NAND_ERR((_T("+NF_WAIT_ECC_DEC_DONE\r\n")));
bECCDecDone = NF_WAIT_ECC_DEC_DONE(pNANDFConReg);
// NAND_ERR((_T("-NF_WAIT_ECC_DEC_DONE\r\n")));
nRet &= ~ECC_NEED_DECODING_AGAIN;
if ( bECCDecDone == TRUE32 )
{
nRet |= Decoding_MainECC(pBuf+NAND_SECTOR_SIZE*nSctOffset);
if ( nRet&ECC_NEED_DECODING_AGAIN )
{
nRet &= ~ECC_NEED_DECODING_AGAIN;
nRet |= ECC_UNCORRECTABLE_ERROR;
NAND_ERR((_T("[FIL:ERR] Read_Sector() : Multiple Decoding Error. Over 4bit Error!!\r\n")));
}
}
else
{
NAND_ERR((_T("Read_Sector: ECC Decoding Timeout Error\r\n")));
nRet |= ECC_UNCORRECTABLE_ERROR;
}
}
#endif
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_ERR((_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_Sector_8BitECC(UINT32 nBank, UINT32 nPpn, UINT32 nSctOffset, UINT8* pBuf, UINT32* pSpareCxt, BOOL32 bCheckAllFF)
{
UINT32 nOffSet;
UINT32 nRet = 0;
UINT32 nMECC[4];
//_STOP_FOR_BREAK();
NAND_MSG((_T("[FIL]++Read_Sector_8BitECC(%d, %d)\r\n"), nPpn, nSctOffset));
// Move pointer to Sector O
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -