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 + -
显示快捷键?