コード例 #1
0
ファイル: pvrsrv.c プロジェクト: MuMu360121/jordan-kernel
IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData)
{
	SYS_DATA			*psSysData = pvSysData;
	if(!psSysData)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n"));
		return;
	}

	
	List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
									&PVRSRVMISR_ForEachCb);

	
	if (PVRSRVProcessQueues(ISR_ID, IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
	{
		PVRSRVProcessQueues(ISR_ID, IMG_FALSE);
	}

	
	if (psSysData->psGlobalEventObject)
	{
		IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
		if(hOSEventKM)
		{
			OSEventObjectSignal(hOSEventKM);
		}
	}
}
コード例 #2
0
PVRSRV_ERROR
TLStreamSync(IMG_HANDLE psStream)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	PTL_STREAM   psTmp;

	PVR_DPF_ENTERED;

	if ( IMG_NULL == psStream )
	{
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
	}
	psTmp = (PTL_STREAM)psStream;
	
	/* Signal clients only when data is available to read */
	if (psTmp->ui32Read != psTmp->ui32Write)
	{
		eError = OSEventObjectSignal(psTmp->psNode->hDataEventObj);
	}

	PVR_DPF_RETURN_RC(eError);
}
コード例 #3
0
ファイル: power.c プロジェクト: STPJ/linux-3.4-sunxi
/*!
******************************************************************************

 @Function	PVRSRVSetDevicePowerStateKM

 @Description	Set the Device into a new state

 @Input		ui32DeviceIndex : device index
 @Input		eNewPowerState : New power state
 @Input		bForced : TRUE if the transition should not fail (e.g. OS request)

 @Return	PVRSRV_ERROR

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32				ui32DeviceIndex,
										 PVRSRV_DEV_POWER_STATE	eNewPowerState,
										 IMG_BOOL				bForced)
{
	PVRSRV_DATA*    psPVRSRVData = PVRSRVGetPVRSRVData();
	PVRSRV_ERROR	eError;
	PVRSRV_DEV_POWER_STATE eOldPowerState;

	eError = PVRSRVGetDevicePowerState(ui32DeviceIndex, &eOldPowerState);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_WARNING, "PVRSRVSetDevicePowerStateKM: Couldn't read power state."));
		eOldPowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
	}

	#if defined(PDUMP)
	if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
	{
		/*
			Pdump a power-up regardless of the default state.
			Then disable pdump and transition to the default power state.
			This ensures that a power-up is always present in the pdump when necessary.
		*/
		eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON, bForced);
		if(eError != PVRSRV_OK)
		{
			goto Exit;
		}

		eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON, bForced);

		if (eError != PVRSRV_OK)
		{
			goto Exit;
		}

		PDUMPPOWCMDSTART();
	}
	#endif /* PDUMP */

	eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState, bForced);
	if(eError != PVRSRV_OK)
	{
		if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
		{
			PDUMPPOWCMDEND();
		}
		goto Exit;
	}

	eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState, bForced);

	if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
	{
		PDUMPPOWCMDEND();
	}

	/* Signal Device Watchdog Thread about power mode change. */
	if (eOldPowerState != eNewPowerState && eNewPowerState == PVRSRV_DEV_POWER_STATE_ON)
	{
		psPVRSRVData->ui32DevicesWatchdogPwrTrans++;

		if (psPVRSRVData->ui32DevicesWatchdogTimeout == DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT)
		{
			if (psPVRSRVData->hDevicesWatchdogEvObj)
			{
				eError = OSEventObjectSignal(psPVRSRVData->hDevicesWatchdogEvObj);
				PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
			}
		}
	}

Exit:

	if (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)
	{
		PVR_DPF((PVR_DBG_MESSAGE,
				"PVRSRVSetDevicePowerStateKM : Transition to %d was denied, Forced=%d", eNewPowerState, bForced));
	}
	else if(eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_WARNING,
				"PVRSRVSetDevicePowerStateKM : Transition to %d FAILED (%s)", eNewPowerState, PVRSRVGetErrorStringKM(eError)));
	}
	
	return eError;
}
コード例 #4
0
PVRSRV_ERROR
TLStreamCommit(IMG_HANDLE hStream, IMG_UINT32 ui32ReqSize)
{
	PTL_STREAM psTmp;
	IMG_UINT32 ui32LRead, ui32OldWrite, ui32LWrite, ui32LPending;
	PVRSRV_ERROR eError;

	PVR_DPF_ENTERED;

	if ( IMG_NULL == hStream )
	{
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
	}
	psTmp = (PTL_STREAM)hStream;

	/* Get a local copy of the stream buffer parameters */
	ui32LRead = psTmp->ui32Read ;
	ui32LWrite = psTmp->ui32Write ;
	ui32LPending = psTmp->ui32Pending ;

	ui32OldWrite = ui32LWrite;

	// Space in buffer is aligned
	ui32ReqSize = PVRSRVTL_ALIGN(ui32ReqSize);

	/* Sanity check. ReqSize + packet header size. */
	if ( ui32LPending != ui32ReqSize + sizeof(PVRSRVTL_PACKETHDR) )
	{
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_MISUSE);
	}

	/* Update pointer to written data. */
	ui32LWrite = (ui32LWrite + ui32LPending) % psTmp->ui32Size;

	/* and reset LPending to 0 since data are now submitted  */
	ui32LPending = NOTHING_PENDING;

	/* If  we have transitioned from an empty buffer to a non-empty buffer,
	 * signal any consumers that may be waiting. */
	if (ui32OldWrite == ui32LRead && !psTmp->bNoSignalOnCommit)
	{
		/* Signal consumers that may be waiting */
		eError = OSEventObjectSignal(psTmp->psNode->hDataEventObj);
		if ( eError != PVRSRV_OK)
		{
			PVR_DPF_RETURN_RC(eError);
		}
	}

    /* Calculate high water mark for debug purposes */
#if defined(TL_BUFFER_UTILIZATION)
	{
		IMG_UINT32 tmp = 0;
		if (ui32LWrite > ui32LRead)
		{
			tmp = (ui32LWrite-ui32LRead);
		}
		else if (ui32LWrite < ui32LRead)
		{
			tmp = (psTmp->ui32Size-ui32LRead+ui32LWrite);
		} /* else equal, ignore */

		if (tmp > psTmp->ui32BufferUt)
		{
			psTmp->ui32BufferUt = tmp;
		}
	}
#endif

	/* Update stream buffer parameters to match local copies */
	psTmp->ui32Write = ui32LWrite ;
	psTmp->ui32Pending = ui32LPending ;

	PVR_DPF_RETURN_OK;
}
コード例 #5
0
/******************************************************************************* 
 * TL Server public API implementation.
 ******************************************************************************/
PVRSRV_ERROR
TLStreamCreate(IMG_HANDLE *phStream,
			   IMG_CHAR *szStreamName,
			   IMG_UINT32 ui32Size,
			   IMG_UINT32 ui32StreamFlags,
               TL_STREAM_SOURCECB pfProducerCB,
               IMG_PVOID pvProducerUD)
{
	PTL_STREAM     psTmp;
	PVRSRV_ERROR   eError;
	IMG_HANDLE     hEventList;
	PTL_SNODE      psn = 0;
	IMG_CHAR       pszBufferLabel[PRVSRVTL_MAX_STREAM_NAME_SIZE+20];

	DEVMEM_FLAGS_T uiMemFlags =  PVRSRV_MEMALLOCFLAG_CPU_READABLE |
								 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | 
								 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
								 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
								 PVRSRV_MEMALLOCFLAG_UNCACHED | /* GPU & CPU */
								 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC |
								 PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE;

	PVR_DPF_ENTERED;
	/* Sanity checks:  */
	/* non NULL handler required */
	if ( NULL == phStream ) 
	{ 
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
	}
	if (OSStringLength(szStreamName) >= PRVSRVTL_MAX_STREAM_NAME_SIZE) 
	{
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
	}
	
	/* Check if there already exists a stream with this name. */
	psn = TLFindStreamNodeByName( szStreamName );
	if ( IMG_NULL != psn )
	{
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_ALREADY_EXISTS);
	}
	
	/* Allocate stream structure container (stream struct) for the new stream */
	psTmp = OSAllocZMem(sizeof(TL_STREAM)) ;
	if ( NULL == psTmp ) 
	{
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_OUT_OF_MEMORY);
	}

	OSStringCopy(psTmp->szName, szStreamName);

	if ( ui32StreamFlags & TL_FLAG_FORCE_FLUSH )
	{
		psTmp->bWaitForEmptyOnDestroy = IMG_TRUE;
	}

	psTmp->bNoSignalOnCommit = (ui32StreamFlags&TL_FLAG_NO_SIGNAL_ON_COMMIT) ?  IMG_TRUE : IMG_FALSE;

	if ( ui32StreamFlags & TL_FLAG_DROP_DATA ) 
	{
		if ( ui32StreamFlags & TL_FLAG_BLOCKING_RESERVE ) 
		{
			eError = PVRSRV_ERROR_INVALID_PARAMS;
			goto e0;
		}
		psTmp->bDrop = IMG_TRUE;
	}
	else if ( ui32StreamFlags & TL_FLAG_BLOCKING_RESERVE ) 
    {	/* Additional synchronization object required for this kind of stream */
        psTmp->bBlock = IMG_TRUE;

		eError = OSEventObjectCreate(NULL, &psTmp->hProducerEventObj);
		if (eError != PVRSRV_OK)
		{
			goto e0;
		}
		/* Create an event handle for this kind of stream */
		eError = OSEventObjectOpen(psTmp->hProducerEventObj, &psTmp->hProducerEvent);
		if (eError != PVRSRV_OK)
		{
			goto e1;
		}
    }

	/* Remember producer supplied CB and data for later */
	psTmp->pfProducerCallback = (IMG_VOID(*)(IMG_VOID))pfProducerCB;
	psTmp->pvProducerUserData = pvProducerUD;

	/* Round the requested bytes to a multiple of array elements' size, eg round 3 to 4 */
	psTmp->ui32Size = PVRSRVTL_ALIGN(ui32Size);
	psTmp->ui32Read = 0;
	psTmp->ui32Write = 0;
	psTmp->ui32Pending = NOTHING_PENDING;

	OSSNPrintf(pszBufferLabel, sizeof(pszBufferLabel), "TLStreamBuf-%s", szStreamName);

	/* Allocate memory for the circular buffer and export it to user space. */
	eError = DevmemAllocateExportable( IMG_NULL,
									   (IMG_HANDLE) TLGetGlobalRgxDevice(),
									   (IMG_DEVMEM_SIZE_T)psTmp->ui32Size,
									   (IMG_DEVMEM_ALIGN_T) OSGetPageSize(),
									   uiMemFlags | PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE,
									   pszBufferLabel,
									   &psTmp->psStreamMemDesc);
	PVR_LOGG_IF_ERROR(eError, "DevmemAllocateExportable", e2);

	eError = DevmemAcquireCpuVirtAddr( psTmp->psStreamMemDesc, (IMG_VOID**) &psTmp->pbyBuffer );
	PVR_LOGG_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", e3);

	eError = DevmemExport(psTmp->psStreamMemDesc, &(psTmp->sExportCookie));
	PVR_LOGG_IF_ERROR(eError, "DevmemExport", e4);

	/* Synchronization object to synchronize with user side data transfers. */
	eError = OSEventObjectCreate(psTmp->szName, &hEventList);
	if (eError != PVRSRV_OK)
	{
		goto e5;
	}

	/* Stream created, now reset the reference count to 1 */
	psTmp->uiRefCount = 1;

//Thread Safety: Not yet implemented		eError = OSLockCreate(&psTmp->hLock, LOCK_TYPE_PASSIVE);
//Thread Safety: Not yet implemented		if (eError != PVRSRV_OK)
//Thread Safety: Not yet implemented		{
//Thread Safety: Not yet implemented			goto e6;
//Thread Safety: Not yet implemented		}

	/* Now remember the stream in the global TL structures */
	psn = TLMakeSNode(hEventList, (TL_STREAM *)psTmp, 0);
	if (psn == NULL)
	{
		eError=PVRSRV_ERROR_OUT_OF_MEMORY;
		goto e7;
	}
	TLAddStreamNode(psn);

	/* Best effort signal, client wait timeout will ultimately let it find the
	 * new stream if this fails, acceptable to avoid cleanup as it is tricky
	 * at this point */
	(void) OSEventObjectSignal(TLGGD()->hTLEventObj);

	/* Pass the newly created stream handle back to caller */
	*phStream = (IMG_HANDLE)psTmp;
	PVR_DPF_RETURN_OK;

e7:
//Thread Safety: Not yet implemented		OSLockDestroy(psTmp->hLock);
//Thread Safety: Not yet implemented e6:
	OSEventObjectDestroy(hEventList);
e5:
	DevmemUnexport(psTmp->psStreamMemDesc, &(psTmp->sExportCookie));
e4:
	DevmemReleaseCpuVirtAddr( psTmp->psStreamMemDesc );
e3:
	DevmemFree(psTmp->psStreamMemDesc);
e2:
	OSEventObjectClose(psTmp->hProducerEvent);
e1:
	OSEventObjectDestroy(psTmp->hProducerEventObj);
e0:
	OSFREEMEM(psTmp);
	PVR_DPF_RETURN_RC(eError);
}