Пример #1
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));
	}
    }
Пример #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 

	/**
	 * 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));
	}
}