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;
}
예제 #3
0
/*
	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);
}