/*! ****************************************************************************** @Function PVRSRVDevicePostClockSpeedChange @Description Notification from system layer that a device clock speed change has just happened. @Input ui32DeviceIndex : device index @Input bIdleDevice : whether the device had been idled @Input pvInfo @Return IMG_VOID ******************************************************************************/ IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex, IMG_BOOL bIdleDevice, IMG_VOID *pvInfo) { PVRSRV_ERROR eError; PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); PVRSRV_POWER_DEV *psPowerDevice; PVR_UNREFERENCED_PARAMETER(pvInfo); /*search the device and then do the post clock speed change*/ psPowerDevice = (PVRSRV_POWER_DEV*) List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList, &MatchPowerDeviceIndex_AnyVaCb, ui32DeviceIndex); if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange) { eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie, bIdleDevice, psPowerDevice->eCurrentPowerState); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x", ui32DeviceIndex, eError)); } } /* This mutex was acquired in PVRSRVDevicePreClockSpeedChange. */ PVRSRVPowerUnlock(); }
/*! ****************************************************************************** @Function PVRSRVDevicePreClockSpeedChange @Description Notification from system layer that a device clock speed change is about to happen. @Input ui32DeviceIndex : device index @Input bIdleDevice : whether the device should be idled @Input pvInfo @Return IMG_VOID ******************************************************************************/ PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex, IMG_BOOL bIdleDevice, IMG_VOID *pvInfo) { PVRSRV_ERROR eError = PVRSRV_OK; PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); PVRSRV_POWER_DEV *psPowerDevice; PVR_UNREFERENCED_PARAMETER(pvInfo); /*search the device and then do the pre clock speed change*/ psPowerDevice = (PVRSRV_POWER_DEV*) List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList, &MatchPowerDeviceIndex_AnyVaCb, ui32DeviceIndex); do { /* This mutex is released in PVRSRVDevicePostClockSpeedChange. */ eError = PVRSRVPowerLock(); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError)); return eError; } if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange) { eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie, bIdleDevice, psPowerDevice->eCurrentPowerState); if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x", ui32DeviceIndex, eError)); } else if (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED) { PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVDevicePreClockSpeedChange : Device %u denied transition to IDLE", ui32DeviceIndex)); PVRSRVPowerUnlock(); OSSleepms(1); } } } while (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED); if (eError != PVRSRV_OK) { PVRSRVPowerUnlock(); } return eError; }
PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex, IMG_BOOL bIdleDevice, IMG_VOID *pvInfo) { PVRSRV_ERROR eError = PVRSRV_OK; SYS_DATA *psSysData; PVRSRV_POWER_DEV *psPowerDevice; PVR_UNREFERENCED_PARAMETER(pvInfo); SysAcquireData(&psSysData); if (bIdleDevice) { eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%lx", eError)); return eError; } } psPowerDevice = (PVRSRV_POWER_DEV*) List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, MatchPowerDeviceIndex_AnyVaCb, ui32DeviceIndex); if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange) { eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie, bIdleDevice, psPowerDevice->eCurrentPowerState); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : Device %lu failed, error:0x%lx", ui32DeviceIndex, eError)); } } if (bIdleDevice && eError != PVRSRV_OK) { PVRSRVPowerUnlock(KERNEL_ID); } return eError; }
/*! ****************************************************************************** @Function PVRSRVGetDevicePowerState @Description Return the device power state @Input ui32DeviceIndex : device index @Output psPowerState : Current power state @Return PVRSRV_ERROR_UNKNOWN_POWER_STATE if device could not be found. PVRSRV_OK otherwise. ******************************************************************************/ IMG_EXPORT PVRSRV_ERROR PVRSRVGetDevicePowerState(IMG_UINT32 ui32DeviceIndex, PPVRSRV_DEV_POWER_STATE pePowerState) { PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); PVRSRV_POWER_DEV *psPowerDevice; psPowerDevice = (PVRSRV_POWER_DEV*) List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList, &MatchPowerDeviceIndex_AnyVaCb, ui32DeviceIndex); if (psPowerDevice == IMG_NULL) { return PVRSRV_ERROR_UNKNOWN_POWER_STATE; } *pePowerState = psPowerDevice->eCurrentPowerState; return PVRSRV_OK; }
/*! ****************************************************************************** @Function PVRSRVRemovePowerDevice @Description Removes device from power management register. Device is located by Device Index @Input ui32DeviceIndex : device index @Return PVRSRV_ERROR ******************************************************************************/ PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex) { PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); PVRSRV_POWER_DEV *psPowerDev; /* find device in list and remove it */ psPowerDev = (PVRSRV_POWER_DEV*) List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList, &MatchPowerDeviceIndex_AnyVaCb, ui32DeviceIndex); if (psPowerDev) { List_PVRSRV_POWER_DEV_Remove(psPowerDev); OSFreeMem(psPowerDev); /*not nulling pointer, copy on stack*/ } return (PVRSRV_OK); }
IMG_EXPORT IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex) { SYS_DATA *psSysData; PVRSRV_POWER_DEV *psPowerDevice; SysAcquireData(&psSysData); if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) || OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID)) { return IMG_FALSE; } psPowerDevice = (PVRSRV_POWER_DEV*) List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, MatchPowerDeviceIndex_AnyVaCb, ui32DeviceIndex); return (psPowerDevice && (psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)) ? IMG_TRUE : IMG_FALSE; }
PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex) { SYS_DATA *psSysData; PVRSRV_POWER_DEV *psPowerDev; SysAcquireData(&psSysData); psPowerDev = (PVRSRV_POWER_DEV*) List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, MatchPowerDeviceIndex_AnyVaCb, ui32DeviceIndex); if (psPowerDev) { List_PVRSRV_POWER_DEV_Remove(psPowerDev); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psPowerDev, IMG_NULL); } return (PVRSRV_OK); }