ocld.cpp
来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 1,751 行 · 第 1/5 页
CPP
1,751 行
astONLDMemAddr[nDev].nDFSDBSMask = 1;
}
else
{
OCLD_REG_FBA_WIDTH(nCAddr) = 12;
OCLD_REG_DBS_DFS_WIDTH(nCAddr) = 0;
astONLDMemAddr[nDev].nDFSDBSMask = 0;
}
astONLDMemAddr[nDev].nFBAShift = 12;
astONLDMemAddr[nDev].nFPAShift = 6;
astONLDMemAddr[nDev].nFSAShift = 4;
astONLDMemAddr[nDev].nFBAMask = 0xFFF;
astONLDMemAddr[nDev].nFPAMask = 0x3F;
astONLDMemAddr[nDev].nFSAMask = 0x3;
break;
default :
break;
}
}
//////////
// Function Name : ONENAND_EnableECCCorrection
// Function Description : Set the ECC Error Correction Operation
// Input : Controller - OneNand Controller Port Number
// uEnable -ONENAND_WITH_CORRECT : ECC Error Correction enable
// ONENAND_WITHOUT_CORRECT : ECC Error Correction disable
// Version : v0.1
void ONENAND_EnableECCCorrection(UINT32 nDev, BOOL32 bEnable)
{
UINT32 uEnableECC;
UINT32 nBAddr;
UINT32 nCAddr;
UINT32 temp = 0xffffffff;
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
uEnableECC = OCLD_REG_MEM_CFG(nCAddr);
if(bEnable == TRUE32)
uEnableECC &= ~BIT_ECC;
else
uEnableECC |= BIT_ECC;
OCLD_REG_MEM_CFG(nCAddr) = uEnableECC;
temp = ONLD_READ_DIRECT(nBAddr, ONLD_REG_SYS_CONF1(0x0));
}
//////////
// Function Name : ONENAND_EnableIOBE
// Function Description : Set the I/O Buffer enable for INT and RDY signals
// Input : Controller - OneNand Controller Port Number
// uEnable - IOBE Enable/Disable
// Version : v0.1
void ONENAND_EnableIOBE(UINT32 nDev, BOOL32 bEnable)
{
UINT32 uEnableIOBE;
UINT32 nBAddr;
UINT32 nCAddr;
UINT32 temp = 0xffffffff;
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
uEnableIOBE = OCLD_REG_MEM_CFG(nCAddr);
uEnableIOBE &= ~(0x7<<5);
uEnableIOBE |= BIT_RDYPOL | BIT_INTPOL | (bEnable<<5);
OCLD_REG_MEM_CFG(nCAddr) = uEnableIOBE;
temp = ONLD_READ_DIRECT(nBAddr, ONLD_REG_SYS_CONF1(0x0));
}
//////////
// Function Name : ONENAND_SetBurstLatency
// Function Description : Sets the burst read latency in cycles
// Input : Controller - OneNand Controller Port Number
// eLatency - (OneNAND_eLATENCY)latency cycle
// Version : v0.1
void ONENAND_SetBurstLatency(UINT32 nDev, OneNAND_eLATENCY eLatency)
{
UINT32 uBurstReadLatency;
UINT32 nBAddr;
UINT32 nCAddr;
UINT32 temp = 0xffffffff;
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
uBurstReadLatency = OCLD_REG_MEM_CFG(nCAddr);
uBurstReadLatency &= ~(0x7<<12);
uBurstReadLatency |= (eLatency<<12);
OCLD_REG_MEM_CFG(nCAddr) = uBurstReadLatency;
temp = ONLD_READ_DIRECT(nBAddr, ONLD_REG_SYS_CONF1(0x0));
}
//////////
// Function Name : ONENAND_SyncMode
// Function Description : Set the OneNand Transfer Mode include burst length
// Input : Controller - OneNand Controller Port Number
// uMode - Read&Write Transfer Mode
// Version : v0.1
void ONENAND_SetSyncMode(UINT32 nDev, OneNAND_eMODE eMode)
{
UINT32 uSyncMode;
UINT32 nBAddr;
UINT32 nCAddr;
UINT32 temp = 0xffffffff;
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
uSyncMode = OCLD_REG_MEM_CFG(nCAddr);
uSyncMode &= ~((1<<15)|(0x7<<9)|(1<<1));
switch (eMode)
{
case eOND_SYNC_CONT:
uSyncMode |= (0x1<<15)|(0x0<<9)|(0x1<<1);
OCLD_REG_BURST_LEN(nCAddr) = BL_16WORDS;
OCLD_REG_MEM_CFG(nCAddr) = uSyncMode; //sync, burst:incr
break;
case eOND_SYNC_BURST4:
uSyncMode |= (0x1<<15)|(0x1<<9)|(0x1<<1);
OCLD_REG_BURST_LEN(nCAddr) = BL_4WORDS;
OCLD_REG_MEM_CFG(nCAddr) = uSyncMode; //sync, burst:4
break;
case eOND_SYNC_BURST8:
uSyncMode |= (0x1<<15)|(0x2<<9)|(0x1<<1);
OCLD_REG_BURST_LEN(nCAddr) = BL_8WORDS;
OCLD_REG_MEM_CFG(nCAddr) = uSyncMode; //sync, burst:8
break;
case eOND_SYNC_BURST16:
uSyncMode |= (0x1<<15)|(0x3<<9)|(0x1<<1);
OCLD_REG_BURST_LEN(nCAddr) = BL_16WORDS;
OCLD_REG_MEM_CFG(nCAddr) = uSyncMode; //sync, burst:16
break;
case eOND_SYNC_BURST32:
uSyncMode |= (0x1<<15)|(0x4<<9)|(0x1<<1);
OCLD_REG_BURST_LEN(nCAddr) = BL_32WORDS;
OCLD_REG_MEM_CFG(nCAddr) = uSyncMode; //sync, burst:16
break;
case eOND_RM_SYNC_WM_ASYNC_BURST16:
uSyncMode |= (0x1<<15)|(0x3<<9)|(0x0<<1);
OCLD_REG_BURST_LEN(nCAddr) = BL_16WORDS;
OCLD_REG_MEM_CFG(nCAddr) = uSyncMode; //rm sync, wm async, burst:16
break;
case eOND_ASYNC:
default:
uSyncMode |= (0x0<<15)|(0x0<<9)|(0x0<<1);
OCLD_REG_BURST_LEN(nCAddr) = 0;
OCLD_REG_MEM_CFG(nCAddr) = uSyncMode; //rm async, burst:4
break;
}
temp = ONLD_READ_DIRECT(nBAddr, ONLD_REG_SYS_CONF1(0x0));
}
//////////
// Function Name : ONENAND_EnableIntPin
// Function Description : Interrupt Pin Enable&Disable
// Input : Controller - OneNand Controller Port Number
// Enable - 1:Enable, 0: Disable
// Version : v0.1
void ONENAND_EnableIntPin(UINT32 nDev, UINT32 nFlag)
{
UINT32 nBAddr;
UINT32 nCAddr;
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
OCLD_REG_INT_PIN_ENABLE(nCAddr) = nFlag & 0x1;
}
void ONENAND_EnableSpareTransfer(UINT32 nDev, UINT32 nFlag)
{
UINT32 nBAddr;
UINT32 nCAddr;
nBAddr = GET_DEV_BADDR(nDev);
nCAddr = GET_ONENANDCON_BADDR(nBAddr);
OCLD_REG_TRANS_SPARE(nCAddr) = nFlag & 0x1;
}
#if (OND_TRANS_MODE == OND_DMA)
BOOL MapDMABuffers()
{
BOOL bRet = TRUE;
ONLD_DBG_PRINT((TEXT("[ONLD:MSG] ++MapDMABuffers()\r\n")));
g_nDMABufferPhyPage = (UINT32)ONLD_PAGEDATA_PA_BASEADDR;
g_nDMABufferVirPage = (UINT32)(ONLD_PAGEDATA_VA_BASEADDR | CACHED_TO_UNCACHED_OFFSET); // uncached area
// g_nDMABufferVirPage = (UINT32)ONLD_PAGEDATA_VA_BASEADDR; // cached area
return bRet;
}
BOOL DMAInitialize()
{
#ifndef USE_SDMA
g_pSYSCONReg->HCLK_GATE |= (1<<12); // DMAC0 HCLK Pass
#else
g_pSYSCONReg->HCLK_GATE |= (1<<26); // SDMAC0 HCLK Pass
#endif
if (!(g_pDMAC0Reg->DMACC3Control0 & TCINT_ENABLE)) // Check channel in use with TC Int Enable Bit !!!
{
g_pDMAC0Reg->DMACC3Control0 |= TCINT_ENABLE; // Set TC Int Enable Bit to reserve this channel!!!
}
if (!(g_pDMAC0Reg->DMACConfiguration & DMAC_ENABLE)) // DMAC0 is Disabled
{
// Enable DMAC0
g_pDMAC0Reg->DMACConfiguration = M1_LITTLE_ENDIAN | M2_LITTLE_ENDIAN | DMAC_ENABLE;
ONLD_DBG_PRINT((TEXT("[ONLD:MSG] DMAC0 Enabled\r\n")));
}
return TRUE;
}
BOOL DMASetOneNAND(UINT32 nOneNANDMode, UINT32 nTransUnit, UINT32 nBurstSize)
{
g_pDMAC0Reg->DMACC3LLI = 0; // Disable LLI
g_pDMAC0Reg->DMACC3Configuration = ALLOW_REQUEST | UNLOCK | FLOWCTRL(MEM_TO_MEM) | DEST_PERI(0) | SRC_PERI(0);
// setting source
g_pDMAC0Reg->DMACC3Control0 = (g_pDMAC0Reg->DMACC3Control0 & ~((1<<26)|(1<<24)|SRC_UNIT_MASK|SRC_BURST_MASK))
|(INCREASE<<26) |(AHB_M1<<24)|(nTransUnit<<18)|(nBurstSize<<12);
// setting destination
g_pDMAC0Reg->DMACC3Control0 = (g_pDMAC0Reg->DMACC3Control0 & ~((1<<27)|(1<<25)|DEST_UNIT_MASK|DEST_BURST_MASK))
|(INCREASE<<27) |(AHB_M1<<25)|(nTransUnit<<21)|(nBurstSize<<15);
// setting OneNAND readpage
g_pDMAC0Reg->DMACC3Configuration &= ~(ONENANDMODEDST|ONENANDMODESRC);
g_pDMAC0Reg->DMACC3Configuration |= nOneNANDMode;
// Clear Interrupt Pending
g_pDMAC0Reg->DMACIntTCClear |= (1<<3);
g_pDMAC0Reg->DMACIntErrClear |= (1<<3);
g_pDMAC0Reg->DMACC3Configuration &= ~(TCINT_UNMASK|ERRINT_UNMASK); // mask interrupt, polling DMA
return TRUE;
}
BOOL DMASetChannelTransSize_Read(UINT32 uSrcAddr, UINT32 uDstAddr, UINT32 uByteCount)
{
g_pDMAC0Reg->DMACC3SrcAddr = (UINT32)(uSrcAddr - CACHED_TO_UNCACHED_OFFSET - ONLD_PHYSICAL_TO_VIRTUAL_OFFSET);
g_pDMAC0Reg->DMACC3DestAddr = (UINT32)uDstAddr;
// setting transter size
g_pDMAC0Reg->DMACC3Control1 = uByteCount;
return TRUE;
}
BOOL DMASetChannelTransSize_Write(UINT32 uSrcAddr, UINT32 uDstAddr, UINT32 uByteCount)
{
g_pDMAC0Reg->DMACC3SrcAddr = (UINT32)uSrcAddr;
g_pDMAC0Reg->DMACC3DestAddr = (UINT32)(uDstAddr - CACHED_TO_UNCACHED_OFFSET - ONLD_PHYSICAL_TO_VIRTUAL_OFFSET);
// setting transter size
g_pDMAC0Reg->DMACC3Control1 = uByteCount;
return TRUE;
}
BOOL DMASetChannelTransSize(UINT32 uSrcAddr, UINT32 uDstAddr, UINT32 uByteCount)
{
if (g_pDMAC0Reg->DMACC3Configuration&ONENANDMODESRC)
{
g_pDMAC0Reg->DMACC3SrcAddr = (UINT32)(uSrcAddr - CACHED_TO_UNCACHED_OFFSET - ONLD_PHYSICAL_TO_VIRTUAL_OFFSET);
g_pDMAC0Reg->DMACC3DestAddr = (UINT32)uDstAddr;
}
else if (g_pDMAC0Reg->DMACC3Configuration&ONENANDMODEDST)
{
g_pDMAC0Reg->DMACC3SrcAddr = (UINT32)uSrcAddr;
g_pDMAC0Reg->DMACC3DestAddr = (UINT32)(uDstAddr - CACHED_TO_UNCACHED_OFFSET - ONLD_PHYSICAL_TO_VIRTUAL_OFFSET);
}
else
{
ONLD_ERR_PRINT((TEXT("[ONLD:ERR] DMACh is not set\r\n")));
}
// setting transter size
g_pDMAC0Reg->DMACC3Control1 = uByteCount;
return TRUE;
}
BOOL DMAChannelStart()
{
// Clear Halt Bit
g_pDMAC0Reg->DMACC3Configuration &= ~HALT;
// Enable Channel
g_pDMAC0Reg->DMACC3Configuration |= CHANNEL_ENABLE;
return TRUE;
}
#endif // OND_TRANS_MODE
/*****************************************************************************/
/* Code Implementation */
/*****************************************************************************/
static VOID
_WriteEmptyData(UINT32 pAddr, UINT32 nScts, UINT32 nSize)
{
UINT32 nBytes;
while (nScts-- > 0)
{
for (nBytes = nSize; nBytes > 0; nBytes -= sizeof(UINT32))
{
*(volatile UINT32 *)pAddr = 0xffffffff;
}
}
}
static VOID
_WriteData(UINT32 pAddr, UINT8 *pBuf, UINT32 nScts, UINT32 nSize)
{
UINT32 *pBuffer = (UINT32 *)pBuf;
#if (OND_TRANS_MODE == OND_POL)
UINT32 nBytes;
while (nScts-- > 0)
{
for (nBytes = nSize; nBytes > 0; nBytes -= sizeof(UINT32))
{
*(volatile UINT32 *)pAddr = *pBuffer++;
}
}
#elif (OND_TRANS_MODE == OND_LDM)
//OneNand4burstPageWrite((UINT32)pBuffer, pAddr, (UINT32)((nSize * nScts)/16));
OneNand8burstPageWrite((UINT32)pBuffer, pAddr, (UINT32)((nSize * nScts)/32));
#endif // OND_TRANS_MODE
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?