⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmpci.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 2 页
字号:

	SDRAMBegin	= (UInt8*)*(UInt32*)(((UInt8*)_MMIO_base) + DRAM_BASE);
	SDRAMEnd	= (UInt8*)((*(UInt32*)(((UInt8*)_MMIO_base) + DRAM_LIMIT)) - 1);

	
	
	if ( ( Destination > SDRAMBegin ) && ( Destination < SDRAMEnd ) )
	{
		/* destination is inside SDRAM range */

		/* make sure that at least the Source is in SDRAM */
		if ( ( Source > SDRAMBegin ) && ( Source < SDRAMEnd ) )
		{
			PRINTF ((
				"tmPCI:Error:Source[%x] & Destination[%x] within SDRAM[%x:%x]\n",
				Source, Destination, SDRAMBegin, SDRAMEnd ));
					
			return PCI_ERR_SDRAM_RANGE;
			/* error - both source and destination are in sdram */			
		}
		else
		{
			/* destination in SDRAM : source in PCI */
			TransferDirection = dmaPCI_TO_SDRAM;
			PCIAddress = Source;
			SDRAMPreAlignAddress = Destination;

		}

	}
	else	/* destination not in SDRAM */
	{
		/* make sure that at least the Source is in SDRAM */
		if ( ( Source > SDRAMBegin ) && ( Source < SDRAMEnd ) )
		{
			/* source in SDRAM : destination in PCI */
			TransferDirection = dmaSDRAM_TO_PCI;
			PCIAddress = Destination;
			SDRAMPreAlignAddress = Source;
		}
		else
		{
			PRINTF ((
				"tmPCI:Error:Source[%x] & Destination[%x] outside SDRAM[%x:%x]\n",
				Source, Destination, SDRAMBegin, SDRAMEnd ));
			return PCI_ERR_SDRAM_RANGE;
			/* error - neither source nor destination in sdram */
		}
	}

	/* 
		the entire SDRAM transfer buffer is broken down into 3 blocks 
		1.	a cache aligned block of length = integral multiple of cache size
		2.	the protion of the buffer before the cache aligned block.
		3.	the protion of the buffer after before the cache aligned block.
	*/


	SDRAMCacheAlignAddress = (UInt8*)ALIGN((UInt32)SDRAMPreAlignAddress, DCACHE_PAGE_SIZE);
	SDRAMPreAlignLength = ALIGN((UInt32)SDRAMPreAlignAddress, DCACHE_PAGE_SIZE) - (UInt32)SDRAMPreAlignAddress;
	SDRAMCacheAlignLength = ( ( Length - SDRAMPreAlignLength ) / DCACHE_PAGE_SIZE ) * DCACHE_PAGE_SIZE;
	SDRAMPostAlignAddress = (UInt8*)(((UInt32)SDRAMPreAlignAddress) + SDRAMPreAlignLength + SDRAMCacheAlignLength);
	SDRAMPostAlignLength = Length - ( SDRAMCacheAlignLength + SDRAMPreAlignLength);


	PRINTF ((
		"tmPCI:PreAddr[%x]:PreLen[%x]:CacheAddr[%x]:Cachelen[%x]:PostAddr[%x]:PostLen[%x]\n",
		SDRAMPreAlignAddress,
		SDRAMPreAlignLength,
		SDRAMCacheAlignAddress,
		SDRAMCacheAlignLength,
		SDRAMPostAlignAddress,
		SDRAMPostAlignLength ));



    if ( (ErrorCode = dmaOpen(&Instance) )) 
	{
		PRINTF ((
			"tmPCI:Error:dmaOpen:FAIL[%x]\n", ErrorCode ));
        return (ErrorCode);
    }

	_cache_copyback(SDRAMCacheAlignAddress, SDRAMCacheAlignLength);

	/* the request contains 1 description */
    DMARequest.slack_function = Null;/*slackFunc; */
    DMARequest.completion_function = Null; /*compFunc; */
    DMARequest.nr_of_descriptions = 1;
    DMARequest.mode = dmaSynchronous;
    DMARequest.done = 0;

    /* this description contains four transfers */
	if ( TransferDirection == dmaSDRAM_TO_PCI )
	{
		DMARequest.descriptions[0].direction = dmaSDRAM_TO_PCI;
		DMARequest.descriptions[0].source = (void *) SDRAMCacheAlignAddress;
		DMARequest.descriptions[0].destination = (void *)(PCIAddress + SDRAMPreAlignLength);
	}
	else
	{
		DMARequest.descriptions[0].direction = dmaPCI_TO_SDRAM;
		DMARequest.descriptions[0].source = (void *)(PCIAddress + SDRAMPreAlignLength);
		DMARequest.descriptions[0].destination = (void *) SDRAMCacheAlignAddress;
	}

	DMARequest.descriptions[0].write_and_invalidate = 1;
	DMARequest.descriptions[0].length = SDRAMCacheAlignLength;
	DMARequest.descriptions[0].nr_of_transfers = 1;
	DMARequest.descriptions[0].source_stride = SDRAMCacheAlignLength;
	DMARequest.descriptions[0].destination_stride = SDRAMCacheAlignLength;

    if ( ( ErrorCode = dmaDispatch(Instance, &DMARequest) ) )
	{
		PRINTF ((
			"tmPCI:Error:dmaDispatch:FAIL[%x]\n", ErrorCode ));
        return (ErrorCode);
	}
    _cache_invalidate(SDRAMCacheAlignAddress, SDRAMCacheAlignLength);

	dmaClose ( Instance );

	if ( TransferDirection == dmaSDRAM_TO_PCI )
	{

		pciDWORDAlignedCopy ( 
			Destination, 
			SDRAMPreAlignAddress, 
			SDRAMPreAlignLength,
			( ALIGN( (UInt32)Destination, sizeof (UInt32) ) - (UInt32)Destination ) );

		pciDWORDAlignedCopy ( 
			Destination + SDRAMPreAlignLength + SDRAMCacheAlignLength, 
			SDRAMPostAlignAddress,
			SDRAMPostAlignLength, 
			( ALIGN( (UInt32)Destination + SDRAMPreAlignLength + SDRAMCacheAlignLength,
			sizeof (UInt32) ) - ((UInt32)Destination + SDRAMPreAlignLength + SDRAMCacheAlignLength )) );
	}
	else 
	{
		pciDWORDAlignedCopy ( 
			SDRAMPreAlignAddress, 
			Source, 
			SDRAMPreAlignLength,
			( ALIGN( (UInt32)Source, sizeof (UInt32) ) - (UInt32)Source ) );

		pciDWORDAlignedCopy ( 
			SDRAMPostAlignAddress, 
			Source + SDRAMPreAlignLength + SDRAMCacheAlignLength, 
			SDRAMPostAlignLength,
			( ALIGN( (UInt32)Source + SDRAMPreAlignLength + SDRAMCacheAlignLength, 
			sizeof (UInt32) ) - ((UInt32)Source + SDRAMPreAlignLength + SDRAMCacheAlignLength) ) );
	}

	

	return TMLIBDEV_OK;
}


extern
tmLibdevErr_t
pciIOReadUInt8(
	UInt32 address,
	UInt32* Data )
{
	#pragma TCS_atomic

	UInt32 Shift,Res;
	UInt32 byte_enable;
	Shift = address & 0x03;
	byte_enable =  ~(0x01 << Shift) & 0x0F;

	/*poll until previous I/O transaction completes */
	while (MMIO(BIU_STATUS) & PCI_IO_BUSY)
	{
		;
	}

	/*clear the DONE bit */
	MMIO(BIU_STATUS) = PCI_IO_DONE;
	MMIO(IO_ADR) = address;
	MMIO(IO_CTL) = PCI_IO_READ | byte_enable;

	/* poll until I/O cycle done  */
	while ((MMIO(BIU_STATUS) & PCI_IO_DONE) == 0)
	{
		;
	}

	/* get the value and clear the DONE bit */
	Res = MMIO(IO_DATA);
	MMIO(BIU_STATUS) = PCI_IO_DONE;

	Res >>=(Shift*8);

	*Data = (Res & 0xFF);

	return TMLIBDEV_OK;
}

extern
tmLibdevErr_t
pciIOWriteUInt8(
	UInt32 address, 
	UInt32 Data)
{
	#pragma TCS_atomic

	UInt32 Shift;
	UInt32 byte_enable;
	Shift = address & 0x03;
	byte_enable =  ~(0x01 << Shift) & 0x0F;

	Data <<=(Shift*8);
	
	/*  poll until previous I/O transaction completes */
	while (MMIO(BIU_STATUS) & PCI_IO_BUSY)
	{
		;
	}

	/* clear the DONE bit */
	MMIO(BIU_STATUS) = PCI_IO_DONE;

	/* perform the write */
	MMIO(IO_ADR) = address;
	MMIO(IO_DATA) = Data;
	MMIO(IO_CTL) = PCI_IO_WRITE | byte_enable;

	/* poll until I/O cycle done */
	while ((MMIO(BIU_STATUS) & PCI_IO_DONE) == 0)
	{
		;
	}

	/* clear the DONE bit */
	MMIO(BIU_STATUS) = PCI_IO_DONE;

	return TMLIBDEV_OK;
}

/*-------------------------------------------------------------------------*/
/*--------------------LOCAL FUNCTIONS--------------------------------------*/
/*-------------------------------------------------------------------------*/

static void pciDWORDAlignedCopy (
	UInt8*	Destination,
	UInt8*	Source,
	UInt32	Length,
	UInt32	AlignmentBase )
{
	UInt32	Copied, Idx;
	UInt32*	Dest32, *Src32;

	UInt32 GlobalInterruptState;
	UInt32 DCLockCtlState;

    GlobalInterruptState = intCLEAR_IEN();
	DCLockCtlState = pciExtractDC_LOCK();
	pciSetDC_LOCK(PCI_DC_LOCK_CTL_HDS);

	Copied = AlignmentBase;
	

	PRINTF ((
		"tmPCI:pciDWORDAlignedCopy1:Dst[%x]:Src[%x]:Len[%x]\n",
		Destination, Source, Copied ));
		
	
	switch ( Copied )
	{
		case 3:
		*Destination++ = *Source++;
		case 2:
		*Destination++ = *Source++;
		case 1:
		*Destination++ = *Source++;
		break;

		case 0:
		default:
		break;
	}

	PRINTF ((
		"tmPCI:pciDWORDAlignedCopy2:Dst[%x]:Src[%x]:Len[%x]\n",
		Destination, Source, (Length/sizeof(UInt32))*sizeof(UInt32) ));

	Dest32 = (UInt32*)Destination;
	Src32 = (UInt32*)Source;

	for ( Idx = 0 ; Idx < Length/sizeof(UInt32) ; Idx ++, Copied+= sizeof(UInt32) )
	{
		*Dest32++ = *Src32++;
	}

	Destination = (UInt8*)Dest32;
	Source = (UInt8*)Src32;

	PRINTF ((
		"tmPCI:pciDWORDAlignedCopy3:Dst[%x]:Src[%x]:Len[%x]\n",
		Destination, Source, Length - Copied ));

	switch ( Length - Copied )
	{
		case 3:
		*Destination++ = *Source++;

		case 2:
		*Destination++ = *Source++;

		case 1:
		*Destination++ = *Source++;
		break;

		case 0:
		default:
		break;
	}

	pciSetDC_LOCK(DCLockCtlState);
    intRESTORE_IEN(GlobalInterruptState);

}


/*---------------------------------------------------------------------------
 Check PCI config cycle status
 Input:        "bits" to check
 Return Value:  0    if BIU_STATUS & bits  == 0 
                1    if timed out or an error
---------------------------------------------------------------------------*/
static int pciConfigStatus (UInt32 bits, UInt32 zero_flag)
{
	int       timeout = 0;
	unsigned  biu_status, x;

	while (timeout < CONFIG_TIMEOUT)
	{
		biu_status = MMIO(BIU_STATUS) ;
		if ((biu_status & 0x100) != 0)
		{
			/*DP(("duplicate config bit set after busy wait\n"));  */
		}
		x = (biu_status & bits);
		if (zero_flag)
		{
			if (x == 0)
			{
			  break;
			}
		}
		else
		{
			if (x != 0)
			{
			  break;
			}
		}
		timeout++ ;
	}

	if (timeout >= CONFIG_TIMEOUT)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -