/********************************************************************** * * Copyright (C) Imagination Technologies Ltd. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful but, except * as otherwise stated in writing, without any warranty; without even the * implied warranty of merchantability or fitness for a particular purpose. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * The full GNU General Public License is included in this distribution in * the file called "COPYING". * * Contact Information: * Imagination Technologies Ltd. * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK * ******************************************************************************/ #if defined(TRANSFER_QUEUE) #include #include "sgxdefs.h" #include "services_headers.h" #include "buffer_manager.h" #include "sgxinfo.h" #include "sysconfig.h" #include "pdump_km.h" #include "mmu.h" #include "pvr_bridge.h" #include "sgx_bridge_km.h" #include "sgxinfokm.h" #include "osfunc.h" #include "pvr_debug.h" #include "sgxutils.h" #include "ttrace.h" #if defined (SUPPORT_SID_INTERFACE) IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK_KM *psKick) #else IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick) #endif { PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; SGXMKIF_COMMAND sCommand = {0}; SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_ERROR eError; IMG_UINT32 loop; IMG_HANDLE hDevMemContext = IMG_NULL; IMG_BOOL abSrcSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS]; IMG_UINT32 ui32RealSrcSyncNum = 0; IMG_BOOL abDstSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS]; IMG_UINT32 ui32RealDstSyncNum = 0; #if defined(PDUMP) IMG_BOOL bPersistentProcess = IMG_FALSE; { PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); if(psPerProc != IMG_NULL) { bPersistentProcess = psPerProc->bPDumpPersistent; } } #endif #if defined(FIX_HW_BRN_31620) hDevMemContext = psKick->hDevMemContext; #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, TRANSFER_TOKEN_SUBMIT); for (loop = 0; loop < SGX_MAX_TRANSFER_SYNC_OPS; loop++) { abSrcSyncEnable[loop] = IMG_TRUE; abDstSyncEnable[loop] = IMG_TRUE; } if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset")); PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, TRANSFER_TOKEN_SUBMIT); return PVRSRV_ERROR_INVALID_PARAMS; } psSharedTransferCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_START, TRANSFER_TOKEN_SUBMIT); PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CCB, TRANSFER_TOKEN_CCB_OFFSET, psKick->ui32SharedCmdCCBOffset); if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_TA_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psSharedTransferCmd->ui32TASyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } else { psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0; psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_3D_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } else { psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0; psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0; } for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumSrcSync); loop++) { IMG_UINT32 i; PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; for (i = 0; i < loop; i++) { if (abSrcSyncEnable[i]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr) { PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same src synchronized multiple times!")); abSrcSyncEnable[loop] = IMG_FALSE; break; } } } if (abSrcSyncEnable[loop]) { ui32RealSrcSyncNum++; } } for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumDstSync); loop++) { IMG_UINT32 i; PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; for (i = 0; i < loop; i++) { if (abDstSyncEnable[i]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i]; if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr) { PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same dst synchronized multiple times!")); abDstSyncEnable[loop] = IMG_FALSE; break; } } } if (abDstSyncEnable[loop]) { ui32RealDstSyncNum++; } } psSharedTransferCmd->ui32NumSrcSyncs = ui32RealSrcSyncNum; psSharedTransferCmd->ui32NumDstSyncs = ui32RealDstSyncNum; if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { IMG_UINT32 i = 0; for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_SRC_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; psSharedTransferCmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; i++; } } PVR_ASSERT(i == ui32RealSrcSyncNum); i = 0; for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_DST_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->asDstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; psSharedTransferCmd->asDstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->asDstSyncs[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; psSharedTransferCmd->asDstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->asDstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psSharedTransferCmd->asDstSyncs[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; i++; } } PVR_ASSERT(i == ui32RealDstSyncNum); for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsPending++; } } for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsPending++; } } } #if defined(PDUMP) if ((PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) && (bPersistentProcess == IMG_FALSE) ) { PDUMPCOMMENT("Shared part of transfer command\r\n"); PDUMPMEM(psSharedTransferCmd, psCCBMemInfo, psKick->ui32CCBDumpWOff, sizeof(SGXMKIF_TRANSFERCMD_SHARED), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { IMG_UINT32 i = 0; for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = psKick->ahSrcSyncInfo[loop]; PDUMPCOMMENT("Hack src surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack src surface read op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); i++; } } i = 0; for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[i]) { IMG_UINT32 ui32PDumpReadOp2 = 0; psSyncInfo = psKick->ahDstSyncInfo[loop]; PDUMPCOMMENT("Hack dest surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack dest surface read op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack dest surface read op2 in transfer cmd\r\n"); PDUMPMEM(&ui32PDumpReadOp2, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal)), sizeof(ui32PDumpReadOp2), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); i++; } } for (loop = 0; loop < (psKick->ui32NumSrcSync); loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } } for (loop = 0; loop < (psKick->ui32NumDstSync); loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = psKick->hTASyncInfo; PDUMPCOMMENT("Tweak TA/TQ surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32TASyncWriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastOpDumpVal++; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = psKick->h3DSyncInfo; PDUMPCOMMENT("Tweak 3D/TQ surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui323DSyncWriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } #endif sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr; PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_END, TRANSFER_TOKEN_SUBMIT); eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE); if (eError == PVRSRV_ERROR_RETRY) { if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsPending--; #if defined(PDUMP) if (PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) { psSyncInfo->psSyncData->ui32LastReadOpDumpVal--; } #endif } } for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsPending--; #if defined(PDUMP) if (PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) { psSyncInfo->psSyncData->ui32LastOpDumpVal--; } #endif } } } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } } else if (PVRSRV_OK != eError) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed.")); PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, TRANSFER_TOKEN_SUBMIT); return eError; } #if defined(NO_HARDWARE) if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0) { for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } } for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, TRANSFER_TOKEN_SUBMIT); return eError; } #if defined(SGX_FEATURE_2D_HARDWARE) #if defined (SUPPORT_SID_INTERFACE) IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK_KM *psKick) #else IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick) #endif { PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; SGXMKIF_COMMAND sCommand = {0}; SGXMKIF_2DCMD_SHARED *ps2DCmd; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_ERROR eError; IMG_UINT32 i; IMG_HANDLE hDevMemContext = IMG_NULL; #if defined(PDUMP) IMG_BOOL bPersistentProcess = IMG_FALSE; { PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); if(psPerProc != IMG_NULL) { bPersistentProcess = psPerProc->bPDumpPersistent; } } #endif #if defined(FIX_HW_BRN_31620) hDevMemContext = psKick->hDevMemContext; #endif if (!CCB_OFFSET_IS_VALID(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset")); return PVRSRV_ERROR_INVALID_PARAMS; } ps2DCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd)); if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; ps2DCmd->sTASyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ps2DCmd->sTASyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; ps2DCmd->s3DSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ps2DCmd->s3DSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync; for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; ps2DCmd->sSrcSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ps2DCmd->sSrcSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; ps2DCmd->sDstSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ps2DCmd->sDstSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->sDstSyncData.ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ps2DCmd->sDstSyncData.sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; } for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending++; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending++; } #if defined(PDUMP) if ((PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) && (bPersistentProcess == IMG_FALSE) ) { PDUMPCOMMENT("Shared part of 2D command\r\n"); PDUMPMEM(ps2DCmd, psCCBMemInfo, psKick->ui32CCBDumpWOff, sizeof(SGXMKIF_2DCMD_SHARED), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; PDUMPCOMMENT("Hack src surface write op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack src surface read op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); } if (psKick->hDstSyncInfo != IMG_NULL) { IMG_UINT32 ui32PDumpReadOp2 = 0; psSyncInfo = psKick->hDstSyncInfo; PDUMPCOMMENT("Hack dest surface write op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack dest surface read op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack dest surface read op2 in 2D cmd\r\n"); PDUMPMEM(&ui32PDumpReadOp2, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOps2PendingVal), sizeof(ui32PDumpReadOp2), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); } for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } #endif sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr; eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE); if (eError == PVRSRV_ERROR_RETRY) { #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal--; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32LastOpDumpVal--; } } #endif for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } } #if defined(NO_HARDWARE) for(i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } #endif return eError; } #endif #endif