static enum PVRSRV_ERROR CreateDCSwapChain(void *hDevice, u32 ui32Flags, struct DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, struct DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, u32 ui32BufferCount, struct PVRSRV_SYNC_DATA **ppsSyncData, u32 ui32OEMFlags, void **phSwapChain, u32 *pui32SwapChainID) { struct OMAPLFB_DEVINFO *psDevInfo; struct OMAPLFB_SWAPCHAIN *psSwapChain; struct OMAPLFB_BUFFER *psBuffer; u32 i; enum PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; PVR_UNREFERENCED_PARAMETER(ui32OEMFlags); PVR_UNREFERENCED_PARAMETER(pui32SwapChainID); if (!hDevice || !psDstSurfAttrib || !psSrcSurfAttrib || !ppsSyncData || !phSwapChain) return PVRSRV_ERROR_INVALID_PARAMS; psDevInfo = (struct OMAPLFB_DEVINFO *)hDevice; if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) return PVRSRV_ERROR_NOT_SUPPORTED; if (psDevInfo->psSwapChain != NULL) return PVRSRV_ERROR_FLIP_CHAIN_EXISTS; if (ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) return PVRSRV_ERROR_TOOMANYBUFFERS; if ((psDevInfo->sFBInfo.ui32RoundedBufferSize * ui32BufferCount) > psDevInfo->sFBInfo.ui32FBSize) return PVRSRV_ERROR_TOOMANYBUFFERS; if (psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) return PVRSRV_ERROR_INVALID_PARAMS; if (psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) return PVRSRV_ERROR_INVALID_PARAMS; PVR_UNREFERENCED_PARAMETER(ui32Flags); psSwapChain = (struct OMAPLFB_SWAPCHAIN *) OMAPLFBAllocKernelMem(sizeof(struct OMAPLFB_SWAPCHAIN)); if (!psSwapChain) return PVRSRV_ERROR_OUT_OF_MEMORY; psBuffer = (struct OMAPLFB_BUFFER *) OMAPLFBAllocKernelMem(sizeof(struct OMAPLFB_BUFFER) * ui32BufferCount); if (!psBuffer) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorFreeSwapChain; } psSwapChain->ui32BufferCount = ui32BufferCount; psSwapChain->psBuffer = psBuffer; psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable; for (i = 0; i < ui32BufferCount - 1; i++) psBuffer[i].psNext = &psBuffer[i + 1]; psBuffer[i].psNext = &psBuffer[0]; for (i = 0; i < ui32BufferCount; i++) { u32 ui32BufferOffset = i * psDevInfo->sFBInfo.ui32RoundedBufferSize; psBuffer[i].psSyncData = ppsSyncData[i]; psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; } psDevInfo->psSwapChain = psSwapChain; eError = EnableLFBEventNotification(psDevInfo); if (eError != PVRSRV_OK) { printk(DRIVER_PREFIX ": Couldn't enable framebuffer event notification\n"); goto ErrorFreeBuffer; } *phSwapChain = (void *) psSwapChain; return PVRSRV_OK; ErrorFreeBuffer: OMAPLFBFreeKernelMem(psBuffer); ErrorFreeSwapChain: OMAPLFBFreeKernelMem(psSwapChain); return eError; }
static OMAPLFB_DEVINFO *OMAPLFBInitDev(unsigned uiFBDevID) { PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2]; OMAPLFB_DEVINFO *psDevInfo = NULL; psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO)); if(psDevInfo == NULL) { printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Couldn't allocate device information structure\n", __FUNCTION__, uiFBDevID); goto ErrorExit; } memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO)); psDevInfo->uiFBDevID = uiFBDevID; if(!(*gpfnGetPVRJTable)(&psDevInfo->sPVRJTable)) { goto ErrorFreeDevInfo; } #ifdef FBDEV_PRESENT if(OMAPLFBInitFBDev(psDevInfo) != OMAPLFB_OK) { goto ErrorFreeDevInfo; } psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize); if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers != 0) { psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1; psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1; } psDevInfo->sDisplayInfo.ui32PhysicalWidthmm = psDevInfo->sFBInfo.ulPhysicalWidthmm; psDevInfo->sDisplayInfo.ui32PhysicalHeightmm = psDevInfo->sFBInfo.ulPhysicalHeightmm; strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat; psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth; psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight; psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride; DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Maximum number of swap chain buffers: %u\n", psDevInfo->uiFBDevID, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)); psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr; psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr; psDevInfo->sSystemBuffer.psDevInfo = psDevInfo; OMAPLFBInitBufferForSwap(&psDevInfo->sSystemBuffer); #else psDevInfo->sSystemBuffer.sCPUVAddr = 0x100; // psDevInfo->sSystemBuffer.ulBufferSize = 600*3200; psDevInfo->sDisplayFormat.pixelformat = 20; psDevInfo->sFBInfo.ulWidth = 800; psDevInfo->sFBInfo.ulHeight = 600; psDevInfo->sFBInfo.ulByteStride = 3200; psDevInfo->sFBInfo.ulFBSize = 8388608; psDevInfo->sFBInfo.ulBufferSize = 600*3200; #endif 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 = SetDCState; if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice( &psDevInfo->sDCJTable, &psDevInfo->uiPVRDevID) != PVRSRV_OK) { printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: PVR Services device registration failed\n", __FUNCTION__, uiFBDevID); goto ErrorDeInitFBDev; } DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: PVR Device ID: %u\n", psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; aui32SyncCountList[DC_FLIP_COMMAND][1] = 2; if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiPVRDevID, &pfnCmdProcList[0], aui32SyncCountList, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) { printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Couldn't register command processing functions with PVR Services\n", __FUNCTION__, uiFBDevID); goto ErrorUnregisterDevice; } OMAPLFBCreateSwapChainLockInit(psDevInfo); OMAPLFBAtomicBoolInit(&psDevInfo->sBlanked, OMAPLFB_FALSE); OMAPLFBAtomicIntInit(&psDevInfo->sBlankEvents, 0); OMAPLFBAtomicBoolInit(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); #if defined(CONFIG_HAS_EARLYSUSPEND) OMAPLFBAtomicBoolInit(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); #endif #if defined(SUPPORT_DRI_DRM) OMAPLFBAtomicBoolInit(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); #endif return psDevInfo; ErrorUnregisterDevice: (void)psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID); ErrorDeInitFBDev: OMAPLFBDeInitFBDev(psDevInfo); ErrorFreeDevInfo: OMAPLFBFreeKernelMem(psDevInfo); ErrorExit: return NULL; }
static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, IMG_UINT32 ui32Flags, DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, IMG_UINT32 ui32BufferCount, PVRSRV_SYNC_DATA **ppsSyncData, IMG_UINT32 ui32OEMFlags, IMG_HANDLE *phSwapChain, IMG_UINT32 *pui32SwapChainID) { OMAPLFB_DEVINFO *psDevInfo; OMAPLFB_SWAPCHAIN *psSwapChain; OMAPLFB_BUFFER *psBuffer; OMAPLFB_VSYNC_FLIP_ITEM *psVSyncFlips; IMG_UINT32 i; PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; unsigned long ulLockFlags; IMG_UINT32 ui32BuffersToSkip; UNREFERENCED_PARAMETER(ui32OEMFlags); UNREFERENCED_PARAMETER(pui32SwapChainID); if(!hDevice || !psDstSurfAttrib || !psSrcSurfAttrib || !ppsSyncData || !phSwapChain) { return (PVRSRV_ERROR_INVALID_PARAMS); } psDevInfo = (OMAPLFB_DEVINFO*)hDevice; if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) { return (PVRSRV_ERROR_NOT_SUPPORTED); } if(psDevInfo->psSwapChain != NULL) { return (PVRSRV_ERROR_FLIP_CHAIN_EXISTS); } if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) { return (PVRSRV_ERROR_TOOMANYBUFFERS); } if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize) { return (PVRSRV_ERROR_TOOMANYBUFFERS); } ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount; if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) { return (PVRSRV_ERROR_INVALID_PARAMS); } if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) { return (PVRSRV_ERROR_INVALID_PARAMS); } UNREFERENCED_PARAMETER(ui32Flags); psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN)); if(!psSwapChain) { return (PVRSRV_ERROR_OUT_OF_MEMORY); } psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount); if(!psBuffer) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorFreeSwapChain; } psVSyncFlips = (OMAPLFB_VSYNC_FLIP_ITEM *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_VSYNC_FLIP_ITEM) * ui32BufferCount); if (!psVSyncFlips) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorFreeBuffers; } psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; psSwapChain->psBuffer = psBuffer; psSwapChain->psVSyncFlips = psVSyncFlips; psSwapChain->ulInsertIndex = 0; psSwapChain->ulRemoveIndex = 0; psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable; psSwapChain->psSwapChainLock = &psDevInfo->sSwapChainLock; for(i=0; i<ui32BufferCount-1; i++) { psBuffer[i].psNext = &psBuffer[i+1]; } psBuffer[i].psNext = &psBuffer[0]; for(i=0; i<ui32BufferCount; i++) { IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip; IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize; psBuffer[i].psSyncData = ppsSyncData[i]; psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; } for(i=0; i<ui32BufferCount; i++) { INIT_LIST_HEAD(&psBuffer[i].list); psVSyncFlips[i].bValid = OMAP_FALSE; psVSyncFlips[i].bFlipped = OMAP_FALSE; psVSyncFlips[i].bCmdCompleted = OMAP_FALSE; } spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); psDevInfo->psSwapChain = psSwapChain; psSwapChain->bFlushCommands = psDevInfo->bFlushCommands; if (psSwapChain->bFlushCommands) { psSwapChain->ulSetFlushStateRefCount = 1; } else { psSwapChain->ulSetFlushStateRefCount = 0; } spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); if (EnableLFBEventNotification(psDevInfo)!= OMAP_OK) { printk(KERN_WARNING DRIVER_PREFIX ": Couldn't enable framebuffer event notification\n"); goto ErrorFreeVsyncFlips; } *phSwapChain = (IMG_HANDLE)psSwapChain; return (PVRSRV_OK); ErrorFreeVsyncFlips: OMAPLFBFreeKernelMem(psVSyncFlips); ErrorFreeBuffers: OMAPLFBFreeKernelMem(psBuffer); ErrorFreeSwapChain: OMAPLFBFreeKernelMem(psSwapChain); return eError; }
static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, IMG_UINT32 ui32Flags, DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, IMG_UINT32 ui32BufferCount, PVRSRV_SYNC_DATA **ppsSyncData, IMG_UINT32 ui32OEMFlags, IMG_HANDLE *phSwapChain, IMG_UINT32 *pui32SwapChainID) { OMAPLFB_DEVINFO *psDevInfo; OMAPLFB_SWAPCHAIN *psSwapChain; OMAPLFB_BUFFER *psBuffer; IMG_UINT32 i; PVRSRV_ERROR eError; IMG_UINT32 ui32BuffersToSkip; UNREFERENCED_PARAMETER(ui32OEMFlags); if(!hDevice || !psDstSurfAttrib || !psSrcSurfAttrib || !ppsSyncData || !phSwapChain) { return PVRSRV_ERROR_INVALID_PARAMS; } psDevInfo = (OMAPLFB_DEVINFO*)hDevice; if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) { return PVRSRV_ERROR_NOT_SUPPORTED; } OMAPLFBCreateSwapChainLock(psDevInfo); if(psDevInfo->psSwapChain != NULL) { eError = PVRSRV_ERROR_FLIP_CHAIN_EXISTS; goto ExitUnLock; } if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) { eError = PVRSRV_ERROR_TOOMANYBUFFERS; goto ExitUnLock; } if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize) { eError = PVRSRV_ERROR_TOOMANYBUFFERS; goto ExitUnLock; } ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount; if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) { eError = PVRSRV_ERROR_INVALID_PARAMS; goto ExitUnLock; } if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) { eError = PVRSRV_ERROR_INVALID_PARAMS; goto ExitUnLock; } UNREFERENCED_PARAMETER(ui32Flags); #if defined(PVR_OMAPFB3_UPDATE_MODE) if (!OMAPLFBSetUpdateMode(psDevInfo, PVR_OMAPFB3_UPDATE_MODE)) { printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set frame buffer update mode %d\n", __FUNCTION__, psDevInfo->uiFBDevID, PVR_OMAPFB3_UPDATE_MODE); } #endif psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN)); if(!psSwapChain) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ExitUnLock; } psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount); if(!psBuffer) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorFreeSwapChain; } psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; psSwapChain->psBuffer = psBuffer; psSwapChain->bNotVSynced = OMAPLFB_TRUE; psSwapChain->uiFBDevID = psDevInfo->uiFBDevID; for(i=0; i<ui32BufferCount-1; i++) { psBuffer[i].psNext = &psBuffer[i+1]; } psBuffer[i].psNext = &psBuffer[0]; for(i=0; i<ui32BufferCount; i++) { IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip; IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize; psBuffer[i].psSyncData = ppsSyncData[i]; psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; psBuffer[i].ulYOffset = ui32BufferOffset / psDevInfo->sFBInfo.ulByteStride; psBuffer[i].psDevInfo = psDevInfo; OMAPLFBInitBufferForSwap(&psBuffer[i]); } if (OMAPLFBCreateSwapQueue(psSwapChain) != OMAPLFB_OK) { printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Failed to create workqueue\n", __FUNCTION__, psDevInfo->uiFBDevID); eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR; goto ErrorFreeBuffers; } if (OMAPLFBEnableLFBEventNotification(psDevInfo)!= OMAPLFB_OK) { eError = PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT; printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't enable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); goto ErrorDestroySwapQueue; } psDevInfo->uiSwapChainID++; if (psDevInfo->uiSwapChainID == 0) { psDevInfo->uiSwapChainID++; } psSwapChain->uiSwapChainID = psDevInfo->uiSwapChainID; psDevInfo->psSwapChain = psSwapChain; *pui32SwapChainID = psDevInfo->uiSwapChainID; *phSwapChain = (IMG_HANDLE)psSwapChain; eError = PVRSRV_OK; goto ExitUnLock; ErrorDestroySwapQueue: OMAPLFBDestroySwapQueue(psSwapChain); ErrorFreeBuffers: OMAPLFBFreeKernelMem(psBuffer); ErrorFreeSwapChain: OMAPLFBFreeKernelMem(psSwapChain); ExitUnLock: OMAPLFBCreateSwapChainUnLock(psDevInfo); return eError; }
OMAP_ERROR OMAPLFBInit(void) { OMAPLFB_DEVINFO *psDevInfo; psDevInfo = GetAnchorPtr(); if (psDevInfo == NULL) { PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2]; psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO)); if(!psDevInfo) { return (OMAP_ERROR_OUT_OF_MEMORY); } memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO)); SetAnchorPtr((void*)psDevInfo); psDevInfo->ulRefCount = 0; if(InitDev(psDevInfo) != OMAP_OK) { return (OMAP_ERROR_INIT_FAILURE); } if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &pfnGetPVRJTable) != OMAP_OK) { return (OMAP_ERROR_INIT_FAILURE); } if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable)) { return (OMAP_ERROR_INIT_FAILURE); } spin_lock_init(&psDevInfo->sSwapChainLock); psDevInfo->psSwapChain = 0; psDevInfo->bFlushCommands = OMAP_FALSE; psDevInfo->bDeviceSuspended = OMAP_FALSE; psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize); if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers == 0) { psDevInfo->sDisplayInfo.ui32MaxSwapChains = 0; psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 0; } else { psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1; psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3; } psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0; strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat; psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth; psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight; psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride; DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Maximum number of swap chain buffers: %lu\n", psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)); psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr; psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr; psDevInfo->sSystemBuffer.ulBufferSize = psDevInfo->sFBInfo.ulRoundedBufferSize; 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 = SetDCState; if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice ( &psDevInfo->sDCJTable, &psDevInfo->ulDeviceID ) != PVRSRV_OK) { return (OMAP_ERROR_DEVICE_REGISTER_FAILED); } pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; aui32SyncCountList[DC_FLIP_COMMAND][1] = 2; if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList (psDevInfo->ulDeviceID, &pfnCmdProcList[0], aui32SyncCountList, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) { printk(KERN_WARNING DRIVER_PREFIX ": Can't register callback\n"); return (OMAP_ERROR_CANT_REGISTER_CALLBACK); } } psDevInfo->ulRefCount++; return (OMAP_OK); }