diff options
Diffstat (limited to 'pvr-source/services4/srvkm/devices/sgx/sgxutils.c')
-rwxr-xr-x | pvr-source/services4/srvkm/devices/sgx/sgxutils.c | 1914 |
1 files changed, 0 insertions, 1914 deletions
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxutils.c b/pvr-source/services4/srvkm/devices/sgx/sgxutils.c deleted file mode 100755 index d5cb3c1..0000000 --- a/pvr-source/services4/srvkm/devices/sgx/sgxutils.c +++ /dev/null @@ -1,1914 +0,0 @@ -/*************************************************************************/ /*! -@Title Device specific utility routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ /**************************************************************************/ - -#include <stddef.h> - -#include "sgxdefs.h" -#include "services_headers.h" -#include "buffer_manager.h" -#include "sgx_bridge_km.h" -#include "sgxapi_km.h" -#include "sgxinfo.h" -#include "sgx_mkif_km.h" -#include "sysconfig.h" -#include "pdump_km.h" -#include "mmu.h" -#include "pvr_bridge_km.h" -#include "osfunc.h" -#include "pvr_debug.h" -#include "sgxutils.h" -#include "ttrace.h" - -#ifdef __linux__ -#include <linux/kernel.h> // sprintf -#include <linux/string.h> // strncpy, strlen -#else -#include <stdio.h> -#endif - -IMG_UINT64 ui64KickCount; - - -#if defined(SYS_CUSTOM_POWERDOWN) -PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID); -#endif - - - -/*! -****************************************************************************** - - @Function SGXPostActivePowerEvent - - @Description - - post power event functionality (e.g. restart) - - @Input psDeviceNode : SGX Device Node - @Input ui32CallerID - KERNEL_ID or ISR_ID - - @Return IMG_VOID : - -******************************************************************************/ -static IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32CallerID) -{ - PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; - - /* Update the counter for stats. */ - psSGXHostCtl->ui32NumActivePowerEvents++; - - if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0) - { - PVR_DPF((PVR_DBG_MESSAGE, "SGXPostActivePowerEvent: SGX requests immediate restart")); - - /* - Events were queued during the active power - request, so SGX will need to be restarted. - */ - if (ui32CallerID == ISR_ID) - { - psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; - } - else - { - SGXScheduleProcessQueuesKM(psDeviceNode); - } - } -} - - -/*! -****************************************************************************** - - @Function SGXTestActivePowerEvent - - @Description - - Checks whether the microkernel has generated an active power event. If so, - perform the power transition. - - @Input psDeviceNode : SGX Device Node - @Input ui32CallerID - KERNEL_ID or ISR_ID - - @Return IMG_VOID : - -******************************************************************************/ -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; - - /* - * Quickly check (without lock) if there is an IDLE or 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_IDLE) == 0) && - ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) != 0)) || - (((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; - } - else 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 IDLE 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_IDLE) == 0) && - ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) != 0)) - { - psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_IDLE; - if (psDevInfo->bSGXIdle == IMG_FALSE) - { - psDevInfo->bSGXIdle = IMG_TRUE; - SysSGXIdleEntered(); - } - } - - /* - * 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)) - { - /* Microkernel is idle and is requesting to be powered down. */ - psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER; - - /* Suspend pdumping. */ - PDUMPSUSPEND(); - -#if defined(SYS_CUSTOM_POWERDOWN) - /* - Some power down code cannot be executed inside an MISR on - some platforms that use mutexes inside the power code. - */ - eError = SysPowerDownMISR(psDeviceNode, ui32CallerID); -#else - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, - PVRSRV_DEV_POWER_STATE_OFF); -#endif - if (eError == PVRSRV_OK) - { - SGXPostActivePowerEvent(psDeviceNode, ui32CallerID); - } - /* Resume pdumping */ - PDUMPRESUME(); - } - - PVRSRVPowerUnlock(ui32CallerID); - } - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%u", eError)); - } -} - - -/****************************************************************************** - FUNCTION : SGXAcquireKernelCCBSlot - - PURPOSE : Attempts to obtain a slot in the Kernel CCB - - PARAMETERS : psCCB - the CCB - - RETURNS : Address of space if available, IMG_NULL otherwise -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(SGXAcquireKernelCCBSlot) -#endif -static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psCCB) -{ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - if(((*psCCB->pui32WriteOffset + 1) & 255) != *psCCB->pui32ReadOffset) - { - return &psCCB->psCommands[*psCCB->pui32WriteOffset]; - } - - OSSleepms(1); - } END_LOOP_UNTIL_TIMEOUT(); - - /* Time out on waiting for CCB space */ - return IMG_NULL; -} - -/*! -****************************************************************************** - - @Function SGXScheduleCCBCommand - - @Description - Submits a CCB command and kicks the ukernel (without - power management) - - @Input psDevInfo - pointer to device info - @Input eCmdType - see SGXMKIF_CMD_* - @Input psCommandData - kernel CCB command - @Input ui32CallerID - KERNEL_ID or ISR_ID - @Input ui32PDumpFlags - - @Return ui32Error - success or failure - -******************************************************************************/ -PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - SGXMKIF_CMD_TYPE eCmdType, - SGXMKIF_COMMAND *psCommandData, - IMG_UINT32 ui32CallerID, - IMG_UINT32 ui32PDumpFlags, - IMG_HANDLE hDevMemContext, - IMG_BOOL bLastInScene) -{ - PVRSRV_SGX_CCB_INFO *psKernelCCB; - PVRSRV_ERROR eError = PVRSRV_OK; - SGXMKIF_COMMAND *psSGXCommand; - PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; -#if defined(FIX_HW_BRN_31620) - IMG_UINT32 ui32CacheMasks[4]; - IMG_UINT32 i; - MMU_CONTEXT *psMMUContext; -#endif -#if defined(PDUMP) - IMG_VOID *pvDumpCommand; - IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended(); - IMG_BOOL bPersistentProcess = IMG_FALSE; -#else - PVR_UNREFERENCED_PARAMETER(ui32CallerID); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); -#endif - -#if defined(FIX_HW_BRN_31620) - for(i=0;i<4;i++) - { - ui32CacheMasks[i] = 0; - } - - psMMUContext = psDevInfo->hKernelMMUContext; - psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[0]); - - /* Put the apps memory context in the bottom half */ - if (hDevMemContext) - { - BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext; - - psMMUContext = psBMContext->psMMUContext; - psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[2]); - } - - /* If we have an outstanding flush request then set the cachecontrol bit */ - if (ui32CacheMasks[0] || ui32CacheMasks[1] || ui32CacheMasks[2] || ui32CacheMasks[3]) - { - psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD; - } -#endif - -#if defined(FIX_HW_BRN_28889) - /* - If the data cache and bif cache need invalidating there has been a cleanup - request. Therefore, we need to send the invalidate seperately and wait - for it to complete. - */ - if ( (eCmdType != SGXMKIF_CMD_PROCESS_QUEUES) && - ((psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_DATA) != 0) && - ((psDevInfo->ui32CacheControl & (SGXMKIF_CC_INVAL_BIF_PT | SGXMKIF_CC_INVAL_BIF_PD)) != 0)) - { - #if defined(PDUMP) - PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo; - #endif - SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; - SGXMKIF_COMMAND sCacheCommand = {0}; - - eError = SGXScheduleCCBCommand(psDeviceNode, - SGXMKIF_CMD_PROCESS_QUEUES, - &sCacheCommand, - ui32CallerID, - ui32PDumpFlags, - hDevMemContext, - bLastInScene); - if (eError != PVRSRV_OK) - { - goto Exit; - } - - /* Wait for the invalidate to happen */ - #if !defined(NO_HARDWARE) - if(PollForValueKM(&psSGXHostCtl->ui32InvalStatus, - PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE, - PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE, - 2 * MAX_HW_TIME_US, - MAX_HW_TIME_US/WAIT_TRY_COUNT, - IMG_FALSE) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommand: Wait for uKernel to Invalidate BIF cache failed")); - PVR_DBG_BREAK; - } - #endif - - #if defined(PDUMP) - /* Pdump the poll as well. */ - PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for BIF cache invalidate request to complete"); - PDUMPMEMPOL(psSGXHostCtlMemInfo, - offsetof(SGXMKIF_HOST_CTL, ui32InvalStatus), - PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE, - PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE, - PDUMP_POLL_OPERATOR_EQUAL, - 0, - MAKEUNIQUETAG(psSGXHostCtlMemInfo)); - #endif /* PDUMP */ - - psSGXHostCtl->ui32InvalStatus &= ~(PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE); - PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psSGXHostCtlMemInfo)); - } -#else - PVR_UNREFERENCED_PARAMETER(hDevMemContext); -#endif - -#if defined(FIX_HW_BRN_31620) - if ((eCmdType != SGXMKIF_CMD_FLUSHPDCACHE) && (psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_BIF_PD)) - { - SGXMKIF_COMMAND sPDECacheCommand = {0}; - IMG_DEV_PHYADDR sDevPAddr; - - /* Put the kernel info in the top 1/2 of the data */ - psMMUContext = psDevInfo->hKernelMMUContext; - - psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr); - sPDECacheCommand.ui32Data[0] = sDevPAddr.uiAddr | 1; - sPDECacheCommand.ui32Data[1] = ui32CacheMasks[0]; - sPDECacheCommand.ui32Data[2] = ui32CacheMasks[1]; - - /* Put the apps memory context in the bottom half */ - if (hDevMemContext) - { - BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext; - - psMMUContext = psBMContext->psMMUContext; - - psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr); - /* Or in 1 to the lsb to show we have a valid context */ - sPDECacheCommand.ui32Data[3] = sDevPAddr.uiAddr | 1; - sPDECacheCommand.ui32Data[4] = ui32CacheMasks[2]; - sPDECacheCommand.ui32Data[5] = ui32CacheMasks[3]; - } - - /* Only do a kick if there is any update */ - if (sPDECacheCommand.ui32Data[1] | sPDECacheCommand.ui32Data[2] | sPDECacheCommand.ui32Data[4] | - sPDECacheCommand.ui32Data[5]) - { - eError = SGXScheduleCCBCommand(psDeviceNode, - SGXMKIF_CMD_FLUSHPDCACHE, - &sPDECacheCommand, - ui32CallerID, - ui32PDumpFlags, - hDevMemContext, - bLastInScene); - if (eError != PVRSRV_OK) - { - goto Exit; - } - } - } -#endif -#if defined(PDUMP) - /* - * For persistent processes, the HW kicks should not go into the - * extended init phase; only keep memory transactions from the - * window system which are necessary to run the client app. - */ - { - PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); - if(psPerProc != IMG_NULL) - { - bPersistentProcess = psPerProc->bPDumpPersistent; - } - } -#endif /* PDUMP */ - psKernelCCB = psDevInfo->psKernelCCBInfo; - - psSGXCommand = SGXAcquireKernelCCBSlot(psKernelCCB); - - /* Wait for CCB space timed out */ - if(!psSGXCommand) - { - PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Wait for CCB space timed out")) ; - eError = PVRSRV_ERROR_TIMEOUT; - goto Exit; - } - - /* embed cache control word */ - psCommandData->ui32CacheControl = psDevInfo->ui32CacheControl; - -#if defined(PDUMP) - /* Accumulate any cache invalidates that may have happened */ - psDevInfo->sPDContext.ui32CacheControl |= psDevInfo->ui32CacheControl; -#endif - - /* and clear it */ - psDevInfo->ui32CacheControl = 0; - - /* Copy command data over */ - *psSGXCommand = *psCommandData; - - if (eCmdType >= SGXMKIF_CMD_MAX) - { - PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Unknown command type: %d", eCmdType)) ; - eError = PVRSRV_ERROR_INVALID_CCB_COMMAND; - goto Exit; - } - - if (eCmdType == SGXMKIF_CMD_2D || - eCmdType == SGXMKIF_CMD_TRANSFER || - ((eCmdType == SGXMKIF_CMD_TA) && bLastInScene)) - { - SYS_DATA *psSysData; - - /* CPU cache clean control */ - SysAcquireData(&psSysData); - - if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) - { - OSFlushCPUCacheKM(); - } - else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) - { - OSCleanCPUCacheKM(); - } - - /* Clear the pending op */ - psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE; - } - - PVR_ASSERT(eCmdType < SGXMKIF_CMD_MAX); - psSGXCommand->ui32ServiceAddress = psDevInfo->aui32HostKickAddr[eCmdType]; /* PRQA S 3689 */ /* misuse of enums for bounds checking */ - -#if defined(PDUMP) - if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) && - (bPersistentProcess == IMG_FALSE) ) - { - /* Poll for space in the CCB. */ - PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for space in the Kernel CCB\r\n"); - PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, - offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), - (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff, - 0xff, - PDUMP_POLL_OPERATOR_NOTEQUAL, - ui32PDumpFlags, - MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); - - PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB command (type == %d)\r\n", eCmdType); - pvDumpCommand = (IMG_VOID *)((IMG_UINT8 *)psKernelCCB->psCCBMemInfo->pvLinAddrKM + (*psKernelCCB->pui32WriteOffset * sizeof(SGXMKIF_COMMAND))); - - PDUMPMEM(pvDumpCommand, - psKernelCCB->psCCBMemInfo, - psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND), - sizeof(SGXMKIF_COMMAND), - ui32PDumpFlags, - MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo)); - - /* Overwrite cache control with pdump shadow */ - PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl, - psKernelCCB->psCCBMemInfo, - psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) + - offsetof(SGXMKIF_COMMAND, ui32CacheControl), - sizeof(IMG_UINT32), - ui32PDumpFlags, - MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo)); - - if (PDumpIsCaptureFrameKM() - || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) - { - /* Clear cache invalidate shadow */ - psDevInfo->sPDContext.ui32CacheControl = 0; - } - } -#endif - -#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) - /* Make sure the previous command has been read before send the next one */ - eError = PollForValueKM (psKernelCCB->pui32ReadOffset, - *psKernelCCB->pui32WriteOffset, - 0xFF, - MAX_HW_TIME_US, - MAX_HW_TIME_US/WAIT_TRY_COUNT, - IMG_FALSE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Timeout waiting for previous command to be read")) ; - eError = PVRSRV_ERROR_TIMEOUT; - goto Exit; - } -#endif - - /* - Increment the write offset - */ - *psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255; - -#if defined(PDUMP) - if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) && - (bPersistentProcess == IMG_FALSE) ) - { - #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) - PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for previous Kernel CCB CMD to be read\r\n"); - PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, - offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), - (psKernelCCB->ui32CCBDumpWOff), - 0xFF, - PDUMP_POLL_OPERATOR_EQUAL, - ui32PDumpFlags, - MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); - #endif - - if (PDumpIsCaptureFrameKM() - || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) - { - psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF; - psDevInfo->ui32KernelCCBEventKickerDumpVal = (psDevInfo->ui32KernelCCBEventKickerDumpVal + 1) & 0xFF; - } - - PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB write offset\r\n"); - PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff, - psKernelCCB->psCCBCtlMemInfo, - offsetof(PVRSRV_SGX_CCB_CTL, ui32WriteOffset), - sizeof(IMG_UINT32), - ui32PDumpFlags, - MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); - PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB event kicker\r\n"); - PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, - psDevInfo->psKernelCCBEventKickerMemInfo, - 0, - sizeof(IMG_UINT32), - ui32PDumpFlags, - MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); - PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kick the SGX microkernel\r\n"); - #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) - PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, ui32PDumpFlags); - #else - PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, ui32PDumpFlags); - #endif - } -#endif - - *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF; - - /* - * New command submission is considered a proper handling of any pending - * IDLE or APM event, so mark them as handled to prevent other host threads - * from taking action. - */ - psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_IDLE; - psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER; - - OSWriteMemoryBarrier(); - - /* Order is importent for post processor! */ - PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE, - MKSYNC_TOKEN_KERNEL_CCB_OFFSET, *psKernelCCB->pui32WriteOffset); - PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE, - MKSYNC_TOKEN_CORE_CLK, psDevInfo->ui32CoreClockSpeed); - PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE, - MKSYNC_TOKEN_UKERNEL_CLK, psDevInfo->ui32uKernelTimerClock); - - -#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) - OSWriteHWReg(psDevInfo->pvRegsBaseKM, - SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), - EUR_CR_EVENT_KICK2_NOW_MASK); -#else - OSWriteHWReg(psDevInfo->pvRegsBaseKM, - SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), - EUR_CR_EVENT_KICK_NOW_MASK); -#endif - - OSMemoryBarrier(); - -#if defined(NO_HARDWARE) - /* Increment read offset */ - *psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255; -#endif - - ui64KickCount++; -Exit: - return eError; -} - - -/*! -****************************************************************************** - - @Function SGXScheduleCCBCommandKM - - @Description - Submits a CCB command and kicks the ukernel - - @Input psDeviceNode - pointer to SGX device node - @Input eCmdType - see SGXMKIF_CMD_* - @Input psCommandData - kernel CCB command - @Input ui32CallerID - KERNEL_ID or ISR_ID - @Input ui32PDumpFlags - - @Return ui32Error - success or failure - -******************************************************************************/ -PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, - SGXMKIF_CMD_TYPE eCmdType, - SGXMKIF_COMMAND *psCommandData, - IMG_UINT32 ui32CallerID, - IMG_UINT32 ui32PDumpFlags, - IMG_HANDLE hDevMemContext, - IMG_BOOL bLastInScene) -{ - PVRSRV_ERROR eError; - PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); - if (eError == PVRSRV_ERROR_RETRY) - { - if (ui32CallerID == ISR_ID) - { - SYS_DATA *psSysData; - - /* - ISR failed to acquire lock so it must be held by a kernel thread. - Bring up and kick SGX if necessary when the lock is available. - */ - psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; - eError = PVRSRV_OK; - - SysAcquireData(&psSysData); - OSScheduleMISR(psSysData); - } - else - { - /* - Return to srvclient for retry. - */ - } - - return eError; - } - else if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - " - "ui32CallerID:%d eError:%u", ui32CallerID, eError)); - return eError; - } - - /* Note that a power-up has been dumped in the init phase. */ - PDUMPSUSPEND(); - - /* Ensure that SGX is powered up before kicking the ukernel. */ - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, - PVRSRV_DEV_POWER_STATE_ON); - - PDUMPRESUME(); - - if (eError == PVRSRV_OK) - { - psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE; - } - else - { - PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - " - "ui32CallerID:%d eError:%u", ui32CallerID, eError)); - return eError; - } - - SysSGXCommandPending(psDevInfo->bSGXIdle); - psDevInfo->bSGXIdle = IMG_FALSE; - - eError = SGXScheduleCCBCommand(psDeviceNode, eCmdType, psCommandData, ui32CallerID, ui32PDumpFlags, hDevMemContext, bLastInScene); - - PVRSRVPowerUnlock(ui32CallerID); - return eError; -} - - -/*! -****************************************************************************** - - @Function SGXScheduleProcessQueuesKM - - @Description - Software command complete handler - - @Input psDeviceNode - SGX device node - -******************************************************************************/ -PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - SGXMKIF_HOST_CTL *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; - IMG_UINT32 ui32PowerStatus; - SGXMKIF_COMMAND sCommand = {0}; - - ui32PowerStatus = psHostCtl->ui32PowerStatus; - if ((ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0) - { - /* The ukernel has no work to do so don't waste power. */ - return PVRSRV_OK; - } - - eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0, IMG_NULL, IMG_FALSE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %u", eError)); - return eError; - } - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function SGXIsDevicePowered - - @Description - - Whether the device is powered, for the purposes of lockup detection. - - @Input psDeviceNode - pointer to device node - - @Return IMG_BOOL : Whether device is powered - -******************************************************************************/ -IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex); -} - -/*! -******************************************************************************* - - @Function SGXGetInternalDevInfoKM - - @Description - Gets device information that is not intended to be passed - on beyond the srvclient libs. - - @Input hDevCookie - - @Output psSGXInternalDevInfo - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie, -#if defined (SUPPORT_SID_INTERFACE) - SGX_INTERNAL_DEVINFO_KM *psSGXInternalDevInfo) -#else - SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo) -#endif -{ - PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; - - psSGXInternalDevInfo->ui32Flags = psDevInfo->ui32Flags; - psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff; - - /* This should be patched up by OS bridge code */ - psSGXInternalDevInfo->hHostCtlKernelMemInfoHandle = - (IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo; - - return PVRSRV_OK; -} - - -/***************************************************************************** - FUNCTION : SGXCleanupRequest - - PURPOSE : Wait for the microkernel to clean up its references to either a - render context or render target. - - PARAMETERS : psDeviceNode - SGX device node - psHWDataDevVAddr - Device Address of the resource - ui32CleanupType - PVRSRV_CLEANUPCMD_* - bForceCleanup - Skips sync polling - - RETURNS : error status -*****************************************************************************/ -PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEV_VIRTADDR *psHWDataDevVAddr, - IMG_UINT32 ui32CleanupType, - IMG_BOOL bForceCleanup) -{ - PVRSRV_ERROR eError; - PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_KERNEL_MEM_INFO *psHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo; - SGXMKIF_HOST_CTL *psHostCtl = psHostCtlMemInfo->pvLinAddrKM; - - SGXMKIF_COMMAND sCommand = {0}; - - - if (bForceCleanup != FORCE_CLEANUP) - { - sCommand.ui32Data[0] = ui32CleanupType; - sCommand.ui32Data[1] = (psHWDataDevVAddr == IMG_NULL) ? 0 : psHWDataDevVAddr->uiAddr; - PDUMPCOMMENTWITHFLAGS(0, "Request ukernel resource clean-up, Type %u, Data 0x%X", sCommand.ui32Data[0], sCommand.ui32Data[1]); - - eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CLEANUP, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command")); - SGXDumpDebugInfo(psDevInfo, IMG_FALSE); - PVR_DBG_BREAK; - return eError; - } - - /* Wait for the uKernel process the cleanup request */ - #if !defined(NO_HARDWARE) - if(PollForValueKM(&psHostCtl->ui32CleanupStatus, - PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, - PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, - 10 * MAX_HW_TIME_US, - 1000, - IMG_TRUE) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up (%u) failed", ui32CleanupType)); - eError = PVRSRV_ERROR_TIMEOUT; - SGXDumpDebugInfo(psDevInfo, IMG_FALSE); - PVR_DBG_BREAK; - } - #endif - - #if defined(PDUMP) - /* - Pdump the poll as well. - Note: - We don't expect the cleanup to report busy as the client should have - ensured the the resource has been finished with before requesting - it's cleanup. This isn't true of the abnormal termination case but - we don't expect to PDump that. Unless/until PDump has flow control - there isn't anything else we can do. - */ - 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_DONE, - PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE, - PDUMP_POLL_OPERATOR_EQUAL, - 0, - MAKEUNIQUETAG(psHostCtlMemInfo)); - #endif /* PDUMP */ - - if (eError != PVRSRV_OK) - { - return eError; - } - } - - if (psHostCtl->ui32CleanupStatus & PVRSRV_USSE_EDM_CLEANUPCMD_BUSY) - { - /* Only one flag should be set */ - 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); - } - - PDUMPMEM(IMG_NULL, psHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHostCtlMemInfo)); - - /* Request the cache invalidate */ -#if defined(SGX_FEATURE_SYSTEM_CACHE) - psDevInfo->ui32CacheControl |= (SGXMKIF_CC_INVAL_BIF_SL | SGXMKIF_CC_INVAL_DATA); -#else - psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_DATA; -#endif - return eError; -} - - -typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_ -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_KERNEL_MEM_INFO *psHWRenderContextMemInfo; - IMG_HANDLE hBlockAlloc; - PRESMAN_ITEM psResItem; - IMG_BOOL bCleanupTimerRunning; - IMG_PVOID pvTimeData; -} SGX_HW_RENDER_CONTEXT_CLEANUP; - - -static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bForceCleanup) -{ - PVRSRV_ERROR eError; - SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup = pvParam; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - - eError = SGXCleanupRequest(psCleanup->psDeviceNode, - &psCleanup->psHWRenderContextMemInfo->sDevVAddr, - PVRSRV_CLEANUPCMD_RC, - bForceCleanup); - - 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) - { - /* Free the Device Mem allocated */ - PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode, - psCleanup->psHWRenderContextMemInfo); - - /* Finally, free the cleanup structure itself */ - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), - psCleanup, - psCleanup->hBlockAlloc); - /*not nulling pointer, copy on stack*/ - } - - return eError; -} - -typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_ -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_KERNEL_MEM_INFO *psHWTransferContextMemInfo; - IMG_HANDLE hBlockAlloc; - PRESMAN_ITEM psResItem; - IMG_BOOL bCleanupTimerRunning; - IMG_PVOID pvTimeData; -} SGX_HW_TRANSFER_CONTEXT_CLEANUP; - - -static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bForceCleanup) -{ - PVRSRV_ERROR eError; - SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - - eError = SGXCleanupRequest(psCleanup->psDeviceNode, - &psCleanup->psHWTransferContextMemInfo->sDevVAddr, - PVRSRV_CLEANUPCMD_TC, - bForceCleanup); - - 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) - { - /* Free the Device Mem allocated */ - PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode, - psCleanup->psHWTransferContextMemInfo); - - /* Finally, free the cleanup structure itself */ - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), - psCleanup, - psCleanup->hBlockAlloc); - /*not nulling pointer, copy on stack*/ - } - - return eError; -} - -IMG_EXPORT -IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE hDeviceNode, - IMG_CPU_VIRTADDR *psHWRenderContextCpuVAddr, - IMG_UINT32 ui32HWRenderContextSize, - IMG_UINT32 ui32OffsetToPDDevPAddr, - IMG_HANDLE hDevMemContext, - IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr, - PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - PVRSRV_ERROR eError; - IMG_HANDLE hBlockAlloc; - SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode; - DEVICE_MEMORY_INFO *psDevMemoryInfo; - DEVICE_MEMORY_HEAP_INFO *psHeapInfo; - IMG_HANDLE hDevMemContextInt; - MMU_CONTEXT *psMMUContext; - IMG_DEV_PHYADDR sPDDevPAddr; - int iPtrByte; - IMG_UINT8 *pSrc; - IMG_UINT8 *pDst; - PRESMAN_ITEM psResItem; - - eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), - (IMG_VOID **)&psCleanup, - &hBlockAlloc, - "SGX Hardware Render Context Cleanup"); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure")); - goto exit0; - } - - psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; - psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID]; - - eError = PVRSRVAllocDeviceMemKM(hDeviceNode, - psPerProc, - psHeapInfo->hDevMemHeap, - PVRSRV_MEM_READ | PVRSRV_MEM_WRITE - | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT - | PVRSRV_MEM_CACHE_CONSISTENT, - ui32HWRenderContextSize, - 32, - IMG_NULL, - 0, - 0,0,0,IMG_NULL, /* No sparse mapping data */ - &psCleanup->psHWRenderContextMemInfo, - "HW Render Context"); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate device memory for HW Render Context")); - goto exit1; - } - - eError = OSCopyFromUser(psPerProc, - psCleanup->psHWRenderContextMemInfo->pvLinAddrKM, - psHWRenderContextCpuVAddr, - ui32HWRenderContextSize); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't copy user-mode copy of HWContext into device memory")); - goto exit2; - } - - /* Pass the DevVAddr of the new context back up through the bridge */ - psHWRenderContextDevVAddr->uiAddr = psCleanup->psHWRenderContextMemInfo->sDevVAddr.uiAddr; - - /* Retrieve the PDDevPAddr */ - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevMemContextInt, - hDevMemContext, - PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Can't lookup DevMem Context")); - goto exit2; - } - - psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt); - sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext); - - /* - patch-in the Page-Directory Device-Physical address. Note that this is - copied-in one byte at a time, as we have no guarantee that the usermode- - provided ui32OffsetToPDDevPAddr is a validly-aligned address for the - current CPU architecture. - */ - pSrc = (IMG_UINT8 *)&sPDDevPAddr; - pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM; - pDst += ui32OffsetToPDDevPAddr; - - for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++) - { - pDst[iPtrByte] = pSrc[iPtrByte]; - } - -#if defined(PDUMP) - /* PDUMP the HW context */ - PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Render context struct"); - - PDUMPMEM( - IMG_NULL, - psCleanup->psHWRenderContextMemInfo, - 0, - ui32HWRenderContextSize, - PDUMP_FLAGS_CONTINUOUS, - MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo)); - - /* PDUMP the PDDevPAddr */ - PDUMPCOMMENT("Page directory address in HW render context"); - PDUMPPDDEVPADDR( - psCleanup->psHWRenderContextMemInfo, - ui32OffsetToPDDevPAddr, - sPDDevPAddr, - MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo), - PDUMP_PD_UNIQUETAG); -#endif - - psCleanup->hBlockAlloc = hBlockAlloc; - psCleanup->psDeviceNode = psDeviceNode; - psCleanup->bCleanupTimerRunning = IMG_FALSE; - - psResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_HW_RENDER_CONTEXT, - (IMG_VOID *)psCleanup, - 0, - &SGXCleanupHWRenderContextCallback); - - if (psResItem == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed")); - goto exit2; - } - - psCleanup->psResItem = psResItem; - - return (IMG_HANDLE)psCleanup; - -/* Error exit paths */ -exit2: - PVRSRVFreeDeviceMemKM(hDeviceNode, - psCleanup->psHWRenderContextMemInfo); -exit1: - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), - psCleanup, - psCleanup->hBlockAlloc); - /*not nulling pointer, out of scope*/ -exit0: - return IMG_NULL; -} - -IMG_EXPORT -PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOOL bForceCleanup) -{ - PVRSRV_ERROR eError; - SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; - - PVR_ASSERT(hHWRenderContext != IMG_NULL); - - psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext; - - if (psCleanup == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWRenderContextKM: invalid parameter")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup); - - return eError; -} - - -IMG_EXPORT -IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE hDeviceNode, - IMG_CPU_VIRTADDR *psHWTransferContextCpuVAddr, - IMG_UINT32 ui32HWTransferContextSize, - IMG_UINT32 ui32OffsetToPDDevPAddr, - IMG_HANDLE hDevMemContext, - IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr, - PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - PVRSRV_ERROR eError; - IMG_HANDLE hBlockAlloc; - SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode; - DEVICE_MEMORY_INFO *psDevMemoryInfo; - DEVICE_MEMORY_HEAP_INFO *psHeapInfo; - IMG_HANDLE hDevMemContextInt; - MMU_CONTEXT *psMMUContext; - IMG_DEV_PHYADDR sPDDevPAddr; - int iPtrByte; - IMG_UINT8 *pSrc; - IMG_UINT8 *pDst; - PRESMAN_ITEM psResItem; - - eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), - (IMG_VOID **)&psCleanup, - &hBlockAlloc, - "SGX Hardware Transfer Context Cleanup"); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure")); - goto exit0; - } - - psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; - psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID]; - - eError = PVRSRVAllocDeviceMemKM(hDeviceNode, - psPerProc, - psHeapInfo->hDevMemHeap, - PVRSRV_MEM_READ | PVRSRV_MEM_WRITE - | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT - | PVRSRV_MEM_CACHE_CONSISTENT, - ui32HWTransferContextSize, - 32, - IMG_NULL, - 0, - 0,0,0,IMG_NULL, /* No sparse mapping data */ - &psCleanup->psHWTransferContextMemInfo, - "HW Render Context"); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate device memory for HW Render Context")); - goto exit1; - } - - eError = OSCopyFromUser(psPerProc, - psCleanup->psHWTransferContextMemInfo->pvLinAddrKM, - psHWTransferContextCpuVAddr, - ui32HWTransferContextSize); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't copy user-mode copy of HWContext into device memory")); - goto exit2; - } - - /* Pass the DevVAddr of the new context back up through the bridge */ - psHWTransferContextDevVAddr->uiAddr = psCleanup->psHWTransferContextMemInfo->sDevVAddr.uiAddr; - - /* Retrieve the PDDevPAddr */ - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevMemContextInt, - hDevMemContext, - PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Can't lookup DevMem Context")); - goto exit2; - } - - psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt); - sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext); - - /* - patch-in the Page-Directory Device-Physical address. Note that this is - copied-in one byte at a time, as we have no guarantee that the usermode- - provided ui32OffsetToPDDevPAddr is a validly-aligned address for the - current CPU architecture. - */ - pSrc = (IMG_UINT8 *)&sPDDevPAddr; - pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM; - pDst += ui32OffsetToPDDevPAddr; - - for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++) - { - pDst[iPtrByte] = pSrc[iPtrByte]; - } - -#if defined(PDUMP) - /* PDUMP the HW Transfer Context */ - PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Transfer context struct"); - - PDUMPMEM( - IMG_NULL, - psCleanup->psHWTransferContextMemInfo, - 0, - ui32HWTransferContextSize, - PDUMP_FLAGS_CONTINUOUS, - MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo)); - - /* PDUMP the PDDevPAddr */ - PDUMPCOMMENT("Page directory address in HW transfer context"); - - PDUMPPDDEVPADDR( - psCleanup->psHWTransferContextMemInfo, - ui32OffsetToPDDevPAddr, - sPDDevPAddr, - MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo), - PDUMP_PD_UNIQUETAG); -#endif - - psCleanup->hBlockAlloc = hBlockAlloc; - psCleanup->psDeviceNode = psDeviceNode; - psCleanup->bCleanupTimerRunning = IMG_FALSE; - - psResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_HW_TRANSFER_CONTEXT, - psCleanup, - 0, - &SGXCleanupHWTransferContextCallback); - - if (psResItem == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed")); - goto exit2; - } - - psCleanup->psResItem = psResItem; - - return (IMG_HANDLE)psCleanup; - -/* Error exit paths */ -exit2: - PVRSRVFreeDeviceMemKM(hDeviceNode, - psCleanup->psHWTransferContextMemInfo); -exit1: - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), - psCleanup, - psCleanup->hBlockAlloc); - /*not nulling pointer, out of scope*/ - -exit0: - return IMG_NULL; -} - -IMG_EXPORT -PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup) -{ - PVRSRV_ERROR eError; - SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; - - PVR_ASSERT(hHWTransferContext != IMG_NULL); - - psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext; - - if (psCleanup == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWTransferContextKM: invalid parameter")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup); - - return eError; -} - -IMG_EXPORT -PVRSRV_ERROR SGXSetTransferContextPriorityKM( - IMG_HANDLE hDeviceNode, - IMG_HANDLE hHWTransferContext, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32OffsetOfPriorityField) -{ - SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; - IMG_UINT8 *pSrc; - IMG_UINT8 *pDst; - int iPtrByte; - PVR_UNREFERENCED_PARAMETER(hDeviceNode); - - if (hHWTransferContext != IMG_NULL) - { - psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext; - - if ((ui32OffsetOfPriorityField + sizeof(ui32Priority)) - >= psCleanup->psHWTransferContextMemInfo->uAllocSize) - { - PVR_DPF(( - PVR_DBG_ERROR, - "SGXSetTransferContextPriorityKM: invalid context prioirty offset")); - - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* - cannot be sure that offset (passed from user-land) is safe to deref - as a word-ptr on current CPU arch: copy one byte at a time. - */ - pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM; - pDst += ui32OffsetOfPriorityField; - pSrc = (IMG_UINT8 *)&ui32Priority; - - for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++) - { - pDst[iPtrByte] = pSrc[iPtrByte]; - } - } - return PVRSRV_OK; -} - -IMG_EXPORT -PVRSRV_ERROR SGXSetRenderContextPriorityKM( - IMG_HANDLE hDeviceNode, - IMG_HANDLE hHWRenderContext, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32OffsetOfPriorityField) -{ - SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; - IMG_UINT8 *pSrc; - IMG_UINT8 *pDst; - int iPtrByte; - PVR_UNREFERENCED_PARAMETER(hDeviceNode); - - if (hHWRenderContext != IMG_NULL) - { - psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext; - if ((ui32OffsetOfPriorityField + sizeof(ui32Priority)) - >= psCleanup->psHWRenderContextMemInfo->uAllocSize) - { - PVR_DPF(( - PVR_DBG_ERROR, - "SGXSetContextPriorityKM: invalid HWRenderContext prioirty offset")); - - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* - cannot be sure that offset (passed from user-land) is safe to deref - as a word-ptr on current CPU arch: copy one byte at a time. - */ - pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM; - pDst += ui32OffsetOfPriorityField; - - pSrc = (IMG_UINT8 *)&ui32Priority; - - for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++) - { - pDst[iPtrByte] = pSrc[iPtrByte]; - } - } - return PVRSRV_OK; -} - -#if defined(SGX_FEATURE_2D_HARDWARE) -typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_ -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - 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, - IMG_UINT32 ui32Param, - IMG_BOOL bForceCleanup) -{ - PVRSRV_ERROR eError; - SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - - /* First, ensure the context is no longer being utilised */ - eError = SGXCleanupRequest(psCleanup->psDeviceNode, - &psCleanup->psHW2DContextMemInfo->sDevVAddr, - PVRSRV_CLEANUPCMD_2DC, - bForceCleanup); - - 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) - { - /* Free the Device Mem allocated */ - PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode, - psCleanup->psHW2DContextMemInfo); - - /* Finally, free the cleanup structure itself */ - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(SGX_HW_2D_CONTEXT_CLEANUP), - psCleanup, - psCleanup->hBlockAlloc); - /*not nulling pointer, copy on stack*/ - } - return eError; -} - -IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE hDeviceNode, - IMG_CPU_VIRTADDR *psHW2DContextCpuVAddr, - IMG_UINT32 ui32HW2DContextSize, - IMG_UINT32 ui32OffsetToPDDevPAddr, - IMG_HANDLE hDevMemContext, - IMG_DEV_VIRTADDR *psHW2DContextDevVAddr, - PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - PVRSRV_ERROR eError; - IMG_HANDLE hBlockAlloc; - SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode; - DEVICE_MEMORY_INFO *psDevMemoryInfo; - DEVICE_MEMORY_HEAP_INFO *psHeapInfo; - IMG_HANDLE hDevMemContextInt; - MMU_CONTEXT *psMMUContext; - IMG_DEV_PHYADDR sPDDevPAddr; - int iPtrByte; - IMG_UINT8 *pSrc; - IMG_UINT8 *pDst; - PRESMAN_ITEM psResItem; - - eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(SGX_HW_2D_CONTEXT_CLEANUP), - (IMG_VOID **)&psCleanup, - &hBlockAlloc, - "SGX Hardware 2D Context Cleanup"); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure")); - goto exit0; - } - - psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; - psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID]; - - eError = PVRSRVAllocDeviceMemKM(hDeviceNode, - psPerProc, - psHeapInfo->hDevMemHeap, - PVRSRV_MEM_READ | PVRSRV_MEM_WRITE - | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT - | PVRSRV_MEM_CACHE_CONSISTENT, - ui32HW2DContextSize, - 32, - IMG_NULL, - 0, - 0,0,0,IMG_NULL, /* No sparse mapping data */ - &psCleanup->psHW2DContextMemInfo, - "HW 2D Context"); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate device memory for HW Render Context")); - goto exit1; - } - - eError = OSCopyFromUser(psPerProc, - psCleanup->psHW2DContextMemInfo->pvLinAddrKM, - psHW2DContextCpuVAddr, - ui32HW2DContextSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't copy user-mode copy of HWContext into device memory")); - goto exit2; - } - - /* Pass the DevVAddr of the new context back up through the bridge */ - psHW2DContextDevVAddr->uiAddr = psCleanup->psHW2DContextMemInfo->sDevVAddr.uiAddr; - - /* Retrieve the PDDevPAddr */ - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevMemContextInt, - hDevMemContext, - PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Can't lookup DevMem Context")); - goto exit2; - } - - psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt); - sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext); - - /* - patch-in the Page-Directory Device-Physical address. Note that this is - copied-in one byte at a time, as we have no guarantee that the usermode- - provided ui32OffsetToPDDevPAddr is a validly-aligned address for the - current CPU architecture. - */ - pSrc = (IMG_UINT8 *)&sPDDevPAddr; - pDst = (IMG_UINT8 *)psCleanup->psHW2DContextMemInfo->pvLinAddrKM; - pDst += ui32OffsetToPDDevPAddr; - - for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++) - { - pDst[iPtrByte] = pSrc[iPtrByte]; - } - -#if defined(PDUMP) - /* PDUMP the HW 2D Context */ - PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW 2D context struct"); - - PDUMPMEM( - IMG_NULL, - psCleanup->psHW2DContextMemInfo, - 0, - ui32HW2DContextSize, - PDUMP_FLAGS_CONTINUOUS, - MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo)); - - /* PDUMP the PDDevPAddr */ - PDUMPCOMMENT("Page directory address in HW 2D transfer context"); - PDUMPPDDEVPADDR( - psCleanup->psHW2DContextMemInfo, - ui32OffsetToPDDevPAddr, - sPDDevPAddr, - MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo), - PDUMP_PD_UNIQUETAG); -#endif - - psCleanup->hBlockAlloc = hBlockAlloc; - psCleanup->psDeviceNode = psDeviceNode; - psCleanup->bCleanupTimerRunning = IMG_FALSE; - - psResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_HW_2D_CONTEXT, - psCleanup, - 0, - &SGXCleanupHW2DContextCallback); - - if (psResItem == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed")); - goto exit2; - } - - psCleanup->psResItem = psResItem; - - return (IMG_HANDLE)psCleanup; - -/* Error exit paths */ -exit2: - PVRSRVFreeDeviceMemKM(hDeviceNode, - psCleanup->psHW2DContextMemInfo); -exit1: - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(SGX_HW_2D_CONTEXT_CLEANUP), - psCleanup, - psCleanup->hBlockAlloc); - /*not nulling pointer, out of scope*/ -exit0: - return IMG_NULL; -} - -IMG_EXPORT -PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext, IMG_BOOL bForceCleanup) -{ - PVRSRV_ERROR eError; - SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; - - PVR_ASSERT(hHW2DContext != IMG_NULL); - - if (hHW2DContext == IMG_NULL) - { - return (PVRSRV_ERROR_INVALID_PARAMS); - } - - psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)hHW2DContext; - - eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup); - - return eError; -} -#endif /* #if defined(SGX_FEATURE_2D_HARDWARE)*/ - -/*!**************************************************************************** - @Function SGX2DQuerySyncOpsCompleteKM - - @Input psSyncInfo : Sync object to be queried - - @Return IMG_TRUE - ops complete, IMG_FALSE - ops pending - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(SGX2DQuerySyncOpsComplete) -#endif -static INLINE -IMG_BOOL SGX2DQuerySyncOpsComplete(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, - IMG_UINT32 ui32ReadOpsPending, - IMG_UINT32 ui32WriteOpsPending) -{ - PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; - - return (IMG_BOOL)( - (psSyncData->ui32ReadOpsComplete >= ui32ReadOpsPending) && - (psSyncData->ui32WriteOpsComplete >= ui32WriteOpsPending) - ); -} - -/*!**************************************************************************** - @Function SGX2DQueryBlitsCompleteKM - - @Input psDevInfo : SGX device info structure - - @Input psSyncInfo : Sync object to be queried - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo, - PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, - IMG_BOOL bWaitForComplete) -{ - IMG_UINT32 ui32ReadOpsPending, ui32WriteOpsPending; - - PVR_UNREFERENCED_PARAMETER(psDevInfo); - - PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Start")); - - ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending; - ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending; - - if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending)) - { - /* Instant success */ - PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Blits complete.")); - return PVRSRV_OK; - } - - /* Not complete yet */ - if (!bWaitForComplete) - { - /* Just report not complete */ - PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Ops pending.")); - return PVRSRV_ERROR_CMD_NOT_PROCESSED; - } - - /* Start polling */ - PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling.")); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - OSSleepms(1); - - if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending)) - { - /* Success */ - PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over. Blits complete.")); - return PVRSRV_OK; - } - - OSSleepms(1); - } END_LOOP_UNTIL_TIMEOUT(); - - /* Timed out */ - PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending.")); - -#if defined(DEBUG) - { - PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; - - PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: 0x%x, Syncdata: 0x%x", - (IMG_UINTPTR_T)psSyncInfo, (IMG_UINTPTR_T)psSyncData)); - - PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Read ops complete: %d, Read ops pending: %d", psSyncData->ui32ReadOpsComplete, psSyncData->ui32ReadOpsPending)); - PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Write ops complete: %d, Write ops pending: %d", psSyncData->ui32WriteOpsComplete, psSyncData->ui32WriteOpsPending)); - - } -#endif - - return PVRSRV_ERROR_TIMEOUT; -} - - -IMG_EXPORT -PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode, - IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr, - IMG_BOOL bForceCleanup) -{ - PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL); - - return SGXCleanupRequest(psDeviceNode, - &sHWRTDataSetDevVAddr, - PVRSRV_CLEANUPCMD_RT, - bForceCleanup); -} - - -IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32TimeWraps, - IMG_UINT32 ui32Time) -{ -#if defined(EUR_CR_TIMER) - PVR_UNREFERENCED_PARAMETER(psDevInfo); - PVR_UNREFERENCED_PARAMETER(ui32TimeWraps); - return ui32Time; -#else - IMG_UINT64 ui64Clocks; - IMG_UINT32 ui32Clocksx16; - - ui64Clocks = ((IMG_UINT64)ui32TimeWraps * psDevInfo->ui32uKernelTimerClock) + - (psDevInfo->ui32uKernelTimerClock - (ui32Time & EUR_CR_EVENT_TIMER_VALUE_MASK)); - ui32Clocksx16 = (IMG_UINT32)(ui64Clocks / 16); - - return ui32Clocksx16; -#endif /* EUR_CR_TIMER */ -} - - -IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32SGXClocks) -{ - /* - Round up to the next microsecond. - */ - OSWaitus(1 + (ui32SGXClocks * 1000000 / psDevInfo->ui32CoreClockSpeed)); -} - - - -/****************************************************************************** - End of file (sgxutils.c) -******************************************************************************/ |