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

📄 dp_hardware_dispatcher.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

/*********************************************************************************
 *********************************************************************************
 **
 ** Name        : dp_hardware_dispatcher.c
 ** Title       : Display pipeline API DMA engine interface
 ** Author      : T. Whalley
 ** Created     : June 2001
 ** 
 ** Copyright   : 2001 by Imagination Technologies Limited. All rights reserved
 **             : No part of this software, either material or conceptual
 **             : may be copied or distributed, transmitted, transcribed,
 **             : stored in a retrieval system or translated into any
 **             : human or computer language in any form by any means,
 **             : electronic, mechanical, manual or other-wise, or
 **             : disclosed to third parties without the express written
 **             : permission of Imagination Technologies Limited, Unit 8,
 **             : HomePark Industrial Estate, King's Langley, Hertfordshire,
 **             : WD4 8LZ, U.K.
 **
 ** Description : Contains all functions for sorting and preparing data for the
 **               DMA engine and for retrieving data from hardware.
 **
 ** Platform    : Platform independent	(modify 'types.h' accordingly)
  **
 *********************************************************************************
 *********************************************************************************/

#include "services_headers.h"

#include "dp_types.h"
#include "dp_init_marathon.h"
#include "dp_hardware.h"
#include "dp_hardware_dispatcher.h"


#if defined DP_SIMULATION_MODE
	#include <windows.h>
	#include <stdio.h>
#endif

#ifdef PDUMP
typedef struct _MEM_INFO_	*PMEM_INFO;
//uncomment if needed #define PDPPDUMP
#endif

DP_UINT_32					DP_DispatcherBufferStorage		[ 2 * DP_SIZE_OF_DISPATCHER_BUFFER_IN_ENTRIES * (sizeof (DP_QueuedMemoryWrite) / sizeof ( DP_UINT_32)) ];

DP_QueuedMemoryWrite *		DP_DispatcherBuffers;

DP_UINT_16					DP_ui16DispatcherBufferSize		[ 2 ];
DP_DMABufferStates			DP_eBufferStates				[ 2 ];
DP_UINT_8					DP_ui8DispatcherBufferOffset	[ 2 ];

DP_PUINT_32					DP_pSharedMemory;

#if defined DP_SIMULATION_MODE
#define		DP_SIMULATION_NO_OF_REGISTERS					0x2000

DP_UINT_32					DP_aui32SimulationMemory		[ DP_SIMULATION_NO_OF_REGISTERS ];

/* This simulates the hardware's ability to detect a write to a register.						*/
DP_BOOL						DP_bNewValuePending			=	DP_FALSE;	

#endif


/***********************************************************************************************
 *
 * Function Name  : DP_CommandSequence
 * Inputs         : eOperation			-	An instance of the 'DP_CommandSequenceOperations'
 *											enumerated type, used to indicate to the function
 *											the type of command sequence operation being
 *											carried out. The following values are supported :
 *
 *											DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND
 *												Specifies that a single field is to be written
 *												to, using the DMA engine. The command (passed by
 *												this functions other two parameters) is
 *												submitted when the function is called.
 *
 *											DP_COMMAND_SEQUENCE_OPERATIONS_NEW_SEQUENCE
 *												Specifies that a new list of commands is to be,
 *												started, and should not be transmitted until
 *												the list is marked complete. This command
 *												the other two parameters passed.
 *
 *											DP_COMMAND_SEQUENCE_OPERATIONS_ADD_COMMAND
 *												Specifies that a command should be added to a
 *												list previously created using the 'new sequence'
 *												command.
 *
 *											DP_COMMAND_SEQUENCE_OPERATIONS_SEND_SEQUENCE
 *												Specifies that a prepared list (using the
 *												'new sequence' and 'add command' settings should
 *												be submitted to the DMA engine.
 *
 *											DP_COMMAND_SEQUENCE_OPERATIONS_SEND_IMMEDIATE
 *												Specifies that a prepated list should be written
 *												directly to the hardware, bypassing the DMA
 *												engine (this mode of writing does not wait for
 *												the VSYNC signal).
 *
 *											DP_COMMAND_SEQUENCE_OPERATIONS_SEND_ON_VSYNC
 *												Specifies that a prepared list should be written
 *												directly to the hardware, bypassing the DMA
 *												engine, but waiting for the next VSYNC signal to
 *												begin prior to writing. The function simply
 *												polls for the VSYNC signal and hence can tie up
 *												the calling process for a significant period.
 *
 *											DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_INSTANT
 *												Specifies that a single field is to be written to
 *												, but bypassing the DMA engine and writing
 *												directly to hardware. The command (passed by
 *												this function's other two parameters) is
 *												submitted when the function is called (this mode
 *												of writing does not wait for the VSYNC signal).
 *														
 *											DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_ON_VSYNC
 *												Specifies that a single field is to be written to
 *												, but bypassing the DMA engine and writing
 *												directly to hardware, after waiting for the next
 *												VSYNC signal. The function simply polls for the 
 *												VSYNC signal and hence can tie up the calling 
 *												process for a significant period.
 *
 *					pasField			-	A pointer to the 'DP_pFieldTarget' structure
 *											which contains the details of the field to be
 *											written to.
 *					
 *					ui32Value			-	The value to be written to the target field.	
 *										
 * Outputs        : None.
 * Returns        : DP_UINT_16			-	Returns one of the defined display pipeline error
 *											codes according to the success of the function, 
 *											within the bounds of limited error checking :
 *											> The function checks that each target field exists
 *											  returning, DP_ERR_EXCEEDS_CAPABILITIES, if it does
 *											  not (regardless of error checking mode).
 *											> The function checks that the passed target value
 *											  will not exceed the bounds of the specified field
 *											  (only when error checking is enabled).
 *												
 * Globals Used   :	None.	
 * Description    : This function is used to generate, add to and ultimately submit to the DMA 
 *					Engine a series	of field writes. By using this function, it can be ensured 
 *					that all memory writes which up a single operation are all submitted to the
 *					DMA Engine as part of the same buffer.		
 *
 ***********************************************************************************************/

DP_UINT_16	DP_CommandSequence				(	DP_CommandSequenceOperations	eOperation,
												DP_pFieldTarget					pasField,
												DP_UINT_32						ui32Value	)
{

static	DP_UINT_8				ui8LengthOfCommandSequence	=	0;
		DP_UINT_16				ui16ReturnValue				=	DP_STANDARD_CODE_NO_ERROR;
		DP_QueuedFieldWrite		sInstruction;	
		DP_UINT_16				ui16SizeOfBuffer			=	0;
		DP_UINT_16				ui16i;

/* Used as a scratch pad for preparing lists of memory writes for immediate actioning (i.e.:	*/
/* not using the DMA Engine). By using the same structures to prepare the lists as ARE used by	*/
/* the DMA Engine, all the same preparation interrogation functions can be used.				*/	
static	DP_QueuedMemoryWrite	DP_TemporaryDispatchBuffer	[ DP_SIZE_OF_DISPATCHER_BUFFER_IN_ENTRIES ];

/* Used as a scratch pad for preparation of memory writes for non-immediate actioning. These	*/
/* memory writes are subsequently submitted to the DMA Engine via the DP_QueueNewDMABuffer		*/
/* function.																					*/
static	DP_QueuedFieldWrite		DP_asCommandSequence		[ DP_MAXIMUM_COMMAND_SEQUENCE_LENGTH ];		

	#if defined DP_DO_NOT_USE_DMA_ENGINE
		switch ( eOperation )
		{
			case DP_COMMAND_SEQUENCE_OPERATIONS_NEW_SEQUENCE:
			case DP_COMMAND_SEQUENCE_OPERATIONS_ADD_COMMAND:
				/* These are nothing to do with sending the actual sequence, anyway	- these		*/
				/* remain unchanged whether or not we are using the DMA Engine					*/
				break;


			case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_SEQUENCE:
				/* This command needs changing to avoid using the DMA Engine					*/
				eOperation = DP_COMMAND_SEQUENCE_OPERATIONS_SEND_IMMEDIATE;
				//eOperation = DP_COMMAND_SEQUENCE_OPERATIONS_SEND_ON_VSYNC;
				break;


			case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND:
				/* This command needs changing to avoid using the DMA Engine					*/
				eOperation = DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_INSTANT;
				//eOperation = DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_ON_VSYNC;
				break;
			
			
			case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_IMMEDIATE:
			case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_ON_VSYNC:
			case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_INSTANT:
			case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_ON_VSYNC:
				/* These commands all instruct the sequence to be sent without the DMA Engine	*/
				/* anyway, so they remain unchanged whether or not we are using the DMA Engine	*/
				break;

		}
	#endif

	ui16ReturnValue = DP_STANDARD_CODE_NO_ERROR;

	switch	( eOperation )
	{
		case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND:	

			/* Higher level API functions rely on being told if a field doesn't exist,			*/
			/* regardless of whether error checking is enabled or not. For this reason, we must */
			/* check 'up front' whether the field is null.										*/

			if	(( pasField != DP_NULL ) &&
				 ( pasField->ui32TargetAddressOffset != DP_NO_REG ))
				
			{

				#if defined DP_ERROR_CHECKING
				/* Confirm that the value to add won't cause a field overflow (i.e.: is the		*/
				/* field larger than the space available for it ?								*/
				if (( ui32Value >> pasField->ui8SourceBitfieldStart ) <= ( pasField->ui32TargetBitfieldMask >> pasField->ui8TargetBitfieldStart )) 
				{
				#endif
				
					sInstruction.pasFieldToWrite = (DP_FieldTarget *) pasField;
					sInstruction.ui32ValueToWrite = ui32Value;

					DP_QueueNewDMABuffer ( &sInstruction, (DP_UINT_8) 1 );

				#if defined DP_ERROR_CHECKING
				}
				else
					ui16ReturnValue = DP_ERR_OUT_OF_RANGE;
				#endif

			}
			else
				ui16ReturnValue = DP_ERR_EXCEEDS_CAPABILITIES;

		break;

		case DP_COMMAND_SEQUENCE_OPERATIONS_NEW_SEQUENCE:
			
			ui8LengthOfCommandSequence = 0;

		break;

		case DP_COMMAND_SEQUENCE_OPERATIONS_ADD_COMMAND:
			
			/* Higher level API functions rely on being told if a field doesn't exist,			*/
			/* regardless of whether error checking is enabled or not. For this reason, we must */
			/* check 'up front' whether the field is null.										*/
			if	(( pasField != DP_NULL ) &&
				 ( pasField->ui32TargetAddressOffset != DP_NO_REG ))
				
			{

				#if defined DP_ERROR_CHECKING
				/* Confirm that the value to add won't cause a field overflow (i.e.: is the		*/
				/* field larger than the space available for it ?								*/
				if (( ui32Value >> pasField->ui8SourceBitfieldStart ) <= ( pasField->ui32TargetBitfieldMask >> pasField->ui8TargetBitfieldStart )) 
				{
				#endif

					DP_asCommandSequence [ ui8LengthOfCommandSequence ].pasFieldToWrite = (DP_FieldTarget *) pasField;
					DP_asCommandSequence [ ui8LengthOfCommandSequence ].ui32ValueToWrite = ui32Value;

					ui8LengthOfCommandSequence ++;

				#if defined DP_ERROR_CHECKING
				}
				else
					ui16ReturnValue = DP_ERR_OUT_OF_RANGE;
					#endif

			}
			else
				ui16ReturnValue = DP_ERR_EXCEEDS_CAPABILITIES;

		break;

		case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_SEQUENCE:

			if ( ui8LengthOfCommandSequence > 0 )		
			{
				DP_QueueNewDMABuffer ( &DP_asCommandSequence [0], ui8LengthOfCommandSequence );

				ui8LengthOfCommandSequence = 0;
			}

		break;


		case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_INSTANT:
		case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_ON_VSYNC:

			/* Higher level API functions rely on being told if a field doesn't exist,			*/
			/* regardless of whether error checking is enabled or not. For this reason, we must */
			/* check 'up front' whether the field is null.										*/

			if	(( pasField != DP_NULL ) &&
				 ( pasField->ui32TargetAddressOffset != DP_NO_REG ))
				
			{

				#if defined DP_ERROR_CHECKING
				/* Confirm that the value to add won't cause a field overflow (i.e.: is the		*/
				/* field larger than the space available for it ?								*/
				if (( ui32Value >> pasField->ui8SourceBitfieldStart ) <= ( pasField->ui32TargetBitfieldMask >> pasField->ui8TargetBitfieldStart )) 
				{
				#endif

					ui8LengthOfCommandSequence = 1;

					DP_asCommandSequence [0].pasFieldToWrite  = (DP_FieldTarget *) pasField;
					DP_asCommandSequence [0].ui32ValueToWrite = ui32Value;

				#if defined DP_ERROR_CHECKING
				}
				else
				{
					ui16ReturnValue = DP_ERR_OUT_OF_RANGE;
					break;
				}
				#endif				

			}
			else
			{
				ui16ReturnValue = DP_ERR_EXCEEDS_CAPABILITIES;
				break;

⌨️ 快捷键说明

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