From: Imre Deak Date: Fri, 18 Nov 2011 14:38:01 +0000 (+0200) Subject: gfx: pvr: make sure power is on during SGX reset X-Git-Tag: 2.1b_release~493 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7242e5e26aa768b9895c47b8a21251ea89e35a58;p=kernel%2Fkernel-mfld-blackbay.git gfx: pvr: make sure power is on during SGX reset There is a race where after calling the SGX power-on function, it's possible that the device will be powered-off through another IOCTL or and SGX interrupt, before we get to perform the actual reset operation. To prevent this, keep the power-lock for the duration of the reset. Note that the current PVR API for powering on/off the devices is suboptimal. Powering on a device requires acquiring the 'power lock', which will be re-tried for a given amount of time, after which the driver will give up. Instead of this we should have a refcount based solution and get rid of the above timeout mechanism. Signed-off-by: Imre Deak Signed-off-by: Kirill A. Shutemov --- diff --git a/drivers/staging/mrst/pvr/pvr_debug_core.c b/drivers/staging/mrst/pvr/pvr_debug_core.c index 004e36a..511fdf0 100644 --- a/drivers/staging/mrst/pvr/pvr_debug_core.c +++ b/drivers/staging/mrst/pvr/pvr_debug_core.c @@ -101,12 +101,13 @@ int sgx_trigger_reset(PVRSRV_DEVICE_NODE *dev_node) err = PVRSRVSetDevicePowerStateKM(dev_node->sDevId.ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON, - KERNEL_ID, IMG_FALSE); + KERNEL_ID, IMG_TRUE); if (err != PVRSRV_OK) return -EIO; - HWRecoveryResetSGX(dev_node, 0, KERNEL_ID); + HWRecoveryResetSGXNoLock(dev_node); + PVRSRVPowerUnlock(KERNEL_ID); /* power down if no activity */ SGXTestActivePowerEvent(dev_node, KERNEL_ID); diff --git a/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxinfokm.h b/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxinfokm.h index be6ca26..ad205f0 100644 --- a/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxinfokm.h +++ b/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxinfokm.h @@ -319,6 +319,8 @@ typedef struct _PVRSRV_SGX_CCB_INFO_ PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode); +IMG_VOID HWRecoveryResetSGXNoLock(PVRSRV_DEVICE_NODE *psDeviceNode); + IMG_VOID HWRecoveryResetSGX(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 ui32Component, IMG_UINT32 ui32CallerID); diff --git a/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxinit.c b/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxinit.c index 6fd2431..1fc54d5 100644 --- a/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxinit.c +++ b/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxinit.c @@ -1039,28 +1039,12 @@ static IMG_VOID SGXDumpDebugInfo (PVRSRV_DEVICE_NODE *dev_node, IMG_BOOL bDumpSG } -IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Component, - IMG_UINT32 ui32CallerID) +IMG_VOID HWRecoveryResetSGXNoLock(PVRSRV_DEVICE_NODE *psDeviceNode) { PVRSRV_ERROR eError; PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; - PVR_UNREFERENCED_PARAMETER(ui32Component); - - - - eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); - if(eError != PVRSRV_OK) - { - - - - PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress")); - return; - } - psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR; PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered")); @@ -1087,17 +1071,33 @@ IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, PDUMPRESUME(); +} + +IMG_VOID HWRecoveryResetSGX(PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_UINT32 ui32Component, + IMG_UINT32 ui32CallerID) +{ + PVRSRV_ERROR eError; + PVRSRV_SGXDEV_INFO *sgx_info; + + PVR_UNREFERENCED_PARAMETER(ui32Component); + + sgx_info = psDeviceNode->pvDevice; + eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); + if (eError != PVRSRV_OK) { + pr_warn("pvr: %s: power transition in progress", __func__); + + return; + } + + HWRecoveryResetSGXNoLock(psDeviceNode); + PVRSRVPowerUnlock(ui32CallerID); - SGXScheduleProcessQueuesKM(psDeviceNode); - - - PVRSRVProcessQueues(ui32CallerID, IMG_TRUE); } - #if defined(SUPPORT_HW_RECOVERY) IMG_VOID SGXOSTimer(IMG_VOID *pvData) {