Пример #1
0
void DmaIntModeDemo(void)
{
    UINT8 ch_no;    //Dma channel number
    UINT32 len = 1023;
    UINT32 tmp_src[1023], tmp_dst[1023];
    UINT8 ret;

    printf("Dma Int Mode Demo.\r\n");
    /* enable Dma Clk */
    ScuDmaClkEn();
    for(ch_no = 0; ch_no < 8; ch_no++)
    {
        trans_finish_flag = FALSE;
        /* initial source data */
        GetTrueRand8((UINT8 *)tmp_src, len << 2);
        /* lock dma channel */
        ret = DmaChLock(ch_no);
        /* setting dma trans interrupt handle */
        ret |= DmaSetIntrHandle(ch_no, DmaFinishHdl, NULL, NULL, NULL);
        /* setting dma trans parameter */
        ret |= SetupMode(ch_no, MEM_MEM, DISCRIC, NO_PER, NO_PER, ENINC, ENINC, W_32BIT, len, H_PRI);
        /* setting dma trans address */
        ret |= SetTransAddress(ch_no, (UINT32)tmp_src, (UINT32)tmp_dst);
        /* start dma trans */
        ret |= DmaStart(ch_no);
        if(ret != DMA_RET_SUCESS)
        {
            printf("dma channel %d trans error, error code %d\r\n", ch_no, ret);
            return;
        }

        /* wait trans finish */
        while(trans_finish_flag == FALSE);
        /* disable dma channel trrans finish interrupt */
        DisDmaIntr(0x1 << ch_no);
        if(Memcmp(tmp_src, tmp_dst, len) != 0)
        {
            printf("dma channel %d trans error, data error\r\n", ch_no);
            return;
        }
        else
        {
            printf("dma channel %d trans sucess\r\n", ch_no);
        }
        DmaChUnlock(ch_no);
    }
    ScuDmaClkDis();
}
_ATTR_LCDDRIVER_ST7637_CODE_    
 int32 ST7637_DMATranfer32 (UINT8 x0,UINT8 y0,UINT8 x1,UINT8 y1,UINT32 *pSrc, pFunc CallBack)
 {
    UINT32 size;
    eDMA_CHN channel; 
    DMA_CFGX DmaCfg = {CTLL_M2LCD_WORD,CFGL_M2LCD_SINGLE,CFGH_M2LCD_SINGLE,0};
    
    ST7637_SetWindow(x0,y0, x1,y1); 
    
    channel = DmaGetChannel();
    if (channel != DMA_FALSE)
    {
        size = (((x1 + 1) - x0) * ((y1+1) - y0)) >> 1;
        Lcd_SplitMode(LCD_SPLIT5);
        DmaStart((uint32)(channel), (UINT32)(pSrc),(uint32)(&(Lcd->data)),size,&DmaCfg, CallBack);
        return channel;
    }
Пример #3
0
/*
--------------------------------------------------------------------------------
  Function name : int32 UartDmaRead(uint8 *pdata, uint32 size, uint32 uartTimeOut, pFunc Callback)
  Author        : 
  Description   : read the uart data by dma.
                  
  Input         : pdata:input data pointer.
                  size: input data size.(byte)
                  uartTimeOut: waiting delay time.
                  Callback:DMA interrupt callback.
                  
  Return        : 0:OK -1:fail

  History:     <author>         <time>         <version>       
              
  desc:       
--------------------------------------------------------------------------------
*/
_ATTR_DRIVER_CODE_
int32 UartDmaRead(uint8 *pdata, uint32 size, uint32 uartTimeOut, pFunc Callback)
{
    eDMA_CHN channel;    
    DMA_CFGX DmaCfg = {DMA_CTLL_UART2M,DMA_CFGL_UART2M,DMA_CFGH_UART2M,0};
    
    while ((UartReg->UART_USR & UART_TRANSMIT_FIFO_NOT_FULL) != UART_TRANSMIT_FIFO_NOT_FULL)
    {
        if (uartTimeOut == 0)
        {
            return (-1);
        }
        uartTimeOut--;
    }
    
    channel = DmaGetChannel();
    if (channel != DMA_FALSE)
    {
        DmaStart((uint32)(channel), (uint32)(&(UartReg->UART_RBR)),(UINT32)(pdata),size, &DmaCfg, Callback);
        return channel;
    }
    
    return (-1);
}
Пример #4
0
//------------------------------------------------------------------------------
SCODE
OMAPDDGPE::DMAFill(
    GPEBltParms* pParms
    )
{
    SCODE   result = S_OK;
    RECTL*  prclDst = pParms->prclDst;
    DWORD   dwWidth  = prclDst->right - prclDst->left;
    DWORD   dwHeight = prclDst->bottom - prclDst->top;
    DWORD   dwStride = pParms->pDst->Stride();
    DWORD   dwOffset = 0;
    
    OMAPDDGPESurface*   pOmapSurf = (OMAPDDGPESurface*) pParms->pDst;
     
    DmaConfigInfo_t DmaSettings = {
        0,                          // elemSize
        1,                          // srcElemIndex
        1,                          // srcFrameIndex
        DMA_CCR_SRC_AMODE_CONST,    // srcAddrMode
        1,                          // dstElemIndex
        1,                          // dstFrameIndex
        DMA_CCR_DST_AMODE_DOUBLE,   // dstAddrMode
        FALSE,                      // dmaPrio
        DMA_SYNCH_TRIGGER_NONE,     // synchTrigger
        DMA_SYNCH_NONE,             // synchMode
        0,                          // interrupts
        0                           // syncMap
    };

    //  Check that a DMA Blt is worth doing
    if( dwWidth < MIN_DMA_WIDTH || dwHeight < MIN_DMA_HEIGHT )
    {
        if (g_Globals.m_dwEnableNeonBlts)
        {
        pParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &OMAPDDGPE::DesignateBlt;
        return OMAPDDGPE::DesignateBlt(pParms);
    }
		else
		{
            pParms->pBlt = &GPE::EmulatedBlt;
            return GPE::EmulatedBlt(pParms);
		}
    }

    //  Allocate DMA channel
    if( g_hDmaChannel1 == NULL )
    {
        g_hDmaChannel1 = DmaAllocateChannel(DMA_TYPE_SYSTEM);
        InitializeCriticalSection( &g_csDmaLock );
    }

    //  Lock access to DMA registers
    EnterCriticalSection( &g_csDmaLock );

    //  Wait for any pending operations to complete
    WaitForNotBusy();

    //  Configure DMA channel for FILL operation
    switch( pParms->pDst->BytesPerPixel() )
    {
        case 1:
            DmaSettings.elemSize = DMA_CSDP_DATATYPE_S8;
            DmaSettings.dstFrameIndex = 1 + dwStride - dwWidth;
            dwOffset = prclDst->top * dwStride + prclDst->left;
            break;

        case 2:
            DmaSettings.elemSize = DMA_CSDP_DATATYPE_S16;
            DmaSettings.dstFrameIndex = 1 + dwStride - 2*dwWidth;
            dwOffset = prclDst->top * dwStride + 2 * prclDst->left;
            break;

        case 4:
            DmaSettings.elemSize = DMA_CSDP_DATATYPE_S32;
            DmaSettings.dstFrameIndex = 1 + dwStride - 4*dwWidth;
            dwOffset = prclDst->top * dwStride + 4 * prclDst->left;
            break;
    }
    
    //  Clear any clipping rect for the operation
    pOmapSurf->OmapSurface()->SetClipping( NULL );

    //  Enable bursting for improved memory performance
    DmaSettings.elemSize |= DMA_CSDP_DST_BURST_64BYTES_16x32_8x64 | DMA_CSDP_DST_PACKED;
    
    
    //  Configure the DMA channel
    DmaConfigure( g_hDmaChannel1, &DmaSettings, 0, &g_tDmaDataInfo1 );

    DmaSetColor( &g_tDmaDataInfo1, DMA_CCR_CONST_FILL_ENABLE, (DWORD)pParms->solidColor );
    DmaSetSrcBuffer( &g_tDmaDataInfo1, NULL, 0 );
    DmaSetDstBuffer( &g_tDmaDataInfo1, NULL, pOmapSurf->OmapSurface()->PhysicalAddr() + dwOffset );
    DmaSetElementAndFrameCount( &g_tDmaDataInfo1, dwWidth, (UINT16) dwHeight );

    //  Start the DMA operation
    DmaStart( &g_tDmaDataInfo1 );
	
    //  Unlock access to DMA registers
    LeaveCriticalSection( &g_csDmaLock );

    return result;    
}
Пример #5
0
//------------------------------------------------------------------------------
SCODE
OMAPDDGPE::DMASrcCopy(
    GPEBltParms* pParms
    )
{
    SCODE   result = S_OK;
    BOOL    bDualDMA = FALSE;
    RECTL*  prclSrc = pParms->prclSrc;
    RECTL*  prclDst = pParms->prclDst;
    DWORD   dwPixelSize = pParms->pDst->BytesPerPixel();
    DWORD   dwWidth  = prclDst->right - prclDst->left;
    DWORD   dwHeight = prclDst->bottom - prclDst->top;
    DWORD   dwSrcStride = pParms->pSrc->Stride();
    DWORD   dwDstStride = pParms->pDst->Stride();
    DWORD   dwSrcOffset = 0;
    DWORD   dwDstOffset = 0;
    DWORD   dwSrcMidpoint = 0;
    DWORD   dwDstMidpoint = 0;
    DWORD   dwWidth1 = dwWidth, 
            dwWidth2 = dwWidth;
    DWORD   dwHeight1 = dwHeight, 
            dwHeight2 = dwHeight;
    
    OMAPDDGPESurface*   pOmapSrcSurf = (OMAPDDGPESurface*) pParms->pSrc;
    OMAPDDGPESurface*   pOmapDstSurf = (OMAPDDGPESurface*) pParms->pDst;
     
    DmaConfigInfo_t DmaSettings = {
        0,                          // elemSize
        1,                          // srcElemIndex
        1,                          // srcFrameIndex
        DMA_CCR_SRC_AMODE_DOUBLE,   // srcAddrMode
        1,                          // dstElemIndex
        1,                          // dstFrameIndex
        DMA_CCR_DST_AMODE_DOUBLE,   // dstAddrMode
        FALSE,                      // dmaPrio
        DMA_SYNCH_TRIGGER_NONE,     // synchTrigger
        DMA_SYNCH_NONE,             // synchMode
        0,                          // interrupts
        0                           // syncMap
    };


    //  Check that a DMA Blt is worth doing
    if( dwWidth < MIN_DMA_WIDTH || dwHeight < MIN_DMA_HEIGHT )
    {
        if (g_Globals.m_dwEnableNeonBlts)
        {
        pParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &OMAPDDGPE::DesignateBlt;
        return OMAPDDGPE::DesignateBlt(pParms);
		}
		else
		{
            pParms->pBlt = &GPE::EmulatedBlt;
            return GPE::EmulatedBlt(pParms);
		}
    }

    //  Allocate DMA channels
    if( g_hDmaChannel1 == NULL )
    {
        g_hDmaChannel1 = DmaAllocateChannel(DMA_TYPE_SYSTEM);
        InitializeCriticalSection( &g_csDmaLock );
    }

    if( g_hDmaChannel2 == NULL )
    {
        g_hDmaChannel2 = DmaAllocateChannel(DMA_TYPE_SYSTEM);
    }


    //  Lock access to DMA registers
    EnterCriticalSection( &g_csDmaLock );

    //  Wait for any pending operations to complete
    WaitForNotBusy();
        
    //  Configure DMA channel for SRCCPY operation
    switch( pParms->pDst->BytesPerPixel() )
    {
        case 1:
            DmaSettings.elemSize = DMA_CSDP_DATATYPE_S8;
            break;

        case 2:
            DmaSettings.elemSize = DMA_CSDP_DATATYPE_S16;
            break;

        case 4:
            DmaSettings.elemSize = DMA_CSDP_DATATYPE_S32;
            break;
    }


    //  Compute element indexing, frame indexing and starting offset for both surfaces
    //  Note that both xPos and yPos will never be both < 0
    //  Also note that xPos !=1 prevents bursting and actually slows DMA down below memcpy speeds
    if( pParms->xPositive )
    {
        //  Index x axis in positive direction (left to right)
        DmaSettings.srcElemIndex = 1;
        DmaSettings.dstElemIndex = 1;
        
        //  Offset from left side of surface
        dwSrcOffset = dwPixelSize * prclSrc->left;
        dwDstOffset = dwPixelSize * prclDst->left;
    }
    else
    {
        //  Index x axis in negative direction (right to left)
        DmaSettings.srcElemIndex = 1 - 2*dwPixelSize;
        DmaSettings.dstElemIndex = 1 - 2*dwPixelSize;

        //  Offset from right side of surface
        dwSrcOffset = dwPixelSize * (prclSrc->right - 1);
        dwDstOffset = dwPixelSize * (prclDst->right - 1);
    }

    if( pParms->yPositive )
    {
        //  Index y axis in positive direction (top to bottom)
        DmaSettings.srcFrameIndex = DmaSettings.srcElemIndex + dwSrcStride;
        DmaSettings.dstFrameIndex = DmaSettings.dstElemIndex + dwDstStride;
        
        if( pParms->xPositive )
        {
            DmaSettings.srcFrameIndex -= dwWidth*dwPixelSize;
            DmaSettings.dstFrameIndex -= dwWidth*dwPixelSize;
        }
        else
        {
            DmaSettings.srcFrameIndex += dwWidth*dwPixelSize;
            DmaSettings.dstFrameIndex += dwWidth*dwPixelSize;
        }

        //  Offset from top side of surface
        dwSrcOffset = dwSrcOffset + prclSrc->top * dwSrcStride;
        dwDstOffset = dwDstOffset + prclDst->top * dwDstStride;
    }
    else
    {
        //  Index y axis in negative direction (bottom to top)
        DmaSettings.srcFrameIndex = DmaSettings.srcElemIndex - dwSrcStride;
        DmaSettings.dstFrameIndex = DmaSettings.dstElemIndex - dwDstStride;

        if( pParms->xPositive )
        {
            DmaSettings.srcFrameIndex -= dwWidth*dwPixelSize;
            DmaSettings.dstFrameIndex -= dwWidth*dwPixelSize;
        }
        else
        {
            DmaSettings.srcFrameIndex += dwWidth*dwPixelSize;
            DmaSettings.dstFrameIndex += dwWidth*dwPixelSize;
        }

        //  Offset from bottom side of surface
        dwSrcOffset = dwSrcOffset + (prclSrc->bottom - 1) * dwSrcStride;
        dwDstOffset = dwDstOffset + (prclDst->bottom - 1) * dwDstStride;
    }
 
    //
    //  Check for fast dual DMA cases
    //
    
    //  Different src and dst surfaces can use dual DMA
    if( pOmapSrcSurf != pOmapDstSurf )
    {
        //  Split work in half vertically
        dwHeight1 = dwHeight/2;  
        dwHeight2 = dwHeight - dwHeight1;
        
        dwSrcMidpoint = (pParms->yPositive) ? dwSrcOffset + dwHeight1*dwSrcStride : dwSrcOffset - dwHeight1*dwSrcStride;  
        dwDstMidpoint = (pParms->yPositive) ? dwDstOffset + dwHeight1*dwDstStride : dwDstOffset - dwHeight1*dwDstStride;  

        bDualDMA = TRUE;     
    }
 
    
    //  Clear any clipping rect for the operation
    pOmapSrcSurf->OmapSurface()->SetClipping( NULL );
    pOmapDstSurf->OmapSurface()->SetClipping( NULL );


    //  Enable bursting for improved memory performance
    DmaSettings.elemSize |= DMA_CSDP_SRC_BURST_64BYTES_16x32_8x64 | DMA_CSDP_SRC_PACKED;
    DmaSettings.elemSize |= DMA_CSDP_DST_BURST_64BYTES_16x32_8x64 | DMA_CSDP_DST_PACKED;
    
    
    //  Configure the DMA channel
    DmaConfigure( g_hDmaChannel1, &DmaSettings, 0, &g_tDmaDataInfo1 );

    DmaSetSrcBuffer( &g_tDmaDataInfo1, NULL, pOmapSrcSurf->OmapSurface()->PhysicalAddr() + dwSrcOffset );
    DmaSetDstBuffer( &g_tDmaDataInfo1, NULL, pOmapDstSurf->OmapSurface()->PhysicalAddr() + dwDstOffset );
    DmaSetElementAndFrameCount( &g_tDmaDataInfo1, dwWidth1, (UINT16) dwHeight1);

    if( bDualDMA )
	{
        DmaConfigure( g_hDmaChannel2, &DmaSettings, 0, &g_tDmaDataInfo2 );

        DmaSetSrcBuffer( &g_tDmaDataInfo2, NULL, pOmapSrcSurf->OmapSurface()->PhysicalAddr() + dwSrcMidpoint );
        DmaSetDstBuffer( &g_tDmaDataInfo2, NULL, pOmapDstSurf->OmapSurface()->PhysicalAddr() + dwDstMidpoint );
        DmaSetElementAndFrameCount( &g_tDmaDataInfo2, dwWidth2, (UINT16) dwHeight2 );
	}

    //  Configure for transparent copy if requested
    if( pParms->bltFlags & BLT_TRANSPARENT )
    {
        DmaSetColor( &g_tDmaDataInfo1, DMA_CCR_TRANSPARENT_COPY_ENABLE, (DWORD)pParms->solidColor );
        if( bDualDMA )
            DmaSetColor( &g_tDmaDataInfo2, DMA_CCR_TRANSPARENT_COPY_ENABLE, (DWORD)pParms->solidColor );
    }
       
       
    //  Start the DMA operation(s)
    DmaStart( &g_tDmaDataInfo1 );
    
    if( bDualDMA )
        DmaStart( &g_tDmaDataInfo2 );

    //  Unlock access to DMA registers
    LeaveCriticalSection( &g_csDmaLock );

    return result;    
}
Пример #6
0
//
// Perform the actual DMA copy
// WARNING!! This function assumes the physical memory is contiguous.
// No check is performed for performance improvement. 
// Buffers passed-in come from CMEM and DISPLAY drivers.
//
DWORD SdmaPx::Copy(  LPVOID pSource,
                     LPVOID pDestination,
                     DWORD  dwClientIdx )
{
    DWORD dwRet = 0;    
    DWORD dwCause, dwStatus;   
    DWORD paSrc, paDst;
    BYTE ffCached = 0; 
    DmaConfigInfo_t dmaSettings = m_SdmaPxClient[dwClientIdx].GetConfig();
    DWORD dwDataLength = m_SdmaPxClient[dwClientIdx].GetDataLength();
    DWORD dwElementCount = m_SdmaPxClient[dwClientIdx].GetElementCount();
    DWORD dwFrameCount = m_SdmaPxClient[dwClientIdx].GetFrameCount();

    ASSERTMSG(L"Client must be configured before Copy I/O control is called !!!\n", m_SdmaPxClient[dwClientIdx].IsClientConfigured());
    
    // Configure SDMA for specific client
    // Need to call this first for length
    // memset() on DmaConfigInfo_t not needed as done in the SdmaPxClient::Init() method.
    // m_SdmaPxClient[dwClientIdx].GetConfig(&dmaSettings, &dwDataLength);
    if(DmaConfigure(m_hDmaChannel, &dmaSettings, 0, &m_dmaInfo) != TRUE)
    {
        ERRORMSG(ZONE_ERROR, (TEXT("ERROR! Unable to configure DMA for client\r\n")));    
        goto cleanUp;
    }
    
	// flush cache if necessary   
    if (ISUNCACHEDADDRESS(pSource) == FALSE)
    {
        ffCached |= SOURCE_CACHED;
    }    
    if (ISUNCACHEDADDRESS(pDestination) == FALSE)
    {
        ffCached |= DESTINATION_CACHED;
    } 
    if (ffCached & (SOURCE_CACHED | DESTINATION_CACHED))
    {
        FlushCache(pSource, pDestination, dwDataLength, ffCached);
    }

    // Retrieve base physical address of buffer to be copied and READ lock the pages on the length.
    if(LockPages(
                    (LPVOID)pSource,
                    (DWORD)dwDataLength,
                    m_rgPFNsrc,
                    LOCKFLAG_READ)  == FALSE)
    {
        ERRORMSG(ZONE_ERROR, (TEXT("LockPages call \"src\" failed. (error code=%d)\r\n"), GetLastError()));
        goto cleanUp;
    }
    // Not necessary to do the page shift on ARM platform as always 0. (ref. MSDN)
    // paSrc = (m_rgPFNsrc[0] << m_pageShift) + ((DWORD)pSource & m_pageMask);
    paSrc = m_rgPFNsrc[0] + ((DWORD)pSource & m_pageMask);
    
    
    // Retrieve base physical address of destination buffer and WRITE lock the pages on the length.
    if(LockPages(
                    (LPVOID)pDestination,
                    dwDataLength,
                    m_rgPFNdst,
                    LOCKFLAG_WRITE)  == FALSE)
     {
        ERRORMSG(ZONE_ERROR, (TEXT("LockPages \"dest\" call failed. (error code=%d)\r\n"), GetLastError()));
        goto cleanUp;
    }           
    // Not necessary to do the page shift on ARM platform as always 0. (ref. MSDN)
    // paDst = (m_rgPFNdst[0] << UserKInfo[KINX_PFN_SHIFT]) + ((DWORD)pDestination & m_pageMask);
    paDst = m_rgPFNdst[0] + ((DWORD)pDestination & m_pageMask);          
    
    // Configure Dest and Src buffers for DMA.   
    DmaSetSrcBuffer(&m_dmaInfo, (UINT8 *)pSource, paSrc);
    DmaSetDstBuffer(&m_dmaInfo, (UINT8 *)pDestination, paDst);
    
    // Watch out parameters in DmaSetElemenAndFrameCount. For e.g., shift right element count by 2 if you have bytes in input and you use 32bits element size.
    DmaSetElementAndFrameCount(&m_dmaInfo, dwElementCount, (UINT16)(dwFrameCount));
    
    // start dma
    DmaStart(&m_dmaInfo);
    
    // wait until we hit the end of buffer 
    // Wait for dma interrupt...  
    dwCause = WaitForSingleObject(m_hEvent, DMA_IRQ_TIMEOUT);         
     
    switch(dwCause)
    {
    case WAIT_OBJECT_0:
        {
            // Verify cause of interrupt was because we hit the end of block
            dwStatus = DmaGetStatus(&m_dmaInfo);
            if ((dwStatus & (dmaSettings.interrupts)) == 0)
            {
                ERRORMSG(ZONE_ERROR, (TEXT("Unexpected cause of interrupt\r\n")));
                break; 
            }

            DmaClearStatus(&m_dmaInfo, dwStatus);
            if (DmaInterruptDone(m_hDmaChannel) == FALSE)
            {
                ERRORMSG(ZONE_ERROR, (TEXT("ERROR! Unable to get status for dma interrupt\r\n")));        
                break; 
            }

			// Do the "good" client job
			DmaStop(&m_dmaInfo);
                        
        break;
        }        
        
    default:
        RETAILMSG(ZONE_ERROR, (TEXT("ERROR! didn't receive DMA interrupt\r\n")));
        break;
    }     
    
#if DEBUG_VERIFY_SDMA_COPY   
    //
    // Beware!! Bring a lot of overhead and can lead to bad display rendering.
    //
    NKDbgPrintfW(L"verify memory\r\n"); 
    if (memcmp(pSource, pDestination, dwDataLength) != 0)
    {
        NKDbgPrintfW(L"ERROR! memory doesn't match up\r\n");
        DebugBreak();
        goto cleanUp; 
    }
#endif
    
    dwRet = dwDataLength; // everything went fine obviously...
cleanUp:
    UnlockPages((LPVOID)pSource, dwDataLength);
    UnlockPages((LPVOID)pDestination, dwDataLength);   
    
    return dwRet;
}