www.pudn.com > DMBDRV.rar > PxaDMA.c


#include  
#include  
 
 
#include "SianoDMA.h" 
#include "PxaDMA.h" 
 
#if (_WINCEOSVER==502) 
#include  
#include "xllp_dmac.h" 
#include "xllp_defs.h" 
#include "dmawince.h" 
#else 
#include "xllp_dmac.h" 
#include "xllp_defs.h" 
#endif 
#include "memmap.h" 
 
 
static const DWORD userBurstSizeToDmaConfig[] = {0x1, 0x2, 0x3}; 
static const DWORD userBusWidthToDmaConfig[] = {0x1, 0x2, 0x3}; 
 
extern  PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);  
 
extern XLLP_STATUS_T	XllpDmacInit(); 
 
extern XLLP_STATUS_T XllpDmacAllocChannel( 
			   		 			  P_XLLP_DMAC_CHANNEL_T        pChannel, 
			     	 			  XLLP_DMAC_CHANNEL_PRIORITY_T aChannelPriority 
			     	 			  ); 
extern void XllpDmacFreeChannel( 
						XLLP_DMAC_CHANNEL_T       aChannel, 
						XLLP_DMAC_DRCMR_T         aDeviceDrcmr 
					    ); 
BOOL PhyDmaSetUp(DMA_DRV_PARAMS_ST* dev) 
{ 
	void* ptr; 
	PHYSICAL_ADDRESS phyAddr; 
	//volatile P_XLLP_DMAC_T	pDmacHandle = NULL; 
	DMA_ADAPTER_OBJECT			adapter; 
 
	if(XllpDmacInit()==0) 
    { 
    	RETAILMSG(1, (TEXT("PhyDmaSetUp, VirtualAllocCopy(): GdeDmacInit Failed\r\n"))); 
    } 
	XllpDmacAllocChannel((XLLP_DMAC_CHANNEL_T*)&dev->channel,XLLP_DMAC_CHANNEL_PRIORITY_HIGH); 
 
 
	phyAddr.LowPart = DMAC_BASE_PHYSICAL; 
	phyAddr.HighPart = 0; 
//	ptr =  MmMapIoSpace(phyAddr, sizeof(DMAC_REGISTERS), FALSE); 
//	RETAILMSG(1, (TEXT("PhyDmaSetUp, MmMapIoSpace ptr: 0x%x\r\n"),ptr)); 
        ptr= (DMAC_REGISTERS *)VirtualAllocCopy(sizeof(DMAC_REGISTERS),"dma registers",(PVOID)(DMAC_BASE_U_VIRTUAL)); 	 
	 
	adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT); 
	adapter.InterfaceType  = Internal; 
	adapter.BusNumber = 0; 
	 
	dev->desc = HalAllocateCommonBuffer( &adapter,  
									sizeof(DMAC_FRAME_DESCRIPTOR_ST),  
									&dev->descPhyAddr,  
									FALSE); 
	dev->pDmacAddr = ptr; 
	return TRUE; 
} 
 
VOID PhyDmaRemoveChannel(DMA_DRV_PARAMS_ST* dev) 
{ 
	DMA_ADAPTER_OBJECT			adapter; 
 
	adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT); 
	adapter.InterfaceType  = Internal; 
	adapter.BusNumber = 0; 
	//Interrupt has ended, free the descriptors memory allocated on channel config. 
	HalFreeCommonBuffer(	&adapter, 
							sizeof(DMAC_FRAME_DESCRIPTOR_ST), 
							dev->descPhyAddr, 
							dev->desc, 
							FALSE); 
 
	XllpDmacFreeChannel(dev->channel, XLLP_DMAC_MEM2MEM_MOVE); 
 
	MmUnmapIoSpace(dev->pDmacAddr, sizeof(DMAC_REGISTERS));  
} 
 
 
BOOL PhyDmaSendDescriptor(DMA_DRV_PARAMS_ST* dev,DMA_DB_NODE_ST* transaction) 
{ 
	volatile DMAC_REGISTERS_P	pDmacAddr; 
	DWORD						tmp; 
	DMAC_FRAME_DESCRIPTOR_ST*	desc; 
	DMA_DESCRIPTOR_ST*			dbDesc = transaction->desc; 
 
	ResetEvent(dev->dmaIntEvent); 
	pDmacAddr = dev->pDmacAddr; 
 
	desc = dev->desc; 
 
	desc->ddadr = 1; 
	desc->dsadr = dbDesc->srcPhyAddr; 
	desc->dtadr = dbDesc->dstPhyAddr; 
	desc->dcmd = dbDesc->len; 
 
	tmp = userBurstSizeToDmaConfig[dev->burstSize]; 
	desc->dcmd |= (tmp<<16);								// BURST 
	tmp = userBusWidthToDmaConfig[dev->busWidth]; 
	desc->dcmd |= (tmp<<14);								// TRANSFER WIDTH	 
 
	if (dbDesc->flags & DMA_INC_SRC_ADDR) 
		desc->dcmd |= DMAC_DCMD_INCSRCADDR; 
	if (dbDesc->flags & DMA_INC_DST_ADDR) 
		desc->dcmd |= DMAC_DCMD_INCTRGADDR; 
 
	if (dbDesc->flags & DMA_USE_DST_FLOW_CONTROL) 
		desc->dcmd |= DMAC_DCMD_FLOWTRG; 
	if (dbDesc->flags & DMA_USE_SRC_FLOW_CONTROL) 
		desc->dcmd |= DMAC_DCMD_FLOWSRC; 
 
 
	desc->dcmd |= DMAC_DCMD_ENDIRQEN;						// Enable end interrupt for last descriptor. 
 
    if (dev->useHWFlowCtrl == TRUE) 
    {//Request to Channel Map for DREQ  
        pDmacAddr->drcmr1[dev->dmaReq] = DMAC_DRCRM_MAP_CHANNEL + dev->channel; 
    } 
 
 
	//Clear all existing interrupts and set mode to no descriptor fetch 
	pDmacAddr->dcsr[dev->channel] = DMAC_DCSR_CLEAR_ALL_INTERRUPTS;		 
	 
 
	// DALGN - DMA ALIGNMENT REG. 
	if ((dbDesc[0].srcPhyAddr & 0x7) || (dbDesc[0].dstPhyAddr & 7)) 
		pDmacAddr->dalgn |= 1<channel; 
	else 
		pDmacAddr->dalgn &= ~(1<channel); 
	 
	//Set DMA first descriptor 
	pDmacAddr->ddg[dev->channel].ddadr = dev->descPhyAddr.LowPart; 
	 
	// Start Running 
	pDmacAddr->dcsr[dev->channel] = DMAC_DCSR_RUN;// | DMAC_DCSR_EORIRQEN; 
 
 
	return TRUE; 
} 
 
DWORD PhyDmaIntHandler(DMA_DRV_PARAMS_ST* dev, DMA_DB_NODE_ST* transaction) 
{ 
	DWORD stReg; 
 
	stReg = GetEventData(dev->dmaIntEvent);	 
	//RETAILMSG(1, (TEXT("DMB dma int.\r\n"))); 
 
	//Check that status returned from DMA controllers is good. 
	if (stReg & DMAC_DCSR_ENDINTR || stReg & DMAC_DCSR_EORINT)	 
		return DMA_STATUS_OK; 
	else 
		return DMA_STATUS_ERR; 
}