aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/sgx/sgxutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/sgx/sgxutils.c')
-rw-r--r--drivers/gpu/pvr/sgx/sgxutils.c171
1 files changed, 141 insertions, 30 deletions
diff --git a/drivers/gpu/pvr/sgx/sgxutils.c b/drivers/gpu/pvr/sgx/sgxutils.c
index bdc3006..528490b 100644
--- a/drivers/gpu/pvr/sgx/sgxutils.c
+++ b/drivers/gpu/pvr/sgx/sgxutils.c
@@ -697,11 +697,18 @@ PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
#if defined(PDUMP)
+
+
+
+
+
+
+
PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete");
PDUMPMEMPOL(psHostCtlMemInfo,
offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus),
- PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
- PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE,
PDUMP_POLL_OPERATOR_EQUAL,
0,
MAKEUNIQUETAG(psHostCtlMemInfo));
@@ -712,8 +719,20 @@ PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
return eError;
}
}
+
+ if (psHostCtl->ui32CleanupStatus & PVRSRV_USSE_EDM_CLEANUPCMD_BUSY)
+ {
+
+ PVR_ASSERT((psHostCtl->ui32CleanupStatus & PVRSRV_USSE_EDM_CLEANUPCMD_DONE) == 0);
+ eError = PVRSRV_ERROR_RETRY;
+ psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_BUSY);
+ }
+ else
+ {
+ eError = PVRSRV_OK;
+ psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE);
+ }
- psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE);
PDUMPMEM(IMG_NULL, psHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHostCtlMemInfo));
@@ -722,7 +741,7 @@ PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
#else
psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_DATA;
#endif
- return PVRSRV_OK;
+ return eError;
}
@@ -732,6 +751,8 @@ typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_
PVRSRV_KERNEL_MEM_INFO *psHWRenderContextMemInfo;
IMG_HANDLE hBlockAlloc;
PRESMAN_ITEM psResItem;
+ IMG_BOOL bCleanupTimerRunning;
+ IMG_PVOID pvTimeData;
} SGX_HW_RENDER_CONTEXT_CLEANUP;
@@ -749,16 +770,44 @@ static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam,
PVRSRV_CLEANUPCMD_RC,
bForceCleanup);
-
- PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
- psCleanup->psHWRenderContextMemInfo);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (!psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US);
+ psCleanup->bCleanupTimerRunning = IMG_TRUE;
+ }
+ else
+ {
+ if (OSTimeHasTimePassed(psCleanup->pvTimeData))
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ }
+ else
+ {
+ if (psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
- psCleanup,
- psCleanup->hBlockAlloc);
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHWRenderContextMemInfo);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+ }
return eError;
}
@@ -769,6 +818,8 @@ typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_
PVRSRV_KERNEL_MEM_INFO *psHWTransferContextMemInfo;
IMG_HANDLE hBlockAlloc;
PRESMAN_ITEM psResItem;
+ IMG_BOOL bCleanupTimerRunning;
+ IMG_PVOID pvTimeData;
} SGX_HW_TRANSFER_CONTEXT_CLEANUP;
@@ -786,16 +837,44 @@ static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam,
PVRSRV_CLEANUPCMD_TC,
bForceCleanup);
-
- PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
- psCleanup->psHWTransferContextMemInfo);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (!psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US);
+ psCleanup->bCleanupTimerRunning = IMG_TRUE;
+ }
+ else
+ {
+ if (OSTimeHasTimePassed(psCleanup->pvTimeData))
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ }
+ else
+ {
+ if (psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
- psCleanup,
- psCleanup->hBlockAlloc);
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHWTransferContextMemInfo);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+ }
return eError;
}
@@ -924,6 +1003,7 @@ IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE hDeviceNode,
psCleanup->hBlockAlloc = hBlockAlloc;
psCleanup->psDeviceNode = psDeviceNode;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
psResItem = ResManRegisterRes(psPerProc->hResManContext,
RESMAN_TYPE_HW_RENDER_CONTEXT,
@@ -1101,6 +1181,7 @@ IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE hDeviceNode,
psCleanup->hBlockAlloc = hBlockAlloc;
psCleanup->psDeviceNode = psDeviceNode;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
psResItem = ResManRegisterRes(psPerProc->hResManContext,
RESMAN_TYPE_HW_TRANSFER_CONTEXT,
@@ -1244,6 +1325,8 @@ typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_
PVRSRV_KERNEL_MEM_INFO *psHW2DContextMemInfo;
IMG_HANDLE hBlockAlloc;
PRESMAN_ITEM psResItem;
+ IMG_BOOL bCleanupTimerRunning;
+ IMG_PVOID pvTimeData;
} SGX_HW_2D_CONTEXT_CLEANUP;
static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam,
@@ -1261,17 +1344,44 @@ static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam,
PVRSRV_CLEANUPCMD_2DC,
bForceCleanup);
-
- PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
- psCleanup->psHW2DContextMemInfo);
-
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
- psCleanup,
- psCleanup->hBlockAlloc);
-
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (!psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US);
+ psCleanup->bCleanupTimerRunning = IMG_TRUE;
+ }
+ else
+ {
+ if (OSTimeHasTimePassed(psCleanup->pvTimeData))
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ }
+ else
+ {
+ if (psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHW2DContextMemInfo);
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+ }
return eError;
}
@@ -1397,6 +1507,7 @@ IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE hDeviceNode,
psCleanup->hBlockAlloc = hBlockAlloc;
psCleanup->psDeviceNode = psDeviceNode;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
psResItem = ResManRegisterRes(psPerProc->hResManContext,
RESMAN_TYPE_HW_2D_CONTEXT,