/* * 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; }
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; }
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; }
/* * 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; }