ocld.cpp
来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 1,751 行 · 第 1/5 页
CPP
1,751 行
/* Device Power Flag and Open Flag Check */
/* Each of Out of Bound Check */
/* */
/*****************************************************************************/
#if defined(STRICT_CHK)
static BOOL32
_StrictChk(UINT32 nDev, UINT32 nPsn, UINT32 nScts)
{
UINT32 nPbn;
/* Check Device Number */
if (nDev > MAX_SUPPORT_DEVS)
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] Invalid Device Number (nDev = %d)\r\n"),
nDev));
return (FALSE32);
}
nPbn = GET_PBN(nDev, nPsn);
/* Check Device Open Flag */
if (CHK_DEV_OPEN_FLAG(nDev) == FALSE32)
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] Device is not opened\r\n")));
return (FALSE32);
}
/* Check Device Power Flag */
if (CHK_DEV_PWR_FLAG(nDev) == FALSE32)
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] Dev PwrFlg is not set\r\n")));
return (FALSE32);
}
/* Check Block Out of Bound */
/* if nBlk > GET_NUM_OF_BLKS then it is an error.*/
if (CHK_BLK_OOB(nDev, nPbn))
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] Pbn is Out of Bound\r\n")));
return (FALSE32);
}
/* Check Sector Out of Bound */
/* if ((nPsn & 0x03) + nSct) > Sectors per Page(=4) then it is an error */
if (CHK_SCT_OOB(nDev, nPsn, nScts))
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] Psn + Scts is Out of Bound\r\n")));
return (FALSE32);
}
/* Everything is OK, then TRUE32 can be returned */
return (TRUE32);
}
#endif /* #if defined(STRICT_CHK) */
#if defined(DEFERRED_CHK)
static INT32
_ChkPrevWriteResult(UINT32 nDev)
{
UINT32 nBAddr;
UINT32 nCAddr;
ONLD_DBG_PRINT((TEXT("[ONLD: IN] ++_ChkPrevWriteResult()\r\n")));
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
// ---------------------------------------------------- //
// Wait until clearing ONGO and PROG bit //
// in OneNAND native Controller Status Register //
// ---------------------------------------------------- //
while ((OCLD_REG_INT_ERR_STAT(nCAddr) & CPEND_WRITE) != (UINT16)CPEND_WRITE)
{
/* Wait until device ready */
/* Write Protection Error Check */
if ((OCLD_REG_INT_ERR_STAT(nCAddr) & BIT_LOCKED_BLK) == BIT_LOCKED_BLK)
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] (WRITE)Write Protection Error\r\n")));
ONLD_DBG_PRINT((TEXT("[ONLD : OUT] --ONLD_Write()\r\n")));
return (ONLD_WR_PROTECT_ERROR | ONLD_PREV_OP_RESULT);
}
OAM_Idle();
}
/* Write Operation Error Check */
if ((OCLD_REG_INT_ERR_STAT(nCAddr) & BIT_PGM_FAIL) == BIT_PGM_FAIL)
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] (WRITE)Write Error\r\n")));
ONLD_DBG_PRINT((TEXT("[ONLD : OUT] --ONLD_Write()\r\n")));
return (ONLD_WRITE_ERROR | ONLD_PREV_OP_RESULT);
}
pstPrevOpInfo[nDev]->ePreOp = NONE;
ONLD_DBG_PRINT((TEXT("[ONLD:OUT] --_ChkPrevWriteResult(nRet = ONLD_SUCCESS)\r\n")));
return ONLD_SUCCESS;
}
static INT32
_ChkPrevEraseResult(UINT32 nDev)
{
UINT32 nBAddr;
UINT32 nCAddr;
UINT32 nPbn;
ONLD_DBG_PRINT((TEXT("[ONLD: IN] ++_ChkPrevEraseResult()\r\n")));
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
nPbn = GET_PBN(nDev, pstPrevOpInfo[nDev]->nPsn);
/* Wait until command is completed */
while (ONLD_READ_CMD(nDev, nBAddr, nPbn, 0) == INPROGRESS);
while ((OCLD_REG_INT_ERR_STAT(nCAddr) & CPEND_ERASE) != (UINT16)CPEND_ERASE)
{
/* Wait until device ready */
/* Write Protection Error Check */
if ((OCLD_REG_INT_ERR_STAT(nCAddr) & BIT_LOCKED_BLK) == BIT_LOCKED_BLK)
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] Previous Write Protection Error\r\n")));
return (ONLD_WR_PROTECT_ERROR | ONLD_PREV_OP_RESULT);
}
OAM_Idle();
}
/* Erase Operation Error Check */
if ((OCLD_REG_INT_ERR_STAT(nCAddr) & BIT_ERS_FAIL) == BIT_ERS_FAIL)
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] (ERASE)Erase Error(nPbn = %d)\r\n"), nPbn));
ONLD_DBG_PRINT((TEXT("[ONLD : OUT] --ONLD_Erase()\r\n")));
return (ONLD_ERASE_ERROR | ONLD_PREV_OP_RESULT);
}
ONLD_DBG_PRINT((TEXT("[ONLD:OUT] --_ChkPrevEraseResult(nRet = ONLD_SUCCESS)\r\n")));
return ONLD_SUCCESS;
}
static INT32
_ChkPrevMEraseResult(UINT32 nDev)
{
UINT32 nBAddr;
UINT32 nCAddr;
UINT32 nPbn;
ONLD_DBG_PRINT((TEXT("[ONLD: IN] ++_ChkPrevMEraseResult()\r\n")));
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
nPbn = GET_PBN(nDev, pstPrevOpInfo[nDev]->nPsn);
/* Wait until command is completed */
while (ONLD_READ_CMD(nDev, nBAddr, nPbn, 0) == INPROGRESS);
while ((OCLD_REG_INT_ERR_STAT(nCAddr) & CPEND_ERASE) != (UINT16)CPEND_ERASE)
{
/* Wait until device ready */
/* Write Protection Error Check */
if ((OCLD_REG_INT_ERR_STAT(nCAddr) & BIT_LOCKED_BLK) == BIT_LOCKED_BLK)
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] Previous Write Protection Error\r\n")));
return (ONLD_WR_PROTECT_ERROR | ONLD_PREV_OP_RESULT);
}
OAM_Idle();
}
/* Erase Operation Error Check */
if ((OCLD_REG_INT_ERR_STAT(nCAddr) & BIT_ERS_FAIL) == BIT_ERS_FAIL)
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] (ERASE)Erase Error(nPbn = %d)\r\n"), nPbn));
ONLD_DBG_PRINT((TEXT("[ONLD : OUT] --ONLD_Erase()\r\n")));
return (ONLD_ERASE_ERROR | ONLD_PREV_OP_RESULT);
}
if (ONLD_EraseVerify(nDev,
pstPrevOpInfo[nDev]->pstPreMEArg,
pstPrevOpInfo[nDev]->nFlag) != ONLD_SUCCESS)
{
ONLD_ERR_PRINT((TEXT("[ONLD:ERR] Previous MErase Error\r\n")));
ONLD_DBG_PRINT((TEXT("[ONLD:OUT] --_ChkPrevMEraseResult()\r\n")));
return (ONLD_MERASE_ERROR | ONLD_PREV_OP_RESULT);
}
ONLD_DBG_PRINT((TEXT("[ONLD:OUT] --_ChkPrevMEraseResult(nRet = ONLD_SUCCESS)\r\n")));
return ONLD_SUCCESS;
}
/*****************************************************************************/
/* */
/* NAME */
/* _ChkPrevOpResult */
/* DESCRIPTION */
/* This function checks the result of previous opreation */
/* PARAMETERS */
/* nDev */
/* Physical Device Number (0 ~ 7) */
/* RETURN VALUES */
/* ONLD_WRITE_ERROR | ONLD_PREV_OP_RESULT */
/* Previous Write Failure */
/* ONLD_ERASE_ERROR | ONLD_PREV_OP_RESULT */
/* Previous Erase Failure */
/* ONLD_WR_PROTECT_ERROR | ONLD_PREV_OP_RESULT */
/* Previous Operation Write Protect Error */
/* NOTES */
/* */
/*****************************************************************************/
static INT32
_ChkPrevOpResult(UINT32 nDev)
{
UINT32 nBAddr, nPbn;
INT32 nRet = ONLD_SUCCESS;
OpType ePrevOp;
UINT32 nCAddr;
ONLD_DBG_PRINT((TEXT("[ONLD: IN] ++_ChkPrevOpResult()\r\n")));
if (GET_PREV_OP_TYPE(nDev) == NONE)
{
return (nRet);
}
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
/* Wait until the device is ready */
while ((OCLD_REG_INT_ERR_STAT(nCAddr) & BIT_INT_ACT) != (UINT16)BIT_INT_ACT);
nPbn = GET_PBN(nDev, pstPrevOpInfo[nDev]->nPsn);
ePrevOp = GET_PREV_OP_TYPE(nDev);
/* Clear the previous operation type */
pstPrevOpInfo[nDev]->ePreOp = NONE;
switch(ePrevOp)
{
case WRITE:
case CPBACK:
nRet = _ChkPrevWriteResult(nDev);
break;
case ERASE:
nRet = _ChkPrevEraseResult(nDev);
break;
case MERASE:
nRet = _ChkPrevMEraseResult(nDev);
break;
case READ:
#if 0
while ((OCLD_REG_INT_ERR_STAT(nCAddr) & CPEND_READ) != (UINT16)CPEND_READ)
{
/* Wait until device ready */
OAM_Idle();
}
#endif
break;
default:
#if 0
while ((OCLD_REG_INT_ERR_STAT(nCAddr) & CPEND_INT) != (UINT16)CPEND_INT)
{
/* Wait until device ready */
OAM_Idle();
}
#endif
break;
}
/* Acknowledge interrupts */
OCLD_REG_INT_ERR_ACK(nCAddr) = (UINT16)CINT_CLEAR;
ONLD_DBG_PRINT((TEXT("[ONLD:OUT] --_ChkPrevOpResult\r\n")));
return (nRet);
}
#endif /* #if defined(DEFERRED_CHK) */
/*****************************************************************************/
/* */
/* NAME */
/* InitializeONDController */
/* DESCRIPTION */
/* This function gets Manufacturer ID, Device ID and Version ID of */
/* NAND flash device. */
/* PARAMETERS */
/* nDev */
/* Physical Device Number (0 ~ 7) */
/* pMID */
/* Manufacturer ID */
/* pDID */
/* Device ID */
/* pVID */
/* Version ID */
/* RETURN VALUES */
/* None */
/* NOTES */
/* */
/*****************************************************************************/
static VOID
InitializeONDController(UINT32 nDev, UINT16 *pMID, UINT16 *pDID, UINT16 *pVID)
{
UINT32 nBAddr;
UINT32 nCAddr;
volatile S3C6410_GPIO_REG *pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE);
volatile S3C6410_SYSCON_REG *pSYSCONReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE);
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
ONLD_DBG_PRINT((TEXT("[ONLD : IN] ++ONDController_Init() nBAddr = 0x%x\r\n"), nBAddr));
if ((pMID == NULL) || (pDID == NULL) || (pVID == NULL))
{
ONLD_ERR_PRINT((TEXT("[ONLD : ERR] (InitializeONDController) NULL Pointer Error\r\n")));
ONLD_DBG_PRINT((TEXT("[ONLD : OUT] --InitializeONDController()\r\n")));
return;
}
// drive strength for GPIO port toward OneNAND
//pGPIOReg->MEM0DRVCON = 0x55000411;
pGPIOReg->MEM0DRVCON = 0xaaaaaaaa;
// setting clock for OneNAND controller
//pSYSCONReg->CLK_DIV0 = (pSYSCONReg->CLK_DIV0 & ~(0x3<<16)) | (ONDNAND_RATIO_2_TO_HCLKx2<<16); // ClkOneNAND = HCLKx2 / (1+1)
//pSYSCONReg->SCLK_GATE |= SCLK_ONENAND_ON;
//pSYSCONReg->MEM_SYS_CFG &= ~(0xf);
//Disable Watchdog Timer reset logic in OneNandd controller
OCLD_REG_FLASH_AUX_CNTRL(nCAddr)=0x1;
// setting delay toward NAND Flash in case of As
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?