]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/blob - drivers/video/omap2/omaplfb/omaplfb_displayclass.c
OMAPDSS: OMAPLFB: Dont foward compositions to DSSCOMP if overlay is Zero
[android-sdk/kernel-video.git] / drivers / video / omap2 / omaplfb / omaplfb_displayclass.c
1 /**********************************************************************
2  *
3  * Copyright (C) Imagination Technologies Ltd. All rights reserved.
4  * 
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.
8  * 
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.
13  * 
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.
17  * 
18  * The full GNU General Public License is included in this distribution in
19  * the file called "COPYING".
20  *
21  * Contact Information:
22  * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23  * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
24  *
25  ******************************************************************************/
27 #include <linux/version.h>
28 #include <linux/kernel.h>
29 #include <linux/console.h>
30 #include <linux/fb.h>
31 #include <linux/module.h>
32 #include <linux/string.h>
33 #include <linux/notifier.h>
34 #include <plat/sgx_omaplfb.h>
36 #include "img_defs.h"
37 #include "servicesext.h"
38 #include "kerneldisplay.h"
39 #include "omaplfb.h"
41 /*
42  * Just use CONFIG_DSSCOMP to distinguish code which previously had
43  * additional mixes of CONFIG_TI_TILER and CONFIG_ION_OMAP. DSSCOMP makes
44  * it a given that ION and the TILER will be used.
45  * For kernel 3.4 we use CONFIG_DRM_OMAP_DMM_TILER instead of CONFIG_TI_TILER
46  */
47 #if defined(CONFIG_DSSCOMP)
48 #if !defined(CONFIG_ION_OMAP)
49 #error Expected CONFIG_ION_OMAP to be defined
50 #endif
51 #if defined(CONFIG_DRM_OMAP_DMM_TILER)
52 #include <../drivers/staging/omapdrm/omap_dmm_tiler.h>
53 #include <../drivers/video/omap2/dsscomp/tiler-utils.h>
54 #elif defined(CONFIG_TI_TILER)
55 #include <mach/tiler.h>
56 #else
57 #error Expected CONFIG_DRM_OMAP_DMM_TILER or CONFIG_TI_TILER to be defined
58 #endif
60 #ifndef DSS_MAX_NUMBER_YUV_PLANES
61 #define DSS_MAX_NUMBER_YUV_PLANES 2
62 #endif
64 #include <linux/ion.h>
65 #include <linux/omap_ion.h>
66 #include <video/dsscomp.h>
67 #include <plat/dsscomp.h>
68 #include <video/omap_hwc.h>
70 extern struct ion_device *omap_ion_device;
71 struct ion_client *gpsIONClient;
73 #endif
75 #define OMAPLFB_COMMAND_COUNT           1
77 #define OMAPLFB_VSYNC_SETTLE_COUNT      5
79 #define OMAPLFB_MAX_NUM_DEVICES         FB_MAX
80 #if (OMAPLFB_MAX_NUM_DEVICES > FB_MAX)
81 #error "OMAPLFB_MAX_NUM_DEVICES must not be greater than FB_MAX"
82 #endif
84 static OMAPLFB_DEVINFO *gapsDevInfo[OMAPLFB_MAX_NUM_DEVICES];
86 static PFN_DC_GET_PVRJTABLE gpfnGetPVRJTable = NULL;
88 static IMG_BOOL gbBvInterfacePresent;
89 static IMG_BOOL gbBvReady = IMG_FALSE;
90 static IMG_BOOL bBltReady = IMG_FALSE;
92 static inline unsigned long RoundUpToMultiple(unsigned long x, unsigned long y)
93 {
94         unsigned long div = x / y;
95         unsigned long rem = x % y;
97         return (div + ((rem == 0) ? 0 : 1)) * y;
98 }
100 static unsigned long GCD(unsigned long x, unsigned long y)
102         while (y != 0)
103         {
104                 unsigned long r = x % y;
105                 x = y;
106                 y = r;
107         }
109         return x;
112 static unsigned long LCM(unsigned long x, unsigned long y)
114         unsigned long gcd = GCD(x, y);
116         return (gcd == 0) ? 0 : ((x / gcd) * y);
119 unsigned OMAPLFBMaxFBDevIDPlusOne(void)
121         return OMAPLFB_MAX_NUM_DEVICES;
124 OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID)
126         WARN_ON(uiFBDevID >= OMAPLFBMaxFBDevIDPlusOne());
128         if (uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES)
129         {
130                 return NULL;
131         }
133         return gapsDevInfo[uiFBDevID];
136 static inline void OMAPLFBSetDevInfoPtr(unsigned uiFBDevID, OMAPLFB_DEVINFO *psDevInfo)
138         WARN_ON(uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES);
140         if (uiFBDevID < OMAPLFB_MAX_NUM_DEVICES)
141         {
142                 gapsDevInfo[uiFBDevID] = psDevInfo;
143         }
146 static inline OMAPLFB_BOOL SwapChainHasChanged(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_SWAPCHAIN *psSwapChain)
148         return (psDevInfo->psSwapChain != psSwapChain) ||
149                 (psDevInfo->uiSwapChainID != psSwapChain->uiSwapChainID);
152 static inline OMAPLFB_BOOL DontWaitForVSync(OMAPLFB_DEVINFO *psDevInfo)
154         OMAPLFB_BOOL bDontWait;
156         bDontWait = OMAPLFBAtomicBoolRead(&psDevInfo->sBlanked) ||
157                         OMAPLFBAtomicBoolRead(&psDevInfo->sFlushCommands);
159 #if defined(CONFIG_HAS_EARLYSUSPEND)
160         bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sEarlySuspendFlag);
161 #endif
162 #if defined(SUPPORT_DRI_DRM)
163         bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT);
164 #endif
165         return bDontWait;
168 static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
170         OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice;
172         switch (ui32State)
173         {
174                 case DC_STATE_FLUSH_COMMANDS:
175                         OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_TRUE);
176                         break;
177                 case DC_STATE_FORCE_SWAP_TO_SYSTEM:
178                         OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer);
179                         break;
180                 case DC_STATE_NO_FLUSH_COMMANDS:
181                         OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_FALSE);
182                         break;
183                 default:
184                         break;
185         }
188 static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 uiPVRDevID,
189                                  IMG_HANDLE *phDevice,
190                                  PVRSRV_SYNC_DATA* psSystemBufferSyncData)
192         OMAPLFB_DEVINFO *psDevInfo;
193         OMAPLFB_ERROR eError;
194         unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne();
195         unsigned i;
197         for (i = 0; i < uiMaxFBDevIDPlusOne; i++)
198         {
199                 psDevInfo = OMAPLFBGetDevInfoPtr(i);
200                 if (psDevInfo != NULL && psDevInfo->uiPVRDevID == uiPVRDevID)
201                 {
202                         break;
203                 }
204         }
205         if (i == uiMaxFBDevIDPlusOne)
206         {
207                 DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
208                         ": %s: PVR Device %u not found\n", __FUNCTION__, uiPVRDevID));
209                 return PVRSRV_ERROR_INVALID_DEVICE;
210         }
212         
213         psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData;
214         
215         eError = OMAPLFBUnblankDisplay(psDevInfo);
216         if (eError != OMAPLFB_OK)
217         {
218                 DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
219                         ": %s: Device %u: OMAPLFBUnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError));
220                 return PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED;
221         }
223         
224         *phDevice = (IMG_HANDLE)psDevInfo;
225         
226         return PVRSRV_OK;
229 static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
231 #if defined(SUPPORT_DRI_DRM)
232         OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice;
234         OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, OMAPLFB_FALSE);
235         (void) OMAPLFBUnblankDisplay(psDevInfo);
236 #else
237         UNREFERENCED_PARAMETER(hDevice);
238 #endif
239         return PVRSRV_OK;
242 static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice,
243                                   IMG_UINT32 *pui32NumFormats,
244                                   DISPLAY_FORMAT *psFormat)
246         OMAPLFB_DEVINFO *psDevInfo;
247         
248         if(!hDevice || !pui32NumFormats)
249         {
250                 return PVRSRV_ERROR_INVALID_PARAMS;
251         }
253         psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
254         
255         *pui32NumFormats = 1;
256         
257         if(psFormat)
258         {
259                 psFormat[0] = psDevInfo->sDisplayFormat;
260         }
262         return PVRSRV_OK;
265 static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice, 
266                                DISPLAY_FORMAT *psFormat,
267                                IMG_UINT32 *pui32NumDims,
268                                DISPLAY_DIMS *psDim)
270         OMAPLFB_DEVINFO *psDevInfo;
272         if(!hDevice || !psFormat || !pui32NumDims)
273         {
274                 return PVRSRV_ERROR_INVALID_PARAMS;
275         }
277         psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
279         *pui32NumDims = 1;
281         
282         if(psDim)
283         {
284                 psDim[0] = psDevInfo->sDisplayDim;
285         }
286         
287         return PVRSRV_OK;
291 static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer)
293         OMAPLFB_DEVINFO *psDevInfo;
294         
295         if(!hDevice || !phBuffer)
296         {
297                 return PVRSRV_ERROR_INVALID_PARAMS;
298         }
300         psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
302         *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer;
304         return PVRSRV_OK;
308 static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
310         OMAPLFB_DEVINFO *psDevInfo;
311         
312         if(!hDevice || !psDCInfo)
313         {
314                 return PVRSRV_ERROR_INVALID_PARAMS;
315         }
317         psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
319         *psDCInfo = psDevInfo->sDisplayInfo;
321         return PVRSRV_OK;
324 static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE        hDevice,
325                                     IMG_HANDLE        hBuffer, 
326                                     IMG_SYS_PHYADDR   **ppsSysAddr,
327                                     IMG_UINT32        *pui32ByteSize,
328                                     IMG_VOID          **ppvCpuVAddr,
329                                     IMG_HANDLE        *phOSMapInfo,
330                                     IMG_BOOL          *pbIsContiguous,
331                                     IMG_UINT32        *pui32TilingStride)
333         OMAPLFB_DEVINFO *psDevInfo;
334         OMAPLFB_BUFFER *psSystemBuffer;
336         UNREFERENCED_PARAMETER(pui32TilingStride);
338         if(!hDevice)
339         {
340                 return PVRSRV_ERROR_INVALID_PARAMS;
341         }
343         if(!hBuffer)
344         {
345                 return PVRSRV_ERROR_INVALID_PARAMS;
346         }
348         if (!ppsSysAddr)
349         {
350                 return PVRSRV_ERROR_INVALID_PARAMS;
351         }
353         if (!pui32ByteSize)
354         {
355                 return PVRSRV_ERROR_INVALID_PARAMS;
356         }
358         psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
360         psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer;
362         *ppsSysAddr = &psSystemBuffer->sSysAddr;
364         *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize;
366         if (ppvCpuVAddr)
367         {
368                 *ppvCpuVAddr = psDevInfo->sFBInfo.bIs2D ? NULL : psSystemBuffer->sCPUVAddr;
369         }
371         if (phOSMapInfo)
372         {
373                 *phOSMapInfo = (IMG_HANDLE)0;
374         }
376         if (pbIsContiguous)
377         {
378                 *pbIsContiguous = !psDevInfo->sFBInfo.bIs2D;
379         }
381 #if defined(CONFIG_DSSCOMP)
382         if (psDevInfo->sFBInfo.bIs2D) {
383                 int i = (psSystemBuffer->sSysAddr.uiAddr - psDevInfo->sFBInfo.psPageList->uiAddr) >> PAGE_SHIFT;
384                 *ppsSysAddr = psDevInfo->sFBInfo.psPageList + psDevInfo->sFBInfo.ulHeight * i;
385         }
386 #endif
388         return PVRSRV_OK;
391 static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice,
392                                       IMG_UINT32 ui32Flags,
393                                       DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
394                                       DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
395                                       IMG_UINT32 ui32BufferCount,
396                                       PVRSRV_SYNC_DATA **ppsSyncData,
397                                       IMG_UINT32 ui32OEMFlags,
398                                       IMG_HANDLE *phSwapChain,
399                                       IMG_UINT32 *pui32SwapChainID)
401         OMAPLFB_DEVINFO *psDevInfo;
402         OMAPLFB_SWAPCHAIN *psSwapChain;
403         OMAPLFB_BUFFER *psBuffer;
404         IMG_UINT32 i;
405         PVRSRV_ERROR eError;
407         UNREFERENCED_PARAMETER(ui32OEMFlags);
408         
409         
410         if(!hDevice
411         || !psDstSurfAttrib
412         || !psSrcSurfAttrib
413         || !ppsSyncData
414         || !phSwapChain)
415         {
416                 return PVRSRV_ERROR_INVALID_PARAMS;
417         }
419         psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
420         
421         
422         if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0)
423         {
424                 return PVRSRV_ERROR_NOT_SUPPORTED;
425         }
427         OMAPLFBCreateSwapChainLock(psDevInfo);
429         
430         if(psDevInfo->psSwapChain != NULL)
431         {
432                 eError = PVRSRV_ERROR_FLIP_CHAIN_EXISTS;
433                 goto ExitUnLock;
434         }
435         
436         
437         if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)
438         {
439                 eError = PVRSRV_ERROR_TOOMANYBUFFERS;
440                 goto ExitUnLock;
441         }
442         
443         if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize)
444         {
445                 eError = PVRSRV_ERROR_TOOMANYBUFFERS;
446                 goto ExitUnLock;
447         }
448         
449         if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat
450         || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride
451         || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width
452         || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height)
453         {
454                 
455                 eError = PVRSRV_ERROR_INVALID_PARAMS;
456                 goto ExitUnLock;
457         }               
459         if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat
460         || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride
461         || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width
462         || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height)
463         {
464                 
465                 eError = PVRSRV_ERROR_INVALID_PARAMS;
466                 goto ExitUnLock;
467         }               
469         UNREFERENCED_PARAMETER(ui32Flags);
470         
471 #if defined(PVR_OMAPFB3_UPDATE_MODE)
472         if (!OMAPLFBSetUpdateMode(psDevInfo, PVR_OMAPFB3_UPDATE_MODE))
473         {
474                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set frame buffer update mode %d\n", __FUNCTION__, psDevInfo->uiFBDevID, PVR_OMAPFB3_UPDATE_MODE);
475         }
476 #endif
477         
478         psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN));
479         if(!psSwapChain)
480         {
481                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
482                 goto ExitUnLock;
483         }
485         psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount);
486         if(!psBuffer)
487         {
488                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
489                 goto ErrorFreeSwapChain;
490         }
492         psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
493         psSwapChain->psBuffer = psBuffer;
494         psSwapChain->bNotVSynced = OMAPLFB_TRUE;
495         psSwapChain->uiFBDevID = psDevInfo->uiFBDevID;
497         
498         for(i=0; i<ui32BufferCount-1; i++)
499         {
500                 psBuffer[i].psNext = &psBuffer[i+1];
501         }
502         
503         psBuffer[i].psNext = &psBuffer[0];
505         for(i=0; i<ui32BufferCount; i++)
506         {
507                 IMG_UINT32 ui32SwapBuffer = i;
508                 IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize;
509                 if (psDevInfo->sFBInfo.bIs2D)
510                 {
511                         ui32BufferOffset = 0;
512                 }
514                 psBuffer[i].psSyncData = ppsSyncData[i];
515                 psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset;
516                 psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset;
517                 psBuffer[i].ulYOffset = ui32BufferOffset / psDevInfo->sFBInfo.ulByteStride;
518                 if (psDevInfo->sFBInfo.bIs2D)
519                 {
520                         psBuffer[i].sSysAddr.uiAddr += ui32SwapBuffer *
521                                 ALIGN((IMG_UINT32)psDevInfo->sFBInfo.ulWidth * psDevInfo->sFBInfo.uiBytesPerPixel, PAGE_SIZE);
522                 }
523                 psBuffer[i].psDevInfo = psDevInfo;
524                 OMAPLFBInitBufferForSwap(&psBuffer[i]);
525                 psBuffer[i].bvmap_handle = NULL;
526         }
529         if (OMAPLFBCreateSwapQueue(psSwapChain) != OMAPLFB_OK)
530         { 
531                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Failed to create workqueue\n", __FUNCTION__, psDevInfo->uiFBDevID);
532                 eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
533                 goto ErrorFreeBuffers;
534         }
536         if (OMAPLFBEnableLFBEventNotification(psDevInfo)!= OMAPLFB_OK)
537         {
538                 eError = PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT;
539                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't enable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID);
540                 goto ErrorDestroySwapQueue;
541         }
543         psDevInfo->uiSwapChainID++;
544         if (psDevInfo->uiSwapChainID == 0)
545         {
546                 psDevInfo->uiSwapChainID++;
547         }
549         psSwapChain->uiSwapChainID = psDevInfo->uiSwapChainID;
551         psDevInfo->psSwapChain = psSwapChain;
553         *pui32SwapChainID = psDevInfo->uiSwapChainID;
555         *phSwapChain = (IMG_HANDLE)psSwapChain;
557         eError = PVRSRV_OK;
558         goto ExitUnLock;
560 ErrorDestroySwapQueue:
561         OMAPLFBDestroySwapQueue(psSwapChain);
562 ErrorFreeBuffers:
563         OMAPLFBFreeKernelMem(psBuffer);
564 ErrorFreeSwapChain:
565         OMAPLFBFreeKernelMem(psSwapChain);
566 ExitUnLock:
567         OMAPLFBCreateSwapChainUnLock(psDevInfo);
568         return eError;
571 static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
572                                        IMG_HANDLE hSwapChain)
574         OMAPLFB_DEVINFO *psDevInfo;
575         OMAPLFB_SWAPCHAIN *psSwapChain;
576         OMAPLFB_ERROR eError;
577         
578         if(!hDevice || !hSwapChain)
579         {
580                 return PVRSRV_ERROR_INVALID_PARAMS;
581         }
582         
583         psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
584         psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
586         OMAPLFBCreateSwapChainLock(psDevInfo);
588         if (SwapChainHasChanged(psDevInfo, psSwapChain))
589         {
590                 printk(KERN_WARNING DRIVER_PREFIX
591                         ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID);
593                 eError = PVRSRV_ERROR_INVALID_PARAMS;
594                 goto ExitUnLock;
595         }
597         
598         OMAPLFBDestroySwapQueue(psSwapChain);
600         eError = OMAPLFBDisableLFBEventNotification(psDevInfo);
601         if (eError != OMAPLFB_OK)
602         {
603                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't disable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID);
604         }
606         OMAPLFBDeInitBltFBs(psDevInfo);
607         gbBvReady = IMG_FALSE;
608         bBltReady = IMG_FALSE;
610         OMAPLFBFreeKernelMem(psSwapChain->psBuffer);
611         OMAPLFBFreeKernelMem(psSwapChain);
613         psDevInfo->psSwapChain = NULL;
615         OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer);
616         (void) OMAPLFBCheckModeAndSync(psDevInfo);
618         eError = PVRSRV_OK;
620 ExitUnLock:
621         OMAPLFBCreateSwapChainUnLock(psDevInfo);
623         return eError;
626 static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice,
627                                  IMG_HANDLE hSwapChain,
628                                  IMG_RECT *psRect)
630         UNREFERENCED_PARAMETER(hDevice);
631         UNREFERENCED_PARAMETER(hSwapChain);
632         UNREFERENCED_PARAMETER(psRect);
634         
635         
636         return PVRSRV_ERROR_NOT_SUPPORTED;
639 static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice,
640                                  IMG_HANDLE hSwapChain,
641                                  IMG_RECT *psRect)
643         UNREFERENCED_PARAMETER(hDevice);
644         UNREFERENCED_PARAMETER(hSwapChain);
645         UNREFERENCED_PARAMETER(psRect);
647         
649         return PVRSRV_ERROR_NOT_SUPPORTED;
652 static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice,
653                                       IMG_HANDLE hSwapChain,
654                                       IMG_UINT32 ui32CKColour)
656         UNREFERENCED_PARAMETER(hDevice);
657         UNREFERENCED_PARAMETER(hSwapChain);
658         UNREFERENCED_PARAMETER(ui32CKColour);
660         
662         return PVRSRV_ERROR_NOT_SUPPORTED;
665 static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice,
666                                       IMG_HANDLE hSwapChain,
667                                       IMG_UINT32 ui32CKColour)
669         UNREFERENCED_PARAMETER(hDevice);
670         UNREFERENCED_PARAMETER(hSwapChain);
671         UNREFERENCED_PARAMETER(ui32CKColour);
673         
675         return PVRSRV_ERROR_NOT_SUPPORTED;
678 static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice,
679                                  IMG_HANDLE hSwapChain,
680                                  IMG_UINT32 *pui32BufferCount,
681                                  IMG_HANDLE *phBuffer)
683         OMAPLFB_DEVINFO   *psDevInfo;
684         OMAPLFB_SWAPCHAIN *psSwapChain;
685         PVRSRV_ERROR eError;
686         unsigned i;
687         
688         
689         if(!hDevice 
690         || !hSwapChain
691         || !pui32BufferCount
692         || !phBuffer)
693         {
694                 return PVRSRV_ERROR_INVALID_PARAMS;
695         }
696         
697         psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
698         psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
700         OMAPLFBCreateSwapChainLock(psDevInfo);
702         if (SwapChainHasChanged(psDevInfo, psSwapChain))
703         {
704                 printk(KERN_WARNING DRIVER_PREFIX
705                         ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID);
707                 eError = PVRSRV_ERROR_INVALID_PARAMS;
708                 goto Exit;
709         }
710         
711         
712         *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount;
713         
714         
715         for(i=0; i<psSwapChain->ulBufferCount; i++)
716         {
717                 phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i];
718         }
719         
720         eError = PVRSRV_OK;
722 Exit:
723         OMAPLFBCreateSwapChainUnLock(psDevInfo);
725         return eError;
728 static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
729                                    IMG_HANDLE hBuffer,
730                                    IMG_UINT32 ui32SwapInterval,
731                                    IMG_HANDLE hPrivateTag,
732                                    IMG_UINT32 ui32ClipRectCount,
733                                    IMG_RECT *psClipRect)
735         UNREFERENCED_PARAMETER(hDevice);
736         UNREFERENCED_PARAMETER(hBuffer);
737         UNREFERENCED_PARAMETER(ui32SwapInterval);
738         UNREFERENCED_PARAMETER(hPrivateTag);
739         UNREFERENCED_PARAMETER(ui32ClipRectCount);
740         UNREFERENCED_PARAMETER(psClipRect);
741         
742         
744         return PVRSRV_OK;
747 #if !defined(CONFIG_GCBV)
748 IMG_BOOL OMAPLFBInitBlt(void)
750         return IMG_FALSE;
753 OMAPLFB_ERROR OMAPLFBInitBltFBs(OMAPLFB_DEVINFO *psDevInfo)
755         return OMAPLFB_ERROR_INIT_FAILURE;
758 void OMAPLFBDeInitBltFBs(OMAPLFB_DEVINFO *psDevInfo)
762 void OMAPLFBGetBltFBsBvHndl(OMAPLFB_FBINFO *psPVRFBInfo, IMG_UINTPTR_T *ppPhysAddr)
764         *ppPhysAddr = 0;
767 void OMAPLFBDoBlits(OMAPLFB_DEVINFO *psDevInfo, PDC_MEM_INFO *ppsMemInfos, struct omap_hwc_blit_data *blit_data, IMG_UINT32 ui32NumMemInfos)
770 #endif /* CONFIG_GCBV */
771 static OMAPLFB_BOOL WaitForVSyncSettle(OMAPLFB_DEVINFO *psDevInfo)
773                 unsigned i;
774                 for(i = 0; i < OMAPLFB_VSYNC_SETTLE_COUNT; i++)
775                 {
776                         if (DontWaitForVSync(psDevInfo) || !OMAPLFBWaitForVSync(psDevInfo))
777                         {
778                                 return OMAPLFB_FALSE;
779                         }
780                 }
782                 return OMAPLFB_TRUE;
785 void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer)
787         OMAPLFB_DEVINFO *psDevInfo = psBuffer->psDevInfo;
788         OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain;
789         OMAPLFB_BOOL bPreviouslyNotVSynced;
791 #if defined(SUPPORT_DRI_DRM)
792         if (!OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT))
793 #endif
794         {
795                 OMAPLFBFlip(psDevInfo, psBuffer);
796         }
798         bPreviouslyNotVSynced = psSwapChain->bNotVSynced;
799         psSwapChain->bNotVSynced = OMAPLFB_TRUE;
802         if (!DontWaitForVSync(psDevInfo))
803         {
804                 OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo);
805                 int iBlankEvents = OMAPLFBAtomicIntRead(&psDevInfo->sBlankEvents);
807                 switch(eMode)
808                 {
809                         case OMAPLFB_UPDATE_MODE_AUTO:
810                                 psSwapChain->bNotVSynced = OMAPLFB_FALSE;
812                                 if (bPreviouslyNotVSynced || psSwapChain->iBlankEvents != iBlankEvents)
813                                 {
814                                         psSwapChain->iBlankEvents = iBlankEvents;
815                                         psSwapChain->bNotVSynced = !WaitForVSyncSettle(psDevInfo);
816                                 } else if (psBuffer->ulSwapInterval != 0)
817                                 {
818                                         psSwapChain->bNotVSynced = !OMAPLFBWaitForVSync(psDevInfo);
819                                 }
820                                 break;
821 #if defined(PVR_OMAPFB3_MANUAL_UPDATE_SYNC_IN_SWAP)
822                         case OMAPLFB_UPDATE_MODE_MANUAL:
823                                 if (psBuffer->ulSwapInterval != 0)
824                                 {
825                                         (void) OMAPLFBManualSync(psDevInfo);
826                                 }
827                                 break;
828 #endif
829                         default:
830                                 break;
831                 }
832         }
834         psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_TRUE);
837 #if defined(CONFIG_DSSCOMP)
840 static void dsscomp_proxy_cmdcomplete(void * cookie, int i)
842         gapsDevInfo[0]->sPVRJTable.pfnPVRSRVCmdComplete(cookie, i);
844 #endif
846 static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie,
847                                                           OMAPLFB_DEVINFO *psDevInfo,
848                                                           OMAPLFB_SWAPCHAIN *psSwapChain,
849                                                           OMAPLFB_BUFFER *psBuffer,
850                                                           unsigned long ulSwapInterval)
852         OMAPLFBCreateSwapChainLock(psDevInfo);
853         
854         if (SwapChainHasChanged(psDevInfo, psSwapChain))
855         {
856                 DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
857                         ": %s: Device %u (PVR Device ID %u): The swap chain has been destroyed\n",
858                         __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID));
859         }
860         else
861         {
862                 psBuffer->hCmdComplete = (OMAPLFB_HANDLE)hCmdCookie;
863                 psBuffer->ulSwapInterval = ulSwapInterval;
864 #if defined(CONFIG_DSSCOMP)
865                 if (is_tiler_addr(psBuffer->sSysAddr.uiAddr)) {
866                         IMG_UINT32 w = psBuffer->psDevInfo->sDisplayDim.ui32Width;
867                         IMG_UINT32 h = psBuffer->psDevInfo->sDisplayDim.ui32Height;
868                         struct dsscomp_setup_dispc_data comp = {
869                                 .num_mgrs = 1,
870                                 .mgrs[0].alpha_blending = 1,
871                                 .num_ovls = 1,
872                                 .ovls[0].cfg = {
873                                         .width = w,
874                                         .win.w = w,
875                                         .crop.w = w,
876                                         .height = h,
877                                         .win.h = h,
878                                         .crop.h = h,
879                                         .stride = psBuffer->psDevInfo->sDisplayDim.ui32ByteStride,
880                                         .color_mode = OMAP_DSS_COLOR_ARGB32,
881                                         .enabled = 1,
882                                         .global_alpha = 255,
883                                 },
884                                 .mode = DSSCOMP_SETUP_DISPLAY,
885                         };
886                         struct tiler_pa_info *pas[1] = { NULL };
887                         comp.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr;
888                         dsscomp_gralloc_queue(&comp, pas, true,
889                                               dsscomp_proxy_cmdcomplete,
890                                               (void *) psBuffer->hCmdComplete);
891                 } else
892 #endif
893                 {
894                         OMAPLFBQueueBufferForSwap(psSwapChain, psBuffer);
895                 }
896         }
898         OMAPLFBCreateSwapChainUnLock(psDevInfo);
900         return IMG_TRUE;
903 #if defined(CONFIG_DSSCOMP) && (defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER))
904 int meminfo_idx_valid(unsigned int meminfo_ix, int num_meminfos)
906         if (meminfo_ix < 0 || meminfo_ix >= num_meminfos) {
907                 WARN(1, "%s: Invalid meminfo index %d, max %d\n",
908                                 __func__, meminfo_ix, num_meminfos);
909                 return 0;
910         }
911         return 1;
914 static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie,
915                               OMAPLFB_DEVINFO *psDevInfo,
916                               PDC_MEM_INFO *ppsMemInfos,
917                               IMG_UINT32 ui32NumMemInfos,
918                               struct omap_hwc_data *psHwcData,
919                               IMG_UINT32 uiHwcDataSz)
921         struct tiler_pa_info *apsTilerPAs[5];
922         IMG_UINT32 i, k;
923         struct {
924                 IMG_UINTPTR_T uiAddr;
925                 IMG_UINTPTR_T uiUVAddr;
926                 struct tiler_pa_info *psTilerInfo;
927         } asMemInfo[5];
929         /* Framebuffer info just used to get FB geometry, the address to
930          * use for blitting (dst buffer) is the first meminfo
931          */
932         int rgz_items;
933         int calcsz;
934         struct dsscomp_setup_dispc_data *psDssData = &(psHwcData->dsscomp_data);
935         int iMemIdx = 0;
936         int iUseBltFB;
937 #ifdef CONFIG_DRM_OMAP_DMM_TILER
938         enum tiler_fmt fmt;
939 #endif
941         if (uiHwcDataSz <= offsetof(struct omap_hwc_data, blit_data))
942                 rgz_items = 0;
943         else
944                 rgz_items = psHwcData->blit_data.rgz_items;
947         psDssData = &(psHwcData->dsscomp_data);
948         calcsz = sizeof(*psHwcData) +
949                 (sizeof(struct rgz_blt_entry) * rgz_items);
950         iUseBltFB = psHwcData->blit_data.rgz_flags & HWC_BLT_FLAG_USE_FB;
952         if (!iUseBltFB && rgz_items > 0) {
953                 WARN(1, "Trying to blit without a pipe configured for the blit FB");
954                 return IMG_FALSE;
955         }
957         if (rgz_items > 0 && !gbBvInterfacePresent)
958         {
959                 /* We cannot blit if BV GC2D is not present!, likely a bug */
960                 WARN(1, "Trying to blit when BV GC2D is not present");
961                 rgz_items = 0; /* Prevent blits */
962         }
964         if (iUseBltFB && !bBltReady)
965         {
966                 /* Defer allocation and mapping of blit buffers */
967                 if (OMAPLFBInitBltFBs(psDevInfo) != OMAPLFB_OK)
968                 {
969                         WARN(1, "Could not initialize blit FBs");
970                         return IMG_FALSE;
971                 }
973                 bBltReady = IMG_TRUE;
974         }
976         memset(asMemInfo, 0, sizeof(asMemInfo));
978         /* Check the size of private data along with the blit operations */
979         if (uiHwcDataSz != calcsz)
980         {
981                 WARN(1, "invalid size of private data (%d vs %d)",
982                      uiHwcDataSz, calcsz);
983         }
985         if (ui32NumMemInfos == 0)
986         {
987                 WARN(1, "must have at least one layer");
988                 return IMG_FALSE;
989         }
991         if (iUseBltFB)
992         {
993                 iMemIdx++;
994                 /* Increment the Blt framebuffer and get new address */
995                 OMAPLFBGetBltFBsBvHndl(&psDevInfo->sFBInfo, &asMemInfo[0].uiAddr);
996         }
998         for (i = 0, k = iMemIdx; i < ui32NumMemInfos && k < ARRAY_SIZE(apsTilerPAs) &&
999                 k < psDssData->num_ovls; i++, k++) {
1001                 struct tiler_pa_info *psTilerInfo;
1002                 IMG_CPU_VIRTADDR virtAddr;
1003                 IMG_CPU_PHYADDR aPhyAddr[DSS_MAX_NUMBER_YUV_PLANES];
1004                 IMG_UINT32 ui32NumPages;
1005                 IMG_SIZE_T uByteSize;
1006                 IMG_UINT32 ui32NumAddrOffsets = DSS_MAX_NUMBER_YUV_PLANES;
1007                 int j;
1009                 memset(aPhyAddr, 0x00, sizeof(aPhyAddr));
1011                 uByteSize = psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuMultiPlanePAddr(
1012                                 ppsMemInfos[i], IMG_NULL /* We want the beginning of the buffers */,
1013                                 aPhyAddr, &ui32NumAddrOffsets);
1015                 if(uByteSize < 0)
1016                         continue;
1018                 ui32NumPages = (uByteSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
1020                 /* TILER buffers do not need meminfos */
1021                 if(is_tiler_addr((u32)aPhyAddr[0].uiAddr))
1022                 {
1023                         asMemInfo[k].uiAddr = aPhyAddr[0].uiAddr;
1024 #ifdef CONFIG_DRM_OMAP_DMM_TILER
1025                         if (tiler_get_fmt((u32)aPhyAddr[0].uiAddr, &fmt) && fmt == TILFMT_8BIT)
1026 #else /* CONFIG_TI_TILER must be defined if CONFIG_DRM_OMAP_DMM_TILER is not */
1027                         if (tiler_fmt((u32)aPhyAddr[0].uiAddr) == TILFMT_8BIT)
1028 #endif
1029                         {
1030                                 if(ui32NumAddrOffsets > 1)
1031                                         asMemInfo[k].uiUVAddr = aPhyAddr[1].uiAddr;
1032                         }
1033                         continue;
1034                 }
1036                 if (aPhyAddr[0].uiAddr >= psDevInfo->psLINFBInfo->fix.smem_start &&
1037                                 aPhyAddr[0].uiAddr < (psDevInfo->psLINFBInfo->fix.smem_start + psDevInfo->psLINFBInfo->fix.smem_len))
1038                 {
1039                         asMemInfo[k].uiAddr = aPhyAddr[0].uiAddr;
1040                         continue;
1041                 }
1042                 /* normal gralloc layer */
1043                 psTilerInfo = kzalloc(sizeof(*psTilerInfo), GFP_KERNEL);
1044                 if(!psTilerInfo)
1045                 {
1046                         continue;
1047                 }
1049                 psTilerInfo->mem = kzalloc(sizeof(*psTilerInfo->mem) * ui32NumPages, GFP_KERNEL);
1050                 if(!psTilerInfo->mem)
1051                 {
1052                         kfree(psTilerInfo);
1053                         continue;
1054                 }
1056                 psTilerInfo->num_pg = ui32NumPages;
1057                 psTilerInfo->memtype = TILER_MEM_USING;
1058                 for(j = 0; j < ui32NumPages; j++)
1059                 {
1060                         IMG_CPU_PHYADDR pagePhyAddr;
1061                         psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], j << PAGE_SHIFT, &pagePhyAddr);
1062                         psTilerInfo->mem[j] = (u32)pagePhyAddr.uiAddr;
1063                 }
1065                 /* need base address for in-page offset */
1066                 psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuVAddr(ppsMemInfos[i], &virtAddr);
1067                 asMemInfo[k].uiAddr = (IMG_UINTPTR_T) virtAddr;
1068                 asMemInfo[k].psTilerInfo = psTilerInfo;
1069         }
1071         for(i = 0; i < psDssData->num_ovls; i++)
1072         {
1073                 unsigned int ix;
1074                 apsTilerPAs[i] = NULL;
1076                 /* only supporting Post2, cloned and fbmem layers */
1077                 if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX &&
1078                     psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_OVL_IX &&
1079                     psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_FB &&
1080                     psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_ION)
1081                         psDssData->ovls[i].cfg.enabled = false;
1083                 if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX)
1084                         continue;
1086                 /* Post2 layers */
1087                 ix = psDssData->ovls[i].ba;
1088                 if (ix >= k)
1089                 {
1090                         WARN(1, "Invalid Post2 layer (%u)", ix);
1091                         psDssData->ovls[i].cfg.enabled = false;
1092                         continue;
1093                 }
1095                 psDssData->ovls[i].addressing = OMAP_DSS_BUFADDR_DIRECT;
1096                 psDssData->ovls[i].ba = (u32) asMemInfo[ix].uiAddr;
1097                 psDssData->ovls[i].uv = (u32) asMemInfo[ix].uiUVAddr;
1098                 apsTilerPAs[i] = asMemInfo[ix].psTilerInfo;
1099         }
1101         if (rgz_items > 0)
1102         {
1103                 OMAPLFBDoBlits(psDevInfo, ppsMemInfos, &psHwcData->blit_data, ui32NumMemInfos);
1104         }
1106         if (psDssData->num_ovls == 0)
1107                 dsscomp_proxy_cmdcomplete((void *)hCmdCookie, IMG_TRUE);
1108         else
1109                 dsscomp_gralloc_queue(psDssData, apsTilerPAs, false,
1110                                                 dsscomp_proxy_cmdcomplete,
1111                                                 (void *)hCmdCookie);
1113         for(i = 0; i < ARRAY_SIZE(asMemInfo); i++)
1114         {
1115                 tiler_pa_free(asMemInfo[i].psTilerInfo);
1116         }
1118         return IMG_TRUE;
1121 #endif
1123 static IMG_BOOL ProcessFlip(IMG_HANDLE  hCmdCookie,
1124                             IMG_UINT32  ui32DataSize,
1125                             IMG_VOID   *pvData)
1127         DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1128         OMAPLFB_DEVINFO *psDevInfo;
1130         if(!hCmdCookie || !pvData)
1131         {
1132                 return IMG_FALSE;
1133         }
1135         psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
1137         if (psFlipCmd == IMG_NULL)
1138         {
1139                 return IMG_FALSE;
1140         }
1142         psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice;
1144         if(psFlipCmd->hExtBuffer)
1145         {
1146                 return ProcessFlipV1(hCmdCookie,
1147                                                          psDevInfo,
1148                                                          psFlipCmd->hExtSwapChain,
1149                                                          psFlipCmd->hExtBuffer,
1150                                                          psFlipCmd->ui32SwapInterval);
1151         }
1152         else
1153         {
1154 #if defined(CONFIG_DSSCOMP) && (defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER))
1155                 DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd2;
1156                 psFlipCmd2 = (DISPLAYCLASS_FLIP_COMMAND2 *)pvData;
1157                 return ProcessFlipV2(hCmdCookie,
1158                                                          psDevInfo,
1159                                                          psFlipCmd2->ppsMemInfos,
1160                                                          psFlipCmd2->ui32NumMemInfos,
1161                                                          psFlipCmd2->pvPrivData,
1162                                                          psFlipCmd2->ui32PrivDataLength);
1163 #else
1164                 BUG();
1165 #endif
1166         }
1169 #if defined(CONFIG_DSSCOMP)
1171 static OMAPLFB_ERROR OMAPLFBInitIonOmap(OMAPLFB_DEVINFO *psDevInfo,
1172                                         struct fb_info *psLINFBInfo,
1173                                         OMAPLFB_FBINFO *psPVRFBInfo)
1175         int n;
1176         int iMaxSwapChainBuffs;
1177         int res;
1178         int i, x, y, w;
1179         ion_phys_addr_t phys;
1180         size_t size;
1181         struct tiler_view_t view;
1183         struct omap_ion_tiler_alloc_data sAllocData = {
1184                 .w = ALIGN(psLINFBInfo->var.xres, PAGE_SIZE / (psLINFBInfo->var.bits_per_pixel / 8)),
1185                 .h = psLINFBInfo->var.yres,
1186                 .fmt = psLINFBInfo->var.bits_per_pixel == 16 ? TILER_PIXEL_FMT_16BIT : TILER_PIXEL_FMT_32BIT,
1187                 .flags = 0,
1188                 .token = 0,
1189                 .out_align = PAGE_SIZE
1190         };
1191         unsigned uiFBDevID = psDevInfo->uiFBDevID;
1192         struct sgx_omaplfb_config *psFBPlatConfig = GetFBPlatConfig(uiFBDevID);
1194 #if defined(CONFIG_ION_OMAP)
1195         gpsIONClient = ion_client_create(omap_ion_device,
1196                         1 << ION_HEAP_TYPE_CARVEOUT |
1197                         1 << OMAP_ION_HEAP_TYPE_TILER |
1198                         1 << ION_HEAP_TYPE_SYSTEM,
1199                         "omaplfb");
1200         if (IS_ERR_OR_NULL(gpsIONClient))
1201         {
1202                 printk(KERN_ERR DRIVER_PREFIX
1203                         " %s: Could not create ion client\n", __FUNCTION__);
1204                 return OMAPLFB_ERROR_INIT_FAILURE;
1205         }
1206 #endif /* defined(CONFIG_ION_OMAP) */
1208         if (!psFBPlatConfig->swap_chain_length)
1209         {
1210                 /* Set a default swap chain length if it's not present in the platform data */
1211                 iMaxSwapChainBuffs = 2;
1212                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Swap chain length missing in "
1213                         "platform data, defaulting to %d\n", __FUNCTION__, psDevInfo->uiFBDevID,
1214                         iMaxSwapChainBuffs);
1215         }
1216         else
1217         {
1218                 iMaxSwapChainBuffs = psFBPlatConfig->swap_chain_length;
1219         }
1221         if (psFBPlatConfig->tiler2d_buffers < iMaxSwapChainBuffs)
1222         {
1223                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Trying to use %d tiler "
1224                         "buffers which is less than the swap chain length of %d, maximum "
1225                         "swap chain length will be set to %d\n", __FUNCTION__, psDevInfo->uiFBDevID,
1226                         psFBPlatConfig->tiler2d_buffers, iMaxSwapChainBuffs, psFBPlatConfig->tiler2d_buffers);
1227                 iMaxSwapChainBuffs = psFBPlatConfig->tiler2d_buffers;
1228         }
1230         psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = iMaxSwapChainBuffs;
1231         n = psFBPlatConfig->tiler2d_buffers;
1233         printk(KERN_DEBUG DRIVER_PREFIX
1234                 ": %s: Device %u: Requesting %d TILER 2D framebuffers\n", __FUNCTION__, uiFBDevID, n);
1235         sAllocData.w *= n;
1237         psPVRFBInfo->uiBytesPerPixel = psLINFBInfo->var.bits_per_pixel >> 3;
1238         psPVRFBInfo->bIs2D = OMAPLFB_TRUE;
1239         res = omap_ion_nonsecure_tiler_alloc(gpsIONClient, &sAllocData);
1240         if (res < 0)
1241         {
1242                 printk(KERN_ERR DRIVER_PREFIX
1243                         " %s: Device %u: Could not allocate 2D framebuffer(%d)\n", __FUNCTION__, uiFBDevID, res);
1244                 return OMAPLFB_ERROR_INIT_FAILURE;
1245         }
1247         ion_phys(gpsIONClient, sAllocData.handle, &phys, &size);
1248         psPVRFBInfo->sSysAddr.uiAddr = phys;
1249         psPVRFBInfo->sCPUVAddr = 0;
1251         psPVRFBInfo->ulWidth = psLINFBInfo->var.xres;
1252         psPVRFBInfo->ulHeight = psLINFBInfo->var.yres;
1253         psPVRFBInfo->ulByteStride = PAGE_ALIGN(psPVRFBInfo->ulWidth * psPVRFBInfo->uiBytesPerPixel);
1254         psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride;
1255         psPVRFBInfo->ulRoundedBufferSize = psPVRFBInfo->ulBufferSize;
1256         w = psPVRFBInfo->ulByteStride >> PAGE_SHIFT;
1258         /* this is an "effective" FB size to get correct number of buffers */
1259         psPVRFBInfo->ulFBSize = sAllocData.h * n * psPVRFBInfo->ulByteStride;
1260         psPVRFBInfo->psPageList = kzalloc(w * n * psPVRFBInfo->ulHeight * sizeof(*psPVRFBInfo->psPageList), GFP_KERNEL);
1261         if (!psPVRFBInfo->psPageList)
1262         {
1263                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Could not allocate page list\n", __FUNCTION__, psDevInfo->uiFBDevID);
1264                 ion_free(gpsIONClient, sAllocData.handle);
1265                 return OMAPLFB_ERROR_INIT_FAILURE;
1266         }
1267         psPVRFBInfo->psIONHandle = sAllocData.handle;
1269         tilview_create(&view, phys, psDevInfo->sFBInfo.ulWidth, psDevInfo->sFBInfo.ulHeight);
1270         for(i=0; i<n; i++)
1271         {
1272                 for(y=0; y<psDevInfo->sFBInfo.ulHeight; y++)
1273                 {
1274                         for(x=0; x<w; x++)
1275                         {
1276                                 psPVRFBInfo->psPageList[i * psDevInfo->sFBInfo.ulHeight * w + y * w + x].uiAddr =
1277                                         phys + view.v_inc * y + ((x + i * w) << PAGE_SHIFT);
1278                         }
1279                 }
1280         }
1281         return OMAPLFB_OK;
1283 #endif
1285 static OMAPLFB_ERROR OMAPLFBInitFBVRAM(OMAPLFB_DEVINFO *psDevInfo,
1286                                         struct fb_info *psLINFBInfo,
1287                                         OMAPLFB_FBINFO *psPVRFBInfo)
1289         struct sgx_omaplfb_config *psFBPlatConfig = GetFBPlatConfig(psDevInfo->uiFBDevID);
1290         unsigned long FBSize = psLINFBInfo->fix.smem_len;
1291         unsigned long ulLCM;
1292         int iMaxSwapChainBuffs;
1293         IMG_UINT32 ui32FBAvailableBuffs;
1295         /* Check if there is VRAM reserved for this FB */
1296         if (FBSize == 0 || psLINFBInfo->fix.line_length == 0)
1297         {
1298                 return OMAPLFB_ERROR_INVALID_DEVICE;
1299         }
1301         /* Fail to init this DC device if vram buffers are not set */
1302         if (!psFBPlatConfig->vram_buffers)
1303         {
1304                 return OMAPLFB_ERROR_INVALID_PARAMS;
1305         }
1307         if (!psFBPlatConfig->swap_chain_length)
1308         {
1309                 /* Set a default swap chain length if it's not present in the platform data */
1310                 iMaxSwapChainBuffs = 2;
1311                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Swap chain length missing in "
1312                         "platform data, defaulting to %d\n", __FUNCTION__, psDevInfo->uiFBDevID,
1313                         iMaxSwapChainBuffs);
1314         }
1315         else
1316         {
1317                 iMaxSwapChainBuffs = psFBPlatConfig->swap_chain_length;
1318         }
1320         if (psFBPlatConfig->vram_buffers < iMaxSwapChainBuffs)
1321         {
1322                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Trying to use %d vram "
1323                         "buffers which is less than the swap chain length of %d, maximum "
1324                         "swap chain length will be set to %d\n", __FUNCTION__, psDevInfo->uiFBDevID,
1325                         psFBPlatConfig->vram_buffers, iMaxSwapChainBuffs, psFBPlatConfig->vram_buffers);
1326                 iMaxSwapChainBuffs = psFBPlatConfig->vram_buffers;
1327         }
1329         ulLCM = LCM(psLINFBInfo->fix.line_length, OMAPLFB_PAGE_SIZE);
1330         psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start;
1331         psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base;
1332         psPVRFBInfo->ulWidth = psLINFBInfo->var.xres;
1333         psPVRFBInfo->ulHeight = psLINFBInfo->var.yres;
1334         psPVRFBInfo->ulByteStride =  psLINFBInfo->fix.line_length;
1335         psPVRFBInfo->ulFBSize = FBSize;
1336         psPVRFBInfo->bIs2D = OMAPLFB_FALSE;
1337         psPVRFBInfo->psPageList = IMG_NULL;
1338         psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride;
1339         psPVRFBInfo->ulRoundedBufferSize = RoundUpToMultiple(psPVRFBInfo->ulBufferSize, ulLCM);
1340         ui32FBAvailableBuffs = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize);
1342         if (!ui32FBAvailableBuffs)
1343         {
1344                 printk(KERN_ERR DRIVER_PREFIX " %s: Device %u: Not enough vram to init swap "
1345                         "chain buffers\n", __FUNCTION__, psDevInfo->uiFBDevID);
1346                 return OMAPLFB_ERROR_INIT_FAILURE;
1347         }
1348         else if (ui32FBAvailableBuffs < psFBPlatConfig->vram_buffers)
1349         {
1350                 printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Not enough vram to hold "
1351                         "%d buffers (available %d), swap chain length will be set to %d\n",
1352                         __FUNCTION__, psDevInfo->uiFBDevID, iMaxSwapChainBuffs, ui32FBAvailableBuffs,
1353                         ui32FBAvailableBuffs);
1354                 iMaxSwapChainBuffs = ui32FBAvailableBuffs;
1355         }
1356         else
1357         {
1358                 iMaxSwapChainBuffs = psFBPlatConfig->vram_buffers;
1359         }
1361         psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = iMaxSwapChainBuffs;
1363         printk(KERN_DEBUG DRIVER_PREFIX ": %s: Device %u: Using %d VRAM framebuffers\n", __FUNCTION__,
1364                 psDevInfo->uiFBDevID, iMaxSwapChainBuffs);
1366         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1367                         ": Device %u: Framebuffer virtual width: %u\n",
1368                         psDevInfo->uiFBDevID, psLINFBInfo->var.xres_virtual));
1369         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1370                         ": Device %u: Framebuffer virtual height: %u\n",
1371                         psDevInfo->uiFBDevID, psLINFBInfo->var.yres_virtual));
1372         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1373                         ": Device %u: LCM of stride and page size: %lu\n",
1374                         psDevInfo->uiFBDevID, ulLCM));
1376         return OMAPLFB_OK;
1379 static OMAPLFB_ERROR OMAPLFBInitFBDev(OMAPLFB_DEVINFO *psDevInfo)
1381         struct fb_info *psLINFBInfo;
1382         struct module *psLINFBOwner;
1383         OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo;
1384         OMAPLFB_ERROR eError = OMAPLFB_ERROR_GENERIC;
1385         unsigned uiFBDevID = psDevInfo->uiFBDevID;
1386         struct sgx_omaplfb_config *psFBPlatConfig;
1388         OMAPLFB_CONSOLE_LOCK();
1390         psLINFBInfo = registered_fb[uiFBDevID];
1391         if (psLINFBInfo == NULL)
1392         {
1393                 eError = OMAPLFB_ERROR_INVALID_DEVICE;
1394                 goto ErrorRelSem;
1395         }
1397         psLINFBOwner = psLINFBInfo->fbops->owner;
1398         if (!try_module_get(psLINFBOwner))
1399         {
1400                 printk(KERN_INFO DRIVER_PREFIX
1401                         ": %s: Device %u: Couldn't get framebuffer module\n", __FUNCTION__, uiFBDevID);
1403                 goto ErrorRelSem;
1404         }
1406         if (psLINFBInfo->fbops->fb_open != NULL)
1407         {
1408                 int res;
1410                 res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0);
1411                 if (res != 0)
1412                 {
1413                         printk(KERN_INFO DRIVER_PREFIX
1414                                 " %s: Device %u: Couldn't open framebuffer(%d)\n", __FUNCTION__, uiFBDevID, res);
1416                         goto ErrorModPut;
1417                 }
1418         }
1420         psDevInfo->psLINFBInfo = psLINFBInfo;
1422         /*
1423          * Abort registering this DC device if no platform data found. This
1424          * shouldn't happen since the FB index must be valid at this point.
1425          */
1426         psFBPlatConfig = GetFBPlatConfig(uiFBDevID);
1427         if (!psFBPlatConfig)
1428         {
1429                 eError = OMAPLFB_ERROR_INVALID_PARAMS;
1430                 goto ErrorModPut;
1431         }
1433 #if defined(CONFIG_DSSCOMP)
1434         if (psFBPlatConfig->tiler2d_buffers)
1435         {
1436                 /* Use ION to create the flip chain buffers with TILER */
1437                 eError = OMAPLFBInitIonOmap(psDevInfo, psLINFBInfo, psPVRFBInfo);
1438                 if (eError != OMAPLFB_OK)
1439                 {
1440                         goto ErrorModPut;
1441                 }
1442         }
1443         else
1444 #endif
1445         {
1446                 /* Fall back to allocate flip chain buffers with VRAM */
1447                 eError = OMAPLFBInitFBVRAM(psDevInfo, psLINFBInfo, psPVRFBInfo);
1448                 if (eError != OMAPLFB_OK)
1449                 {
1450                         goto ErrorModPut;
1451                 }
1452         }
1454         OMAPLFBPrintInfo(psDevInfo);
1455         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1456                         ": Device %u: Framebuffer physical address: %p\n",
1457                         psDevInfo->uiFBDevID, (void *)psPVRFBInfo->sSysAddr.uiAddr));
1458         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1459                         ": Device %u: Framebuffer virtual address: %p\n",
1460                         psDevInfo->uiFBDevID, (void *)psPVRFBInfo->sCPUVAddr));
1461         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1462                         ": Device %u: Framebuffer size: %lu\n",
1463                         psDevInfo->uiFBDevID, psPVRFBInfo->ulFBSize));
1464         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1465                         ": Device %u: Framebuffer width: %lu\n",
1466                         psDevInfo->uiFBDevID, psPVRFBInfo->ulWidth));
1467         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1468                         ": Device %u: Framebuffer height: %lu\n",
1469                         psDevInfo->uiFBDevID, psPVRFBInfo->ulHeight));
1470         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1471                         ": Device %u: Framebuffer stride: %lu\n",
1472                         psDevInfo->uiFBDevID, psPVRFBInfo->ulByteStride));
1474         if(psLINFBInfo->var.bits_per_pixel == 16)
1475         {
1476                 if((psLINFBInfo->var.red.length == 5) &&
1477                         (psLINFBInfo->var.green.length == 6) && 
1478                         (psLINFBInfo->var.blue.length == 5) && 
1479                         (psLINFBInfo->var.red.offset == 11) &&
1480                         (psLINFBInfo->var.green.offset == 5) && 
1481                         (psLINFBInfo->var.blue.offset == 0) && 
1482                         (psLINFBInfo->var.red.msb_right == 0))
1483                 {
1484                         psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565;
1485                 }
1486                 else
1487                 {
1488                         printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID);
1489                 }
1490         }
1491         else if(psLINFBInfo->var.bits_per_pixel == 32)
1492         {
1493                 if((psLINFBInfo->var.red.length == 8) &&
1494                         (psLINFBInfo->var.green.length == 8) && 
1495                         (psLINFBInfo->var.blue.length == 8) && 
1496                         (psLINFBInfo->var.red.offset == 16) &&
1497                         (psLINFBInfo->var.green.offset == 8) && 
1498                         (psLINFBInfo->var.blue.offset == 0) && 
1499                         (psLINFBInfo->var.red.msb_right == 0))
1500                 {
1501                         psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888;
1502                 }
1503                 else
1504                 {
1505                         printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID);
1506                 }
1507         }       
1508         else
1509         {
1510                 printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID);
1511         }
1513         psDevInfo->sFBInfo.ulPhysicalWidthmm =
1514                 ((int)psLINFBInfo->var.width  > 0) ? psLINFBInfo->var.width  : 90;
1516         psDevInfo->sFBInfo.ulPhysicalHeightmm =
1517                 ((int)psLINFBInfo->var.height > 0) ? psLINFBInfo->var.height : 54;
1519         
1520         psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr;
1521         psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr;
1523         eError = OMAPLFB_OK;
1524         goto ErrorRelSem;
1526 ErrorModPut:
1527         module_put(psLINFBOwner);
1528 ErrorRelSem:
1529         OMAPLFB_CONSOLE_UNLOCK();
1531         return eError;
1534 static void OMAPLFBDeInitFBDev(OMAPLFB_DEVINFO *psDevInfo)
1536         struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo;
1537         OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo;
1538         struct module *psLINFBOwner;
1540         OMAPLFB_CONSOLE_LOCK();
1542         psLINFBOwner = psLINFBInfo->fbops->owner;
1544 #if defined(CONFIG_DSSCOMP)
1545         kfree(psPVRFBInfo->psPageList);
1546         if (psPVRFBInfo->psIONHandle)
1547         {
1548                 ion_free(gpsIONClient, psPVRFBInfo->psIONHandle);
1549         }
1550         if (psPVRFBInfo->psBltFBsIonHndl)
1551         {
1552                 ion_free(gpsIONClient, psPVRFBInfo->psBltFBsIonHndl);
1553         }
1554         if (psPVRFBInfo->psBltFBsBvHndl)
1555         {
1556                 int i;
1557                 for (i = 0; i < psPVRFBInfo->psBltFBsNo; i++)
1558                 {
1559                         if (psPVRFBInfo->psBltFBsBvHndl[i])
1560                         {
1561                                 kfree(psPVRFBInfo->psBltFBsBvHndl[i]);
1562                         }
1563                 }
1564                 kfree(psPVRFBInfo->psBltFBsBvHndl);
1565                 kfree(psPVRFBInfo->psBltFBsBvPhys);
1566         }
1567 #endif
1568         if (psLINFBInfo->fbops->fb_release != NULL) 
1569         {
1570                 (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0);
1571         }
1573         module_put(psLINFBOwner);
1575         OMAPLFB_CONSOLE_UNLOCK();
1578 static OMAPLFB_DEVINFO *OMAPLFBInitDev(unsigned uiFBDevID)
1580         PFN_CMD_PROC            pfnCmdProcList[OMAPLFB_COMMAND_COUNT];
1581         IMG_UINT32              aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2];
1582         OMAPLFB_DEVINFO         *psDevInfo = NULL;
1584         
1585         psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO));
1587         if(psDevInfo == NULL)
1588         {
1589                 printk(KERN_ERR DRIVER_PREFIX
1590                         ": %s: Device %u: Couldn't allocate device information structure\n", __FUNCTION__, uiFBDevID);
1592                 goto ErrorExit;
1593         }
1595         
1596         memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO));
1598         psDevInfo->uiFBDevID = uiFBDevID;
1600         
1601         if(!(*gpfnGetPVRJTable)(&psDevInfo->sPVRJTable))
1602         {
1603                 goto ErrorFreeDevInfo;
1604         }
1606         
1607         if(OMAPLFBInitFBDev(psDevInfo) != OMAPLFB_OK)
1608         {
1609                 
1610                 goto ErrorFreeDevInfo;
1611         }
1613         if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers != 0)
1614         {
1615                 psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1;
1616                 psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1;
1617         }
1619         psDevInfo->sDisplayInfo.ui32PhysicalWidthmm = psDevInfo->sFBInfo.ulPhysicalWidthmm;
1620         psDevInfo->sDisplayInfo.ui32PhysicalHeightmm = psDevInfo->sFBInfo.ulPhysicalHeightmm;
1622         strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
1624         psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat;
1625         psDevInfo->sDisplayDim.ui32Width      = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth;
1626         psDevInfo->sDisplayDim.ui32Height     = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight;
1627         psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride;
1629         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1630                 ": Device %u: Maximum number of swap chain buffers: %u\n",
1631                 psDevInfo->uiFBDevID, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers));
1633         
1634         psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr;
1635         psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr;
1636         psDevInfo->sSystemBuffer.psDevInfo = psDevInfo;
1638         OMAPLFBInitBufferForSwap(&psDevInfo->sSystemBuffer);
1640         
1642         psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
1643         psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
1644         psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
1645         psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
1646         psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
1647         psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
1648         psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
1649         psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
1650         psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
1651         psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain;
1652         psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
1653         psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
1654         psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
1655         psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
1656         psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
1657         psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
1658         psDevInfo->sDCJTable.pfnSetDCState = SetDCState;
1660         
1661         if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice(
1662                 &psDevInfo->sDCJTable,
1663                 &psDevInfo->uiPVRDevID) != PVRSRV_OK)
1664         {
1665                 printk(KERN_ERR DRIVER_PREFIX
1666                         ": %s: Device %u: PVR Services device registration failed\n", __FUNCTION__, uiFBDevID);
1668                 goto ErrorDeInitFBDev;
1669         }
1670         DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
1671                 ": Device %u: PVR Device ID: %u\n",
1672                 psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID));
1673         
1674         
1675         pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
1677         
1678         aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; 
1679         if (gbBvInterfacePresent)
1680         {
1681                 aui32SyncCountList[DC_FLIP_COMMAND][1] = 32;
1682         }
1683         else
1684         {
1685                 aui32SyncCountList[DC_FLIP_COMMAND][1] = 10;
1686         }
1688         
1692         if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiPVRDevID,
1693                         &pfnCmdProcList[0],
1694                         aui32SyncCountList,
1695                         OMAPLFB_COMMAND_COUNT) != PVRSRV_OK)
1696         {
1697                 printk(KERN_ERR DRIVER_PREFIX
1698                         ": %s: Device %u: Couldn't register command processing functions with PVR Services\n", __FUNCTION__, uiFBDevID);
1699                 goto ErrorUnregisterDevice;
1700         }
1702         OMAPLFBCreateSwapChainLockInit(psDevInfo);
1704         OMAPLFBAtomicBoolInit(&psDevInfo->sBlanked, OMAPLFB_FALSE);
1705         OMAPLFBAtomicIntInit(&psDevInfo->sBlankEvents, 0);
1706         OMAPLFBAtomicBoolInit(&psDevInfo->sFlushCommands, OMAPLFB_FALSE);
1707 #if defined(CONFIG_HAS_EARLYSUSPEND)
1708         OMAPLFBAtomicBoolInit(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE);
1709 #endif
1710 #if defined(SUPPORT_DRI_DRM)
1711         OMAPLFBAtomicBoolInit(&psDevInfo->sLeaveVT, OMAPLFB_FALSE);
1712 #endif
1713         return psDevInfo;
1715 ErrorUnregisterDevice:
1716         (void)psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID);
1717 ErrorDeInitFBDev:
1718         OMAPLFBDeInitFBDev(psDevInfo);
1719 ErrorFreeDevInfo:
1720         OMAPLFBFreeKernelMem(psDevInfo);
1721 ErrorExit:
1722         return NULL;
1725 #if defined(CONFIG_OMAPLFB)
1726 int OMAPLFBRegisterPVRDriver(PFN_DC_GET_PVRJTABLE pfnFuncTable)
1728         gpfnGetPVRJTable = pfnFuncTable;
1730         if(OMAPLFBInit() != OMAPLFB_OK)
1731         {
1732                 printk(KERN_ERR DRIVER_PREFIX
1733                         " %s: Could not create ion client\n", __FUNCTION__);
1734                 return -1;
1735         }
1736         return 0;
1738 EXPORT_SYMBOL(OMAPLFBRegisterPVRDriver);
1739 #endif
1741 OMAPLFB_ERROR OMAPLFBInit(void)
1743         unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne();
1744         unsigned i;
1745         unsigned uiDevicesFound = 0;
1747 #if !defined(CONFIG_OMAPLFB)
1748         if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &gpfnGetPVRJTable) != OMAPLFB_OK)
1749         {
1750                 return OMAPLFB_ERROR_INIT_FAILURE;
1751         }
1752 #endif
1754         gbBvInterfacePresent = OMAPLFBInitBlt();
1756         if (!gbBvInterfacePresent)
1757         {
1758                 printk(KERN_INFO DRIVER_PREFIX "%s: Blitsville gc2d "
1759                         "not present, blits disabled\n", __func__);
1760         }
1761         for(i = uiMaxFBDevIDPlusOne; i-- != 0;)
1762         {
1763                 OMAPLFB_DEVINFO *psDevInfo = OMAPLFBInitDev(i);
1765                 if (psDevInfo != NULL)
1766                 {
1767                         
1768                         OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, psDevInfo);
1769                         uiDevicesFound++;
1770                 }
1771         }
1773         return (uiDevicesFound != 0) ? OMAPLFB_OK : OMAPLFB_ERROR_INIT_FAILURE;
1776 static OMAPLFB_BOOL OMAPLFBDeInitDev(OMAPLFB_DEVINFO *psDevInfo)
1778         PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable = &psDevInfo->sPVRJTable;
1780         OMAPLFBCreateSwapChainLockDeInit(psDevInfo);
1782         OMAPLFBAtomicBoolDeInit(&psDevInfo->sBlanked);
1783         OMAPLFBAtomicIntDeInit(&psDevInfo->sBlankEvents);
1784         OMAPLFBAtomicBoolDeInit(&psDevInfo->sFlushCommands);
1785 #if defined(CONFIG_HAS_EARLYSUSPEND)
1786         OMAPLFBAtomicBoolDeInit(&psDevInfo->sEarlySuspendFlag);
1787 #endif
1788 #if defined(SUPPORT_DRI_DRM)
1789         OMAPLFBAtomicBoolDeInit(&psDevInfo->sLeaveVT);
1790 #endif
1791         psPVRJTable = &psDevInfo->sPVRJTable;
1793         if (psPVRJTable->pfnPVRSRVRemoveCmdProcList (psDevInfo->uiPVRDevID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK)
1794         {
1795                 printk(KERN_ERR DRIVER_PREFIX
1796                         ": %s: Device %u: PVR Device %u: Couldn't unregister command processing functions\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID);
1797                 return OMAPLFB_FALSE;
1798         }
1800         
1801         if (psPVRJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID) != PVRSRV_OK)
1802         {
1803                 printk(KERN_ERR DRIVER_PREFIX
1804                         ": %s: Device %u: PVR Device %u: Couldn't remove device from PVR Services\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID);
1805                 return OMAPLFB_FALSE;
1806         }
1807         
1808         OMAPLFBDeInitFBDev(psDevInfo);
1810         OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, NULL);
1812         
1813         OMAPLFBFreeKernelMem(psDevInfo);
1815         return OMAPLFB_TRUE;
1818 OMAPLFB_ERROR OMAPLFBDeInit(void)
1820         unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne();
1821         unsigned i;
1822         OMAPLFB_BOOL bError = OMAPLFB_FALSE;
1824         for(i = 0; i < uiMaxFBDevIDPlusOne; i++)
1825         {
1826                 OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i);
1828                 if (psDevInfo != NULL)
1829                 {
1830                         bError |= !OMAPLFBDeInitDev(psDevInfo);
1831                 }
1832         }
1834         return (bError) ? OMAPLFB_ERROR_INIT_FAILURE : OMAPLFB_OK;