DC_ERROR Init(void) { DC_NOHW_DEVINFO *psDevInfo; DC_ERROR eError; unsigned long ulBBuf; unsigned long ulNBBuf; psDevInfo = GetAnchorPtr(); if (psDevInfo == 0) { PFN_CMD_PROC pfnCmdProcList[DC_NOHW_COMMAND_COUNT]; IMG_UINT32 aui32SyncCountList[DC_NOHW_COMMAND_COUNT][2]; psDevInfo = (DC_NOHW_DEVINFO *)AllocKernelMem(sizeof(*psDevInfo)); if(!psDevInfo) { eError = DC_ERROR_OUT_OF_MEMORY; goto ExitError; } memset(psDevInfo, 0, sizeof(*psDevInfo)); SetAnchorPtr((void*)psDevInfo); psDevInfo->ulRefCount = 0UL; if(OpenPVRServices(&psDevInfo->hPVRServices) != DC_OK) { eError = DC_ERROR_INIT_FAILURE; goto ExitFreeDevInfo; } if(GetLibFuncAddr (psDevInfo->hPVRServices, "PVRGetDisplayClassJTable", &pfnGetPVRJTable) != DC_OK) { eError = DC_ERROR_INIT_FAILURE; goto ExitCloseServices; } if((*pfnGetPVRJTable)(&psDevInfo->sPVRJTable) == IMG_FALSE) { eError = DC_ERROR_INIT_FAILURE; goto ExitCloseServices; } psDevInfo->psSwapChain = 0; psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0UL; psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1UL; psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1UL; psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = DC_NOHW_MAX_BACKBUFFERS; strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); psDevInfo->ulNumFormats = 1UL; psDevInfo->ulNumDims = 1UL; #if defined(DC_NOHW_GET_BUFFER_DIMENSIONS) if (!GetBufferDimensions(&psDevInfo->asDisplayDimList[0].ui32Width, &psDevInfo->asDisplayDimList[0].ui32Height, &psDevInfo->asDisplayFormatList[0].pixelformat, &psDevInfo->asDisplayDimList[0].ui32ByteStride)) { eError = DC_ERROR_INIT_FAILURE; goto ExitCloseServices; } #else #if defined (ENABLE_DISPLAY_MODE_TRACKING) psDevInfo->asDisplayFormatList[0].pixelformat = DC_NOHW_BUFFER_PIXEL_FORMAT; psDevInfo->asDisplayDimList[0].ui32Width = 0; psDevInfo->asDisplayDimList[0].ui32Height = 0; psDevInfo->asDisplayDimList[0].ui32ByteStride = 0; #else psDevInfo->asDisplayFormatList[0].pixelformat = DC_NOHW_BUFFER_PIXEL_FORMAT; psDevInfo->asDisplayDimList[0].ui32Width = DC_NOHW_BUFFER_WIDTH; psDevInfo->asDisplayDimList[0].ui32Height = DC_NOHW_BUFFER_HEIGHT; psDevInfo->asDisplayDimList[0].ui32ByteStride = DC_NOHW_BUFFER_BYTE_STRIDE; #endif #endif psDevInfo->sSysFormat = psDevInfo->asDisplayFormatList[0]; psDevInfo->sSysDims.ui32Width = psDevInfo->asDisplayDimList[0].ui32Width; psDevInfo->sSysDims.ui32Height = psDevInfo->asDisplayDimList[0].ui32Height; psDevInfo->sSysDims.ui32ByteStride = psDevInfo->asDisplayDimList[0].ui32ByteStride; psDevInfo->ui32BufferSize = psDevInfo->sSysDims.ui32Height * psDevInfo->sSysDims.ui32ByteStride; for(ulBBuf=0; ulBBuf<DC_NOHW_MAX_BACKBUFFERS; ulBBuf++) { #if defined(USE_BASE_VIDEO_FRAMEBUFFER) || defined (ENABLE_DISPLAY_MODE_TRACKING) psDevInfo->asBackBuffers[ulBBuf].sSysAddr.uiAddr = IMG_NULL; psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr = IMG_NULL; #else #if defined(DC_NOHW_DISCONTIG_BUFFERS) if (AllocDiscontigMemory(psDevInfo->ui32BufferSize, &psDevInfo->asBackBuffers[ulBBuf].hMemChunk, &psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr, &psDevInfo->asBackBuffers[ulBBuf].psSysAddr) != DC_OK) { eError = DC_ERROR_INIT_FAILURE; goto ExitFreeMem; } #else IMG_CPU_PHYADDR sBufferCPUPAddr; if (AllocContigMemory(psDevInfo->ui32BufferSize, &psDevInfo->asBackBuffers[ulBBuf].hMemChunk, &psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr, &sBufferCPUPAddr) != DC_OK) { eError = DC_ERROR_INIT_FAILURE; goto ExitFreeMem; } psDevInfo->asBackBuffers[ulBBuf].sSysAddr = CpuPAddrToSysPAddr(sBufferCPUPAddr); #endif #endif psDevInfo->asBackBuffers[ulBBuf].sDevVAddr.uiAddr = 0UL; psDevInfo->asBackBuffers[ulBBuf].hSwapChain = 0; psDevInfo->asBackBuffers[ulBBuf].psSyncData = 0; psDevInfo->asBackBuffers[ulBBuf].psNext = 0; } psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE); psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice; psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice; psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats; psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims; psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer; psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo; psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr; psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain; psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain; psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect; psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect; psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey; psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey; psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers; psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer; psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem; psDevInfo->sDCJTable.pfnSetDCState = IMG_NULL; if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice (&psDevInfo->sDCJTable, &psDevInfo->uiDeviceID ) != PVRSRV_OK) { eError = DC_ERROR_DEVICE_REGISTER_FAILED; goto ExitFreeMem; } pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; aui32SyncCountList[DC_FLIP_COMMAND][0] = 0UL; aui32SyncCountList[DC_FLIP_COMMAND][1] = 2UL; if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiDeviceID, &pfnCmdProcList[0], aui32SyncCountList, DC_NOHW_COMMAND_COUNT) != PVRSRV_OK) { eError = DC_ERROR_CANT_REGISTER_CALLBACK; goto ExitRemoveDevice; } } psDevInfo->ulRefCount++; return (DC_OK); ExitRemoveDevice: (IMG_VOID) psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiDeviceID); ExitFreeMem: ulNBBuf = ulBBuf; for(ulBBuf=0; ulBBuf<ulNBBuf; ulBBuf++) { #if defined(DC_NOHW_DISCONTIG_BUFFERS) FreeDiscontigMemory(psDevInfo->ui32BufferSize, psDevInfo->asBackBuffers[ulBBuf].hMemChunk, psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr, psDevInfo->asBackBuffers[ulBBuf].psSysAddr); #else #if !defined(USE_BASE_VIDEO_FRAMEBUFFER) FreeContigMemory(psDevInfo->ui32BufferSize, psDevInfo->asBackBuffers[ulBBuf].hMemChunk, psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr, SysPAddrToCpuPAddr(psDevInfo->asBackBuffers[ulBBuf].sSysAddr)); #endif #endif } ExitCloseServices: (void)ClosePVRServices(psDevInfo->hPVRServices); ExitFreeDevInfo: FreeKernelMem(psDevInfo); SetAnchorPtr(0); ExitError: return eError; }
DC_ERROR Init(void) { DC_NOHW_DEVINFO *psDevInfo; DC_ERROR eError; unsigned long ulBBuf; unsigned long ulNBBuf; /* - connect to services - register with services - allocate and setup private data structure */ /* in kernel driver, data structures must be anchored to something for subsequent retrieval this may be a single global pointer or TLS or something else - up to you call API to retrieve this ptr */ /* get the anchor pointer */ psDevInfo = GetAnchorPtr(); if (psDevInfo == 0) { PFN_CMD_PROC pfnCmdProcList[DC_NOHW_COMMAND_COUNT]; IMG_UINT32 aui32SyncCountList[DC_NOHW_COMMAND_COUNT][2]; /* allocate device info. structure */ psDevInfo = (DC_NOHW_DEVINFO *)AllocKernelMem(sizeof(*psDevInfo)); if(!psDevInfo) { eError = DC_ERROR_OUT_OF_MEMORY;/* failure */ goto ExitError; } /* initialise allocation */ memset(psDevInfo, 0, sizeof(*psDevInfo)); /* set the top-level anchor */ SetAnchorPtr((void*)psDevInfo); /* set ref count */ psDevInfo->ulRefCount = 0UL; if(OpenPVRServices(&psDevInfo->hPVRServices) != DC_OK) { eError = DC_ERROR_INIT_FAILURE; goto ExitFreeDevInfo; } if(GetLibFuncAddr (psDevInfo->hPVRServices, "PVRGetDisplayClassJTable", &pfnGetPVRJTable) != DC_OK) { eError = DC_ERROR_INIT_FAILURE; goto ExitCloseServices; } /* got the kernel services function table */ if((*pfnGetPVRJTable)(&psDevInfo->sPVRJTable) == IMG_FALSE) { eError = DC_ERROR_INIT_FAILURE; goto ExitCloseServices; } /* Setup the devinfo */ psDevInfo->psSwapChain = 0; psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0UL; psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1UL; psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1UL; psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = DC_NOHW_MAX_BACKBUFFERS; strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); psDevInfo->ulNumFormats = 1UL; psDevInfo->ulNumDims = 1UL; #if defined(DC_NOHW_GET_BUFFER_DIMENSIONS) if (!GetBufferDimensions(&psDevInfo->asDisplayDimList[0].ui32Width, &psDevInfo->asDisplayDimList[0].ui32Height, &psDevInfo->asDisplayFormatList[0].pixelformat, &psDevInfo->asDisplayDimList[0].ui32ByteStride)) { eError = DC_ERROR_INIT_FAILURE; goto ExitCloseServices; } #else /* defined(DC_NOHW_GET_BUFFER_DIMENSIONS) */ #if defined (ENABLE_DISPLAY_MODE_TRACKING) // Set sizes to zero to force re-alloc on display mode change. psDevInfo->asDisplayFormatList[0].pixelformat = DC_NOHW_BUFFER_PIXEL_FORMAT; psDevInfo->asDisplayDimList[0].ui32Width = 0; psDevInfo->asDisplayDimList[0].ui32Height = 0; psDevInfo->asDisplayDimList[0].ui32ByteStride = 0; #else psDevInfo->asDisplayFormatList[0].pixelformat = DC_NOHW_BUFFER_PIXEL_FORMAT; psDevInfo->asDisplayDimList[0].ui32Width = DC_NOHW_BUFFER_WIDTH; psDevInfo->asDisplayDimList[0].ui32Height = DC_NOHW_BUFFER_HEIGHT; psDevInfo->asDisplayDimList[0].ui32ByteStride = DC_NOHW_BUFFER_BYTE_STRIDE; #endif #endif /* defined(DC_NOHW_GET_BUFFER_DIMENSIONS) */ psDevInfo->sSysFormat = psDevInfo->asDisplayFormatList[0]; psDevInfo->sSysDims.ui32Width = psDevInfo->asDisplayDimList[0].ui32Width; psDevInfo->sSysDims.ui32Height = psDevInfo->asDisplayDimList[0].ui32Height; psDevInfo->sSysDims.ui32ByteStride = psDevInfo->asDisplayDimList[0].ui32ByteStride; psDevInfo->ui32BufferSize = psDevInfo->sSysDims.ui32Height * psDevInfo->sSysDims.ui32ByteStride; /* setup swapchain details */ for(ulBBuf=0; ulBBuf<DC_NOHW_MAX_BACKBUFFERS; ulBBuf++) { #if defined(USE_BASE_VIDEO_FRAMEBUFFER) || defined (ENABLE_DISPLAY_MODE_TRACKING) psDevInfo->asBackBuffers[ulBBuf].sSysAddr.uiAddr = IMG_NULL; psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr = IMG_NULL; #else #if defined(DC_NOHW_DISCONTIG_BUFFERS) if (AllocDiscontigMemory(psDevInfo->ui32BufferSize, &psDevInfo->asBackBuffers[ulBBuf].hMemChunk, &psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr, &psDevInfo->asBackBuffers[ulBBuf].psSysAddr) != DC_OK) { eError = DC_ERROR_INIT_FAILURE; goto ExitFreeMem; } #else IMG_CPU_PHYADDR sBufferCPUPAddr; if (AllocContigMemory(psDevInfo->ui32BufferSize, &psDevInfo->asBackBuffers[ulBBuf].hMemChunk, &psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr, &sBufferCPUPAddr) != DC_OK) { eError = DC_ERROR_INIT_FAILURE; goto ExitFreeMem; } psDevInfo->asBackBuffers[ulBBuf].sSysAddr = CpuPAddrToSysPAddr(sBufferCPUPAddr); #endif #endif /* #if defined(USE_BASE_VIDEO_FRAMEBUFFER) */ /* sDevVAddr not meaningful for nohw */ psDevInfo->asBackBuffers[ulBBuf].sDevVAddr.uiAddr = 0UL; psDevInfo->asBackBuffers[ulBBuf].hSwapChain = 0; psDevInfo->asBackBuffers[ulBBuf].psSyncData = 0; psDevInfo->asBackBuffers[ulBBuf].psNext = 0; } /* setup the DC Jtable so SRVKM can call into this driver */ psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE); psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice; psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice; psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats; psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims; psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer; psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo; psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr; psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain; psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain; psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect; psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect; psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey; psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey; psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers; psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer; psDevInfo->sDCJTable.pfnSetDCState = IMG_NULL; /* register device with services and retrieve device index */ if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice (&psDevInfo->sDCJTable, &psDevInfo->uiDeviceID ) != PVRSRV_OK) { eError = DC_ERROR_DEVICE_REGISTER_FAILED; goto ExitFreeMem; } /* setup private command processing function table */ pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; /* and associated sync count(s) */ aui32SyncCountList[DC_FLIP_COMMAND][0] = 0UL;/* no writes */ aui32SyncCountList[DC_FLIP_COMMAND][1] = 2UL;/* 2 reads: To / From */ /* register private command processing functions with the Command Queue Manager and setup the general command complete function in the devinfo */ if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiDeviceID, &pfnCmdProcList[0], aui32SyncCountList, DC_NOHW_COMMAND_COUNT) != PVRSRV_OK) { eError = DC_ERROR_CANT_REGISTER_CALLBACK; goto ExitRemoveDevice; } } /* increment the ref count */ psDevInfo->ulRefCount++; /* return success */ return (DC_OK); ExitRemoveDevice: (IMG_VOID) psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiDeviceID); ExitFreeMem: ulNBBuf = ulBBuf; for(ulBBuf=0; ulBBuf<ulNBBuf; ulBBuf++) { #if defined(DC_NOHW_DISCONTIG_BUFFERS) FreeDiscontigMemory(psDevInfo->ui32BufferSize, psDevInfo->asBackBuffers[ulBBuf].hMemChunk, psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr, psDevInfo->asBackBuffers[ulBBuf].psSysAddr); #else #if !defined(USE_BASE_VIDEO_FRAMEBUFFER) FreeContigMemory(psDevInfo->ui32BufferSize, psDevInfo->asBackBuffers[ulBBuf].hMemChunk, psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr, SysPAddrToCpuPAddr(psDevInfo->asBackBuffers[ulBBuf].sSysAddr)); #endif /* #if defined(USE_BASE_VIDEO_FRAMEBUFFER) */ #endif /* #if defined(DC_NOHW_DISCONTIG_BUFFERS) */ } ExitCloseServices: (void)ClosePVRServices(psDevInfo->hPVRServices); ExitFreeDevInfo: FreeKernelMem(psDevInfo); SetAnchorPtr(0); ExitError: return eError; }