1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
27 #include <linux/version.h>
28 #include <linux/kernel.h>
29 #include <linux/console.h>
31 #include <linux/module.h>
32 #include <linux/string.h>
33 #include <linux/notifier.h>
36 #include "servicesext.h"
37 #include "kerneldisplay.h"
40 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
41 #define acquire_console_sem console_lock
42 #define release_console_sem console_unlock
45 static void *gpvAnchor;
47 static int fb_idx = 0;
49 #define OMAPLFB_COMMAND_COUNT 1
51 static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = 0;
52 static void OMAPLFBVSyncIHandler(struct work_struct*);
54 #define OMAPLFB_PAGE_SIZE 4096
56 /* Greatest common divisor */
57 static unsigned long gcd(unsigned long a, unsigned long b)
67 while ((r = a % b) != 0) {
76 * Workout the smallest size that is aligned to both 4K (for the SGX)
77 * and line length (for the fbdev driver).
79 static unsigned int sgx_buffer_align(unsigned stride, unsigned size)
86 lcm = stride * OMAPLFB_PAGE_SIZE / gcd(stride,
89 return roundup(size, lcm);
92 OMAPLFB_DEVINFO * GetAnchorPtr(void)
94 return (OMAPLFB_DEVINFO *)gpvAnchor;
97 static void SetAnchorPtr(OMAPLFB_DEVINFO *psDevInfo)
99 gpvAnchor = (void*)psDevInfo;
103 static void FlushInternalVSyncQueue(OMAPLFB_SWAPCHAIN *psSwapChain)
105 OMAPLFB_VSYNC_FLIP_ITEM *psFlipItem;
106 unsigned long ulMaxIndex;
110 psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
111 ulMaxIndex = psSwapChain->ulBufferCount - 1;
113 for(i = 0; i < psSwapChain->ulBufferCount; i++)
115 if (psFlipItem->bValid == OMAP_FALSE)
120 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Flushing swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex));
122 if(psFlipItem->bFlipped == OMAP_FALSE)
125 OMAPLFBFlip(psSwapChain, (unsigned long)psFlipItem->sSysAddr);
128 if(psFlipItem->bCmdCompleted == OMAP_FALSE)
130 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Calling command complete for swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex));
132 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_TRUE);
136 psSwapChain->ulRemoveIndex++;
138 if(psSwapChain->ulRemoveIndex > ulMaxIndex)
140 psSwapChain->ulRemoveIndex = 0;
144 psFlipItem->bFlipped = OMAP_FALSE;
145 psFlipItem->bCmdCompleted = OMAP_FALSE;
146 psFlipItem->bValid = OMAP_FALSE;
149 psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
152 psSwapChain->ulInsertIndex = 0;
153 psSwapChain->ulRemoveIndex = 0;
156 static void SetFlushStateInternalNoLock(OMAPLFB_DEVINFO* psDevInfo,
157 OMAP_BOOL bFlushState)
159 OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain;
161 if (psSwapChain == NULL)
168 if (psSwapChain->ulSetFlushStateRefCount == 0)
170 psSwapChain->bFlushCommands = OMAP_TRUE;
171 FlushInternalVSyncQueue(psSwapChain);
173 psSwapChain->ulSetFlushStateRefCount++;
177 if (psSwapChain->ulSetFlushStateRefCount != 0)
179 psSwapChain->ulSetFlushStateRefCount--;
180 if (psSwapChain->ulSetFlushStateRefCount == 0)
182 psSwapChain->bFlushCommands = OMAP_FALSE;
188 static IMG_VOID SetFlushStateInternal(OMAPLFB_DEVINFO* psDevInfo,
189 OMAP_BOOL bFlushState)
191 mutex_lock(&psDevInfo->sSwapChainLockMutex);
193 SetFlushStateInternalNoLock(psDevInfo, bFlushState);
195 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
198 static void SetFlushStateExternal(OMAPLFB_DEVINFO* psDevInfo,
199 OMAP_BOOL bFlushState)
201 mutex_lock(&psDevInfo->sSwapChainLockMutex);
204 if (psDevInfo->bFlushCommands != bFlushState)
206 psDevInfo->bFlushCommands = bFlushState;
207 SetFlushStateInternalNoLock(psDevInfo, bFlushState);
210 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
213 static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
215 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice;
219 case DC_STATE_FLUSH_COMMANDS:
220 SetFlushStateExternal(psDevInfo, OMAP_TRUE);
222 case DC_STATE_NO_FLUSH_COMMANDS:
223 SetFlushStateExternal(psDevInfo, OMAP_FALSE);
232 static int FrameBufferEvents(struct notifier_block *psNotif,
233 unsigned long event, void *data)
235 OMAPLFB_DEVINFO *psDevInfo;
236 OMAPLFB_SWAPCHAIN *psSwapChain;
237 struct fb_event *psFBEvent = (struct fb_event *)data;
241 if (event != FB_EVENT_BLANK)
246 psDevInfo = GetAnchorPtr();
247 psSwapChain = psDevInfo->psSwapChain;
249 bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? OMAP_TRUE: OMAP_FALSE;
251 if (bBlanked != psSwapChain->bBlanked)
253 psSwapChain->bBlanked = bBlanked;
258 SetFlushStateInternal(psDevInfo, OMAP_TRUE);
263 SetFlushStateInternal(psDevInfo, OMAP_FALSE);
271 static OMAP_ERROR UnblankDisplay(OMAPLFB_DEVINFO *psDevInfo)
275 acquire_console_sem();
276 res = fb_blank(psDevInfo->psLINFBInfo, 0);
277 release_console_sem();
278 if (res != 0 && res != -EINVAL)
280 printk(KERN_WARNING DRIVER_PREFIX
281 ": fb_blank failed (%d)", res);
282 return (OMAP_ERROR_GENERIC);
288 #if defined (CONFIG_OMAP2_DSS)
289 #include <linux/omapfb.h>
290 #include <linux/workqueue.h>
292 struct fb_var_screeninfo var;
293 struct fb_info *psLINFBInfo;
294 struct work_struct work;
296 struct wq_flip wq_flipdss2;
298 static void dss2_pan_display (struct work_struct *work)
300 struct wq_flip *ptrwq_flip =
301 container_of(work, struct wq_flip, work);
302 if (ptrwq_flip->psLINFBInfo->fbops->fb_pan_display != NULL) {
303 ptrwq_flip->psLINFBInfo->fbops->fb_pan_display (&ptrwq_flip->var, ptrwq_flip->psLINFBInfo);
310 Flip implementation for DSS2 using fb_pan_display
312 IMG_VOID OMAPLFBFlipDSS2(OMAPLFB_SWAPCHAIN *psSwapChain,
313 IMG_UINT32 aPhyAddr, int now)
315 OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr ();
316 struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo;
317 memcpy ( &wq_flipdss2.var, &psLINFBInfo->var, sizeof(struct fb_var_screeninfo));
318 wq_flipdss2.var.yoffset = (aPhyAddr-psLINFBInfo->fix.smem_start)/psLINFBInfo->fix.line_length;
319 wq_flipdss2.psLINFBInfo = psLINFBInfo;
321 dss2_pan_display(&wq_flipdss2.work);
323 schedule_work (&wq_flipdss2.work);
327 void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
329 OMAPLFBFlipDSS2 (psSwapChain, aPhyAddr, 0);
332 void OMAPLFBWaitForVSync(void)
335 if (lcd_mgr && lcd_mgr->device)
336 lcd_mgr->device->wait_vsync(lcd_mgr->device);
340 static OMAP_ERROR EnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo)
345 OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain;
348 memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock));
350 psDevInfo->sLINNotifBlock.notifier_call = FrameBufferEvents;
352 psSwapChain->bBlanked = OMAP_FALSE;
354 res = fb_register_client(&psDevInfo->sLINNotifBlock);
357 printk(KERN_WARNING DRIVER_PREFIX
358 ": fb_register_client failed (%d)", res);
360 return (OMAP_ERROR_GENERIC);
363 eError = UnblankDisplay(psDevInfo);
364 if (eError != OMAP_OK)
366 DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
367 ": UnblankDisplay failed (%d)", eError));
374 static OMAP_ERROR DisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo)
380 res = fb_unregister_client(&psDevInfo->sLINNotifBlock);
383 printk(KERN_WARNING DRIVER_PREFIX
384 ": fb_unregister_client failed (%d)", res);
385 return (OMAP_ERROR_GENERIC);
391 static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID,
392 IMG_HANDLE *phDevice,
393 PVRSRV_SYNC_DATA* psSystemBufferSyncData)
395 OMAPLFB_DEVINFO *psDevInfo;
398 UNREFERENCED_PARAMETER(ui32DeviceID);
400 psDevInfo = GetAnchorPtr();
403 psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData;
405 eError = UnblankDisplay(psDevInfo);
406 if (eError != OMAP_OK)
408 DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
409 ": UnblankDisplay failed (%d)", eError));
410 return (PVRSRV_ERROR_GENERIC);
414 *phDevice = (IMG_HANDLE)psDevInfo;
419 static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
421 UNREFERENCED_PARAMETER(hDevice);
426 static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice,
427 IMG_UINT32 *pui32NumFormats,
428 DISPLAY_FORMAT *psFormat)
430 OMAPLFB_DEVINFO *psDevInfo;
432 if(!hDevice || !pui32NumFormats)
434 return (PVRSRV_ERROR_INVALID_PARAMS);
437 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
439 *pui32NumFormats = 1;
443 psFormat[0] = psDevInfo->sDisplayFormat;
449 static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice,
450 DISPLAY_FORMAT *psFormat,
451 IMG_UINT32 *pui32NumDims,
454 OMAPLFB_DEVINFO *psDevInfo;
456 if(!hDevice || !psFormat || !pui32NumDims)
458 return (PVRSRV_ERROR_INVALID_PARAMS);
461 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
468 psDim[0] = psDevInfo->sDisplayDim;
475 static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer)
477 OMAPLFB_DEVINFO *psDevInfo;
479 if(!hDevice || !phBuffer)
481 return (PVRSRV_ERROR_INVALID_PARAMS);
484 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
486 *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer;
492 static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
494 OMAPLFB_DEVINFO *psDevInfo;
496 if(!hDevice || !psDCInfo)
498 return (PVRSRV_ERROR_INVALID_PARAMS);
501 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
503 *psDCInfo = psDevInfo->sDisplayInfo;
508 static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice,
510 IMG_SYS_PHYADDR **ppsSysAddr,
511 IMG_UINT32 *pui32ByteSize,
512 IMG_VOID **ppvCpuVAddr,
513 IMG_HANDLE *phOSMapInfo,
514 IMG_BOOL *pbIsContiguous)
516 OMAPLFB_DEVINFO *psDevInfo;
517 OMAPLFB_BUFFER *psSystemBuffer;
521 return (PVRSRV_ERROR_INVALID_PARAMS);
523 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
527 return (PVRSRV_ERROR_INVALID_PARAMS);
529 psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer;
533 return (PVRSRV_ERROR_INVALID_PARAMS);
536 *ppsSysAddr = &psSystemBuffer->sSysAddr;
540 return (PVRSRV_ERROR_INVALID_PARAMS);
543 *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize;
547 *ppvCpuVAddr = psSystemBuffer->sCPUVAddr;
552 *phOSMapInfo = (IMG_HANDLE)0;
557 *pbIsContiguous = IMG_TRUE;
563 static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice,
564 IMG_UINT32 ui32Flags,
565 DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
566 DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
567 IMG_UINT32 ui32BufferCount,
568 PVRSRV_SYNC_DATA **ppsSyncData,
569 IMG_UINT32 ui32OEMFlags,
570 IMG_HANDLE *phSwapChain,
571 IMG_UINT32 *pui32SwapChainID)
573 OMAPLFB_DEVINFO *psDevInfo;
574 OMAPLFB_SWAPCHAIN *psSwapChain;
575 OMAPLFB_BUFFER *psBuffer;
576 OMAPLFB_VSYNC_FLIP_ITEM *psVSyncFlips;
578 PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC;
579 IMG_UINT32 ui32BuffersToSkip;
580 UNREFERENCED_PARAMETER(ui32OEMFlags);
581 UNREFERENCED_PARAMETER(pui32SwapChainID);
590 return (PVRSRV_ERROR_INVALID_PARAMS);
593 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
596 if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0)
598 return (PVRSRV_ERROR_NOT_SUPPORTED);
602 if(psDevInfo->psSwapChain != NULL)
604 return (PVRSRV_ERROR_FLIP_CHAIN_EXISTS);
608 if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)
610 return (PVRSRV_ERROR_TOOMANYBUFFERS);
613 if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize)
615 return (PVRSRV_ERROR_TOOMANYBUFFERS);
619 ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount;
622 if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat
623 || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride
624 || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width
625 || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height)
628 return (PVRSRV_ERROR_INVALID_PARAMS);
631 if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat
632 || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride
633 || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width
634 || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height)
637 return (PVRSRV_ERROR_INVALID_PARAMS);
641 UNREFERENCED_PARAMETER(ui32Flags);
644 psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN));
647 return (PVRSRV_ERROR_OUT_OF_MEMORY);
650 psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount);
653 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
654 goto ErrorFreeSwapChain;
657 psVSyncFlips = (OMAPLFB_VSYNC_FLIP_ITEM *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_VSYNC_FLIP_ITEM) * ui32BufferCount);
660 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
661 goto ErrorFreeBuffers;
664 psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
665 psSwapChain->psBuffer = psBuffer;
666 psSwapChain->psVSyncFlips = psVSyncFlips;
667 psSwapChain->ulInsertIndex = 0;
668 psSwapChain->ulRemoveIndex = 0;
669 psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable;
670 psSwapChain->pvDevInfo = (void*)psDevInfo;
672 /* Init the workqueue and its own work */
673 INIT_WORK(&psDevInfo->vsync_work, OMAPLFBVSyncIHandler);
674 psDevInfo->vsync_isr_wq = create_workqueue("pvr_vsync_wq");
676 for(i=0; i<ui32BufferCount-1; i++)
678 psBuffer[i].psNext = &psBuffer[i+1];
681 psBuffer[i].psNext = &psBuffer[0];
684 for(i=0; i<ui32BufferCount; i++)
686 IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip;
687 IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize;
689 psBuffer[i].psSyncData = ppsSyncData[i];
691 psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset;
692 psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset;
695 for(i=0; i<ui32BufferCount; i++)
697 psVSyncFlips[i].bValid = OMAP_FALSE;
698 psVSyncFlips[i].bFlipped = OMAP_FALSE;
699 psVSyncFlips[i].bCmdCompleted = OMAP_FALSE;
702 mutex_lock(&psDevInfo->sSwapChainLockMutex);
704 psDevInfo->psSwapChain = psSwapChain;
706 psSwapChain->bFlushCommands = psDevInfo->bFlushCommands;
708 if (psSwapChain->bFlushCommands)
710 psSwapChain->ulSetFlushStateRefCount = 1;
714 psSwapChain->ulSetFlushStateRefCount = 0;
717 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
719 if (EnableLFBEventNotification(psDevInfo)!= OMAP_OK)
721 printk(KERN_WARNING DRIVER_PREFIX ": Couldn't enable framebuffer event notification\n");
722 goto ErrorDisableDisplayRegisters;
725 /* this is often 2 but could be 3, why oh why? */
726 printk(KERN_INFO "CreateDCSwapChain ui32BufferCount: %u\n", (u32)ui32BufferCount);
728 *phSwapChain = (IMG_HANDLE)psSwapChain;
732 ErrorDisableDisplayRegisters:
733 OMAPLFBFreeKernelMem(psVSyncFlips);
735 OMAPLFBFreeKernelMem(psBuffer);
737 OMAPLFBFreeKernelMem(psSwapChain);
742 static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
743 IMG_HANDLE hSwapChain)
745 OMAPLFB_DEVINFO *psDevInfo;
746 OMAPLFB_SWAPCHAIN *psSwapChain;
750 if(!hDevice || !hSwapChain)
752 return (PVRSRV_ERROR_INVALID_PARAMS);
755 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
756 psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
757 if (psSwapChain != psDevInfo->psSwapChain)
759 return (PVRSRV_ERROR_INVALID_PARAMS);
762 eError = DisableLFBEventNotification(psDevInfo);
763 if (eError != OMAP_OK)
765 printk(KERN_WARNING DRIVER_PREFIX ": Couldn't disable framebuffer event notification\n");
768 mutex_lock(&psDevInfo->sSwapChainLockMutex);
770 FlushInternalVSyncQueue(psSwapChain);
772 OMAPLFBFlip(psSwapChain, (unsigned long)psDevInfo->sFBInfo.sSysAddr.uiAddr);
774 psDevInfo->psSwapChain = NULL;
776 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
778 /* Destroy the workqueue */
779 flush_workqueue(psDevInfo->vsync_isr_wq);
780 destroy_workqueue(psDevInfo->vsync_isr_wq);
782 OMAPLFBFreeKernelMem(psSwapChain->psVSyncFlips);
783 OMAPLFBFreeKernelMem(psSwapChain->psBuffer);
784 OMAPLFBFreeKernelMem(psSwapChain);
789 static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice,
790 IMG_HANDLE hSwapChain,
793 UNREFERENCED_PARAMETER(hDevice);
794 UNREFERENCED_PARAMETER(hSwapChain);
795 UNREFERENCED_PARAMETER(psRect);
799 return (PVRSRV_ERROR_NOT_SUPPORTED);
802 static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice,
803 IMG_HANDLE hSwapChain,
806 UNREFERENCED_PARAMETER(hDevice);
807 UNREFERENCED_PARAMETER(hSwapChain);
808 UNREFERENCED_PARAMETER(psRect);
812 return (PVRSRV_ERROR_NOT_SUPPORTED);
815 static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice,
816 IMG_HANDLE hSwapChain,
817 IMG_UINT32 ui32CKColour)
819 UNREFERENCED_PARAMETER(hDevice);
820 UNREFERENCED_PARAMETER(hSwapChain);
821 UNREFERENCED_PARAMETER(ui32CKColour);
825 return (PVRSRV_ERROR_NOT_SUPPORTED);
828 static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice,
829 IMG_HANDLE hSwapChain,
830 IMG_UINT32 ui32CKColour)
832 UNREFERENCED_PARAMETER(hDevice);
833 UNREFERENCED_PARAMETER(hSwapChain);
834 UNREFERENCED_PARAMETER(ui32CKColour);
838 return (PVRSRV_ERROR_NOT_SUPPORTED);
841 static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice,
842 IMG_HANDLE hSwapChain,
843 IMG_UINT32 *pui32BufferCount,
844 IMG_HANDLE *phBuffer)
846 OMAPLFB_DEVINFO *psDevInfo;
847 OMAPLFB_SWAPCHAIN *psSwapChain;
856 return (PVRSRV_ERROR_INVALID_PARAMS);
859 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
860 psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
861 if (psSwapChain != psDevInfo->psSwapChain)
863 return (PVRSRV_ERROR_INVALID_PARAMS);
867 *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount;
870 for(i=0; i<psSwapChain->ulBufferCount; i++)
872 phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i];
878 static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
880 IMG_UINT32 ui32SwapInterval,
881 IMG_HANDLE hPrivateTag,
882 IMG_UINT32 ui32ClipRectCount,
883 IMG_RECT *psClipRect)
885 OMAPLFB_DEVINFO *psDevInfo;
887 UNREFERENCED_PARAMETER(ui32SwapInterval);
888 UNREFERENCED_PARAMETER(hPrivateTag);
889 UNREFERENCED_PARAMETER(psClipRect);
893 || (ui32ClipRectCount != 0))
895 return (PVRSRV_ERROR_INVALID_PARAMS);
898 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
904 static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice,
905 IMG_HANDLE hSwapChain)
907 OMAPLFB_DEVINFO *psDevInfo;
908 OMAPLFB_SWAPCHAIN *psSwapChain;
910 if(!hDevice || !hSwapChain)
912 return (PVRSRV_ERROR_INVALID_PARAMS);
915 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
916 psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
917 if (psSwapChain != psDevInfo->psSwapChain)
919 return (PVRSRV_ERROR_INVALID_PARAMS);
922 mutex_lock(&psDevInfo->sSwapChainLockMutex);
924 FlushInternalVSyncQueue(psSwapChain);
926 OMAPLFBFlip(psSwapChain, (unsigned long)psDevInfo->sFBInfo.sSysAddr.uiAddr);
928 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
933 static void OMAPLFBVSyncIHandler(struct work_struct *work)
935 OMAPLFB_DEVINFO *psDevInfo = container_of(work, OMAPLFB_DEVINFO, vsync_work);
936 OMAPLFB_VSYNC_FLIP_ITEM *psFlipItem;
937 OMAPLFB_SWAPCHAIN *psSwapChain;
938 unsigned long ulMaxIndex;
940 mutex_lock(&psDevInfo->sSwapChainLockMutex);
942 psSwapChain = psDevInfo->psSwapChain;
943 if (!psSwapChain || psSwapChain->bFlushCommands)
946 psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
947 ulMaxIndex = psSwapChain->ulBufferCount - 1;
949 /* VSync with the display here */
950 OMAPLFBWaitForVSync();
952 while(psFlipItem->bValid)
955 if(psFlipItem->bFlipped)
958 if(!psFlipItem->bCmdCompleted)
961 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_TRUE);
964 psFlipItem->bCmdCompleted = OMAP_TRUE;
968 psFlipItem->ulSwapInterval--;
971 if(psFlipItem->ulSwapInterval == 0)
974 psSwapChain->ulRemoveIndex++;
976 if(psSwapChain->ulRemoveIndex > ulMaxIndex)
978 psSwapChain->ulRemoveIndex = 0;
982 psFlipItem->bCmdCompleted = OMAP_FALSE;
983 psFlipItem->bFlipped = OMAP_FALSE;
986 psFlipItem->bValid = OMAP_FALSE;
990 queue_work(psDevInfo->vsync_isr_wq, &psDevInfo->vsync_work);
997 OMAPLFBFlip(psSwapChain, (unsigned long)psFlipItem->sSysAddr);
999 psFlipItem->bFlipped = OMAP_TRUE;
1002 * If the flip has been presented here then we need in the next
1003 * VSYNC execute the command complete, schedule another work
1005 queue_work(psDevInfo->vsync_isr_wq, &psDevInfo->vsync_work);
1011 psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
1015 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1019 static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie,
1020 IMG_UINT32 ui32DataSize,
1023 DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1024 OMAPLFB_DEVINFO *psDevInfo;
1025 OMAPLFB_BUFFER *psBuffer;
1026 OMAPLFB_SWAPCHAIN *psSwapChain;
1027 #if defined(SYS_USING_INTERRUPTS)
1028 OMAPLFB_VSYNC_FLIP_ITEM* psFlipItem;
1031 if(!hCmdCookie || !pvData)
1037 psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
1039 if (psFlipCmd == IMG_NULL || sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize)
1045 psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice;
1047 psBuffer = (OMAPLFB_BUFFER*)psFlipCmd->hExtBuffer;
1048 psSwapChain = (OMAPLFB_SWAPCHAIN*) psFlipCmd->hExtSwapChain;
1050 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1052 if (psDevInfo->bDeviceSuspended)
1054 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE);
1055 goto ExitTrueUnlock;
1058 #if defined(SYS_USING_INTERRUPTS)
1060 // if(psFlipCmd->ui32SwapInterval == 0 || psSwapChain->bFlushCommands == OMAP_TRUE)
1064 OMAPLFBFlipDSS2(psSwapChain, psBuffer->sSysAddr.uiAddr, 1);
1066 if (psSwapChain->ulBufferCount == 2)
1067 psDevInfo->psLINFBInfo->fbops->fb_ioctl(
1068 psDevInfo->psLINFBInfo, OMAPFB_WAITFORGO, 0);
1070 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE);
1072 #if defined(SYS_USING_INTERRUPTS)
1073 goto ExitTrueUnlock;
1076 psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulInsertIndex];
1079 if(psFlipItem->bValid == OMAP_FALSE)
1081 unsigned long ulMaxIndex = psSwapChain->ulBufferCount - 1;
1083 if(psSwapChain->ulInsertIndex == psSwapChain->ulRemoveIndex)
1085 /* If both indexes are equal the queue is empty, present immediatly */
1086 OMAPLFBFlip(psSwapChain, (unsigned long)psBuffer->sSysAddr.uiAddr);
1088 psFlipItem->bFlipped = OMAP_TRUE;
1092 psFlipItem->bFlipped = OMAP_FALSE;
1095 /* The buffer is queued here, must be consumed by the VSYNC workqueue */
1096 psFlipItem->hCmdComplete = (OMAP_HANDLE)hCmdCookie;
1097 psFlipItem->ulSwapInterval = (unsigned long)psFlipCmd->ui32SwapInterval;
1098 psFlipItem->sSysAddr = &psBuffer->sSysAddr;
1099 psFlipItem->bValid = OMAP_TRUE;
1101 psSwapChain->ulInsertIndex++;
1102 if(psSwapChain->ulInsertIndex > ulMaxIndex)
1104 psSwapChain->ulInsertIndex = 0;
1107 /* Give work to the workqueue to sync with the display */
1108 queue_work(psDevInfo->vsync_isr_wq, &psDevInfo->vsync_work);
1110 goto ExitTrueUnlock;
1113 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1119 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1124 static OMAP_ERROR InitDev(OMAPLFB_DEVINFO *psDevInfo)
1126 struct fb_info *psLINFBInfo;
1127 struct module *psLINFBOwner;
1128 OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo;
1129 OMAP_ERROR eError = OMAP_ERROR_GENERIC;
1130 unsigned long FBSize;
1132 acquire_console_sem();
1134 if (fb_idx < 0 || fb_idx >= num_registered_fb)
1136 eError = OMAP_ERROR_INVALID_DEVICE;
1140 psLINFBInfo = registered_fb[fb_idx];
1142 psLINFBOwner = psLINFBInfo->fbops->owner;
1143 if (!try_module_get(psLINFBOwner))
1145 printk(KERN_INFO DRIVER_PREFIX
1146 ": Couldn't get framebuffer module\n");
1151 if (psLINFBInfo->fbops->fb_open != NULL)
1155 res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0);
1158 printk(KERN_INFO DRIVER_PREFIX
1159 ": Couldn't open framebuffer: %d\n", res);
1165 psDevInfo->psLINFBInfo = psLINFBInfo;
1167 FBSize = (psLINFBInfo->screen_size) != 0 ?
1168 psLINFBInfo->screen_size :
1169 psLINFBInfo->fix.smem_len;
1170 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1171 ": Framebuffer physical address: 0x%lx\n",
1172 psLINFBInfo->fix.smem_start));
1173 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1174 ": Framebuffer virtual address: 0x%lx\n",
1175 (unsigned long)psLINFBInfo->screen_base));
1176 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1177 ": Framebuffer size: %lu\n",
1179 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1180 ": Framebuffer virtual width: %u\n",
1181 psLINFBInfo->var.xres_virtual));
1182 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1183 ": Framebuffer virtual height: %u\n",
1184 psLINFBInfo->var.yres_virtual));
1185 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1186 ": Framebuffer width: %u\n",
1187 psLINFBInfo->var.xres));
1188 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1189 ": Framebuffer height: %u\n",
1190 psLINFBInfo->var.yres));
1191 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1192 ": Framebuffer stride: %u\n",
1193 psLINFBInfo->fix.line_length));
1196 psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start;
1197 psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base;
1199 psPVRFBInfo->ulWidth = psLINFBInfo->var.xres;
1200 psPVRFBInfo->ulHeight = psLINFBInfo->var.yres;
1201 psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length;
1202 psPVRFBInfo->ulFBSize = FBSize;
1203 psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride;
1205 psPVRFBInfo->ulRoundedBufferSize =
1206 sgx_buffer_align(psPVRFBInfo->ulByteStride,
1207 psPVRFBInfo->ulBufferSize);
1209 if(psLINFBInfo->var.bits_per_pixel == 16)
1211 if((psLINFBInfo->var.red.length == 5) &&
1212 (psLINFBInfo->var.green.length == 6) &&
1213 (psLINFBInfo->var.blue.length == 5) &&
1214 (psLINFBInfo->var.red.offset == 11) &&
1215 (psLINFBInfo->var.green.offset == 5) &&
1216 (psLINFBInfo->var.blue.offset == 0) &&
1217 (psLINFBInfo->var.red.msb_right == 0))
1219 psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565;
1223 printk("Unknown FB format\n");
1226 else if(psLINFBInfo->var.bits_per_pixel == 32)
1228 if((psLINFBInfo->var.red.length == 8) &&
1229 (psLINFBInfo->var.green.length == 8) &&
1230 (psLINFBInfo->var.blue.length == 8) &&
1231 (psLINFBInfo->var.red.offset == 16) &&
1232 (psLINFBInfo->var.green.offset == 8) &&
1233 (psLINFBInfo->var.blue.offset == 0) &&
1234 (psLINFBInfo->var.red.msb_right == 0))
1236 psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888;
1240 printk("Unknown FB format\n");
1245 printk("Unknown FB format\n");
1249 psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr;
1250 psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr;
1252 #ifdef CONFIG_OMAP2_DSS
1253 INIT_WORK (&wq_flipdss2.work, dss2_pan_display);
1260 module_put(psLINFBOwner);
1262 release_console_sem();
1266 static void DeInitDev(OMAPLFB_DEVINFO *psDevInfo)
1268 struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo;
1269 struct module *psLINFBOwner;
1271 acquire_console_sem();
1273 psLINFBOwner = psLINFBInfo->fbops->owner;
1275 if (psLINFBInfo->fbops->fb_release != NULL)
1277 (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0);
1280 module_put(psLINFBOwner);
1282 release_console_sem();
1285 OMAP_ERROR OMAPLFBInit(void)
1287 OMAPLFB_DEVINFO *psDevInfo;
1289 psDevInfo = GetAnchorPtr();
1291 if (psDevInfo == NULL)
1293 PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT];
1294 IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2];
1296 psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO));
1300 return (OMAP_ERROR_OUT_OF_MEMORY);
1304 memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO));
1307 SetAnchorPtr((void*)psDevInfo);
1310 psDevInfo->ulRefCount = 0;
1313 if(InitDev(psDevInfo) != OMAP_OK)
1315 return (OMAP_ERROR_INIT_FAILURE);
1318 if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &pfnGetPVRJTable) != OMAP_OK)
1320 return (OMAP_ERROR_INIT_FAILURE);
1324 if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable))
1326 return (OMAP_ERROR_INIT_FAILURE);
1329 mutex_init(&psDevInfo->sSwapChainLockMutex);
1331 psDevInfo->psSwapChain = 0;
1332 psDevInfo->bFlushCommands = OMAP_FALSE;
1333 psDevInfo->bDeviceSuspended = OMAP_FALSE;
1335 psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize);
1336 #if !defined (SUPPORT_TI_DSS_FW)
1337 /* Limiting the ui32MaxSwapChainBuffers to 3 */
1338 if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers > 3)
1339 psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = 3;
1341 if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers == 0)
1343 psDevInfo->sDisplayInfo.ui32MaxSwapChains = 0;
1344 psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 0;
1348 psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1;
1349 psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3;
1351 psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0;
1353 strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
1355 psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat;
1356 psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth;
1357 psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight;
1358 psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride;
1360 DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1361 ": Maximum number of swap chain buffers: %lu\n",
1362 psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers));
1365 psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr;
1366 psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr;
1367 psDevInfo->sSystemBuffer.ulBufferSize = psDevInfo->sFBInfo.ulRoundedBufferSize;
1371 psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
1372 psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
1373 psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
1374 psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
1375 psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
1376 psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
1377 psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
1378 psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
1379 psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
1380 psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain;
1381 psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
1382 psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
1383 psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
1384 psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
1385 psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
1386 psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
1387 psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem;
1388 psDevInfo->sDCJTable.pfnSetDCState = SetDCState;
1391 if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice (
1392 &psDevInfo->sDCJTable,
1393 &psDevInfo->ulDeviceID ) != PVRSRV_OK)
1395 return (OMAP_ERROR_DEVICE_REGISTER_FAILED);
1398 pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
1401 aui32SyncCountList[DC_FLIP_COMMAND][0] = 0;
1402 aui32SyncCountList[DC_FLIP_COMMAND][1] = 2;
1408 if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList (psDevInfo->ulDeviceID,
1411 OMAPLFB_COMMAND_COUNT) != PVRSRV_OK)
1413 printk(KERN_WARNING DRIVER_PREFIX ": Can't register callback\n");
1414 return (OMAP_ERROR_CANT_REGISTER_CALLBACK);
1420 psDevInfo->ulRefCount++;
1427 OMAP_ERROR OMAPLFBDeinit(void)
1429 OMAPLFB_DEVINFO *psDevInfo, *psDevFirst;
1431 psDevFirst = GetAnchorPtr();
1432 psDevInfo = psDevFirst;
1435 if (psDevInfo == NULL)
1437 return (OMAP_ERROR_GENERIC);
1441 psDevInfo->ulRefCount--;
1443 if (psDevInfo->ulRefCount == 0)
1446 PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable = &psDevInfo->sPVRJTable;
1448 if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList (psDevInfo->ulDeviceID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK)
1450 return (OMAP_ERROR_GENERIC);
1454 if (psJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->ulDeviceID) != PVRSRV_OK)
1456 return (OMAP_ERROR_GENERIC);
1459 DeInitDev(psDevInfo);
1462 OMAPLFBFreeKernelMem(psDevInfo);
1473 #if defined(LDM_PLATFORM)
1474 void OMAPLFBDriverSuspend(void)
1476 OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr();
1478 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1480 if (psDevInfo->bDeviceSuspended)
1484 psDevInfo->bDeviceSuspended = OMAP_TRUE;
1487 SetFlushStateInternalNoLock(psDevInfo, OMAP_TRUE);
1489 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1494 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1497 void OMAPLFBDriverResume(void)
1499 OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr();
1501 if (psDevInfo->bDeviceSuspended == OMAP_FALSE)
1506 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1508 SetFlushStateInternalNoLock(psDevInfo, OMAP_FALSE);
1510 psDevInfo->bDeviceSuspended = OMAP_FALSE;
1512 mutex_unlock(&psDevInfo->sSwapChainLockMutex);