static IMG_INT PVRSRVBridgeServerSyncPrimSet(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_SERVERSYNCPRIMSET *psServerSyncPrimSetIN, PVRSRV_BRIDGE_OUT_SERVERSYNCPRIMSET *psServerSyncPrimSetOUT, CONNECTION_DATA *psConnection) { SERVER_SYNC_PRIMITIVE * psSyncHandleInt = IMG_NULL; IMG_HANDLE hSyncHandleInt2 = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_SERVERSYNCPRIMSET); { /* Look up the address from the handle */ psServerSyncPrimSetOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hSyncHandleInt2, psServerSyncPrimSetIN->hSyncHandle, PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE); if(psServerSyncPrimSetOUT->eError != PVRSRV_OK) { goto ServerSyncPrimSet_exit; } /* Look up the data from the resman address */ psServerSyncPrimSetOUT->eError = ResManFindPrivateDataByPtr(hSyncHandleInt2, (IMG_VOID **) &psSyncHandleInt); if(psServerSyncPrimSetOUT->eError != PVRSRV_OK) { goto ServerSyncPrimSet_exit; } } psServerSyncPrimSetOUT->eError = PVRSRVServerSyncPrimSetKM( psSyncHandleInt, psServerSyncPrimSetIN->ui32Value); ServerSyncPrimSet_exit: return 0; }
IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncPrimSet(IMG_HANDLE hBridge, IMG_HANDLE hSyncHandle, IMG_UINT32 ui32Value) { PVRSRV_ERROR eError; SERVER_SYNC_PRIMITIVE * psSyncHandleInt; PVR_UNREFERENCED_PARAMETER(hBridge); psSyncHandleInt = (SERVER_SYNC_PRIMITIVE *) hSyncHandle; eError = PVRSRVServerSyncPrimSetKM( psSyncHandleInt, ui32Value); return eError; }
/* Fill in the server syncs data and release the CCB space */ IMG_VOID RGXCmdHelperReleaseCmdCCB(IMG_UINT32 ui32CmdCount, RGX_CCB_CMD_HELPER_DATA *asCmdHelperData, const IMG_CHAR *pcszDMName, IMG_UINT32 ui32CtxAddr) { IMG_UINT32 ui32AllocSize = 0; IMG_UINT32 i; /* Workout how much space we need for all the command(s) */ ui32AllocSize = RGXCmdHelperGetCommandSize(ui32CmdCount, asCmdHelperData); /* For each command fill in the server sync info */ for (i=0;i<ui32CmdCount;i++) { RGX_CCB_CMD_HELPER_DATA *psCmdHelperData = &asCmdHelperData[i]; IMG_UINT8 *pui8ServerFenceStart = psCmdHelperData->pui8ServerFenceStart; IMG_UINT8 *pui8ServerUpdateStart = psCmdHelperData->pui8ServerUpdateStart; IMG_UINT32 j; /* Now fill in the server fence and updates together */ for (j = 0; j < psCmdHelperData->ui32ServerSyncCount; j++) { RGXFWIF_UFO *psUFOPtr; IMG_UINT32 ui32UpdateValue; IMG_UINT32 ui32FenceValue; PVRSRV_ERROR eError; IMG_BOOL bFence = ((psCmdHelperData->paui32ServerSyncFlags[j] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK)!=0)?IMG_TRUE:IMG_FALSE; IMG_BOOL bUpdate = ((psCmdHelperData->paui32ServerSyncFlags[j] & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE)!=0)?IMG_TRUE:IMG_FALSE; eError = PVRSRVServerSyncQueueHWOpKM(psCmdHelperData->papsServerSyncs[j], bUpdate, &ui32FenceValue, &ui32UpdateValue); /* This function can't fail */ PVR_ASSERT(eError == PVRSRV_OK); /* As server syncs always fence (we have a check in RGXCmcdHelperInitCmdCCB which ensures the client is playing ball) the filling in of the fence is unconditional. */ if (bFence) { PVR_ASSERT(pui8ServerFenceStart != 0); psUFOPtr = (RGXFWIF_UFO *) pui8ServerFenceStart; psUFOPtr->puiAddrUFO.ui32Addr = ServerSyncGetFWAddr(psCmdHelperData->papsServerSyncs[j]); psUFOPtr->ui32Value = ui32FenceValue; pui8ServerFenceStart += sizeof(RGXFWIF_UFO); #if defined(LINUX) trace_rogue_fence_checks(pcszDMName, ui32CtxAddr, psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize, 1, &psUFOPtr->puiAddrUFO, &psUFOPtr->ui32Value); #endif } /* If there is an update then fill that in as well */ if (bUpdate) { PVR_ASSERT(pui8ServerUpdateStart != 0); psUFOPtr = (RGXFWIF_UFO *) pui8ServerUpdateStart; psUFOPtr->puiAddrUFO.ui32Addr = ServerSyncGetFWAddr(psCmdHelperData->papsServerSyncs[j]); psUFOPtr->ui32Value = ui32UpdateValue; pui8ServerUpdateStart += sizeof(RGXFWIF_UFO); #if defined(LINUX) trace_rogue_fence_updates(pcszDMName, ui32CtxAddr, psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize, 1, &psUFOPtr->puiAddrUFO, &psUFOPtr->ui32Value); #endif #if defined(NO_HARDWARE) /* There is no FW so the host has to do any Sync updates (client sync updates are done in the client */ PVRSRVServerSyncPrimSetKM(psCmdHelperData->papsServerSyncs[j], ui32UpdateValue); #endif } } #if defined(LINUX) trace_rogue_fence_checks(pcszDMName, ui32CtxAddr, psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize, psCmdHelperData->ui32ClientFenceCount, psCmdHelperData->pauiFenceUFOAddress, psCmdHelperData->paui32FenceValue); trace_rogue_fence_updates(pcszDMName, ui32CtxAddr, psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize, psCmdHelperData->ui32ClientUpdateCount, psCmdHelperData->pauiUpdateUFOAddress, psCmdHelperData->paui32UpdateValue); #endif if (psCmdHelperData->ui32ServerSyncCount) { /* Do some sanity checks to ensure we did the point math right */ if (pui8ServerFenceStart != 0) { PVR_ASSERT(pui8ServerFenceStart == (psCmdHelperData->pui8StartPtr + psCmdHelperData->ui32FenceCmdSize)); } if (pui8ServerUpdateStart != 0) { PVR_ASSERT(pui8ServerUpdateStart == psCmdHelperData->pui8StartPtr + psCmdHelperData->ui32FenceCmdSize + psCmdHelperData->ui32PreTimeStampCmdSize + psCmdHelperData->ui32DMCmdSize + psCmdHelperData->ui32RMWUFOCmdSize + psCmdHelperData->ui32PostTimeStampCmdSize + psCmdHelperData->ui32UpdateCmdSize); } } /* All the commands have been filled in so release the CCB space. The FW still won't run this command until we kick it */ PDUMPCOMMENTWITHFLAGS((psCmdHelperData->bPDumpContinuous) ? PDUMP_FLAGS_CONTINUOUS : 0, "%s Command Server Release on FWCtx %08x", psCmdHelperData->pszCommandName, ui32CtxAddr); } _RGXClientCCBDumpCommands(asCmdHelperData[0].psClientCCB, asCmdHelperData[0].psClientCCB->ui32HostWriteOffset, ui32AllocSize); RGXReleaseCCB(asCmdHelperData[0].psClientCCB, ui32AllocSize, asCmdHelperData[0].bPDumpContinuous); }