diff options
Diffstat (limited to 'pvr-source/services4/srvkm/common/queue.c')
-rwxr-xr-x | pvr-source/services4/srvkm/common/queue.c | 1503 |
1 files changed, 0 insertions, 1503 deletions
diff --git a/pvr-source/services4/srvkm/common/queue.c b/pvr-source/services4/srvkm/common/queue.c deleted file mode 100755 index 09892e3..0000000 --- a/pvr-source/services4/srvkm/common/queue.c +++ /dev/null @@ -1,1503 +0,0 @@ -/*************************************************************************/ /*! -@Title Kernel side command queue functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@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 "services_headers.h" -#include "pvr_bridge_km.h" - -#include "lists.h" -#include "ttrace.h" - -/* - * The number of commands of each type which can be in flight at once. - */ -#if defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) -#define DC_NUM_COMMANDS_PER_TYPE 2 -#else -#define DC_NUM_COMMANDS_PER_TYPE 1 -#endif - -/* - * List of private command processing function pointer tables and command - * complete tables for a device in the system. - * Each table is allocated when the device registers its private command - * processing functions. - */ -typedef struct _DEVICE_COMMAND_DATA_ -{ - PFN_CMD_PROC pfnCmdProc; - PCOMMAND_COMPLETE_DATA apsCmdCompleteData[DC_NUM_COMMANDS_PER_TYPE]; - IMG_UINT32 ui32CCBOffset; - IMG_UINT32 ui32MaxDstSyncCount; /*!< Maximum number of dest syncs */ - IMG_UINT32 ui32MaxSrcSyncCount; /*!< Maximum number of source syncs */ -} DEVICE_COMMAND_DATA; - - -#if defined(__linux__) && defined(__KERNEL__) - -#include "proc.h" - -/***************************************************************************** - FUNCTION : ProcSeqShowQueue - - PURPOSE : Print the content of queue element to /proc file - (See env/linux/proc.c:CreateProcReadEntrySeq) - - PARAMETERS : sfile - /proc seq_file - el - Element to print -*****************************************************************************/ -void ProcSeqShowQueue(struct seq_file *sfile,void* el) -{ - PVRSRV_QUEUE_INFO *psQueue = (PVRSRV_QUEUE_INFO*)el; - IMG_INT cmds = 0; - IMG_SIZE_T ui32ReadOffset; - IMG_SIZE_T ui32WriteOffset; - PVRSRV_COMMAND *psCmd; - - if(el == PVR_PROC_SEQ_START_TOKEN) - { - seq_printf( sfile, - "Command Queues\n" - "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n"); - return; - } - - ui32ReadOffset = psQueue->ui32ReadOffset; - ui32WriteOffset = psQueue->ui32WriteOffset; - - while (ui32ReadOffset != ui32WriteOffset) - { - psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset); - - seq_printf(sfile, "%x %x %5u %6u %3u %5u %2u %2u %3u \n", - (IMG_UINTPTR_T)psQueue, - (IMG_UINTPTR_T)psCmd, - psCmd->ui32ProcessID, - psCmd->CommandType, - psCmd->uCmdSize, - psCmd->ui32DevIndex, - psCmd->ui32DstSyncCount, - psCmd->ui32SrcSyncCount, - psCmd->uDataSize); - { - IMG_UINT32 i; - for (i = 0; i < psCmd->ui32SrcSyncCount; i++) - { - PVRSRV_SYNC_DATA *psSyncData = psCmd->psSrcSync[i].psKernelSyncInfoKM->psSyncData; - seq_printf(sfile, " Sync %u: ROP/ROC: 0x%x/0x%x WOP/WOC: 0x%x/0x%x ROC-VA: 0x%x WOC-VA: 0x%x\n", - i, - psCmd->psSrcSync[i].ui32ReadOps2Pending, - psSyncData->ui32ReadOps2Complete, - psCmd->psSrcSync[i].ui32WriteOpsPending, - psSyncData->ui32WriteOpsComplete, - psCmd->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmd->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr); - } - } - - /* taken from UPDATE_QUEUE_ROFF in queue.h */ - ui32ReadOffset += psCmd->uCmdSize; - ui32ReadOffset &= psQueue->ui32QueueSize - 1; - cmds++; - } - - if (cmds == 0) - { - seq_printf(sfile, "%x <empty>\n", (IMG_UINTPTR_T)psQueue); - } -} - -/***************************************************************************** - FUNCTION : ProcSeqOff2ElementQueue - - PURPOSE : Transale offset to element (/proc stuff) - - PARAMETERS : sfile - /proc seq_file - off - the offset into the buffer - - RETURNS : element to print -*****************************************************************************/ -void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off) -{ - PVRSRV_QUEUE_INFO *psQueue = IMG_NULL; - SYS_DATA *psSysData; - - PVR_UNREFERENCED_PARAMETER(sfile); - - if(!off) - { - return PVR_PROC_SEQ_START_TOKEN; - } - - - psSysData = SysAcquireDataNoCheck(); - if (psSysData != IMG_NULL) - { - for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM); - } - - return psQueue; -} -#endif /* __linux__ && __KERNEL__ */ - -/*! - * Macro to return space in given command queue - */ -#define GET_SPACE_IN_CMDQ(psQueue) \ - ((((psQueue)->ui32ReadOffset - (psQueue)->ui32WriteOffset) \ - + ((psQueue)->ui32QueueSize - 1)) & ((psQueue)->ui32QueueSize - 1)) - -/*! - * Macro to Write Offset in given command queue - */ -#define UPDATE_QUEUE_WOFF(psQueue, ui32Size) \ - (psQueue)->ui32WriteOffset = ((psQueue)->ui32WriteOffset + (ui32Size)) \ - & ((psQueue)->ui32QueueSize - 1); - -/*! - * Check if an ops complete value has gone past the pending value. - * This can happen when dummy processing multiple operations, e.g. hardware recovery. - */ -#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \ - ((ui32OpsComplete) >= (ui32OpsPending)) - -/*! -**************************************************************************** - @Function : PVRSRVGetWriteOpsPending - - @Description : Gets the next operation to wait for in a sync object - - @Input : psSyncInfo - pointer to sync information struct - @Input : bIsReadOp - Is this a read or write op - - @Return : Next op value -*****************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVGetWriteOpsPending) -#endif -static INLINE -IMG_UINT32 PVRSRVGetWriteOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp) -{ - IMG_UINT32 ui32WriteOpsPending; - - if(bIsReadOp) - { - ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending; - } - else - { - /* - Note: This needs to be atomic and is provided the - kernel driver is single threaded (non-rentrant) - */ - ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending++; - } - - return ui32WriteOpsPending; -} - -/*! -***************************************************************************** - @Function : PVRSRVGetReadOpsPending - - @Description : Gets the number of pending read ops - - @Input : psSyncInfo - pointer to sync information struct - @Input : bIsReadOp - Is this a read or write op - - @Return : Next op value -*****************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVGetReadOpsPending) -#endif -static INLINE -IMG_UINT32 PVRSRVGetReadOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp) -{ - IMG_UINT32 ui32ReadOpsPending; - - if(bIsReadOp) - { - ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOps2Pending++; - } - else - { - ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOps2Pending; - } - - return ui32ReadOpsPending; -} - -static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData, - IMG_UINT32 i, - IMG_BOOL bIsSrc) -{ - PVRSRV_SYNC_OBJECT *psSyncObject; - - psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync; - - if (psCmdCompleteData->bInUse) - { - PVR_LOG(("\t%s %u: ROC DevVAddr:0x%X ROP:0x%x ROC:0x%x, WOC DevVAddr:0x%X WOP:0x%x WOC:0x%x", - bIsSrc ? "SRC" : "DEST", i, - psSyncObject[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Pending, - psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete, - psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending, - psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete)) - } - else - { - PVR_LOG(("\t%s %u: (Not in use)", bIsSrc ? "SRC" : "DEST", i)) - } -} - - -static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY) - { - IMG_UINT32 ui32CmdCounter, ui32SyncCounter; - SYS_DATA *psSysData; - DEVICE_COMMAND_DATA *psDeviceCommandData; - PCOMMAND_COMPLETE_DATA psCmdCompleteData; - - SysAcquireData(&psSysData); - - psDeviceCommandData = psSysData->apsDeviceCommandData[psDeviceNode->sDevId.ui32DeviceIndex]; - - if (psDeviceCommandData != IMG_NULL) - { - for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++) - { - psCmdCompleteData = psDeviceCommandData[DC_FLIP_COMMAND].apsCmdCompleteData[ui32CmdCounter]; - - PVR_LOG(("Flip Command Complete Data %u for display device %u:", - ui32CmdCounter, psDeviceNode->sDevId.ui32DeviceIndex)) - - for (ui32SyncCounter = 0; - ui32SyncCounter < psCmdCompleteData->ui32SrcSyncCount; - ui32SyncCounter++) - { - QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_TRUE); - } - - for (ui32SyncCounter = 0; - ui32SyncCounter < psCmdCompleteData->ui32DstSyncCount; - ui32SyncCounter++) - { - QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_FALSE); - } - } - } - else - { - PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex)) - } - } -} - - -IMG_VOID QueueDumpDebugInfo(IMG_VOID) -{ - SYS_DATA *psSysData; - SysAcquireData(&psSysData); - List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, &QueueDumpDebugInfo_ForEachCb); -} - - -/***************************************************************************** - Kernel-side functions of User->Kernel transitions -******************************************************************************/ - -static IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value) -{ - IMG_SIZE_T ui32Temp, ui32Result = 1; - - if(!ui32Value) - return 0; - - ui32Temp = ui32Value - 1; - while(ui32Temp) - { - ui32Result <<= 1; - ui32Temp >>= 1; - } - - return ui32Result; -} - - -/*! -****************************************************************************** - - @Function PVRSRVCreateCommandQueueKM - - @Description - Creates a new command queue into which render/blt commands etc can be - inserted. - - @Input ui32QueueSize : - - @Output ppsQueueInfo : - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize, - PVRSRV_QUEUE_INFO **ppsQueueInfo) -{ - PVRSRV_QUEUE_INFO *psQueueInfo; - IMG_SIZE_T ui32Power2QueueSize = NearestPower2(ui32QueueSize); - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - IMG_HANDLE hMemBlock; - - SysAcquireData(&psSysData); - - /* allocate an internal queue info structure */ - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_QUEUE_INFO), - (IMG_VOID **)&psQueueInfo, &hMemBlock, - "Queue Info"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct")); - goto ErrorExit; - } - OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO)); - - psQueueInfo->hMemBlock[0] = hMemBlock; - psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); - - /* allocate the command queue buffer - allow for overrun */ - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE, - &psQueueInfo->pvLinQueueKM, &hMemBlock, - "Command Queue"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer")); - goto ErrorExit; - } - - psQueueInfo->hMemBlock[1] = hMemBlock; - psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM; - - /* Sanity check: Should be zeroed by OSMemSet */ - PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0); - PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0); - - psQueueInfo->ui32QueueSize = ui32Power2QueueSize; - - /* if this is the first q, create a lock resource for the q list */ - if (psSysData->psQueueList == IMG_NULL) - { - eError = OSCreateResource(&psSysData->sQProcessResource); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - } - - /* Ensure we don't corrupt queue list, by blocking access */ - eError = OSLockResource(&psSysData->sQProcessResource, - KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - - psQueueInfo->psNextKM = psSysData->psQueueList; - psSysData->psQueueList = psQueueInfo; - - eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - - *ppsQueueInfo = psQueueInfo; - - return PVRSRV_OK; - -ErrorExit: - - if(psQueueInfo) - { - if(psQueueInfo->pvLinQueueKM) - { - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - psQueueInfo->ui32QueueSize, - psQueueInfo->pvLinQueueKM, - psQueueInfo->hMemBlock[1]); - psQueueInfo->pvLinQueueKM = IMG_NULL; - } - - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_QUEUE_INFO), - psQueueInfo, - psQueueInfo->hMemBlock[0]); - /*not nulling pointer, out of scope*/ - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVDestroyCommandQueueKM - - @Description Destroys a command queue - - @Input psQueueInfo : - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo) -{ - PVRSRV_QUEUE_INFO *psQueue; - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - IMG_BOOL bTimeout = IMG_TRUE; - - SysAcquireData(&psSysData); - - psQueue = psSysData->psQueueList; - - /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset) - { - bTimeout = IMG_FALSE; - break; - } - OSSleepms(1); - } END_LOOP_UNTIL_TIMEOUT(); - - if (bTimeout) - { - /* The command queue could not be flushed within the timeout period. - Allow the queue to be destroyed before returning the error code. */ - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue")); - eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE; - goto ErrorExit; - } - - /* Ensure we don't corrupt queue list, by blocking access */ - eError = OSLockResource(&psSysData->sQProcessResource, - KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - - if(psQueue == psQueueInfo) - { - psSysData->psQueueList = psQueueInfo->psNextKM; - - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - NearestPower2(psQueueInfo->ui32QueueSize) + PVRSRV_MAX_CMD_SIZE, - psQueueInfo->pvLinQueueKM, - psQueueInfo->hMemBlock[1]); - psQueueInfo->pvLinQueueKM = IMG_NULL; - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_QUEUE_INFO), - psQueueInfo, - psQueueInfo->hMemBlock[0]); - /* PRQA S 3199 1 */ /* see note */ - psQueueInfo = IMG_NULL; /*it's a copy on stack, but null it because the function doesn't end right here*/ - } - else - { - while(psQueue) - { - if(psQueue->psNextKM == psQueueInfo) - { - psQueue->psNextKM = psQueueInfo->psNextKM; - - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - psQueueInfo->ui32QueueSize, - psQueueInfo->pvLinQueueKM, - psQueueInfo->hMemBlock[1]); - psQueueInfo->pvLinQueueKM = IMG_NULL; - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_QUEUE_INFO), - psQueueInfo, - psQueueInfo->hMemBlock[0]); - /* PRQA S 3199 1 */ /* see note */ - psQueueInfo = IMG_NULL; /*it's a copy on stack, but null it because the function doesn't end right here*/ - break; - } - psQueue = psQueue->psNextKM; - } - - if(!psQueue) - { - eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto ErrorExit; - } - } - - /* unlock the Q list lock resource */ - eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - - /* if the Q list is now empty, destroy the Q list lock resource */ - if (psSysData->psQueueList == IMG_NULL) - { - eError = OSDestroyResource(&psSysData->sQProcessResource); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - } - -ErrorExit: - - return eError; -} - - -/*! -***************************************************************************** - - @Function : PVRSRVGetQueueSpaceKM - - @Description : Waits for queue access rights and checks for available space in - queue for task param structure - - @Input : psQueue - pointer to queue information struct - @Input : ui32ParamSize - size of task data structure - @Output : ppvSpace - - @Return : PVRSRV_ERROR -*****************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue, - IMG_SIZE_T ui32ParamSize, - IMG_VOID **ppvSpace) -{ - IMG_BOOL bTimeout = IMG_TRUE; - - /* round to 4byte units */ - ui32ParamSize = (ui32ParamSize+3) & 0xFFFFFFFC; - - if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE) - { - PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE)); - return PVRSRV_ERROR_CMD_TOO_BIG; - } - - /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize) - { - bTimeout = IMG_FALSE; - break; - } - OSSleepms(1); - } END_LOOP_UNTIL_TIMEOUT(); - - if (bTimeout == IMG_TRUE) - { - *ppvSpace = IMG_NULL; - - return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE; - } - else - { - *ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset); - } - - return PVRSRV_OK; -} - - -/*! -***************************************************************************** - @Function PVRSRVInsertCommandKM - - @Description : - command insertion utility - - waits for space in the queue for a new command - - fills in generic command information - - returns a pointer to the caller who's expected to then fill - in the private data. - The caller should follow PVRSRVInsertCommand with PVRSRVSubmitCommand - which will update the queue's write offset so the command can be - executed. - - @Input psQueue : pointer to queue information struct - - @Output ppvCmdData : holds pointer to space in queue for private cmd data - - @Return PVRSRV_ERROR -*****************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue, - PVRSRV_COMMAND **ppsCommand, - IMG_UINT32 ui32DevIndex, - IMG_UINT16 CommandType, - IMG_UINT32 ui32DstSyncCount, - PVRSRV_KERNEL_SYNC_INFO *apsDstSync[], - IMG_UINT32 ui32SrcSyncCount, - PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[], - IMG_SIZE_T ui32DataByteSize, - PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete, - IMG_HANDLE hCallbackData) -{ - PVRSRV_ERROR eError; - PVRSRV_COMMAND *psCommand; - IMG_SIZE_T ui32CommandSize; - IMG_UINT32 i; - SYS_DATA *psSysData; - DEVICE_COMMAND_DATA *psDeviceCommandData; - - /* Check that we've got enough space in our command complete data for this command */ - SysAcquireData(&psSysData); - psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex]; - - if ((psDeviceCommandData[CommandType].ui32MaxDstSyncCount < ui32DstSyncCount) || - (psDeviceCommandData[CommandType].ui32MaxSrcSyncCount < ui32SrcSyncCount)) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVInsertCommandKM: Too many syncs")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Round up to nearest 32 bit size so pointer arithmetic works */ - ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL; - - /* calc. command size */ - ui32CommandSize = sizeof(PVRSRV_COMMAND) - + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT)) - + ui32DataByteSize; - - /* wait for space in queue */ - eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand); - if(eError != PVRSRV_OK) - { - return eError; - } - - psCommand->ui32ProcessID = OSGetCurrentProcessIDKM(); - - /* setup the command */ - psCommand->uCmdSize = ui32CommandSize; /* this may change if cmd shrinks */ - psCommand->ui32DevIndex = ui32DevIndex; - psCommand->CommandType = CommandType; - psCommand->ui32DstSyncCount = ui32DstSyncCount; - psCommand->ui32SrcSyncCount = ui32SrcSyncCount; - /* override QAC warning about stricter pointers */ - /* PRQA S 3305 END_PTR_ASSIGNMENTS */ - psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND)); - - - psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync) - + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); - - psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync) - + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); -/* PRQA L:END_PTR_ASSIGNMENTS */ - - psCommand->uDataSize = ui32DataByteSize;/* this may change if cmd shrinks */ - - psCommand->pfnCommandComplete = pfnCommandComplete; - psCommand->hCallbackData = hCallbackData; - - PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_START, QUEUE_TOKEN_INSERTKM); - PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_NONE, - QUEUE_TOKEN_COMMAND_TYPE, CommandType); - - /* setup dst sync objects and their sync dependencies */ - for (i=0; i<ui32DstSyncCount; i++) - { - PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC, - apsDstSync[i], PVRSRV_SYNCOP_SAMPLE); - - psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i]; - psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE); - psCommand->psDstSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE); - - PVRSRVKernelSyncInfoIncRef(apsDstSync[i], IMG_NULL); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", - i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCommand->psDstSync[i].ui32ReadOps2Pending, - psCommand->psDstSync[i].ui32WriteOpsPending)); - } - - /* setup src sync objects and their sync dependencies */ - for (i=0; i<ui32SrcSyncCount; i++) - { - PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC, - apsSrcSync[i], PVRSRV_SYNCOP_SAMPLE); - - psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i]; - psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE); - psCommand->psSrcSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE); - - PVRSRVKernelSyncInfoIncRef(apsSrcSync[i], IMG_NULL); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", - i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCommand->psSrcSync[i].ui32ReadOps2Pending, - psCommand->psSrcSync[i].ui32WriteOpsPending)); - } - PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_END, QUEUE_TOKEN_INSERTKM); - - /* return pointer to caller to fill out private data */ - *ppsCommand = psCommand; - - return PVRSRV_OK; -} - - -/*! -******************************************************************************* - @Function : PVRSRVSubmitCommandKM - - @Description : - updates the queue's write offset so the command can be executed. - - @Input : psQueue - queue command is in - @Input : psCommand - - @Return : PVRSRV_ERROR -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue, - PVRSRV_COMMAND *psCommand) -{ - /* override QAC warnings about stricter pointers */ - /* PRQA S 3305 END_PTR_ASSIGNMENTS2 */ - /* patch pointers in the command to be kernel pointers */ - if (psCommand->ui32DstSyncCount > 0) - { - psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM) - + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)); - } - - if (psCommand->ui32SrcSyncCount > 0) - { - psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM) - + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND) - + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); - } - - psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM) - + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND) - + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)) - + (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); - -/* PRQA L:END_PTR_ASSIGNMENTS2 */ - - /* update write offset before releasing access lock */ - UPDATE_QUEUE_WOFF(psQueue, psCommand->uCmdSize); - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function CheckIfSyncIsQueued - - @Description Check if the specificed sync object is already queued and - can safely be given to the display controller. - This check is required as a 3rd party displayclass device can - have several flips "in flight" and we need to ensure that we - keep their pipeline full and don't deadlock waiting for them - to complete an operation on a surface. - - @Input psSysData : system data - @Input psCmdData : COMMAND_COMPLETE_DATA structure - - @Return PVRSRV_ERROR - -******************************************************************************/ -static -PVRSRV_ERROR CheckIfSyncIsQueued(PVRSRV_SYNC_OBJECT *psSync, COMMAND_COMPLETE_DATA *psCmdData) -{ - IMG_UINT32 k; - - if (psCmdData->bInUse) - { - for (k=0;k<psCmdData->ui32SrcSyncCount;k++) - { - if (psSync->psKernelSyncInfoKM == psCmdData->psSrcSync[k].psKernelSyncInfoKM) - { - PVRSRV_SYNC_DATA *psSyncData = psSync->psKernelSyncInfoKM->psSyncData; - IMG_UINT32 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; - - /* - We still need to ensure that we don't we don't give a command - to the display controller if writes are outstanding on it - */ - if (ui32WriteOpsComplete == psSync->ui32WriteOpsPending) - { - return PVRSRV_OK; - } - else - { - if (SYNCOPS_STALE(ui32WriteOpsComplete, psSync->ui32WriteOpsPending)) - { - PVR_DPF((PVR_DBG_WARNING, - "CheckIfSyncIsQueued: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x", - (IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psSync->ui32WriteOpsPending)); - return PVRSRV_OK; - } - } - } - } - } - return PVRSRV_ERROR_FAILED_DEPENDENCIES; -} - -/*! -****************************************************************************** - - @Function PVRSRVProcessCommand - - @Description Tries to process a command - - @Input psSysData : system data - @Input psCommand : PVRSRV_COMMAND structure - @Input bFlush : Check for stale dependencies (only used for HW recovery) - - @Return PVRSRV_ERROR - -******************************************************************************/ -static -PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA *psSysData, - PVRSRV_COMMAND *psCommand, - IMG_BOOL bFlush) -{ - PVRSRV_SYNC_OBJECT *psWalkerObj; - PVRSRV_SYNC_OBJECT *psEndObj; - IMG_UINT32 i; - COMMAND_COMPLETE_DATA *psCmdCompleteData; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32WriteOpsComplete; - IMG_UINT32 ui32ReadOpsComplete; - DEVICE_COMMAND_DATA *psDeviceCommandData; - IMG_UINT32 ui32CCBOffset; - - /* satisfy sync dependencies on the DST(s) */ - psWalkerObj = psCommand->psDstSync; - psEndObj = psWalkerObj + psCommand->ui32DstSyncCount; - while (psWalkerObj < psEndObj) - { - PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData; - - ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; - ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete; - /* fail if reads or writes are not up to date */ - if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending) - || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending)) - { - if (!bFlush || - !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) || - !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending)) - { - return PVRSRV_ERROR_FAILED_DEPENDENCIES; - } - } - - psWalkerObj++; - } - - /* satisfy sync dependencies on the SRC(s) */ - psWalkerObj = psCommand->psSrcSync; - psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount; - while (psWalkerObj < psEndObj) - { - PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData; - - ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete; - ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; - /* fail if writes are not up to date */ - if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending) - || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending)) - { - if (!bFlush && - SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) && - SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending)) - { - PVR_DPF((PVR_DBG_WARNING, - "PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x", - (IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending)); - } - - if (!bFlush || - !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) || - !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending)) - { - IMG_UINT32 j; - PVRSRV_ERROR eError; - IMG_BOOL bFound = IMG_FALSE; - - psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex]; - for (j=0;j<DC_NUM_COMMANDS_PER_TYPE;j++) - { - eError = CheckIfSyncIsQueued(psWalkerObj, psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[j]); - - if (eError == PVRSRV_OK) - { - bFound = IMG_TRUE; - } - } - if (!bFound) - return PVRSRV_ERROR_FAILED_DEPENDENCIES; - } - } - psWalkerObj++; - } - - /* validate device type */ - if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVProcessCommand: invalid DeviceType 0x%x", - psCommand->ui32DevIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* fish out the appropriate storage structure for the duration of the command */ - psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex]; - ui32CCBOffset = psDeviceCommandData[psCommand->CommandType].ui32CCBOffset; - psCmdCompleteData = psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[ui32CCBOffset]; - if (psCmdCompleteData->bInUse) - { - /* can use this to protect against concurrent execution of same command */ - return PVRSRV_ERROR_FAILED_DEPENDENCIES; - } - - /* mark the structure as in use */ - psCmdCompleteData->bInUse = IMG_TRUE; - - /* copy src updates over */ - psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount; - for (i=0; i<psCommand->ui32DstSyncCount; i++) - { - psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i]; - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)", - i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending, - psCmdCompleteData->psDstSync[i].ui32WriteOpsPending, - ui32CCBOffset)); - } - - psCmdCompleteData->pfnCommandComplete = psCommand->pfnCommandComplete; - psCmdCompleteData->hCallbackData = psCommand->hCallbackData; - - /* copy dst updates over */ - psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount; - for (i=0; i<psCommand->ui32SrcSyncCount; i++) - { - psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i]; - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)", - i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending, - psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending, - ui32CCBOffset)); - } - - /* - call the cmd specific handler: - it should: - - check the cmd specific dependencies - - setup private cmd complete structure - - execute cmd on HW - - store psCmdCompleteData `cookie' and later pass as - argument to Generic Command Complete Callback - - n.b. ui32DataSize (packet size) is useful for packet validation - */ - if (psDeviceCommandData[psCommand->CommandType].pfnCmdProc((IMG_HANDLE)psCmdCompleteData, - (IMG_UINT32)psCommand->uDataSize, - psCommand->pvData) == IMG_FALSE) - { - /* - clean-up: - free cmd complete structure - */ - psCmdCompleteData->bInUse = IMG_FALSE; - eError = PVRSRV_ERROR_CMD_NOT_PROCESSED; - PVR_LOG(("Failed to submit command from queue processor, this could cause sync wedge!")); - } - else - { - /* Increment the CCB offset */ - psDeviceCommandData[psCommand->CommandType].ui32CCBOffset = (ui32CCBOffset + 1) % DC_NUM_COMMANDS_PER_TYPE; - } - - return eError; -} - - -static IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (psDeviceNode->bReProcessDeviceCommandComplete && - psDeviceNode->pfnDeviceCommandComplete != IMG_NULL) - { - (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode); - } -} - -/*! -****************************************************************************** - - @Function PVRSRVProcessQueues - - @Description Tries to process a command from each Q - - @input ui32CallerID - used to distinguish between async ISR/DPC type calls - the synchronous services driver - @input bFlush - flush commands with stale dependencies (only used for HW recovery) - - @Return PVRSRV_ERROR - -******************************************************************************/ - -IMG_EXPORT -PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL bFlush) -{ - PVRSRV_QUEUE_INFO *psQueue; - SYS_DATA *psSysData; - PVRSRV_COMMAND *psCommand; -/* PVRSRV_DEVICE_NODE *psDeviceNode;*/ - - SysAcquireData(&psSysData); - - /* Ensure we don't corrupt queue list, by blocking access. This is required for OSs where - multiple ISR threads may exist simultaneously (eg WinXP DPC routines) - */ - while (OSLockResource(&psSysData->sQProcessResource, ISR_ID) != PVRSRV_OK) - { - OSWaitus(1); - }; - - psQueue = psSysData->psQueueList; - - if(!psQueue) - { - PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands")); - } - - if (bFlush) - { - PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS); - } - - while (psQueue) - { - while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset) - { - psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset); - - if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK) - { - /* processed cmd so update queue */ - UPDATE_QUEUE_ROFF(psQueue, psCommand->uCmdSize) - continue; - } - - break; - } - psQueue = psQueue->psNextKM; - } - - if (bFlush) - { - PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS); - } - - /* Re-process command complete handlers if necessary. */ - List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, - &PVRSRVProcessQueues_ForEachCb); - - OSUnlockResource(&psSysData->sQProcessResource, ISR_ID); - - return PVRSRV_OK; -} - -#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) -/*! -****************************************************************************** - - @Function PVRSRVCommandCompleteKM - - @Description Updates non-private command complete sync objects - - @Input hCmdCookie : command cookie - @Input bScheduleMISR : obsolete parameter - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_INTERNAL -IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie, - IMG_BOOL bScheduleMISR) -{ - COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie; - SYS_DATA *psSysData; - - PVR_UNREFERENCED_PARAMETER(bScheduleMISR); - - SysAcquireData(&psSysData); - - /* free command complete storage */ - psCmdCompleteData->bInUse = IMG_FALSE; - - /* FIXME: This may cause unrelated devices to be woken up. */ - PVRSRVScheduleDeviceCallbacks(); - - /* the MISR is always scheduled, regardless of bScheduleMISR */ - OSScheduleMISR(psSysData); -} - -#endif /* (SUPPORT_CUSTOM_SWAP_OPERATIONS) */ - -#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) -extern void sgxfreq_notif_sgx_frame_done(void); -#endif /* (SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ - -/*! -****************************************************************************** - - @Function PVRSRVCommandCompleteKM - - @Description Updates non-private command complete sync objects - - @Input hCmdCookie : command cookie - @Input bScheduleMISR : boolean to schedule MISR - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, - IMG_BOOL bScheduleMISR) -{ - IMG_UINT32 i; - COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie; - SYS_DATA *psSysData; - -#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) - sgxfreq_notif_sgx_frame_done(); -#endif /* (SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ - - SysAcquireData(&psSysData); - - PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_START, - QUEUE_TOKEN_COMMAND_COMPLETE); - - /* update DST(s) syncs */ - for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++) - { - psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++; - - PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM, IMG_NULL); - - PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST, - psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM, - PVRSRV_SYNCOP_COMPLETE); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", - i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending, - psCmdCompleteData->psDstSync[i].ui32WriteOpsPending)); - } - - /* update SRC(s) syncs */ - for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++) - { - psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete++; - - PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM, IMG_NULL); - - PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC, - psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM, - PVRSRV_SYNCOP_COMPLETE); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", - i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending, - psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending)); - } - - PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_END, - QUEUE_TOKEN_COMMAND_COMPLETE); - - if (psCmdCompleteData->pfnCommandComplete) - { - psCmdCompleteData->pfnCommandComplete(psCmdCompleteData->hCallbackData); - } - - /* free command complete storage */ - psCmdCompleteData->bInUse = IMG_FALSE; - - /* FIXME: This may cause unrelated devices to be woken up. */ - PVRSRVScheduleDeviceCallbacks(); - - if(bScheduleMISR) - { - OSScheduleMISR(psSysData); - } -} - - - - -/*! -****************************************************************************** - - @Function PVRSRVRegisterCmdProcListKM - - @Description - - registers a list of private command processing functions with the Command - Queue Manager - - @Input ui32DevIndex : device index - - @Input ppfnCmdProcList : function ptr table of private command processors - - @Input ui32MaxSyncsPerCmd : max number of syncobjects used by command - - @Input ui32CmdCount : number of entries in function ptr table - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex, - PFN_CMD_PROC *ppfnCmdProcList, - IMG_UINT32 ui32MaxSyncsPerCmd[][2], - IMG_UINT32 ui32CmdCount) -{ - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - IMG_UINT32 ui32CmdCounter, ui32CmdTypeCounter; - IMG_SIZE_T ui32AllocSize; - DEVICE_COMMAND_DATA *psDeviceCommandData; - COMMAND_COMPLETE_DATA *psCmdCompleteData; - - /* validate device type */ - if(ui32DevIndex >= SYS_DEVICE_COUNT) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x", - ui32DevIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* acquire system data structure */ - SysAcquireData(&psSysData); - - /* array of pointers for each command store */ - ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData); - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - ui32AllocSize, - (IMG_VOID **)&psDeviceCommandData, IMG_NULL, - "Array of Pointers for Command Store"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data")); - goto ErrorExit; - } - - psSysData->apsDeviceCommandData[ui32DevIndex] = psDeviceCommandData; - - for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++) - { - psDeviceCommandData[ui32CmdTypeCounter].pfnCmdProc = ppfnCmdProcList[ui32CmdTypeCounter]; - psDeviceCommandData[ui32CmdTypeCounter].ui32CCBOffset = 0; - psDeviceCommandData[ui32CmdTypeCounter].ui32MaxDstSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]; - psDeviceCommandData[ui32CmdTypeCounter].ui32MaxSrcSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1]; - for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++) - { - /* - allocate storage for the sync update on command complete - */ - ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA) /* space for one GENERIC_CMD_COMPLETE */ - + ((ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0] - + ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1]) - * sizeof(PVRSRV_SYNC_OBJECT)); /* space for max sync objects */ - - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - ui32AllocSize, - (IMG_VOID **)&psCmdCompleteData, - IMG_NULL, - "Command Complete Data"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d", ui32CmdTypeCounter)); - goto ErrorExit; - } - - psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = psCmdCompleteData; - - /* clear memory */ - OSMemSet(psCmdCompleteData, 0x00, ui32AllocSize); - - /* setup sync pointers */ - psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*) - (((IMG_UINTPTR_T)psCmdCompleteData) - + sizeof(COMMAND_COMPLETE_DATA)); - psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*) - (((IMG_UINTPTR_T)psCmdCompleteData->psDstSync) - + (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0])); - - psCmdCompleteData->ui32AllocSize = (IMG_UINT32)ui32AllocSize; - } - } - - return PVRSRV_OK; - -ErrorExit: - - /* clean-up if things went wrong */ - if (PVRSRVRemoveCmdProcListKM(ui32DevIndex, ui32CmdCount) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVRegisterCmdProcListKM: Failed to clean up after error, device 0x%x", - ui32DevIndex)); - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVRemoveCmdProcListKM - - @Description - - removes a list of private command processing functions and data from the - Queue Manager - - @Input ui32DevIndex : device index - - @Input ui32CmdCount : number of entries in function ptr table - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex, - IMG_UINT32 ui32CmdCount) -{ - SYS_DATA *psSysData; - IMG_UINT32 ui32CmdTypeCounter, ui32CmdCounter; - DEVICE_COMMAND_DATA *psDeviceCommandData; - COMMAND_COMPLETE_DATA *psCmdCompleteData; - IMG_SIZE_T ui32AllocSize; - - /* validate device type */ - if(ui32DevIndex >= SYS_DEVICE_COUNT) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x", - ui32DevIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* acquire system data structure */ - SysAcquireData(&psSysData); - - psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex]; - if(psDeviceCommandData != IMG_NULL) - { - for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++) - { - for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++) - { - psCmdCompleteData = psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter]; - - /* free the cmd complete structure array entries */ - if (psCmdCompleteData != IMG_NULL) - { - PVR_ASSERT(psCmdCompleteData->bInUse == IMG_FALSE); - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize, - psCmdCompleteData, IMG_NULL); - psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL; - } - } - } - - /* free the cmd complete structure array for the device */ - ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData); - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psDeviceCommandData, IMG_NULL); - psSysData->apsDeviceCommandData[ui32DevIndex] = IMG_NULL; - } - - return PVRSRV_OK; -} - -/****************************************************************************** - End of file (queue.c) -******************************************************************************/ |