示例#1
0
enum PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(u32 ui32DeviceIndex,
				     enum PVR_POWER_STATE eNewPowerState,
				     u32 ui32CallerID, IMG_BOOL bRetainMutex)
{
	enum PVRSRV_ERROR eError;
	struct SYS_DATA *psSysData;

	eError = SysAcquireData(&psSysData);
	if (eError != PVRSRV_OK)
		return eError;

	eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
	if (eError != PVRSRV_OK)
		return eError;
#if defined(PDUMP)
	if (eNewPowerState == PVRSRV_POWER_Unspecified) {
		eError =
		    PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex,
							PVRSRV_POWER_STATE_D0);
		if (eError != PVRSRV_OK)
			goto Exit;
		eError =
		    PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex,
							 PVRSRV_POWER_STATE_D0);
		if (eError != PVRSRV_OK)
			goto Exit;

		PDUMPSUSPEND();
	}
#endif

	eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex,
						eNewPowerState);
	if (eError != PVRSRV_OK) {
		if (eNewPowerState == PVRSRV_POWER_Unspecified)
			PDUMPRESUME();
		goto Exit;
	}

	eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex,
					 eNewPowerState);

	if (eNewPowerState == PVRSRV_POWER_Unspecified)
		PDUMPRESUME();

Exit:

	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVSetDevicePowerStateKM : "
					"Transition to %d FAILED 0x%x",
			 eNewPowerState, eError);
	}

	if (!bRetainMutex || (eError != PVRSRV_OK))
		PVRSRVPowerUnlock(ui32CallerID);

	return eError;
}
示例#2
0
IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE	*psDeviceNode,
								  IMG_UINT32			ui32CallerID)
{
	PVRSRV_ERROR		eError = PVRSRV_OK;
	PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
	SGXMKIF_HOST_CTL	*psSGXHostCtl = psDevInfo->psSGXHostCtl;

#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK)
	if (!psDevInfo->bSGXIdle &&
		((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) != 0))
	{
		psDevInfo->bSGXIdle = IMG_TRUE;
		SysSGXIdleTransition(psDevInfo->bSGXIdle);
	}
	else if (psDevInfo->bSGXIdle &&
			((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) == 0))
	{
		psDevInfo->bSGXIdle = IMG_FALSE;
		SysSGXIdleTransition(psDevInfo->bSGXIdle);
	}
#endif

	if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0) &&
		((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0))
	{

		psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;

		PDUMPSUSPEND();

#if defined(SYS_CUSTOM_POWERDOWN)

		eError = SysPowerDownMISR(psDeviceNode, ui32CallerID);
#else
		eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
											 PVRSRV_DEV_POWER_STATE_OFF,
											 ui32CallerID, IMG_FALSE);
		if (eError == PVRSRV_OK)
		{
			SGXPostActivePowerEvent(psDeviceNode, ui32CallerID);
		}
#endif
		if (eError == PVRSRV_ERROR_RETRY)
		{

			psSGXHostCtl->ui32InterruptClearFlags &= ~PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
			eError = PVRSRV_OK;
		}

		PDUMPRESUME();
	}

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%u", eError));
	}
    }
IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE	*psDeviceNode,
								  IMG_UINT32			ui32CallerID)
{
	PVRSRV_ERROR		eError = PVRSRV_OK;
	PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
	SGXMKIF_HOST_CTL	*psSGXHostCtl = psDevInfo->psSGXHostCtl;

#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK)
	if (!psDevInfo->bSGXIdle &&
		((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) != 0))
	{
		psDevInfo->bSGXIdle = IMG_TRUE;
		SysSGXIdleTransition(psDevInfo->bSGXIdle);
	}
	else if (psDevInfo->bSGXIdle &&
			((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) == 0))
	{
		psDevInfo->bSGXIdle = IMG_FALSE;
		SysSGXIdleTransition(psDevInfo->bSGXIdle);
	}
#endif 

	/**
	 * Quickly check (without lock) if there is an APM event we should handle.
	 * This check fails most of the time so we don't want to incur lock overhead.
	 * Check the flags in the reverse order that microkernel clears them to prevent
	 * us from seeing an inconsistent state.
	*/
	if (((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0) &&
		((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0))
	{
		
		eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
		if (eError == PVRSRV_ERROR_RETRY)
			return;
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"SGXTestActivePowerEvent failed to acquire lock - "
					 "ui32CallerID:%d eError:%u", ui32CallerID, eError));
			return;
		}

		/**
		 * Check again (with lock) if APM event has been cleared or handled. A race
		 * condition may allow multiple threads to pass the quick check.
		*/
		if (((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0) ||
			((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0))
		{
			PVRSRVPowerUnlock(ui32CallerID);
			return;
		}

		psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;

		
		PDUMPSUSPEND();

#if defined(SYS_CUSTOM_POWERDOWN)
		


		eError = SysPowerDownMISR(psDeviceNode, ui32CallerID);
#else
		eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
											 PVRSRV_DEV_POWER_STATE_OFF);
		if (eError == PVRSRV_OK)
		{
			SGXPostActivePowerEvent(psDeviceNode, ui32CallerID);
		}
#endif
		PVRSRVPowerUnlock(ui32CallerID);


		
		PDUMPRESUME();
	}

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%u", eError));
	}
}
示例#4
0
IMG_EXPORT
PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32				ui32DeviceIndex,
										 PVRSRV_DEV_POWER_STATE	eNewPowerState,
										 IMG_UINT32				ui32CallerID,
										 IMG_BOOL				bRetainMutex)
{
	PVRSRV_ERROR	eError;
	SYS_DATA		*psSysData;

	SysAcquireData(&psSysData);

	eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
	if(eError != PVRSRV_OK)
	{
		return eError;
	}

	#if defined(PDUMP)
	if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
	{




		eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
		if(eError != PVRSRV_OK)
		{
			goto Exit;
		}

		eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);

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

		PDUMPSUSPEND();
	}
	#endif

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

	eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);

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

Exit:

	if(eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
				"PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError));
	}

	if (!bRetainMutex || (eError != PVRSRV_OK))
	{
		PVRSRVPowerUnlock(ui32CallerID);
	}

	return eError;
}