static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice, IMG_HANDLE hSwapChain) { MTKLFB_DEVINFO *psDevInfo; MTKLFB_SWAPCHAIN *psSwapChain; MTKLFB_ERROR eError; if(!hDevice || !hSwapChain) { return PVRSRV_ERROR_INVALID_PARAMS; } psDevInfo = (MTKLFB_DEVINFO*)hDevice; psSwapChain = (MTKLFB_SWAPCHAIN*)hSwapChain; MTKLFBCreateSwapChainLock(psDevInfo); if (SwapChainHasChanged(psDevInfo, psSwapChain)) { printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); eError = PVRSRV_ERROR_INVALID_PARAMS; goto ExitUnLock; } MTKLFBDestroySwapQueue(psSwapChain); eError = MTKLFBDisableLFBEventNotification(psDevInfo); if (eError != MTKLFB_OK) { printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't disable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); } MTKLFBFreeKernelMem(psSwapChain->psBuffer); MTKLFBFreeKernelMem(psSwapChain); psDevInfo->psSwapChain = NULL; MTKLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); (void) MTKLFBCheckModeAndSync(psDevInfo); eError = PVRSRV_OK; ExitUnLock: MTKLFBCreateSwapChainUnLock(psDevInfo); return eError; }
static MTKLFB_BOOL MTKLFBDeInitDev(MTKLFB_DEVINFO *psDevInfo) { PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable = &psDevInfo->sPVRJTable; MTKLFBCreateSwapChainLockDeInit(psDevInfo); MTKLFBAtomicBoolDeInit(&psDevInfo->sBlanked); MTKLFBAtomicIntDeInit(&psDevInfo->sBlankEvents); MTKLFBAtomicBoolDeInit(&psDevInfo->sFlushCommands); #if defined(CONFIG_HAS_EARLYSUSPEND) MTKLFBAtomicBoolDeInit(&psDevInfo->sEarlySuspendFlag); #endif #if defined(SUPPORT_DRI_DRM) MTKLFBAtomicBoolDeInit(&psDevInfo->sLeaveVT); #endif psPVRJTable = &psDevInfo->sPVRJTable; if (psPVRJTable->pfnPVRSRVRemoveCmdProcList (psDevInfo->uiPVRDevID, MTKLFB_COMMAND_COUNT) != PVRSRV_OK) { xlog_printk(ANDROID_LOG_ERROR, DRIVER_PREFIX, DRIVER_PREFIX ": %s: Device %u: PVR Device %u: Couldn't unregister command processing functions\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); return MTKLFB_FALSE; } if (psPVRJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID) != PVRSRV_OK) { xlog_printk(ANDROID_LOG_ERROR, DRIVER_PREFIX, DRIVER_PREFIX ": %s: Device %u: PVR Device %u: Couldn't remove device from PVR Services\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); return MTKLFB_FALSE; } MTKLFBDeInitFBDev(psDevInfo); MTKLFBSetDevInfoPtr(psDevInfo->uiFBDevID, NULL); MTKLFBFreeKernelMem(psDevInfo); return MTKLFB_TRUE; }
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) { MTKLFB_DEVINFO *psDevInfo; MTKLFB_SWAPCHAIN *psSwapChain; MTKLFB_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 = (MTKLFB_DEVINFO*)hDevice; if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) { return PVRSRV_ERROR_NOT_SUPPORTED; } MTKLFBCreateSwapChainLock(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_MTKFB3_UPDATE_MODE) if (!MTKLFBSetUpdateMode(psDevInfo, PVR_MTKFB3_UPDATE_MODE)) { xlog_printk(ANDROID_LOG_WARN, DRIVER_PREFIX, DRIVER_PREFIX ": %s: Device %u: Couldn't set frame buffer update mode %d\n", __FUNCTION__, psDevInfo->uiFBDevID, PVR_MTKFB3_UPDATE_MODE); } #endif psSwapChain = (MTKLFB_SWAPCHAIN*)MTKLFBAllocKernelMem(sizeof(MTKLFB_SWAPCHAIN)); if(!psSwapChain) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ExitUnLock; } psBuffer = (MTKLFB_BUFFER*)MTKLFBAllocKernelMem(sizeof(MTKLFB_BUFFER) * ui32BufferCount); if(!psBuffer) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorFreeSwapChain; } psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; psSwapChain->psBuffer = psBuffer; psSwapChain->bNotVSynced = MTKLFB_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; MTKLFBInitBufferForSwap(&psBuffer[i]); } if (MTKLFBCreateSwapQueue(psSwapChain) != MTKLFB_OK) { xlog_printk(ANDROID_LOG_WARN, DRIVER_PREFIX, DRIVER_PREFIX ": %s: Device %u: Failed to create workqueue\n", __FUNCTION__, psDevInfo->uiFBDevID); eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR; goto ErrorFreeBuffers; } if (MTKLFBEnableLFBEventNotification(psDevInfo)!= MTKLFB_OK) { eError = PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT; xlog_printk(ANDROID_LOG_WARN, DRIVER_PREFIX, 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: MTKLFBDestroySwapQueue(psSwapChain); ErrorFreeBuffers: MTKLFBFreeKernelMem(psBuffer); ErrorFreeSwapChain: MTKLFBFreeKernelMem(psSwapChain); ExitUnLock: MTKLFBCreateSwapChainUnLock(psDevInfo); return eError; }
static MTKLFB_DEVINFO *MTKLFBInitDev(unsigned uiFBDevID) { PFN_CMD_PROC pfnCmdProcList[MTKLFB_COMMAND_COUNT]; IMG_UINT32 aui32SyncCountList[MTKLFB_COMMAND_COUNT][2]; MTKLFB_DEVINFO *psDevInfo = NULL; psDevInfo = (MTKLFB_DEVINFO *)MTKLFBAllocKernelMem(sizeof(MTKLFB_DEVINFO)); if(psDevInfo == NULL) { xlog_printk(ANDROID_LOG_ERROR, DRIVER_PREFIX, DRIVER_PREFIX ": %s: Device %u: Couldn't allocate device information structure\n", __FUNCTION__, uiFBDevID); goto ErrorExit; } memset(psDevInfo, 0, sizeof(MTKLFB_DEVINFO)); psDevInfo->uiFBDevID = uiFBDevID; if(!(*gpfnGetPVRJTable)(&psDevInfo->sPVRJTable)) { goto ErrorFreeDevInfo; } if(MTKLFBInitFBDev(psDevInfo) != MTKLFB_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; MTKLFBInitBufferForSwap(&psDevInfo->sSystemBuffer); 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 = SetDCState; if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice( &psDevInfo->sDCJTable, &psDevInfo->uiPVRDevID) != PVRSRV_OK) { xlog_printk(ANDROID_LOG_ERROR, DRIVER_PREFIX, 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] = 10; if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiPVRDevID, &pfnCmdProcList[0], aui32SyncCountList, MTKLFB_COMMAND_COUNT) != PVRSRV_OK) { xlog_printk(ANDROID_LOG_ERROR, DRIVER_PREFIX, DRIVER_PREFIX ": %s: Device %u: Couldn't register command processing functions with PVR Services\n", __FUNCTION__, uiFBDevID); goto ErrorUnregisterDevice; } MTKLFBCreateSwapChainLockInit(psDevInfo); MTKLFBAtomicBoolInit(&psDevInfo->sBlanked, MTKLFB_FALSE); MTKLFBAtomicIntInit(&psDevInfo->sBlankEvents, 0); MTKLFBAtomicBoolInit(&psDevInfo->sFlushCommands, MTKLFB_FALSE); #if defined(CONFIG_HAS_EARLYSUSPEND) MTKLFBAtomicBoolInit(&psDevInfo->sEarlySuspendFlag, MTKLFB_FALSE); #endif #if defined(SUPPORT_DRI_DRM) MTKLFBAtomicBoolInit(&psDevInfo->sLeaveVT, MTKLFB_FALSE); #endif return psDevInfo; ErrorUnregisterDevice: (void)psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID); ErrorDeInitFBDev: MTKLFBDeInitFBDev(psDevInfo); ErrorFreeDevInfo: MTKLFBFreeKernelMem(psDevInfo); ErrorExit: return NULL; }