Esempio n. 1
0
IMG_VOID
ServerSyncUnref(SERVER_SYNC_PRIMITIVE *psSync)
{
	IMG_UINT32 ui32RefCount;

	OSLockAcquire(psSync->hLock);
	ui32RefCount = --psSync->ui32RefCount;
	OSLockRelease(psSync->hLock);

	if (ui32RefCount == 0)
	{
		SYNC_REFCOUNT_PRINT("%s: Server sync %p, refcount = %d",
							__FUNCTION__, psSync, ui32RefCount);

		/* Remove the sync from the global list */
		OSLockAcquire(g_hListLock);
		dllist_remove_node(&psSync->sNode);
		OSLockRelease(g_hListLock);

		OSLockDestroy(psSync->hLock);
		SyncPrimFree(psSync->psSync);
		OSFreeMem(psSync);
	}
	else
	{
		SYNC_REFCOUNT_PRINT("%s: Server sync %p, refcount = %d",
							__FUNCTION__, psSync, ui32RefCount);
	}
}
Esempio n. 2
0
IMG_EXPORT
PVRSRV_ERROR PVRSRVRGXDestroyComputeContextKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext)
{
	PVRSRV_ERROR				eError = PVRSRV_OK;

	/* Check if the FW has finished with this resource ... */
	eError = RGXFWRequestCommonContextCleanUp(psComputeContext->psDeviceNode,
											  FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext),
											  psComputeContext->psSync,
											  RGXFWIF_DM_CDM);

	if (eError == PVRSRV_ERROR_RETRY)
	{
		return eError;
	}
	else if (eError != PVRSRV_OK)
	{
		PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)",
				__FUNCTION__,
				PVRSRVGetErrorStringKM(eError)));
	}

	/* ... it has so we can free its resources */

	dllist_remove_node(&(psComputeContext->sListNode));

	FWCommonContextFree(psComputeContext->psServerCommonContext);
	DevmemFwFree(psComputeContext->psFWFrameworkMemDesc);
	DevmemFwFree(psComputeContext->psFWComputeContextStateMemDesc);
	SyncPrimFree(psComputeContext->psSync);
	OSFreeMem(psComputeContext);

	return PVRSRV_OK;
}
Esempio n. 3
0
static
IMG_VOID _ServerSyncUnref(SERVER_SYNC_PRIMITIVE *psSync)
{
	if (--psSync->ui32RefCount == 0)
	{
		SYNC_REFCOUNT_PRINT("%s: Server sync %p, refcount = %d",
							__FUNCTION__, psSync, psSync->ui32RefCount);
		SyncPrimFree(psSync->psSync);
		OSFreeMem(psSync);	
	}
	else
	{
		SYNC_REFCOUNT_PRINT("%s: Server sync %p, refcount = %d",
							__FUNCTION__, psSync, psSync->ui32RefCount);
	}
}
Esempio n. 4
0
/*
 * PVRSRVRGXDestroyTQ2DContextKM
 */
IMG_EXPORT
PVRSRV_ERROR PVRSRVRGXDestroyTQ2DContextKM(RGX_TQ2D_CLEANUP_DATA *psCleanupData)
{
	PVRSRV_ERROR				eError = PVRSRV_OK;
	PRGXFWIF_FWCOMMONCONTEXT	psFWComContextFWAddr;

	RGXSetFirmwareAddress(&psFWComContextFWAddr,
							psCleanupData->psFWTQ2DContextMemDesc,
							0,
							RFW_FWADDR_NOREF_FLAG);

	eError = RGXFWRequestCommonContextCleanUp(psCleanupData->psDeviceNode,
											  psFWComContextFWAddr,
											  psCleanupData->psCleanupSync,
											  RGXFWIF_DM_2D);

	/*
		If we get retry error then we can't free this resource
		as it's still in use and we will be called again
	*/
	if (eError != PVRSRV_ERROR_RETRY)
	{
		eError = RGXDeinitFWCommonContext(&psCleanupData->sFWComContextCleanup);
	
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXDestroyTQ2DContextKM : failed to deinit fw common ctx. Error:%u", eError));
			goto e0;
		}
	
		/* Free the framework buffer */
		DevmemFwFree(psCleanupData->psFWFrameworkMemDesc);
		
		/*
		 * Free the firmware common context.
		 */
		DevmemFwFree(psCleanupData->psFWTQ2DContextMemDesc);

		/* Free the cleanup sync */
		SyncPrimFree(psCleanupData->psCleanupSync);

		OSFreeMem(psCleanupData);
	}

e0:
	return eError;
}
Esempio n. 5
0
IMG_EXPORT
PVRSRV_ERROR PVRSRVRGXDestroyTransferContextKM(RGX_SERVER_TQ_CONTEXT *psTransferContext)
{
	PVRSRV_ERROR eError;

	if (psTransferContext->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_2D)
	{
		eError = _Destroy2DTransferContext(&psTransferContext->s2DData,
										   psTransferContext->psDeviceNode,
										   psTransferContext->psCleanupSync);
		if (eError != PVRSRV_OK)
		{
			goto fail_destroy2d;
		}
		/* We've freed the 2D context, don't try to free it again */
		psTransferContext->ui32Flags &= ~RGX_SERVER_TQ_CONTEXT_FLAGS_2D;
	}

	if (psTransferContext->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_3D)
	{
		eError = _Destroy3DTransferContext(&psTransferContext->s3DData,
										   psTransferContext->psDeviceNode,
										   psTransferContext->psCleanupSync);
		if (eError != PVRSRV_OK)
		{
			goto fail_destroy3d;
		}
		/* We've freed the 3D context, don't try to free it again */
		psTransferContext->ui32Flags &= ~RGX_SERVER_TQ_CONTEXT_FLAGS_3D;
	}
	dllist_remove_node(&(psTransferContext->sListNode));
	DevmemFwFree(psTransferContext->psFWFrameworkMemDesc);
	SyncPrimFree(psTransferContext->psCleanupSync);

	OSFreeMem(psTransferContext);

	return PVRSRV_OK;

fail_destroy2d:
fail_destroy3d:
	PVR_ASSERT(eError != PVRSRV_OK);
	return eError;
}
IMG_EXPORT
PVRSRV_ERROR PVRSRVRGXDestroyComputeContextKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext)
{
	PVRSRV_ERROR				eError = PVRSRV_OK;
	PVRSRV_RGXDEV_INFO *psDevInfo = psComputeContext->psDeviceNode->pvDevice;

	/* Check if the FW has finished with this resource ... */
	eError = RGXFWRequestCommonContextCleanUp(psComputeContext->psDeviceNode,
											  psComputeContext->psServerCommonContext,
											  psComputeContext->psSync,
											  RGXFWIF_DM_CDM);

	if (eError == PVRSRV_ERROR_RETRY)
	{
		return eError;
	}
	else if (eError != PVRSRV_OK)
	{
		PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)",
				__FUNCTION__,
				PVRSRVGetErrorStringKM(eError)));
		return eError;
	}

	/* ... it has so we can free its resources */

	OSWRLockAcquireWrite(psDevInfo->hComputeCtxListLock);
	dllist_remove_node(&(psComputeContext->sListNode));
	OSWRLockReleaseWrite(psDevInfo->hComputeCtxListLock);

	FWCommonContextFree(psComputeContext->psServerCommonContext);
	DevmemFwFree(psComputeContext->psFWFrameworkMemDesc);
	DevmemFwFree(psComputeContext->psFWComputeContextStateMemDesc);
	SyncPrimFree(psComputeContext->psSync);

	SyncAddrListDeinit(&psComputeContext->sSyncAddrListFence);
	SyncAddrListDeinit(&psComputeContext->sSyncAddrListUpdate);

	OSFreeMem(psComputeContext);

	return PVRSRV_OK;
}
Esempio n. 7
0
/*
 * PVRSRVCreateTransferContextKM
 */
IMG_EXPORT
PVRSRV_ERROR PVRSRVRGXCreateTransferContextKM(CONNECTION_DATA		*psConnection,
										   PVRSRV_DEVICE_NODE		*psDeviceNode,
										   IMG_UINT32				ui32Priority,
										   IMG_DEV_VIRTADDR			sMCUFenceAddr,
										   IMG_UINT32				ui32FrameworkCommandSize,
										   IMG_PBYTE				pabyFrameworkCommand,
										   IMG_HANDLE				hMemCtxPrivData,
										   RGX_SERVER_TQ_CONTEXT	**ppsTransferContext)
{
	RGX_SERVER_TQ_CONTEXT	*psTransferContext;
	DEVMEM_MEMDESC			*psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData);
	RGX_COMMON_CONTEXT_INFO	sInfo;
	PVRSRV_ERROR			eError = PVRSRV_OK;

	/* Allocate the server side structure */
	psTransferContext = OSAllocMem(sizeof(*psTransferContext));
	if (psTransferContext == IMG_NULL)
	{
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	OSMemSet(psTransferContext, 0, sizeof(*psTransferContext));
	*ppsTransferContext = psTransferContext;

	psTransferContext->psDeviceNode = psDeviceNode;

	/* Allocate cleanup sync */
	eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
						   &psTransferContext->psCleanupSync);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateTransferContextKM: Failed to allocate cleanup sync (0x%x)",
				eError));
		goto fail_syncalloc;
	}

	/* 
	 * Create the FW framework buffer
	 */
	eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode,
										&psTransferContext->psFWFrameworkMemDesc,
										ui32FrameworkCommandSize);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateTransferContextKM: Failed to allocate firmware GPU framework state (%u)",
				eError));
		goto fail_frameworkcreate;
	}

	/* Copy the Framework client data into the framework buffer */
	eError = PVRSRVRGXFrameworkCopyCommand(psTransferContext->psFWFrameworkMemDesc,
										   pabyFrameworkCommand,
										   ui32FrameworkCommandSize);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateTransferContextKM: Failed to populate the framework buffer (%u)",
				eError));
		goto fail_frameworkcopy;
	}

	sInfo.psFWFrameworkMemDesc = psTransferContext->psFWFrameworkMemDesc;
	sInfo.psMCUFenceAddr = &sMCUFenceAddr;

	eError = _Create3DTransferContext(psConnection,
									  psDeviceNode,
									  psFWMemContextMemDesc,
									  ui32Priority,
									  &sInfo,
									  &psTransferContext->s3DData);
	if (eError != PVRSRV_OK)
	{
		goto fail_3dtransfercontext;
	}
	psTransferContext->ui32Flags |= RGX_SERVER_TQ_CONTEXT_FLAGS_3D;

	eError = _Create2DTransferContext(psConnection,
									  psDeviceNode,
									  psFWMemContextMemDesc,
									  ui32Priority,
									  &sInfo,
									  &psTransferContext->s2DData);
	if (eError != PVRSRV_OK)
	{
		goto fail_2dtransfercontext;
	}
	psTransferContext->ui32Flags |= RGX_SERVER_TQ_CONTEXT_FLAGS_2D;

	{
		PVRSRV_RGXDEV_INFO			*psDevInfo = psDeviceNode->pvDevice;
		dllist_add_to_tail(&(psDevInfo->sTransferCtxtListHead), &(psTransferContext->sListNode));
	}

	return PVRSRV_OK;

fail_2dtransfercontext:
	_Destroy3DTransferContext(&psTransferContext->s3DData,
							  psTransferContext->psDeviceNode,
							  psTransferContext->psCleanupSync);
fail_3dtransfercontext:
fail_frameworkcopy:
	DevmemFwFree(psTransferContext->psFWFrameworkMemDesc);
fail_frameworkcreate:
	SyncPrimFree(psTransferContext->psCleanupSync);
fail_syncalloc:
	OSFreeMem(psTransferContext);
	PVR_ASSERT(eError != PVRSRV_OK);
	return eError;
}
Esempio n. 8
0
IMG_EXPORT
PVRSRV_ERROR PVRSRVRGXCreateComputeContextKM(CONNECTION_DATA			*psConnection,
											 PVRSRV_DEVICE_NODE			*psDeviceNode,
											 IMG_UINT32					ui32Priority,
											 IMG_DEV_VIRTADDR			sMCUFenceAddr,
											 IMG_UINT32					ui32FrameworkCommandSize,
											 IMG_PBYTE					pbyFrameworkCommand,
											 IMG_HANDLE					hMemCtxPrivData,
											 RGX_SERVER_COMPUTE_CONTEXT	**ppsComputeContext)
{
	PVRSRV_RGXDEV_INFO 			*psDevInfo = psDeviceNode->pvDevice;
	DEVMEM_MEMDESC				*psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData);
	RGX_SERVER_COMPUTE_CONTEXT	*psComputeContext;
	RGX_COMMON_CONTEXT_INFO		sInfo;
	PVRSRV_ERROR				eError = PVRSRV_OK;

	/* Prepare cleanup struct */
	*ppsComputeContext = IMG_NULL;
	psComputeContext = OSAllocMem(sizeof(*psComputeContext));
	if (psComputeContext == IMG_NULL)
	{
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	OSMemSet(psComputeContext, 0, sizeof(*psComputeContext));

	psComputeContext->psDeviceNode = psDeviceNode;

	/* Allocate cleanup sync */
	eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
						   &psComputeContext->psSync);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate cleanup sync (0x%x)",
				eError));
		goto fail_syncalloc;
	}

	/*
		Allocate device memory for the firmware GPU context suspend state.
		Note: the FW reads/writes the state to memory by accessing the GPU register interface.
	*/
	PDUMPCOMMENT("Allocate RGX firmware compute context suspend state");

	eError = DevmemFwAllocate(psDevInfo,
							  sizeof(RGXFWIF_COMPUTECTX_STATE),
							  RGX_FWCOMCTX_ALLOCFLAGS,
							  "ComputeContextState",
							  &psComputeContext->psFWComputeContextStateMemDesc);

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate firmware GPU context suspend state (%u)",
				eError));
		goto fail_contextsuspendalloc;
	}

	/* 
	 * Create the FW framework buffer
	 */
	eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode,
										&psComputeContext->psFWFrameworkMemDesc,
										ui32FrameworkCommandSize);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate firmware GPU framework state (%u)",
				eError));
		goto fail_frameworkcreate;
	}

	/* Copy the Framework client data into the framework buffer */
	eError = PVRSRVRGXFrameworkCopyCommand(psComputeContext->psFWFrameworkMemDesc,
										   pbyFrameworkCommand,
										   ui32FrameworkCommandSize);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to populate the framework buffer (%u)",
				eError));
		goto fail_frameworkcopy;
	}
	
	sInfo.psFWFrameworkMemDesc = psComputeContext->psFWFrameworkMemDesc;
	sInfo.psMCUFenceAddr = &sMCUFenceAddr;

	eError = FWCommonContextAllocate(psConnection,
									 psDeviceNode,
									 "CDM",
									 IMG_NULL,
									 0,
									 psFWMemContextMemDesc,
									 psComputeContext->psFWComputeContextStateMemDesc,
									 RGX_CCB_SIZE_LOG2,
									 ui32Priority,
									 &sInfo,
									 &psComputeContext->psServerCommonContext);
	if (eError != PVRSRV_OK)
	{
		goto fail_contextalloc;
	}

	{
		PVRSRV_RGXDEV_INFO			*psDevInfo = psDeviceNode->pvDevice;
		dllist_add_to_tail(&(psDevInfo->sComputeCtxtListHead), &(psComputeContext->sListNode));
	}

	*ppsComputeContext = psComputeContext;
	return PVRSRV_OK;

fail_contextalloc:
fail_frameworkcopy:
	DevmemFwFree(psComputeContext->psFWFrameworkMemDesc);
fail_frameworkcreate:
	DevmemFwFree(psComputeContext->psFWComputeContextStateMemDesc);
fail_contextsuspendalloc:
	SyncPrimFree(psComputeContext->psSync);
fail_syncalloc:
	OSFreeMem(psComputeContext);
	return eError;
}
Esempio n. 9
0
PVRSRV_ERROR
PVRSRVServerSyncAllocKM(PVRSRV_DEVICE_NODE *psDevNode,
						SERVER_SYNC_PRIMITIVE **ppsSync,
						IMG_UINT32 *pui32SyncPrimVAddr,
						IMG_UINT32 ui32ClassNameSize,
						const IMG_CHAR *pszClassName)
{
	SERVER_SYNC_PRIMITIVE *psNewSync;
	PVRSRV_ERROR eError;

	psNewSync = OSAllocMem(sizeof(SERVER_SYNC_PRIMITIVE));
	if (psNewSync == IMG_NULL)
	{
			return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	/* szClassName must be setup now and used for the SyncPrimAlloc call because
	 * pszClassName is allocated in the bridge code is not NULL terminated 
	 */
	if(pszClassName)
	{
		if (ui32ClassNameSize >= SYNC_MAX_CLASS_NAME_LEN)
			ui32ClassNameSize = SYNC_MAX_CLASS_NAME_LEN - 1;
		/* Copy over the class name annotation */
		OSStringNCopy(psNewSync->szClassName, pszClassName, ui32ClassNameSize);
		psNewSync->szClassName[ui32ClassNameSize] = 0;
	}
	else
	{
		/* No class name annotation */
		psNewSync->szClassName[0] = 0;
	}

	eError = SyncPrimAlloc(psDevNode->hSyncPrimContext,
						   &psNewSync->psSync,
						   psNewSync->szClassName);
	if (eError != PVRSRV_OK)
	{
		goto fail_sync_alloc;
	}

	eError = OSLockCreate(&psNewSync->hLock, LOCK_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		goto fail_lock_create;
	}

	SyncPrimSet(psNewSync->psSync, 0);

	psNewSync->ui32NextOp = 0;
	psNewSync->ui32RefCount = 1;
	psNewSync->ui32UID = g_ServerSyncUID++;
	psNewSync->ui32LastSyncRequesterID = SYNC_REQUESTOR_UNKNOWN;
	psNewSync->bSWOperation = IMG_FALSE;
	psNewSync->ui32LastHWUpdate = 0x0bad592c;
	psNewSync->bPDumped = IMG_FALSE;

	/* Add the sync to the global list */
	OSLockAcquire(g_hListLock);
	dllist_add_to_head(&g_sAllServerSyncs, &psNewSync->sNode);
	OSLockRelease(g_hListLock);

	*pui32SyncPrimVAddr = SyncPrimGetFirmwareAddr(psNewSync->psSync);
	SYNC_UPDATES_PRINT("%s: sync: %p, fwaddr: %8.8X", __FUNCTION__, psNewSync, *pui32SyncPrimVAddr);
	*ppsSync = psNewSync;
	return PVRSRV_OK;

fail_lock_create:
	SyncPrimFree(psNewSync->psSync);

fail_sync_alloc:
	OSFreeMem(psNewSync);
	return eError;
}
Esempio n. 10
0
IMG_EXPORT
PVRSRV_ERROR PVRSRVRGXCreateTQ2DContextKM(PVRSRV_DEVICE_NODE		*psDeviceNode,
										  DEVMEM_MEMDESC 			*psTQ2DCCBMemDesc,
										  DEVMEM_MEMDESC 			*psTQ2DCCBCtlMemDesc,
										  RGX_TQ2D_CLEANUP_DATA		**ppsCleanupData,
										  DEVMEM_MEMDESC 			**ppsFWTQ2DContextMemDesc,
										  IMG_UINT32				ui32Priority,
										  IMG_UINT32				ui32FrameworkRegisterSize,
										  IMG_PBYTE					pbyFrameworkRegisters,
										  IMG_HANDLE				hMemCtxPrivData)
{
	PVRSRV_ERROR			eError = PVRSRV_OK;
	PVRSRV_RGXDEV_INFO 		*psDevInfo = psDeviceNode->pvDevice;	
	RGXFWIF_FWCOMMONCONTEXT	*psFWTQ2DContext;
	RGX_TQ2D_CLEANUP_DATA	*psTmpCleanup;
	DEVMEM_MEMDESC 			*psFWFrameworkMemDesc;

	/* Prepare cleanup struct */
	psTmpCleanup = OSAllocMem(sizeof(*psTmpCleanup));
	if (psTmpCleanup == IMG_NULL)
	{
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	OSMemSet(psTmpCleanup, 0, sizeof(*psTmpCleanup));
	*ppsCleanupData = psTmpCleanup;

	/* Allocate cleanup sync */
	eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
						   &psTmpCleanup->psCleanupSync);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate cleanup sync (0x%x)",
				eError));
		goto fail_syncalloc;
	}

	/*
		Allocate device memory for the firmware TQ 2D context.
	*/
	PDUMPCOMMENT("Allocate RGX firmware TQ 2D context");
	
	eError = DevmemFwAllocate(psDevInfo,
							sizeof(*psFWTQ2DContext),
							RGX_FWCOMCTX_ALLOCFLAGS,
							ppsFWTQ2DContextMemDesc);

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to allocate firmware TQ 2D context (%u)",
				eError));
		goto fail_contextalloc;
	}
	psTmpCleanup->psFWTQ2DContextMemDesc = *ppsFWTQ2DContextMemDesc;
	psTmpCleanup->psDeviceNode = psDeviceNode;

	/*
		Temporarily map the firmware TQ 2D context to the kernel.
	*/
	eError = DevmemAcquireCpuVirtAddr(*ppsFWTQ2DContextMemDesc,
                                      (IMG_VOID **)&psFWTQ2DContext);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to map firmware TQ 2D context (%u)",
				eError));
		goto fail_cpuvirtacquire;
	}

	/* 
	 * Create the FW framework buffer
	 */
	eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode, & psFWFrameworkMemDesc, ui32FrameworkRegisterSize);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to allocate firmware GPU framework state (%u)",
				eError));
		goto fail_frameworkcreate;
	}
	
	psTmpCleanup->psFWFrameworkMemDesc = psFWFrameworkMemDesc;

	/* Copy the Framework client data into the framework buffer */
	eError = PVRSRVRGXFrameworkCopyRegisters(psFWFrameworkMemDesc, pbyFrameworkRegisters, ui32FrameworkRegisterSize);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to populate the framework buffer (%u)",
				eError));
		goto fail_frameworkcopy;
	}

	eError = RGXInitFWCommonContext(psFWTQ2DContext,
									psTQ2DCCBMemDesc,
									psTQ2DCCBCtlMemDesc,
									hMemCtxPrivData,
									psFWFrameworkMemDesc,
									ui32Priority,
									IMG_NULL,
									& psTmpCleanup->sFWComContextCleanup);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to init firmware common context (%u)",
				eError));
		goto fail_contextinit;
	}

	/*
	 * Dump the TQ2D and the memory contexts
	 */
	PDUMPCOMMENT("Dump FWTQ2DContext");
	DevmemPDumpLoadMem(*ppsFWTQ2DContextMemDesc, 0, sizeof(*psFWTQ2DContext), PDUMP_FLAGS_CONTINUOUS);

	/* Release address acquired above. */
	DevmemReleaseCpuVirtAddr(*ppsFWTQ2DContextMemDesc);

	return PVRSRV_OK;
fail_contextinit:
fail_frameworkcopy:
	DevmemFwFree(psFWFrameworkMemDesc);
fail_frameworkcreate:
	DevmemReleaseCpuVirtAddr(*ppsFWTQ2DContextMemDesc);
fail_cpuvirtacquire:
	DevmemFwFree(*ppsFWTQ2DContextMemDesc);
fail_contextalloc:
	SyncPrimFree(psTmpCleanup->psCleanupSync);
fail_syncalloc:
	OSFreeMem(psTmpCleanup);
	return eError;
}
Esempio n. 11
0
/*
 * PVRSRVRGXDestroyTQ3DContextKM
 */
IMG_EXPORT
PVRSRV_ERROR PVRSRVRGXDestroyTQ3DContextKM(RGX_TQ3D_CLEANUP_DATA *psCleanupData)
{
	PVRSRV_ERROR				eError = PVRSRV_OK;
	PRGXFWIF_FWCOMMONCONTEXT	psFWComContextFWAddr;

	RGXSetFirmwareAddress(&psFWComContextFWAddr,
							psCleanupData->psFWTQ3DContextMemDesc,
							0,
							RFW_FWADDR_NOREF_FLAG);

	eError = RGXFWRequestCommonContextCleanUp(psCleanupData->psDeviceNode,
											  psFWComContextFWAddr,
											  psCleanupData->psCleanupSync,
											  RGXFWIF_DM_3D);

	/*
		If we get retry error then we can't free this resource
		as it's still in use and we will be called again
	*/
	if (eError != PVRSRV_ERROR_RETRY)
	{
		eError = RGXDeinitFWCommonContext(&psCleanupData->sFWComContextCleanup);
	
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXDestroyTQ3DContextKM : failed to deinit fw common ctx. Error:%u", eError));
			goto e0;
		}
	
	#if defined(DEBUG)
		/* Log the number of TQ3D context stores which occurred */
		{
			RGXFWIF_3DCTX_STATE	*psFWState;

			eError = DevmemAcquireCpuVirtAddr(psCleanupData->psFWTQ3DContextStateMemDesc,
											  (IMG_VOID**)&psFWState);
			if (eError != PVRSRV_OK)
			{
				PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateRenderContextKM: Failed to map firmware render context state (%u)",
						eError));
			}
			else
			{
	
				PVR_DPF((PVR_DBG_WARNING,"Number of context stores on FW TQ3D context 0x%010x: %u",
						psFWComContextFWAddr.ui32Addr,
						psFWState->ui32NumStores));

				/* Release the CPU virt addr */
				DevmemReleaseCpuVirtAddr(psCleanupData->psFWTQ3DContextStateMemDesc);
			}
		}
	#endif
	
		/*
		 * Unmap the TA/3D context state buffer pointers
		 */
		RGXUnsetFirmwareAddress(psCleanupData->psFWTQ3DContextStateMemDesc);

		/*
		 * Free the firmware TQ/3D context state buffer
		 */
		DevmemFwFree(psCleanupData->psFWTQ3DContextStateMemDesc);

		/* Free the framework buffer */
		DevmemFwFree(psCleanupData->psFWFrameworkMemDesc);

		/*
		 * Free the firmware common context.
		 */
		DevmemFwFree(psCleanupData->psFWTQ3DContextMemDesc);

		/* Free the cleanup sync */
		SyncPrimFree(psCleanupData->psCleanupSync);

		OSFreeMem(psCleanupData);
	}
e0:
	return eError;
}
Esempio n. 12
0
/*
 * PVRSRVRGXCreateTQ3DContextKM
 */
IMG_EXPORT
PVRSRV_ERROR PVRSRVRGXCreateTQ3DContextKM(PVRSRV_DEVICE_NODE		*psDeviceNode,
										  DEVMEM_MEMDESC 			*psTQ3DCCBMemDesc,
										  DEVMEM_MEMDESC 			*psTQ3DCCBCtlMemDesc,
										  RGX_TQ3D_CLEANUP_DATA		**ppsCleanupData,
										  DEVMEM_MEMDESC 			**ppsFWTQ3DContextMemDesc,
										  DEVMEM_MEMDESC 			**ppsFWTQ3DContextStateMemDesc,
										  IMG_UINT32				ui32Priority,
										  IMG_DEV_VIRTADDR			sMCUFenceAddr,
										  IMG_UINT32				ui32FrameworkRegisterSize,
										  IMG_PBYTE					pbyFrameworkRegisters,
										  IMG_HANDLE				hMemCtxPrivData)
{
	PVRSRV_ERROR			eError = PVRSRV_OK;
	PVRSRV_RGXDEV_INFO 		*psDevInfo = psDeviceNode->pvDevice;	
	RGXFWIF_FWCOMMONCONTEXT	*psFWTQ3DContext;
	RGX_TQ3D_CLEANUP_DATA	*psTmpCleanup;
	DEVMEM_MEMDESC 			*psFWFrameworkMemDesc;

	/* Prepare cleanup struct */
	psTmpCleanup = OSAllocMem(sizeof(*psTmpCleanup));
	if (psTmpCleanup == IMG_NULL)
	{
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}


	OSMemSet(psTmpCleanup, 0, sizeof(*psTmpCleanup));
	*ppsCleanupData = psTmpCleanup;

	/* Allocate cleanup sync */
	eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
						   &psTmpCleanup->psCleanupSync);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate cleanup sync (0x%x)",
				eError));
		goto fail_syncalloc;
	}

	/*
		Allocate device memory for the firmware TQ 3D context.
	*/
	PDUMPCOMMENT("Allocate RGX firmware TQ 3D context");
	
	eError = DevmemFwAllocate(psDevInfo,
							sizeof(*psFWTQ3DContext),
							RGX_FWCOMCTX_ALLOCFLAGS,
							ppsFWTQ3DContextMemDesc);

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to allocate firmware TQ 3D context (%u)",
				eError));
		goto fail_contextalloc;
	}
	psTmpCleanup->psFWTQ3DContextMemDesc = *ppsFWTQ3DContextMemDesc;
	psTmpCleanup->psDeviceNode = psDeviceNode;

	/*
		Temporarily map the firmware TQ 3D context to the kernel.
	*/
	eError = DevmemAcquireCpuVirtAddr(*ppsFWTQ3DContextMemDesc,
                                      (IMG_VOID **)&psFWTQ3DContext);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to map firmware TQ 3D context (%u)",
				eError));
		goto fail_cpuvirtacquire;
	}

	/*
		Allocate device memory for the firmware GPU context suspend state.
		Note: the FW reads/writes the state to memory by accessing the GPU register interface.
	*/
	PDUMPCOMMENT("Allocate RGX firmware TQ/3D context suspend state");

	eError = DevmemFwAllocate(psDevInfo,
							sizeof(RGXFWIF_3DCTX_STATE),
							RGX_FWCOMCTX_ALLOCFLAGS,
							ppsFWTQ3DContextStateMemDesc);

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to allocate firmware GPU context suspend state (%u)",
				eError));
		goto fail_contextsuspendalloc;
	}
	psTmpCleanup->psFWTQ3DContextStateMemDesc = *ppsFWTQ3DContextStateMemDesc;

	/* 
	 * Create the FW framework buffer
	 */
	eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode, & psFWFrameworkMemDesc, ui32FrameworkRegisterSize);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to allocate firmware GPU framework state (%u)",
				eError));
		goto fail_frameworkcreate;
	}
	
	psTmpCleanup->psFWFrameworkMemDesc = psFWFrameworkMemDesc;

	/* Copy the Framework client data into the framework buffer */
	eError = PVRSRVRGXFrameworkCopyRegisters(psFWFrameworkMemDesc, pbyFrameworkRegisters, ui32FrameworkRegisterSize);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to populate the framework buffer (%u)",
				eError));
		goto fail_frameworkcopy;
	}

	/* Init TQ/3D FW common context */
	eError = RGXInitFWCommonContext(psFWTQ3DContext,
									psTQ3DCCBMemDesc,
									psTQ3DCCBCtlMemDesc,
									hMemCtxPrivData,
									psFWFrameworkMemDesc,
									ui32Priority,
									&sMCUFenceAddr,
									&psTmpCleanup->sFWComContextCleanup);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to init firmware common context (%u)",
				eError));
		goto fail_contextinit;
	}

	/*
	 * Set the firmware GPU context state buffer.
	 * 
	 * The common context stores a dword pointer (FW) so we can cast the generic buffer to
	 * the correct 3D (3D/TQ = normal 3D) state structure type in the FW.
	 */
	RGXSetFirmwareAddress(&psFWTQ3DContext->psContextState,
								   *ppsFWTQ3DContextStateMemDesc,
								   0,
								   RFW_FWADDR_FLAG_NONE);

	/*
	 * Dump the TQ3D and the memory contexts
	 */
	PDUMPCOMMENT("Dump FWTQ3DContext");
	DevmemPDumpLoadMem(*ppsFWTQ3DContextMemDesc, 0, sizeof(*psFWTQ3DContext), PDUMP_FLAGS_CONTINUOUS);

	/*
	 * Dump the FW TQ/3D context suspend state buffer
	 */
	PDUMPCOMMENT("Dump FWTQ3DContextState");
	DevmemPDumpLoadMem(*ppsFWTQ3DContextStateMemDesc, 0, sizeof(RGXFWIF_3DCTX_STATE), PDUMP_FLAGS_CONTINUOUS);

	/* Release address acquired above. */
	DevmemReleaseCpuVirtAddr(*ppsFWTQ3DContextMemDesc);

	return PVRSRV_OK;

fail_contextinit:
fail_frameworkcopy:
	DevmemFwFree(psFWFrameworkMemDesc);
fail_frameworkcreate:
	DevmemFwFree(*ppsFWTQ3DContextStateMemDesc);
fail_contextsuspendalloc:
	DevmemReleaseCpuVirtAddr(*ppsFWTQ3DContextMemDesc);
fail_cpuvirtacquire:
	DevmemFwFree(*ppsFWTQ3DContextMemDesc);
fail_contextalloc:
	SyncPrimFree(psTmpCleanup->psCleanupSync);
fail_syncalloc:
	OSFreeMem(psTmpCleanup);
	return eError;
}