diff options
author | Hemant Hariyani <hemanthariyani@ti.com> | 2012-07-26 14:16:53 -0500 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-03 01:18:03 +0200 |
commit | 13f3d31e6b535329e620ef034372245027033537 (patch) | |
tree | a1c1ac65587f859901a71db68387a7bfa7b0d789 | |
parent | 456dfbe66f41011d7478682d1d25982504b05098 (diff) | |
download | kernel_samsung_tuna-13f3d31e6b535329e620ef034372245027033537.zip kernel_samsung_tuna-13f3d31e6b535329e620ef034372245027033537.tar.gz kernel_samsung_tuna-13f3d31e6b535329e620ef034372245027033537.tar.bz2 |
omaplfb: Add omaplfb to the kernel tree
omaplfb has dependencies on several kernel components and it will
be easier to maintain it in the kernel tree.
Sync'd to DDK omaplfb patch:
omaplfb: Allocate a clear buffer with 8 pixel stride per GC requirement
Change-Id: I0c781007350fea724aa498f7f8d328db66f9d41c
Signed-off-by: Hemant Hariyani <hemanthariyani@ti.com>
Signed-off-by: Tony Lofthouse <a0741364@ti.com>
-rw-r--r-- | drivers/video/omap2/Kconfig | 1 | ||||
-rw-r--r-- | drivers/video/omap2/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/Kconfig | 6 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/Makefile | 18 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/img_defs.h | 154 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/img_types.h | 215 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/kerneldisplay.h | 244 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/omaplfb.h | 334 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/omaplfb_bv.c | 588 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/omaplfb_displayclass.c | 1833 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/omaplfb_linux.c | 1197 | ||||
-rw-r--r-- | drivers/video/omap2/omaplfb/servicesext.h | 966 |
12 files changed, 5557 insertions, 0 deletions
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig index c4ec41a..3cde67a 100644 --- a/drivers/video/omap2/Kconfig +++ b/drivers/video/omap2/Kconfig @@ -9,3 +9,4 @@ source "drivers/video/omap2/omapfb/Kconfig" source "drivers/video/omap2/displays/Kconfig" source "drivers/video/omap2/dsscomp/Kconfig" source "drivers/video/omap2/hdcp/Kconfig" +source "drivers/video/omap2/omaplfb/Kconfig" diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile index ceb1dd9..1b15760 100644 --- a/drivers/video/omap2/Makefile +++ b/drivers/video/omap2/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_FB_OMAP2) += omapfb/ obj-$(CONFIG_OMAP4_HDCP) += hdcp/ obj-y += displays/ obj-y += dsscomp/ +obj-$(CONFIG_OMAPLFB) += omaplfb/ diff --git a/drivers/video/omap2/omaplfb/Kconfig b/drivers/video/omap2/omaplfb/Kconfig new file mode 100644 index 0000000..6b90ccd --- /dev/null +++ b/drivers/video/omap2/omaplfb/Kconfig @@ -0,0 +1,6 @@ +config OMAPLFB + bool "In-kernel omaplfb: interface between display and kernel side PowerVR graphics driver" + depends on OMAP2_DSS && DSSCOMP + default y + help + Support for in-kernel omaplfb. This is used by PVR kernel module. diff --git a/drivers/video/omap2/omaplfb/Makefile b/drivers/video/omap2/omaplfb/Makefile new file mode 100644 index 0000000..c949aca --- /dev/null +++ b/drivers/video/omap2/omaplfb/Makefile @@ -0,0 +1,18 @@ +obj-$(CONFIG_OMAPLFB) := omaplfb.o + +ccflags-y += \ + -I$(KERNELDIR)/drivers/video/omap2 \ + -I$(KERNELDIR)/arch/arm/plat-omap/include + +ccflags-y += \ + -DLINUX \ + -D__linux__ \ + -D__KERNEL__ \ + -DPVR_LINUX_USING_WORKQUEUES + +omaplfb-y += \ + omaplfb_linux.o \ + omaplfb_displayclass.o + +omaplfb-$(CONFIG_GCBV) += \ + omaplfb_bv.o diff --git a/drivers/video/omap2/omaplfb/img_defs.h b/drivers/video/omap2/omaplfb/img_defs.h new file mode 100644 index 0000000..ce84b0e --- /dev/null +++ b/drivers/video/omap2/omaplfb/img_defs.h @@ -0,0 +1,154 @@ +/*************************************************************************/ /*! +@Title Common header containing type definitions for portability +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Contains variable and structure definitions. Any platform + specific types should be defined in this file. +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ +#if !defined (__IMG_DEFS_H__) +#define __IMG_DEFS_H__ + +#include "img_types.h" + +typedef enum img_tag_TriStateSwitch +{ + IMG_ON = 0x00, + IMG_OFF, + IMG_IGNORE + +} img_TriStateSwitch, * img_pTriStateSwitch; + +#define IMG_SUCCESS 0 + +#define IMG_NO_REG 1 + +#if defined (NO_INLINE_FUNCS) + #define INLINE + #define FORCE_INLINE +#else +#if defined (__cplusplus) + #define INLINE inline + #define FORCE_INLINE inline +#else +#if !defined(INLINE) + #define INLINE __inline +#endif + #define FORCE_INLINE static __inline +#endif +#endif + + +/* Use this in any file, or use attributes under GCC - see below */ +#ifndef PVR_UNREFERENCED_PARAMETER +#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param) +#endif + +/* The best way to supress unused parameter warnings using GCC is to use a + * variable attribute. Place the unref__ between the type and name of an + * unused parameter in a function parameter list, eg `int unref__ var'. This + * should only be used in GCC build environments, for example, in files that + * compile only on Linux. Other files should use UNREFERENCED_PARAMETER */ +#ifdef __GNUC__ +#define unref__ __attribute__ ((unused)) +#else +#define unref__ +#endif + +/* + Wide character definitions +*/ +#ifndef _TCHAR_DEFINED +#if defined(UNICODE) +typedef unsigned short TCHAR, *PTCHAR, *PTSTR; +#else /* #if defined(UNICODE) */ +typedef char TCHAR, *PTCHAR, *PTSTR; +#endif /* #if defined(UNICODE) */ +#define _TCHAR_DEFINED +#endif /* #ifndef _TCHAR_DEFINED */ + + + #if defined(__linux__) || defined(__QNXNTO__) || defined(__METAG) + + #define IMG_CALLCONV + #define IMG_INTERNAL __attribute__((visibility("hidden"))) + #define IMG_EXPORT __attribute__((visibility("default"))) + #define IMG_IMPORT + #define IMG_RESTRICT __restrict__ + + #else + #error("define an OS") + #endif + +// Use default definition if not overridden +#ifndef IMG_ABORT + #define IMG_ABORT() abort() +#endif + +#ifndef IMG_MALLOC + #define IMG_MALLOC(A) malloc (A) +#endif + +#ifndef IMG_FREE + #define IMG_FREE(A) free (A) +#endif + +#define IMG_CONST const + +#if defined(__GNUC__) +#define IMG_FORMAT_PRINTF(x,y) __attribute__((format(printf,x,y))) +#else +#define IMG_FORMAT_PRINTF(x,y) +#endif + +/* + * Cleanup request defines + */ +#define CLEANUP_WITH_POLL IMG_FALSE +#define FORCE_CLEANUP IMG_TRUE + +#if defined (_WIN64) +#define IMG_UNDEF (~0ULL) +#else +#define IMG_UNDEF (~0UL) +#endif + +#endif /* #if !defined (__IMG_DEFS_H__) */ +/***************************************************************************** + End of file (IMG_DEFS.H) +*****************************************************************************/ diff --git a/drivers/video/omap2/omaplfb/img_types.h b/drivers/video/omap2/omaplfb/img_types.h new file mode 100644 index 0000000..922aa28 --- /dev/null +++ b/drivers/video/omap2/omaplfb/img_types.h @@ -0,0 +1,215 @@ +/*************************************************************************/ /*! +@Title Global types for use by IMG APIs +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Defines type aliases for use by IMG APIs. +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ +#ifndef __IMG_TYPES_H__ +#define __IMG_TYPES_H__ + +/* define all address space bit depths: */ +/* CPU virtual address space defaults to 32bits */ +#if !defined(IMG_ADDRSPACE_CPUVADDR_BITS) +#define IMG_ADDRSPACE_CPUVADDR_BITS 32 +#endif + +/* Physical address space defaults to 32bits */ +#if !defined(IMG_ADDRSPACE_PHYSADDR_BITS) +#define IMG_ADDRSPACE_PHYSADDR_BITS 32 +#endif + +typedef unsigned int IMG_UINT, *IMG_PUINT; +typedef signed int IMG_INT, *IMG_PINT; + +typedef unsigned char IMG_UINT8, *IMG_PUINT8; +typedef unsigned char IMG_BYTE, *IMG_PBYTE; +typedef signed char IMG_INT8, *IMG_PINT8; +typedef char IMG_CHAR, *IMG_PCHAR; + +typedef unsigned short IMG_UINT16, *IMG_PUINT16; +typedef signed short IMG_INT16, *IMG_PINT16; +#if !defined(IMG_UINT32_IS_ULONG) +typedef unsigned int IMG_UINT32, *IMG_PUINT32; +typedef signed int IMG_INT32, *IMG_PINT32; +#else +typedef unsigned long IMG_UINT32, *IMG_PUINT32; +typedef signed long IMG_INT32, *IMG_PINT32; +#endif +#if !defined(IMG_UINT32_MAX) + #define IMG_UINT32_MAX 0xFFFFFFFFUL +#endif + +#if defined(USE_CODE) + +typedef unsigned __int64 IMG_UINT64, *IMG_PUINT64; +typedef __int64 IMG_INT64, *IMG_PINT64; + +#else + #if ((defined(LINUX) || defined(__METAG)) || defined(__QNXNTO__)) + typedef unsigned long long IMG_UINT64, *IMG_PUINT64; + typedef long long IMG_INT64, *IMG_PINT64; + #else + #error("define an OS") + #endif +#endif + +#if !(defined(LINUX) && defined (__KERNEL__)) +/* Linux kernel mode does not use floating point */ +typedef float IMG_FLOAT, *IMG_PFLOAT; +typedef double IMG_DOUBLE, *IMG_PDOUBLE; +#endif + +typedef enum tag_img_bool +{ + IMG_FALSE = 0, + IMG_TRUE = 1, + IMG_FORCE_ALIGN = 0x7FFFFFFF +} IMG_BOOL, *IMG_PBOOL; + +typedef void IMG_VOID, *IMG_PVOID; + +typedef IMG_INT32 IMG_RESULT; + +#if defined(_WIN64) + typedef unsigned __int64 IMG_UINTPTR_T; + typedef signed __int64 IMG_PTRDIFF_T; + typedef IMG_UINT64 IMG_SIZE_T; +#else + typedef unsigned int IMG_UINTPTR_T; + typedef IMG_UINT32 IMG_SIZE_T; +#endif + +typedef IMG_PVOID IMG_HANDLE; + +typedef void** IMG_HVOID, * IMG_PHVOID; + +#define IMG_NULL 0 + +/* services/stream ID */ +typedef IMG_UINT32 IMG_SID; + +typedef IMG_UINT32 IMG_EVENTSID; + +/* + * Address types. + * All types used to refer to a block of memory are wrapped in structures + * to enforce some degree of type safety, i.e. a IMG_DEV_VIRTADDR cannot + * be assigned to a variable of type IMG_DEV_PHYADDR because they are not the + * same thing. + * + * There is an assumption that the system contains at most one non-cpu mmu, + * and a memory block is only mapped by the MMU once. + * + * Different devices could have offset views of the physical address space. + * + */ + + +/* + * + * +------------+ +------------+ +------------+ +------------+ + * | CPU | | DEV | | DEV | | DEV | + * +------------+ +------------+ +------------+ +------------+ + * | | | | + * | PVOID |IMG_DEV_VIRTADDR |IMG_DEV_VIRTADDR | + * | \-------------------/ | + * | | | + * +------------+ +------------+ | + * | MMU | | MMU | | + * +------------+ +------------+ | + * | | | + * | | | + * | | | + * +--------+ +---------+ +--------+ + * | Offset | | (Offset)| | Offset | + * +--------+ +---------+ +--------+ + * | | IMG_DEV_PHYADDR | + * | | | + * | | IMG_DEV_PHYADDR | + * +---------------------------------------------------------------------+ + * | System Address bus | + * +---------------------------------------------------------------------+ + * + */ + +typedef IMG_PVOID IMG_CPU_VIRTADDR; + +/* device virtual address */ +typedef struct _IMG_DEV_VIRTADDR +{ + /* device virtual addresses are 32bit for now */ + IMG_UINT32 uiAddr; +#define IMG_CAST_TO_DEVVADDR_UINT(var) (IMG_UINT32)(var) + +} IMG_DEV_VIRTADDR; + +typedef IMG_UINT32 IMG_DEVMEM_SIZE_T; + +/* cpu physical address */ +typedef struct _IMG_CPU_PHYADDR +{ + /* variable sized type (32,64) */ + IMG_UINTPTR_T uiAddr; +} IMG_CPU_PHYADDR; + +/* device physical address */ +typedef struct _IMG_DEV_PHYADDR +{ +#if IMG_ADDRSPACE_PHYSADDR_BITS == 32 + /* variable sized type (32,64) */ + IMG_UINTPTR_T uiAddr; +#else + IMG_UINT32 uiAddr; + IMG_UINT32 uiHighAddr; +#endif +} IMG_DEV_PHYADDR; + +/* system physical address */ +typedef struct _IMG_SYS_PHYADDR +{ + /* variable sized type (32,64) */ + IMG_UINTPTR_T uiAddr; +} IMG_SYS_PHYADDR; + +#include "img_defs.h" + +#endif /* __IMG_TYPES_H__ */ +/****************************************************************************** + End of file (img_types.h) +******************************************************************************/ diff --git a/drivers/video/omap2/omaplfb/kerneldisplay.h b/drivers/video/omap2/omaplfb/kerneldisplay.h new file mode 100644 index 0000000..e22a9c1 --- /dev/null +++ b/drivers/video/omap2/omaplfb/kerneldisplay.h @@ -0,0 +1,244 @@ +/*************************************************************************/ /*! +@Title Display device class API structures and prototypes +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Provides display device class API structures and prototypes + for kernel services to kernel 3rd party display. +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ + +#if !defined (__KERNELDISPLAY_H__) +#define __KERNELDISPLAY_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef PVRSRV_ERROR (*PFN_OPEN_DC_DEVICE)(IMG_UINT32, IMG_HANDLE*, PVRSRV_SYNC_DATA*); +typedef PVRSRV_ERROR (*PFN_CLOSE_DC_DEVICE)(IMG_HANDLE); +typedef PVRSRV_ERROR (*PFN_ENUM_DC_FORMATS)(IMG_HANDLE, IMG_UINT32*, DISPLAY_FORMAT*); +typedef PVRSRV_ERROR (*PFN_ENUM_DC_DIMS)(IMG_HANDLE, + DISPLAY_FORMAT*, + IMG_UINT32*, + DISPLAY_DIMS*); +typedef PVRSRV_ERROR (*PFN_GET_DC_SYSTEMBUFFER)(IMG_HANDLE, IMG_HANDLE*); +typedef PVRSRV_ERROR (*PFN_GET_DC_INFO)(IMG_HANDLE, DISPLAY_INFO*); +typedef PVRSRV_ERROR (*PFN_CREATE_DC_SWAPCHAIN)(IMG_HANDLE, + IMG_UINT32, + DISPLAY_SURF_ATTRIBUTES*, + DISPLAY_SURF_ATTRIBUTES*, + IMG_UINT32, + PVRSRV_SYNC_DATA**, + IMG_UINT32, + IMG_HANDLE*, + IMG_UINT32*); +typedef PVRSRV_ERROR (*PFN_DESTROY_DC_SWAPCHAIN)(IMG_HANDLE, + IMG_HANDLE); +typedef PVRSRV_ERROR (*PFN_SET_DC_DSTRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*); +typedef PVRSRV_ERROR (*PFN_SET_DC_SRCRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*); +typedef PVRSRV_ERROR (*PFN_SET_DC_DSTCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_SET_DC_SRCCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_GET_DC_BUFFERS)(IMG_HANDLE, + IMG_HANDLE, + IMG_UINT32*, + IMG_HANDLE*); +typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_BUFFER)(IMG_HANDLE, + IMG_HANDLE, + IMG_UINT32, + IMG_HANDLE, + IMG_UINT32, + IMG_RECT*); +typedef IMG_VOID (*PFN_QUERY_SWAP_COMMAND_ID)(IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_UINT16*, IMG_BOOL*); +typedef IMG_VOID (*PFN_SET_DC_STATE)(IMG_HANDLE, IMG_UINT32); + +/* + Function table for SRVKM->DISPLAY +*/ +typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG +{ + IMG_UINT32 ui32TableSize; + PFN_OPEN_DC_DEVICE pfnOpenDCDevice; + PFN_CLOSE_DC_DEVICE pfnCloseDCDevice; + PFN_ENUM_DC_FORMATS pfnEnumDCFormats; + PFN_ENUM_DC_DIMS pfnEnumDCDims; + PFN_GET_DC_SYSTEMBUFFER pfnGetDCSystemBuffer; + PFN_GET_DC_INFO pfnGetDCInfo; + PFN_GET_BUFFER_ADDR pfnGetBufferAddr; + PFN_CREATE_DC_SWAPCHAIN pfnCreateDCSwapChain; + PFN_DESTROY_DC_SWAPCHAIN pfnDestroyDCSwapChain; + PFN_SET_DC_DSTRECT pfnSetDCDstRect; + PFN_SET_DC_SRCRECT pfnSetDCSrcRect; + PFN_SET_DC_DSTCK pfnSetDCDstColourKey; + PFN_SET_DC_SRCCK pfnSetDCSrcColourKey; + PFN_GET_DC_BUFFERS pfnGetDCBuffers; + PFN_SWAP_TO_DC_BUFFER pfnSwapToDCBuffer; + PFN_SET_DC_STATE pfnSetDCState; + PFN_QUERY_SWAP_COMMAND_ID pfnQuerySwapCommandID; + +} PVRSRV_DC_SRV2DISP_KMJTABLE; + +/* ISR callback pfn prototype */ +typedef IMG_BOOL (*PFN_ISR_HANDLER)(IMG_VOID*); + +/* + functions exported by kernel services for use by 3rd party kernel display class device driver +*/ +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_DISPLAY_DEV)(PVRSRV_DC_SRV2DISP_KMJTABLE*, IMG_UINT32*); +typedef PVRSRV_ERROR (*PFN_DC_REMOVE_DISPLAY_DEV)(IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_DC_OEM_FUNCTION)(IMG_UINT32, IMG_VOID*, IMG_UINT32, IMG_VOID*, IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_COMMANDPROCLIST)(IMG_UINT32, PPFN_CMD_PROC,IMG_UINT32[][2], IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_DC_REMOVE_COMMANDPROCLIST)(IMG_UINT32, IMG_UINT32); +typedef IMG_VOID (*PFN_DC_CMD_COMPLETE)(IMG_HANDLE, IMG_BOOL); +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_SYS_ISR)(PFN_ISR_HANDLER, IMG_VOID*, IMG_UINT32, IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POST_POWER, + PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE, + IMG_HANDLE, PVRSRV_DEV_POWER_STATE, PVRSRV_DEV_POWER_STATE); + +typedef struct _PVRSRV_KERNEL_MEM_INFO_* PDC_MEM_INFO; + +typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_VADDR)(PDC_MEM_INFO, IMG_CPU_VIRTADDR *pVAddr); +typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_PADDR)(PDC_MEM_INFO, IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr); +typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_BYTE_SIZE)(PDC_MEM_INFO, IMG_SIZE_T *uByteSize); +typedef IMG_BOOL (*PFN_DC_MEMINFO_IS_PHYS_CONTIG)(PDC_MEM_INFO); +typedef PVRSRV_ERROR (*PFN_DC_GETBVHANDLE)(PDC_MEM_INFO, IMG_VOID **handle); +typedef IMG_INT32 (*PFN_DC_MEMINFO_GET_MULTI_PLANE_CPU_PADDRS)(PDC_MEM_INFO, IMG_SIZE_T* puByteOffsets, + IMG_CPU_PHYADDR *pPAddrs, IMG_UINT32* pui32NumAddrOffsets); + +/* + Function table for DISPLAY->SRVKM +*/ +typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG +{ + IMG_UINT32 ui32TableSize; + PFN_DC_REGISTER_DISPLAY_DEV pfnPVRSRVRegisterDCDevice; + PFN_DC_REMOVE_DISPLAY_DEV pfnPVRSRVRemoveDCDevice; + PFN_DC_OEM_FUNCTION pfnPVRSRVOEMFunction; + PFN_DC_REGISTER_COMMANDPROCLIST pfnPVRSRVRegisterCmdProcList; + PFN_DC_REMOVE_COMMANDPROCLIST pfnPVRSRVRemoveCmdProcList; + PFN_DC_CMD_COMPLETE pfnPVRSRVCmdComplete; + PFN_DC_REGISTER_SYS_ISR pfnPVRSRVRegisterSystemISRHandler; + PFN_DC_REGISTER_POWER pfnPVRSRVRegisterPowerDevice; + PFN_DC_CMD_COMPLETE pfnPVRSRVFreeCmdCompletePacket; + PFN_DC_MEMINFO_GET_CPU_VADDR pfnPVRSRVDCMemInfoGetCpuVAddr; + PFN_DC_MEMINFO_GET_CPU_PADDR pfnPVRSRVDCMemInfoGetCpuPAddr; + PFN_DC_MEMINFO_GET_BYTE_SIZE pfnPVRSRVDCMemInfoGetByteSize; + PFN_DC_MEMINFO_IS_PHYS_CONTIG pfnPVRSRVDCMemInfoIsPhysContig; + PFN_DC_GETBVHANDLE pfnPVRSRVDCMemInfoGetBvHandle; + PFN_DC_MEMINFO_GET_MULTI_PLANE_CPU_PADDRS pfnPVRSRVDCMemInfoGetCpuMultiPlanePAddr; + +} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE; + + +typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG +{ + /* Ext Device Handle */ + IMG_HANDLE hExtDevice; + + /* Ext SwapChain Handle */ + IMG_HANDLE hExtSwapChain; + + /* Ext Buffer Handle (Buffer to Flip to) */ + IMG_HANDLE hExtBuffer; + + /* private tag */ + IMG_HANDLE hPrivateTag; + + /* number of clip rects */ + IMG_UINT32 ui32ClipRectCount; + + /* clip rects */ + IMG_RECT *psClipRect; + + /* number of vsync intervals between successive flips */ + IMG_UINT32 ui32SwapInterval; + +} DISPLAYCLASS_FLIP_COMMAND; + + +typedef struct DISPLAYCLASS_FLIP_COMMAND2_TAG +{ + /* Ext Device Handle */ + IMG_HANDLE hExtDevice; + + /* Ext SwapChain Handle */ + IMG_HANDLE hExtSwapChain; + + /* Unused field, padding for compatibility with above structure */ + IMG_HANDLE hUnused; + + /* number of vsync intervals between successive flips */ + IMG_UINT32 ui32SwapInterval; + + /* private data from userspace */ + IMG_PVOID pvPrivData; + + /* length of private data in bytes */ + IMG_UINT32 ui32PrivDataLength; + + /* meminfos */ + PDC_MEM_INFO *ppsMemInfos; + + /* number of meminfos */ + IMG_UINT32 ui32NumMemInfos; + +} DISPLAYCLASS_FLIP_COMMAND2; + +/* start command IDs from 0 */ +#define DC_FLIP_COMMAND 0 + +/* States used in PFN_SET_DC_STATE */ +#define DC_STATE_NO_FLUSH_COMMANDS 0 +#define DC_STATE_FLUSH_COMMANDS 1 +#define DC_STATE_FORCE_SWAP_TO_SYSTEM 2 + +/* function to retrieve kernel services function table from kernel services */ +typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE); + +/* Prototype for platforms that access the JTable via linkage */ +IMG_IMPORT IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable); + + +#if defined (__cplusplus) +} +#endif + +#endif/* #if !defined (__KERNELDISPLAY_H__) */ + +/****************************************************************************** + End of file (kerneldisplay.h) +******************************************************************************/ diff --git a/drivers/video/omap2/omaplfb/omaplfb.h b/drivers/video/omap2/omaplfb/omaplfb.h new file mode 100644 index 0000000..b5075a7 --- /dev/null +++ b/drivers/video/omap2/omaplfb/omaplfb.h @@ -0,0 +1,334 @@ +/********************************************************************** + * + * Copyright (C) Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. <gpl-support@imgtec.com> + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __OMAPLFB_H__ +#define __OMAPLFB_H__ + +#include <linux/version.h> + +#include <asm/atomic.h> + +#include <linux/kernel.h> +#include <linux/console.h> +#include <linux/fb.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/notifier.h> +#include <linux/mutex.h> +#include <plat/sgx_omaplfb.h> + +#ifdef CONFIG_ION_OMAP +#include <linux/ion.h> +#endif +#ifdef CONFIG_HAS_EARLYSUSPEND +#include <linux/earlysuspend.h> +#endif + +#include <video/dsscomp.h> +#include <linux/bltsville.h> +#include <video/omap_hwc.h> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +#define OMAPLFB_CONSOLE_LOCK() console_lock() +#define OMAPLFB_CONSOLE_UNLOCK() console_unlock() +#else +#define OMAPLFB_CONSOLE_LOCK() acquire_console_sem() +#define OMAPLFB_CONSOLE_UNLOCK() release_console_sem() +#endif + +#define unref__ __attribute__ ((unused)) + +typedef void * OMAPLFB_HANDLE; + +typedef bool OMAPLFB_BOOL, *OMAPLFB_PBOOL; +#define OMAPLFB_FALSE false +#define OMAPLFB_TRUE true + +typedef atomic_t OMAPLFB_ATOMIC_BOOL; + +typedef atomic_t OMAPLFB_ATOMIC_INT; + +typedef struct OMAPLFB_BUFFER_TAG +{ + struct OMAPLFB_BUFFER_TAG *psNext; + struct OMAPLFB_DEVINFO_TAG *psDevInfo; + + struct work_struct sWork; + + + unsigned long ulYOffset; + + + + IMG_SYS_PHYADDR sSysAddr; + IMG_CPU_VIRTADDR sCPUVAddr; + PVRSRV_SYNC_DATA *psSyncData; + + OMAPLFB_HANDLE hCmdComplete; + unsigned long ulSwapInterval; + void *bvmap_handle; +} OMAPLFB_BUFFER; + +typedef struct OMAPLFB_SWAPCHAIN_TAG +{ + + unsigned int uiSwapChainID; + + + unsigned long ulBufferCount; + + + OMAPLFB_BUFFER *psBuffer; + + + struct workqueue_struct *psWorkQueue; + + + OMAPLFB_BOOL bNotVSynced; + + + int iBlankEvents; + + + unsigned int uiFBDevID; +} OMAPLFB_SWAPCHAIN; + +typedef struct OMAPLFB_FBINFO_TAG +{ + unsigned long ulFBSize; + unsigned long ulBufferSize; + unsigned long ulRoundedBufferSize; + unsigned long ulWidth; + unsigned long ulHeight; + unsigned long ulByteStride; + unsigned long ulPhysicalWidthmm; + unsigned long ulPhysicalHeightmm; + + IMG_SYS_PHYADDR sSysAddr; + IMG_CPU_VIRTADDR sCPUVAddr; + + + PVRSRV_PIXEL_FORMAT ePixelFormat; + + OMAPLFB_BOOL bIs2D; + IMG_SYS_PHYADDR *psPageList; +#if defined(CONFIG_DSSCOMP) + struct ion_handle *psIONHandle; + /* This is the ION handle for the blit framebuffers */ + struct ion_handle *psBltFBsIonHndl; + /* The number of blit framebuffers */ + IMG_UINT32 psBltFBsNo; + /* These are the BV handles for the framebuffers */ + void **psBltFBsBvHndl; + /* Physical addresses of the blit framebuffers */ + IMG_UINTPTR_T *psBltFBsBvPhys; + /* The current blit buffer index */ + unsigned int iBltFBsIdx; + IMG_UINT uiBltFBsByteStride; + /* Buffer used to clear the screen */ + void *pvClearBuffer; +#endif + IMG_UINT32 uiBytesPerPixel; +}OMAPLFB_FBINFO; + +typedef struct OMAPLFB_DEVINFO_TAG +{ + + unsigned int uiFBDevID; + + + unsigned int uiPVRDevID; + + + struct mutex sCreateSwapChainMutex; + + + OMAPLFB_BUFFER sSystemBuffer; + + + PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable; + + + PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable; + + + OMAPLFB_FBINFO sFBInfo; + + + OMAPLFB_SWAPCHAIN *psSwapChain; + + + unsigned int uiSwapChainID; + + + OMAPLFB_ATOMIC_BOOL sFlushCommands; + + + struct fb_info *psLINFBInfo; + + + struct notifier_block sLINNotifBlock; + + + + + + IMG_DEV_VIRTADDR sDisplayDevVAddr; + + DISPLAY_INFO sDisplayInfo; + + + DISPLAY_FORMAT sDisplayFormat; + + + DISPLAY_DIMS sDisplayDim; + + + OMAPLFB_ATOMIC_BOOL sBlanked; + + + OMAPLFB_ATOMIC_INT sBlankEvents; + +#ifdef CONFIG_HAS_EARLYSUSPEND + + OMAPLFB_ATOMIC_BOOL sEarlySuspendFlag; + + struct early_suspend sEarlySuspend; +#endif + +#if defined(SUPPORT_DRI_DRM) + OMAPLFB_ATOMIC_BOOL sLeaveVT; +#endif + +} OMAPLFB_DEVINFO; + +struct omaplfb_device { + struct device *dev; +}; + +#define OMAPLFB_PAGE_SIZE 4096 + +#ifdef DEBUG +#define DEBUG_PRINTK(x) printk x +#else +#define DEBUG_PRINTK(x) +#endif + +#define DISPLAY_DEVICE_NAME "PowerVR OMAP Linux Display Driver" +#define DRVNAME "omaplfb" +#define DEVNAME DRVNAME +#define DRIVER_PREFIX DRVNAME + +typedef enum _OMAPLFB_ERROR_ +{ + OMAPLFB_OK = 0, + OMAPLFB_ERROR_GENERIC = 1, + OMAPLFB_ERROR_OUT_OF_MEMORY = 2, + OMAPLFB_ERROR_TOO_FEW_BUFFERS = 3, + OMAPLFB_ERROR_INVALID_PARAMS = 4, + OMAPLFB_ERROR_INIT_FAILURE = 5, + OMAPLFB_ERROR_CANT_REGISTER_CALLBACK = 6, + OMAPLFB_ERROR_INVALID_DEVICE = 7, + OMAPLFB_ERROR_DEVICE_REGISTER_FAILED = 8, + OMAPLFB_ERROR_SET_UPDATE_MODE_FAILED = 9 +} OMAPLFB_ERROR; + +typedef enum _OMAPLFB_UPDATE_MODE_ +{ + OMAPLFB_UPDATE_MODE_UNDEFINED = 0, + OMAPLFB_UPDATE_MODE_MANUAL = 1, + OMAPLFB_UPDATE_MODE_AUTO = 2, + OMAPLFB_UPDATE_MODE_DISABLED = 3 +} OMAPLFB_UPDATE_MODE; + +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(param) (param) = (param) +#endif + +OMAPLFB_ERROR OMAPLFBInit(void); +OMAPLFB_ERROR OMAPLFBDeInit(void); + +OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID); +unsigned OMAPLFBMaxFBDevIDPlusOne(void); +void *OMAPLFBAllocKernelMem(unsigned long ulSize); +void OMAPLFBFreeKernelMem(void *pvMem); +OMAPLFB_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable); +OMAPLFB_ERROR OMAPLFBCreateSwapQueue (OMAPLFB_SWAPCHAIN *psSwapChain); +void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain); +void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer); +void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer); +void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer); +void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer); +OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo); +OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode); +OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo); +OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo); +OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo); +OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo); +OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); +OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); +void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo); +void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo); +void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo); +void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo); +void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); +void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic); +void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); +OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic); +void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); +void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic); +void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); +int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic); +void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic); +IMG_UINT32 GetVramStart(OMAPLFB_DEVINFO *psDevInfo); +unsigned long GetVramFBSize(OMAPLFB_DEVINFO *psDevInfo); +unsigned long GetVramFBTotalSize(struct fb_info *psLINFBInfo); +struct sgx_omaplfb_config *GetFBPlatConfig(int fbidx); + +#if defined (CONFIG_DSSCOMP) +int meminfo_idx_valid(unsigned int meminfo_ix, int num_meminfos); +#endif + +/* Blt stubs implemented when CONFIG_GCBV is enabled */ +IMG_BOOL OMAPLFBInitBlt(void); +OMAPLFB_ERROR OMAPLFBInitBltFBs(OMAPLFB_DEVINFO *psDevInfo); +void OMAPLFBDeInitBltFBs(OMAPLFB_DEVINFO *psDevInfo); +void OMAPLFBGetBltFBsBvHndl(OMAPLFB_FBINFO *psPVRFBInfo, IMG_UINTPTR_T *ppPhysAddr); +void OMAPLFBDoBlits(OMAPLFB_DEVINFO *psDevInfo, PDC_MEM_INFO *ppsMemInfos, + struct omap_hwc_blit_data *blit_data, IMG_UINT32 ui32NumMemInfos); + +#if defined(DEBUG) +void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo); +#else +#define OMAPLFBPrintInfo(psDevInfo) +#endif + +#if defined(CONFIG_GCBV) +/* + * This is the number of framebuffers rendered to by GC320 + */ +#define OMAPLFB_NUM_BLT_FBS 2 +#endif /* CONFIG_GCBV */ +#endif /* __OMAPLFB_H__ */ diff --git a/drivers/video/omap2/omaplfb/omaplfb_bv.c b/drivers/video/omap2/omaplfb/omaplfb_bv.c new file mode 100644 index 0000000..67b7bba --- /dev/null +++ b/drivers/video/omap2/omaplfb/omaplfb_bv.c @@ -0,0 +1,588 @@ +/* + * BltsVille support in omaplfb + * + * Copyright (C) 2012 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/console.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/notifier.h> + +#include <linux/ion.h> +#include <linux/omap_ion.h> +#include <mach/tiler.h> +#include <linux/gcbv-iface.h> + +#include "img_defs.h" +#include "servicesext.h" +#include "kerneldisplay.h" +#include "omaplfb.h" + +static int debugbv = 0; +extern struct ion_client *gpsIONClient; + +/* + * Are the blit framebuffers in VRAM? + */ +#define OMAPLFB_BLT_FBS_VRAM 1 +/* + * GC needs buffers aligned to 8 pixels, we need the clear buffer honor this + * requirement, a 32bpp buffer with 8 pixels for the destination is enough. + */ +#define OMAPLFB_GCSTRIDE_PIXEL_ALIGN 8 +#define OMAPLFB_CLRBUFF_SZ OMAPLFB_GCSTRIDE_PIXEL_ALIGN * 4 + +#define OMAPLFB_COMMAND_COUNT 1 + +#define OMAPLFB_VSYNC_SETTLE_COUNT 5 + +#define OMAPLFB_MAX_NUM_DEVICES FB_MAX +#if (OMAPLFB_MAX_NUM_DEVICES > FB_MAX) +#error "OMAPLFB_MAX_NUM_DEVICES must not be greater than FB_MAX" +#endif + +static IMG_BOOL gbBvInterfacePresent; +static struct bventry gsBvInterface; + +static void print_bvparams(struct bvbltparams *bltparams, + unsigned int pSrc1DescInfo, unsigned int pSrc2DescInfo) +{ + struct bvphysdesc *physdesc = NULL; + if (bltparams->flags & BVFLAG_BLEND) + { + printk(KERN_INFO "%s: param %s %x (%s), flags %ld\n", + "bv", "blend", bltparams->op.blend, + bltparams->op.blend == BVBLEND_SRC1OVER ? "src1over" : "??", + bltparams->flags); + } + + if (bltparams->flags & BVFLAG_ROP) + { + printk(KERN_INFO "%s: param %s %x (%s), flags %ld\n", + "bv", "rop", bltparams->op.rop, + bltparams->op.rop == 0xCCCC ? "srccopy" : "??", + bltparams->flags); + } + + if (bltparams->dstdesc->auxtype == BVAT_PHYSDESC) + physdesc = bltparams->dstdesc->auxptr; + + printk(KERN_INFO "%s: dst %d,%d rect{%d,%d sz %d,%d}" + " stride %ld desc 0x%p\n", "bv", + bltparams->dstgeom->width, + bltparams->dstgeom->height, + bltparams->dstrect.left, bltparams->dstrect.top, + bltparams->dstrect.width, bltparams->dstrect.height, + bltparams->dstgeom->virtstride, + physdesc ? physdesc->pagearray : NULL); + + printk(KERN_INFO "%s: src1 %d,%d rect{%d,%d sz %d,%d}" + " stride %ld, %s 0x%x (0x%x)\n", "bv", + bltparams->src1geom->width, + bltparams->src1geom->height, bltparams->src1rect.left, + bltparams->src1rect.top, bltparams->src1rect.width, + bltparams->src1rect.height, bltparams->src1geom->virtstride, + bltparams->src1.desc->auxtype == BVAT_PHYSDESC ? "phys" : "unk", + bltparams->src1.desc->auxtype == BVAT_PHYSDESC ? (unsigned int)bltparams->src1.desc : 0, + pSrc1DescInfo); + + if (!(bltparams->flags & BVFLAG_BLEND)) + return; + + printk(KERN_INFO "%s: src2 %d,%d rect{%d,%d sz %d,%d}" + " stride %ld, %s 0x%x (0x%x)\n", "bv", + bltparams->src2geom->width, + bltparams->src2geom->height, bltparams->src2rect.left, + bltparams->src2rect.top, bltparams->src2rect.width, + bltparams->src2rect.height, bltparams->src2geom->virtstride, + bltparams->src2.desc->auxtype == BVAT_PHYSDESC ? "phys" : "unk", + bltparams->src2.desc->auxtype == BVAT_PHYSDESC ? (unsigned int)bltparams->src2.desc : 0, + pSrc2DescInfo); +} + +void OMAPLFBGetBltFBsBvHndl(OMAPLFB_FBINFO *psPVRFBInfo, IMG_UINTPTR_T *ppPhysAddr) +{ + if (++psPVRFBInfo->iBltFBsIdx >= OMAPLFB_NUM_BLT_FBS) + { + psPVRFBInfo->iBltFBsIdx = 0; + } + *ppPhysAddr = psPVRFBInfo->psBltFBsBvPhys[psPVRFBInfo->iBltFBsIdx]; +} + +static OMAPLFB_ERROR InitBltFBsCommon(OMAPLFB_DEVINFO *psDevInfo) +{ + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + IMG_INT n = OMAPLFB_NUM_BLT_FBS; + + psPVRFBInfo->psBltFBsNo = n; + psPVRFBInfo->psBltFBsIonHndl = NULL; + psPVRFBInfo->psBltFBsBvHndl = kzalloc(n * sizeof(*psPVRFBInfo->psBltFBsBvHndl), GFP_KERNEL); + if (!psPVRFBInfo->psBltFBsBvHndl) + { + return OMAPLFB_ERROR_INIT_FAILURE; + } + + psPVRFBInfo->psBltFBsBvPhys = kzalloc(n * sizeof(*psPVRFBInfo->psBltFBsBvPhys), GFP_KERNEL); + if (!psPVRFBInfo->psBltFBsBvPhys) + { + return OMAPLFB_ERROR_INIT_FAILURE; + } + + psPVRFBInfo->pvClearBuffer = kzalloc(OMAPLFB_CLRBUFF_SZ, GFP_KERNEL); + if (!psPVRFBInfo->pvClearBuffer) + { + return OMAPLFB_ERROR_INIT_FAILURE; + } + + /* Freeing of resources is handled in deinit code */ + return OMAPLFB_OK; +} + +/* + * Initialize the blit framebuffers and create the Bltsville mappings, these + * buffers are separate from the swapchain to reduce complexity + */ +static OMAPLFB_ERROR InitBltFBsVram(OMAPLFB_DEVINFO *psDevInfo) +{ + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + IMG_UINT uiBltFBSize = psDevInfo->sFBInfo.ulHeight * psDevInfo->psLINFBInfo->fix.line_length; + IMG_UINT uiNumPages = uiBltFBSize >> PAGE_SHIFT; + IMG_UINT uiFb; + + if (InitBltFBsCommon(psDevInfo) != OMAPLFB_OK) + { + return OMAPLFB_ERROR_INIT_FAILURE; + } + psPVRFBInfo->uiBltFBsByteStride = psDevInfo->psLINFBInfo->fix.line_length; + + for (uiFb = 0; uiFb < psPVRFBInfo->psBltFBsNo; uiFb++) + { + unsigned long *pPaddrs; + enum bverror iBvErr; + IMG_UINT j; + struct bvbuffdesc *pBvDesc; + struct bvphysdesc *pBvPhysDesc; + IMG_UINT uiVramStart; + IMG_UINT uiFbOff; + + pPaddrs = kzalloc(sizeof(*pPaddrs) * + uiNumPages, GFP_KERNEL); + if (!pPaddrs) + { + return OMAPLFB_ERROR_OUT_OF_MEMORY; + } + + pBvPhysDesc = kzalloc(sizeof(*pBvPhysDesc), GFP_KERNEL); + if (!pBvPhysDesc) + { + kfree(pPaddrs); + return OMAPLFB_ERROR_OUT_OF_MEMORY; + } + + pBvDesc = kzalloc(sizeof(*pBvDesc), GFP_KERNEL); + if (!pBvDesc) + { + kfree(pPaddrs); + kfree(pBvPhysDesc); + return OMAPLFB_ERROR_OUT_OF_MEMORY; + } + /* + * Handle the swapchain buffers being located in TILER2D or in + * VRAM + */ + uiFbOff = psPVRFBInfo->bIs2D ? 0 : + psDevInfo->sFBInfo.ulRoundedBufferSize * + psDevInfo->psSwapChain->ulBufferCount; + uiVramStart = psDevInfo->psLINFBInfo->fix.smem_start + uiFbOff + + (uiBltFBSize * uiFb); + + for(j = 0; j < uiNumPages; j++) + { + pPaddrs[j] = uiVramStart + (j * PAGE_SIZE); + } + psPVRFBInfo->psBltFBsBvPhys[uiFb] = pPaddrs[0]; + + pBvDesc->structsize = sizeof(*pBvDesc); + pBvDesc->auxtype = BVAT_PHYSDESC; + pBvPhysDesc->structsize = sizeof(*pBvPhysDesc); + pBvPhysDesc->pagesize = PAGE_SIZE; + pBvPhysDesc->pagearray = pPaddrs; + pBvPhysDesc->pagecount = uiNumPages; + pBvDesc->length = pBvPhysDesc->pagecount * pBvPhysDesc->pagesize; + pBvDesc->auxptr = pBvPhysDesc; + + iBvErr = gsBvInterface.bv_map(pBvDesc); + if (iBvErr) + { + WARN(1, "%s: BV map Blt FB buffer failed %d\n", + __func__, iBvErr); + kfree(pBvDesc); + kfree(pBvPhysDesc); + kfree(pPaddrs); + return OMAPLFB_ERROR_GENERIC; + } + psPVRFBInfo->psBltFBsBvHndl[uiFb] = pBvDesc; + } + return OMAPLFB_OK; +} + +static PVRSRV_ERROR InitBltFBsMapTiler2D(OMAPLFB_DEVINFO *psDevInfo) +{ + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; + struct bvbuffdesc *pBvDesc; + struct bvphysdesc *pBvPhysDesc; + struct bventry *pBvEntry; + enum bverror eBvErr; + int iFB; + ion_phys_addr_t phys; + size_t size; + int res = PVRSRV_OK; + + pBvEntry = &gsBvInterface; + ion_phys(gpsIONClient, psPVRFBInfo->psBltFBsIonHndl, &phys, &size); + + for (iFB = 0; iFB < psPVRFBInfo->psBltFBsNo; iFB++) + { + unsigned long *pPageList; + + struct tiler_view_t view; + int wpages = psPVRFBInfo->uiBltFBsByteStride >> PAGE_SHIFT; + int h = psLINFBInfo->var.yres; + int x, y; + + phys += psPVRFBInfo->uiBltFBsByteStride * iFB; + pPageList = kzalloc( + wpages * h * sizeof(*pPageList), + GFP_KERNEL); + if ( !pPageList) { + printk(KERN_WARNING DRIVER_PREFIX + ": %s: Could not allocate page list\n", + __FUNCTION__); + return OMAPLFB_ERROR_INIT_FAILURE; + } + tilview_create(&view, phys, psLINFBInfo->var.xres, h); + for (y = 0; y < h; y++) { + for (x = 0; x < wpages; x++) { + pPageList[y * wpages + x] = phys + view.v_inc * y + + (x << PAGE_SHIFT); + } + } + pBvDesc = kzalloc(sizeof(*pBvDesc), GFP_KERNEL); + pBvDesc->structsize = sizeof(*pBvDesc); + pBvDesc->auxtype = BVAT_PHYSDESC; + + pBvPhysDesc = kzalloc(sizeof(*pBvPhysDesc), GFP_KERNEL); + pBvPhysDesc->pagesize = PAGE_SIZE; + pBvPhysDesc->pagearray = pPageList; + pBvPhysDesc->pagecount = wpages * h; + + pBvDesc->auxptr = pBvPhysDesc; + + eBvErr = pBvEntry->bv_map(pBvDesc); + + pBvPhysDesc->pagearray = NULL; + + if (eBvErr) + { + WARN(1, "%s: BV map blt buffer failed %d\n",__func__, eBvErr); + psPVRFBInfo->psBltFBsBvHndl[iFB]= NULL; + kfree(pBvDesc); + kfree(pBvPhysDesc); + res = PVRSRV_ERROR_OUT_OF_MEMORY; + } + else + { + psPVRFBInfo->psBltFBsBvHndl[iFB] = pBvDesc; + psPVRFBInfo->psBltFBsBvPhys[iFB] = pPageList[0]; + } + } + + return res; +} + +/* + * Allocate buffers from the blit 'framebuffers'. These buffers are not shared + * with the SGX flip chain to reduce complexity + */ +static OMAPLFB_ERROR InitBltFBsTiler2D(OMAPLFB_DEVINFO *psDevInfo) +{ + /* + * Pick up the calculated bytes per pixel from the deduced + * OMAPLFB_FBINFO, get the rest of the display parameters from the + * struct fb_info + */ + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; + int res, w, h; + + struct omap_ion_tiler_alloc_data sAllocData = { + .fmt = psPVRFBInfo->uiBytesPerPixel == 2 ? TILER_PIXEL_FMT_16BIT : TILER_PIXEL_FMT_32BIT, + .flags = 0, + }; + + if (InitBltFBsCommon(psDevInfo) != OMAPLFB_OK) + { + return OMAPLFB_ERROR_INIT_FAILURE; + } + psPVRFBInfo->uiBltFBsByteStride = PAGE_ALIGN(psLINFBInfo->var.xres * psPVRFBInfo->uiBytesPerPixel); + + /* TILER will align width to 128-bytes */ + /* however, SGX must have full page width */ + w = ALIGN(psLINFBInfo->var.xres, PAGE_SIZE / psPVRFBInfo->uiBytesPerPixel); + h = psLINFBInfo->var.yres; + sAllocData.h = h; + sAllocData.w = psPVRFBInfo->psBltFBsNo * w; + + printk(KERN_INFO DRIVER_PREFIX + ":BltFBs alloc %d x (%d x %d) [stride %d]\n", + psPVRFBInfo->psBltFBsNo, w, h, psPVRFBInfo->uiBltFBsByteStride); + res = omap_ion_nonsecure_tiler_alloc(gpsIONClient, &sAllocData); + if (res < 0) + { + printk(KERN_ERR DRIVER_PREFIX + "Could not allocate BltFBs\n"); + return OMAPLFB_ERROR_INIT_FAILURE; + } + + psPVRFBInfo->psBltFBsIonHndl = sAllocData.handle; + + res = InitBltFBsMapTiler2D(psDevInfo); + if (res != OMAPLFB_OK) + { + return OMAPLFB_ERROR_INIT_FAILURE; + } + return OMAPLFB_OK; +} + +static struct bvbuffdesc *GetBvDescriptor(OMAPLFB_DEVINFO *psDevInfo, PDC_MEM_INFO *ppsMemInfos, IMG_UINT32 ui32Idx, IMG_UINT32 ui32NumMemInfos) +{ + struct bvbuffdesc *pBvDesc; + if (!meminfo_idx_valid(ui32Idx, ui32NumMemInfos)) { + WARN(1, "%s: index out of range\n", __func__); + return NULL; + } + + psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetBvHandle(ppsMemInfos[ui32Idx], (IMG_VOID**)&pBvDesc); + WARN(!pBvDesc, "%s: null handle\n", __func__); + return pBvDesc; +} + +static void OMAPLFBSetNV12Params(struct bvsurfgeom *geom, struct bvbuffdesc *desc) +{ + if (geom->format != OCDFMT_NV12) + return; + + /* Fixup stride for NV12 format */ + geom->virtstride = (desc->length * 2) / (geom->height * 3); +} + +void OMAPLFBDoBlits(OMAPLFB_DEVINFO *psDevInfo, PDC_MEM_INFO *ppsMemInfos, struct omap_hwc_blit_data *blit_data, IMG_UINT32 ui32NumMemInfos) +{ + struct rgz_blt_entry *entry_list; + struct bventry *bv_entry = &gsBvInterface; + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + int rgz_items = blit_data->rgz_items; + int j; + void* lastBatch = NULL; + unsigned int batchFlags; + + /* DSS pipes are setup up to this point, we can begin blitting here */ + entry_list = (struct rgz_blt_entry *) (blit_data->rgz_blts); + for (j = 0; j < rgz_items; j++) + { + struct rgz_blt_entry *entry = &entry_list[j]; + enum bverror bv_error = 0; + unsigned int meminfo_ix; + unsigned int iSrc1DescInfo = 0, iSrc2DescInfo = 0; + + /* Destination data */ + entry->dstgeom.virtstride = psDevInfo->sFBInfo.uiBltFBsByteStride; + entry->bp.dstdesc = psPVRFBInfo->psBltFBsBvHndl[psPVRFBInfo->iBltFBsIdx]; + entry->bp.dstgeom = &entry->dstgeom; + OMAPLFBSetNV12Params(entry->bp.dstgeom, entry->bp.dstdesc); + + /* Src1 buffer data */ + meminfo_ix = (unsigned int)entry->src1desc.auxptr; + if (meminfo_ix == -1) + { + /* Making fill with transparent pixels, fixup stride and clear buffer */ + entry->bp.src1geom = &entry->src1geom; + entry->bp.src1geom->virtstride = OMAPLFB_CLRBUFF_SZ; + entry->bp.src1.desc = &entry->src1desc; + entry->bp.src1.desc->virtaddr = psPVRFBInfo->pvClearBuffer; + } + else if (meminfo_ix & HWC_BLT_DESC_FLAG) + { + /* This code might be redundant? Do we want to ever blit out of the framebuffer? */ + if (meminfo_ix & HWC_BLT_DESC_FB) + { + entry->bp.src1.desc = entry->bp.dstdesc; + entry->bp.src1geom = entry->bp.dstgeom; + } + else + { + WARN(1, "%s: Unable to determine scr1 buffer\n", + __func__); + continue; + } + } + else + { + struct bvbuffdesc *pBvDesc; + pBvDesc = GetBvDescriptor(psDevInfo, ppsMemInfos, + meminfo_ix, ui32NumMemInfos); + if (!pBvDesc) + continue; + + entry->bp.src1.desc = pBvDesc; + entry->bp.src1geom = &entry->src1geom; + OMAPLFBSetNV12Params(entry->bp.src1geom, pBvDesc); + } + + /* Src2 buffer data + * Check if this blit involves src2 as the FB or another + * buffer, if the last case is true then map the src2 buffer + */ + if (entry->bp.flags & BVFLAG_BLEND) + { + meminfo_ix = (unsigned int)entry->src2desc.auxptr; + if (meminfo_ix & HWC_BLT_DESC_FLAG) + { + if (meminfo_ix & HWC_BLT_DESC_FB) + { + /* Blending with destination (FB) */ + entry->bp.src2.desc = entry->bp.dstdesc; + entry->bp.src2geom = entry->bp.dstgeom; + } + else + { + WARN(1, "%s: Unable to determine scr2 buffer\n", + __func__); + continue; + } + } + else + { + struct bvbuffdesc *pBvDesc; + pBvDesc = GetBvDescriptor(psDevInfo, + ppsMemInfos, meminfo_ix, + ui32NumMemInfos); + if (!pBvDesc) + continue; + + entry->bp.src2.desc = pBvDesc; + entry->bp.src2geom = &entry->src2geom; + OMAPLFBSetNV12Params(entry->bp.src2geom, pBvDesc); + } + } + else + { + entry->bp.src2.desc = NULL; + } + + if (debugbv) + { + iSrc1DescInfo = (unsigned int)entry->src1desc.auxptr; + iSrc2DescInfo = (unsigned int)entry->src2desc.auxptr; + print_bvparams(&entry->bp, iSrc1DescInfo, iSrc2DescInfo); + } + + batchFlags = entry->bp.flags & BVFLAG_BATCH_MASK; + switch (batchFlags) { + case BVFLAG_BATCH_CONTINUE: + case BVFLAG_BATCH_END: + entry->bp.batch = lastBatch; + break; + case BVFLAG_BATCH_BEGIN: + entry->bp.batch = NULL; + } + + bv_error = bv_entry->bv_blt(&entry->bp); + if (bv_error) + printk(KERN_ERR "%s: blit failed %d\n", + __func__, bv_error); + + if (batchFlags == BVFLAG_BATCH_BEGIN) { + /* cache the batch handle */ + lastBatch = entry->bp.batch; + } + } +} + +OMAPLFB_ERROR OMAPLFBInitBltFBs(OMAPLFB_DEVINFO *psDevInfo) +{ + return (OMAPLFB_BLT_FBS_VRAM) ? InitBltFBsVram(psDevInfo) : InitBltFBsTiler2D(psDevInfo); +} + +void OMAPLFBDeInitBltFBs(OMAPLFB_DEVINFO *psDevInfo) +{ + struct bventry *bv_entry = &gsBvInterface; + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + struct bvbuffdesc *pBufDesc; + + if (!gbBvInterfacePresent) + { + return; + } + + if (psPVRFBInfo->pvClearBuffer) { + kfree(psPVRFBInfo->pvClearBuffer); + psPVRFBInfo->pvClearBuffer = NULL; + } + + if (psPVRFBInfo->psBltFBsBvHndl) + { + IMG_INT i; + for (i = 0; i < psPVRFBInfo->psBltFBsNo; i++) + { + pBufDesc = psPVRFBInfo->psBltFBsBvHndl[i]; + if (pBufDesc) + { + struct bvphysdesc *pPhyDesc; + bv_entry->bv_unmap(pBufDesc); + pPhyDesc = (struct bvphysdesc*) pBufDesc->auxptr; + kfree(pPhyDesc->pagearray); + kfree(pPhyDesc); + kfree(pBufDesc); + } + } + kfree(psPVRFBInfo->psBltFBsBvHndl); + psPVRFBInfo->psBltFBsBvHndl = NULL; + } + + if (psPVRFBInfo->psBltFBsIonHndl) + { + ion_free(gpsIONClient, psPVRFBInfo->psBltFBsIonHndl); + psPVRFBInfo->psBltFBsIonHndl = NULL; + } +} + +IMG_BOOL OMAPLFBInitBlt(void) +{ +#if defined(CONFIG_GCBV) + /* Get the GC2D Bltsville implementation */ + gcbv_init(&gsBvInterface); + gbBvInterfacePresent = gsBvInterface.bv_map ? IMG_TRUE : IMG_FALSE; +#else + gbBvInterfacePresent = IMG_FALSE; +#endif + return gbBvInterfacePresent; +} diff --git a/drivers/video/omap2/omaplfb/omaplfb_displayclass.c b/drivers/video/omap2/omaplfb/omaplfb_displayclass.c new file mode 100644 index 0000000..cf463d3 --- /dev/null +++ b/drivers/video/omap2/omaplfb/omaplfb_displayclass.c @@ -0,0 +1,1833 @@ +/********************************************************************** + * + * Copyright (C) Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. <gpl-support@imgtec.com> + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/console.h> +#include <linux/fb.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/notifier.h> +#include <plat/sgx_omaplfb.h> + +#include "img_defs.h" +#include "servicesext.h" +#include "kerneldisplay.h" +#include "omaplfb.h" + +/* + * Just use CONFIG_DSSCOMP to distinguish code which previously had + * additional mixes of CONFIG_TI_TILER and CONFIG_ION_OMAP. DSSCOMP makes + * it a given that ION and the TILER will be used. + * For kernel 3.4 we use CONFIG_DRM_OMAP_DMM_TILER instead of CONFIG_TI_TILER + */ +#if defined(CONFIG_DSSCOMP) +#if !defined(CONFIG_ION_OMAP) +#error Expected CONFIG_ION_OMAP to be defined +#endif +#if defined(CONFIG_DRM_OMAP_DMM_TILER) +#include <../drivers/staging/omapdrm/omap_dmm_tiler.h> +#include <../drivers/video/omap2/dsscomp/tiler-utils.h> +#elif defined(CONFIG_TI_TILER) +#include <mach/tiler.h> +#else +#error Expected CONFIG_DRM_OMAP_DMM_TILER or CONFIG_TI_TILER to be defined +#endif + +#ifndef DSS_MAX_NUMBER_YUV_PLANES +#define DSS_MAX_NUMBER_YUV_PLANES 2 +#endif + +#include <linux/ion.h> +#include <linux/omap_ion.h> +#include <video/dsscomp.h> +#include <plat/dsscomp.h> +#include <video/omap_hwc.h> + +extern struct ion_device *omap_ion_device; +struct ion_client *gpsIONClient; + +#endif + +#define OMAPLFB_COMMAND_COUNT 1 + +#define OMAPLFB_VSYNC_SETTLE_COUNT 5 + +#define OMAPLFB_MAX_NUM_DEVICES FB_MAX +#if (OMAPLFB_MAX_NUM_DEVICES > FB_MAX) +#error "OMAPLFB_MAX_NUM_DEVICES must not be greater than FB_MAX" +#endif + +static OMAPLFB_DEVINFO *gapsDevInfo[OMAPLFB_MAX_NUM_DEVICES]; + +static PFN_DC_GET_PVRJTABLE gpfnGetPVRJTable = NULL; + +static IMG_BOOL gbBvInterfacePresent; +static IMG_BOOL gbBvReady = IMG_FALSE; +static IMG_BOOL bBltReady = IMG_FALSE; + +static inline unsigned long RoundUpToMultiple(unsigned long x, unsigned long y) +{ + unsigned long div = x / y; + unsigned long rem = x % y; + + return (div + ((rem == 0) ? 0 : 1)) * y; +} + +static unsigned long GCD(unsigned long x, unsigned long y) +{ + while (y != 0) + { + unsigned long r = x % y; + x = y; + y = r; + } + + return x; +} + +static unsigned long LCM(unsigned long x, unsigned long y) +{ + unsigned long gcd = GCD(x, y); + + return (gcd == 0) ? 0 : ((x / gcd) * y); +} + +unsigned OMAPLFBMaxFBDevIDPlusOne(void) +{ + return OMAPLFB_MAX_NUM_DEVICES; +} + +OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID) +{ + WARN_ON(uiFBDevID >= OMAPLFBMaxFBDevIDPlusOne()); + + if (uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES) + { + return NULL; + } + + return gapsDevInfo[uiFBDevID]; +} + +static inline void OMAPLFBSetDevInfoPtr(unsigned uiFBDevID, OMAPLFB_DEVINFO *psDevInfo) +{ + WARN_ON(uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES); + + if (uiFBDevID < OMAPLFB_MAX_NUM_DEVICES) + { + gapsDevInfo[uiFBDevID] = psDevInfo; + } +} + +static inline OMAPLFB_BOOL SwapChainHasChanged(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_SWAPCHAIN *psSwapChain) +{ + return (psDevInfo->psSwapChain != psSwapChain) || + (psDevInfo->uiSwapChainID != psSwapChain->uiSwapChainID); +} + +static inline OMAPLFB_BOOL DontWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) +{ + OMAPLFB_BOOL bDontWait; + + bDontWait = OMAPLFBAtomicBoolRead(&psDevInfo->sBlanked) || + OMAPLFBAtomicBoolRead(&psDevInfo->sFlushCommands); + +#if defined(CONFIG_HAS_EARLYSUSPEND) + bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sEarlySuspendFlag); +#endif +#if defined(SUPPORT_DRI_DRM) + bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT); +#endif + return bDontWait; +} + +static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State) +{ + OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; + + switch (ui32State) + { + case DC_STATE_FLUSH_COMMANDS: + OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_TRUE); + break; + case DC_STATE_FORCE_SWAP_TO_SYSTEM: + OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); + break; + case DC_STATE_NO_FLUSH_COMMANDS: + OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); + break; + default: + break; + } +} + +static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 uiPVRDevID, + IMG_HANDLE *phDevice, + PVRSRV_SYNC_DATA* psSystemBufferSyncData) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_ERROR eError; + unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); + unsigned i; + + for (i = 0; i < uiMaxFBDevIDPlusOne; i++) + { + psDevInfo = OMAPLFBGetDevInfoPtr(i); + if (psDevInfo != NULL && psDevInfo->uiPVRDevID == uiPVRDevID) + { + break; + } + } + if (i == uiMaxFBDevIDPlusOne) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX + ": %s: PVR Device %u not found\n", __FUNCTION__, uiPVRDevID)); + return PVRSRV_ERROR_INVALID_DEVICE; + } + + + psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData; + + eError = OMAPLFBUnblankDisplay(psDevInfo); + if (eError != OMAPLFB_OK) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX + ": %s: Device %u: OMAPLFBUnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError)); + return PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED; + } + + + *phDevice = (IMG_HANDLE)psDevInfo; + + return PVRSRV_OK; +} + +static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice) +{ +#if defined(SUPPORT_DRI_DRM) + OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; + + OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); + (void) OMAPLFBUnblankDisplay(psDevInfo); +#else + UNREFERENCED_PARAMETER(hDevice); +#endif + return PVRSRV_OK; +} + +static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice, + IMG_UINT32 *pui32NumFormats, + DISPLAY_FORMAT *psFormat) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !pui32NumFormats) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *pui32NumFormats = 1; + + if(psFormat) + { + psFormat[0] = psDevInfo->sDisplayFormat; + } + + return PVRSRV_OK; +} + +static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice, + DISPLAY_FORMAT *psFormat, + IMG_UINT32 *pui32NumDims, + DISPLAY_DIMS *psDim) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !psFormat || !pui32NumDims) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *pui32NumDims = 1; + + + if(psDim) + { + psDim[0] = psDevInfo->sDisplayDim; + } + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !phBuffer) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer; + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !psDCInfo) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *psDCInfo = psDevInfo->sDisplayInfo; + + return PVRSRV_OK; +} + +static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice, + IMG_HANDLE hBuffer, + IMG_SYS_PHYADDR **ppsSysAddr, + IMG_UINT32 *pui32ByteSize, + IMG_VOID **ppvCpuVAddr, + IMG_HANDLE *phOSMapInfo, + IMG_BOOL *pbIsContiguous, + IMG_UINT32 *pui32TilingStride) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_BUFFER *psSystemBuffer; + + UNREFERENCED_PARAMETER(pui32TilingStride); + + if(!hDevice) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + if(!hBuffer) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + if (!ppsSysAddr) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + if (!pui32ByteSize) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer; + + *ppsSysAddr = &psSystemBuffer->sSysAddr; + + *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize; + + if (ppvCpuVAddr) + { + *ppvCpuVAddr = psDevInfo->sFBInfo.bIs2D ? NULL : psSystemBuffer->sCPUVAddr; + } + + if (phOSMapInfo) + { + *phOSMapInfo = (IMG_HANDLE)0; + } + + if (pbIsContiguous) + { + *pbIsContiguous = !psDevInfo->sFBInfo.bIs2D; + } + +#if defined(CONFIG_DSSCOMP) + if (psDevInfo->sFBInfo.bIs2D) { + int i = (psSystemBuffer->sSysAddr.uiAddr - psDevInfo->sFBInfo.psPageList->uiAddr) >> PAGE_SHIFT; + *ppsSysAddr = psDevInfo->sFBInfo.psPageList + psDevInfo->sFBInfo.ulHeight * i; + } +#endif + + return PVRSRV_OK; +} + +static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, + IMG_UINT32 ui32Flags, + DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, + DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, + IMG_UINT32 ui32BufferCount, + PVRSRV_SYNC_DATA **ppsSyncData, + IMG_UINT32 ui32OEMFlags, + IMG_HANDLE *phSwapChain, + IMG_UINT32 *pui32SwapChainID) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + OMAPLFB_BUFFER *psBuffer; + IMG_UINT32 i; + PVRSRV_ERROR eError; + + UNREFERENCED_PARAMETER(ui32OEMFlags); + + + if(!hDevice + || !psDstSurfAttrib + || !psSrcSurfAttrib + || !ppsSyncData + || !phSwapChain) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + + if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) + { + return PVRSRV_ERROR_NOT_SUPPORTED; + } + + OMAPLFBCreateSwapChainLock(psDevInfo); + + + if(psDevInfo->psSwapChain != NULL) + { + eError = PVRSRV_ERROR_FLIP_CHAIN_EXISTS; + goto ExitUnLock; + } + + + if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) + { + eError = PVRSRV_ERROR_TOOMANYBUFFERS; + goto ExitUnLock; + } + + if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize) + { + eError = PVRSRV_ERROR_TOOMANYBUFFERS; + goto ExitUnLock; + } + + if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat + || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride + || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width + || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) + { + + eError = PVRSRV_ERROR_INVALID_PARAMS; + goto ExitUnLock; + } + + if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat + || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride + || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width + || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) + { + + eError = PVRSRV_ERROR_INVALID_PARAMS; + goto ExitUnLock; + } + + UNREFERENCED_PARAMETER(ui32Flags); + +#if defined(PVR_OMAPFB3_UPDATE_MODE) + if (!OMAPLFBSetUpdateMode(psDevInfo, PVR_OMAPFB3_UPDATE_MODE)) + { + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set frame buffer update mode %d\n", __FUNCTION__, psDevInfo->uiFBDevID, PVR_OMAPFB3_UPDATE_MODE); + } +#endif + + psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN)); + if(!psSwapChain) + { + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ExitUnLock; + } + + psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount); + if(!psBuffer) + { + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorFreeSwapChain; + } + + psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; + psSwapChain->psBuffer = psBuffer; + psSwapChain->bNotVSynced = OMAPLFB_TRUE; + psSwapChain->uiFBDevID = psDevInfo->uiFBDevID; + + + for(i=0; i<ui32BufferCount-1; i++) + { + psBuffer[i].psNext = &psBuffer[i+1]; + } + + psBuffer[i].psNext = &psBuffer[0]; + + for(i=0; i<ui32BufferCount; i++) + { + IMG_UINT32 ui32SwapBuffer = i; + IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize; + if (psDevInfo->sFBInfo.bIs2D) + { + ui32BufferOffset = 0; + } + + psBuffer[i].psSyncData = ppsSyncData[i]; + psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; + psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; + psBuffer[i].ulYOffset = ui32BufferOffset / psDevInfo->sFBInfo.ulByteStride; + if (psDevInfo->sFBInfo.bIs2D) + { + psBuffer[i].sSysAddr.uiAddr += ui32SwapBuffer * + ALIGN((IMG_UINT32)psDevInfo->sFBInfo.ulWidth * psDevInfo->sFBInfo.uiBytesPerPixel, PAGE_SIZE); + } + psBuffer[i].psDevInfo = psDevInfo; + OMAPLFBInitBufferForSwap(&psBuffer[i]); + psBuffer[i].bvmap_handle = NULL; + } + + + if (OMAPLFBCreateSwapQueue(psSwapChain) != OMAPLFB_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Failed to create workqueue\n", __FUNCTION__, psDevInfo->uiFBDevID); + eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR; + goto ErrorFreeBuffers; + } + + if (OMAPLFBEnableLFBEventNotification(psDevInfo)!= OMAPLFB_OK) + { + eError = PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT; + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't enable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); + goto ErrorDestroySwapQueue; + } + + psDevInfo->uiSwapChainID++; + if (psDevInfo->uiSwapChainID == 0) + { + psDevInfo->uiSwapChainID++; + } + + psSwapChain->uiSwapChainID = psDevInfo->uiSwapChainID; + + psDevInfo->psSwapChain = psSwapChain; + + *pui32SwapChainID = psDevInfo->uiSwapChainID; + + *phSwapChain = (IMG_HANDLE)psSwapChain; + + eError = PVRSRV_OK; + goto ExitUnLock; + +ErrorDestroySwapQueue: + OMAPLFBDestroySwapQueue(psSwapChain); +ErrorFreeBuffers: + OMAPLFBFreeKernelMem(psBuffer); +ErrorFreeSwapChain: + OMAPLFBFreeKernelMem(psSwapChain); +ExitUnLock: + OMAPLFBCreateSwapChainUnLock(psDevInfo); + return eError; +} + +static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + OMAPLFB_ERROR eError; + + if(!hDevice || !hSwapChain) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; + + OMAPLFBCreateSwapChainLock(psDevInfo); + + if (SwapChainHasChanged(psDevInfo, psSwapChain)) + { + printk(KERN_WARNING DRIVER_PREFIX + ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); + + eError = PVRSRV_ERROR_INVALID_PARAMS; + goto ExitUnLock; + } + + + OMAPLFBDestroySwapQueue(psSwapChain); + + eError = OMAPLFBDisableLFBEventNotification(psDevInfo); + if (eError != OMAPLFB_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't disable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); + } + + OMAPLFBDeInitBltFBs(psDevInfo); + gbBvReady = IMG_FALSE; + bBltReady = IMG_FALSE; + + OMAPLFBFreeKernelMem(psSwapChain->psBuffer); + OMAPLFBFreeKernelMem(psSwapChain); + + psDevInfo->psSwapChain = NULL; + + OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); + (void) OMAPLFBCheckModeAndSync(psDevInfo); + + eError = PVRSRV_OK; + +ExitUnLock: + OMAPLFBCreateSwapChainUnLock(psDevInfo); + + return eError; +} + +static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(psRect); + + + + return PVRSRV_ERROR_NOT_SUPPORTED; +} + +static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(psRect); + + + + return PVRSRV_ERROR_NOT_SUPPORTED; +} + +static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(ui32CKColour); + + + + return PVRSRV_ERROR_NOT_SUPPORTED; +} + +static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(ui32CKColour); + + + + return PVRSRV_ERROR_NOT_SUPPORTED; +} + +static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 *pui32BufferCount, + IMG_HANDLE *phBuffer) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + PVRSRV_ERROR eError; + unsigned i; + + + if(!hDevice + || !hSwapChain + || !pui32BufferCount + || !phBuffer) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; + + OMAPLFBCreateSwapChainLock(psDevInfo); + + if (SwapChainHasChanged(psDevInfo, psSwapChain)) + { + printk(KERN_WARNING DRIVER_PREFIX + ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); + + eError = PVRSRV_ERROR_INVALID_PARAMS; + goto Exit; + } + + + *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount; + + + for(i=0; i<psSwapChain->ulBufferCount; i++) + { + phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i]; + } + + eError = PVRSRV_OK; + +Exit: + OMAPLFBCreateSwapChainUnLock(psDevInfo); + + return eError; +} + +static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice, + IMG_HANDLE hBuffer, + IMG_UINT32 ui32SwapInterval, + IMG_HANDLE hPrivateTag, + IMG_UINT32 ui32ClipRectCount, + IMG_RECT *psClipRect) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hBuffer); + UNREFERENCED_PARAMETER(ui32SwapInterval); + UNREFERENCED_PARAMETER(hPrivateTag); + UNREFERENCED_PARAMETER(ui32ClipRectCount); + UNREFERENCED_PARAMETER(psClipRect); + + + + return PVRSRV_OK; +} + +#if !defined(CONFIG_GCBV) +IMG_BOOL OMAPLFBInitBlt(void) +{ + return IMG_FALSE; +} + +OMAPLFB_ERROR OMAPLFBInitBltFBs(OMAPLFB_DEVINFO *psDevInfo) +{ + return OMAPLFB_ERROR_INIT_FAILURE; +} + +void OMAPLFBDeInitBltFBs(OMAPLFB_DEVINFO *psDevInfo) +{ +} + +void OMAPLFBGetBltFBsBvHndl(OMAPLFB_FBINFO *psPVRFBInfo, IMG_UINTPTR_T *ppPhysAddr) +{ + *ppPhysAddr = 0; +} + +void OMAPLFBDoBlits(OMAPLFB_DEVINFO *psDevInfo, PDC_MEM_INFO *ppsMemInfos, struct omap_hwc_blit_data *blit_data, IMG_UINT32 ui32NumMemInfos) +{ +} +#endif /* CONFIG_GCBV */ +static OMAPLFB_BOOL WaitForVSyncSettle(OMAPLFB_DEVINFO *psDevInfo) +{ + unsigned i; + for(i = 0; i < OMAPLFB_VSYNC_SETTLE_COUNT; i++) + { + if (DontWaitForVSync(psDevInfo) || !OMAPLFBWaitForVSync(psDevInfo)) + { + return OMAPLFB_FALSE; + } + } + + return OMAPLFB_TRUE; +} + +void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer) +{ + OMAPLFB_DEVINFO *psDevInfo = psBuffer->psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; + OMAPLFB_BOOL bPreviouslyNotVSynced; + +#if defined(SUPPORT_DRI_DRM) + if (!OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT)) +#endif + { + OMAPLFBFlip(psDevInfo, psBuffer); + } + + bPreviouslyNotVSynced = psSwapChain->bNotVSynced; + psSwapChain->bNotVSynced = OMAPLFB_TRUE; + + + if (!DontWaitForVSync(psDevInfo)) + { + OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); + int iBlankEvents = OMAPLFBAtomicIntRead(&psDevInfo->sBlankEvents); + + switch(eMode) + { + case OMAPLFB_UPDATE_MODE_AUTO: + psSwapChain->bNotVSynced = OMAPLFB_FALSE; + + if (bPreviouslyNotVSynced || psSwapChain->iBlankEvents != iBlankEvents) + { + psSwapChain->iBlankEvents = iBlankEvents; + psSwapChain->bNotVSynced = !WaitForVSyncSettle(psDevInfo); + } else if (psBuffer->ulSwapInterval != 0) + { + psSwapChain->bNotVSynced = !OMAPLFBWaitForVSync(psDevInfo); + } + break; +#if defined(PVR_OMAPFB3_MANUAL_UPDATE_SYNC_IN_SWAP) + case OMAPLFB_UPDATE_MODE_MANUAL: + if (psBuffer->ulSwapInterval != 0) + { + (void) OMAPLFBManualSync(psDevInfo); + } + break; +#endif + default: + break; + } + } + + psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_TRUE); +} + +#if defined(CONFIG_DSSCOMP) + + +static void dsscomp_proxy_cmdcomplete(void * cookie, int i) +{ + gapsDevInfo[0]->sPVRJTable.pfnPVRSRVCmdComplete(cookie, i); +} +#endif + +static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie, + OMAPLFB_DEVINFO *psDevInfo, + OMAPLFB_SWAPCHAIN *psSwapChain, + OMAPLFB_BUFFER *psBuffer, + unsigned long ulSwapInterval) +{ + OMAPLFBCreateSwapChainLock(psDevInfo); + + if (SwapChainHasChanged(psDevInfo, psSwapChain)) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX + ": %s: Device %u (PVR Device ID %u): The swap chain has been destroyed\n", + __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); + } + else + { + psBuffer->hCmdComplete = (OMAPLFB_HANDLE)hCmdCookie; + psBuffer->ulSwapInterval = ulSwapInterval; +#if defined(CONFIG_DSSCOMP) + if (is_tiler_addr(psBuffer->sSysAddr.uiAddr)) { + IMG_UINT32 w = psBuffer->psDevInfo->sDisplayDim.ui32Width; + IMG_UINT32 h = psBuffer->psDevInfo->sDisplayDim.ui32Height; + struct dsscomp_setup_dispc_data comp = { + .num_mgrs = 1, + .mgrs[0].alpha_blending = 1, + .num_ovls = 1, + .ovls[0].cfg = { + .width = w, + .win.w = w, + .crop.w = w, + .height = h, + .win.h = h, + .crop.h = h, + .stride = psBuffer->psDevInfo->sDisplayDim.ui32ByteStride, + .color_mode = OMAP_DSS_COLOR_ARGB32, + .enabled = 1, + .global_alpha = 255, + }, + .mode = DSSCOMP_SETUP_DISPLAY, + }; + struct tiler_pa_info *pas[1] = { NULL }; + comp.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr; + dsscomp_gralloc_queue(&comp, pas, true, + dsscomp_proxy_cmdcomplete, + (void *) psBuffer->hCmdComplete); + } else +#endif + { + OMAPLFBQueueBufferForSwap(psSwapChain, psBuffer); + } + } + + OMAPLFBCreateSwapChainUnLock(psDevInfo); + + return IMG_TRUE; +} + +#if defined(CONFIG_DSSCOMP) && (defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER)) +int meminfo_idx_valid(unsigned int meminfo_ix, int num_meminfos) +{ + if (meminfo_ix < 0 || meminfo_ix >= num_meminfos) { + WARN(1, "%s: Invalid meminfo index %d, max %d\n", + __func__, meminfo_ix, num_meminfos); + return 0; + } + return 1; +} + +static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie, + OMAPLFB_DEVINFO *psDevInfo, + PDC_MEM_INFO *ppsMemInfos, + IMG_UINT32 ui32NumMemInfos, + struct omap_hwc_data *psHwcData, + IMG_UINT32 uiHwcDataSz) +{ + struct tiler_pa_info *apsTilerPAs[5]; + IMG_UINT32 i, k; + struct { + IMG_UINTPTR_T uiAddr; + IMG_UINTPTR_T uiUVAddr; + struct tiler_pa_info *psTilerInfo; + } asMemInfo[5]; + + /* Framebuffer info just used to get FB geometry, the address to + * use for blitting (dst buffer) is the first meminfo + */ + int rgz_items; + int calcsz; + struct dsscomp_setup_dispc_data *psDssData = &(psHwcData->dsscomp_data); + int iMemIdx = 0; + int iUseBltFB; +#ifdef CONFIG_DRM_OMAP_DMM_TILER + enum tiler_fmt fmt; +#endif + + if (uiHwcDataSz <= offsetof(struct omap_hwc_data, blit_data)) + rgz_items = 0; + else + rgz_items = psHwcData->blit_data.rgz_items; + + + psDssData = &(psHwcData->dsscomp_data); + calcsz = sizeof(*psHwcData) + + (sizeof(struct rgz_blt_entry) * rgz_items); + iUseBltFB = psHwcData->blit_data.rgz_flags & HWC_BLT_FLAG_USE_FB; + + if (!iUseBltFB && rgz_items > 0) { + WARN(1, "Trying to blit without a pipe configured for the blit FB"); + return IMG_FALSE; + } + + if (rgz_items > 0 && !gbBvInterfacePresent) + { + /* We cannot blit if BV GC2D is not present!, likely a bug */ + WARN(1, "Trying to blit when BV GC2D is not present"); + rgz_items = 0; /* Prevent blits */ + } + + if (iUseBltFB && !bBltReady) + { + /* Defer allocation and mapping of blit buffers */ + if (OMAPLFBInitBltFBs(psDevInfo) != OMAPLFB_OK) + { + WARN(1, "Could not initialize blit FBs"); + return IMG_FALSE; + } + + bBltReady = IMG_TRUE; + } + + memset(asMemInfo, 0, sizeof(asMemInfo)); + + /* Check the size of private data along with the blit operations */ + if (uiHwcDataSz != calcsz) + { + WARN(1, "invalid size of private data (%d vs %d)", + uiHwcDataSz, calcsz); + } + + if(psDssData->num_ovls == 0 || ui32NumMemInfos == 0) + { + WARN(1, "must have at least one layer"); + return IMG_FALSE; + } + + if (iUseBltFB) + { + iMemIdx++; + /* Increment the Blt framebuffer and get new address */ + OMAPLFBGetBltFBsBvHndl(&psDevInfo->sFBInfo, &asMemInfo[0].uiAddr); + } + + for (i = 0, k = iMemIdx; i < ui32NumMemInfos && k < ARRAY_SIZE(apsTilerPAs) && + k < psDssData->num_ovls; i++, k++) { + + struct tiler_pa_info *psTilerInfo; + IMG_CPU_VIRTADDR virtAddr; + IMG_CPU_PHYADDR aPhyAddr[DSS_MAX_NUMBER_YUV_PLANES]; + IMG_UINT32 ui32NumPages; + IMG_SIZE_T uByteSize; + IMG_UINT32 ui32NumAddrOffsets = DSS_MAX_NUMBER_YUV_PLANES; + int j; + + memset(aPhyAddr, 0x00, sizeof(aPhyAddr)); + + uByteSize = psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuMultiPlanePAddr( + ppsMemInfos[i], IMG_NULL /* We want the beginning of the buffers */, + aPhyAddr, &ui32NumAddrOffsets); + + if(uByteSize < 0) + continue; + + ui32NumPages = (uByteSize + PAGE_SIZE - 1) >> PAGE_SHIFT; + + /* TILER buffers do not need meminfos */ + if(is_tiler_addr((u32)aPhyAddr[0].uiAddr)) + { + asMemInfo[k].uiAddr = aPhyAddr[0].uiAddr; +#ifdef CONFIG_DRM_OMAP_DMM_TILER + if (tiler_get_fmt((u32)aPhyAddr[0].uiAddr, &fmt) && fmt == TILFMT_8BIT) +#else /* CONFIG_TI_TILER must be defined if CONFIG_DRM_OMAP_DMM_TILER is not */ + if (tiler_fmt((u32)aPhyAddr[0].uiAddr) == TILFMT_8BIT) +#endif + { + if(ui32NumAddrOffsets > 1) + asMemInfo[k].uiUVAddr = aPhyAddr[1].uiAddr; + } + continue; + } + + if (aPhyAddr[0].uiAddr >= psDevInfo->psLINFBInfo->fix.smem_start && + aPhyAddr[0].uiAddr < (psDevInfo->psLINFBInfo->fix.smem_start + psDevInfo->psLINFBInfo->fix.smem_len)) + { + asMemInfo[k].uiAddr = aPhyAddr[0].uiAddr; + continue; + } + /* normal gralloc layer */ + psTilerInfo = kzalloc(sizeof(*psTilerInfo), GFP_KERNEL); + if(!psTilerInfo) + { + continue; + } + + psTilerInfo->mem = kzalloc(sizeof(*psTilerInfo->mem) * ui32NumPages, GFP_KERNEL); + if(!psTilerInfo->mem) + { + kfree(psTilerInfo); + continue; + } + + psTilerInfo->num_pg = ui32NumPages; + psTilerInfo->memtype = TILER_MEM_USING; + for(j = 0; j < ui32NumPages; j++) + { + IMG_CPU_PHYADDR pagePhyAddr; + psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], j << PAGE_SHIFT, &pagePhyAddr); + psTilerInfo->mem[j] = (u32)pagePhyAddr.uiAddr; + } + + /* need base address for in-page offset */ + psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuVAddr(ppsMemInfos[i], &virtAddr); + asMemInfo[k].uiAddr = (IMG_UINTPTR_T) virtAddr; + asMemInfo[k].psTilerInfo = psTilerInfo; + } + + for(i = 0; i < psDssData->num_ovls; i++) + { + unsigned int ix; + apsTilerPAs[i] = NULL; + + /* only supporting Post2, cloned and fbmem layers */ + if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX && + psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_OVL_IX && + psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_FB && + psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_ION) + psDssData->ovls[i].cfg.enabled = false; + + if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX) + continue; + + /* Post2 layers */ + ix = psDssData->ovls[i].ba; + if (ix >= k) + { + WARN(1, "Invalid Post2 layer (%u)", ix); + psDssData->ovls[i].cfg.enabled = false; + continue; + } + + psDssData->ovls[i].addressing = OMAP_DSS_BUFADDR_DIRECT; + psDssData->ovls[i].ba = (u32) asMemInfo[ix].uiAddr; + psDssData->ovls[i].uv = (u32) asMemInfo[ix].uiUVAddr; + apsTilerPAs[i] = asMemInfo[ix].psTilerInfo; + } + + if (rgz_items > 0) + { + OMAPLFBDoBlits(psDevInfo, ppsMemInfos, &psHwcData->blit_data, ui32NumMemInfos); + } + + dsscomp_gralloc_queue(psDssData, apsTilerPAs, false, + dsscomp_proxy_cmdcomplete, + (void *)hCmdCookie); + + for(i = 0; i < ARRAY_SIZE(asMemInfo); i++) + { + tiler_pa_free(asMemInfo[i].psTilerInfo); + } + + return IMG_TRUE; +} + +#endif + +static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, + IMG_UINT32 ui32DataSize, + IMG_VOID *pvData) +{ + DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; + OMAPLFB_DEVINFO *psDevInfo; + + if(!hCmdCookie || !pvData) + { + return IMG_FALSE; + } + + psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData; + + if (psFlipCmd == IMG_NULL) + { + return IMG_FALSE; + } + + psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice; + + if(psFlipCmd->hExtBuffer) + { + return ProcessFlipV1(hCmdCookie, + psDevInfo, + psFlipCmd->hExtSwapChain, + psFlipCmd->hExtBuffer, + psFlipCmd->ui32SwapInterval); + } + else + { +#if defined(CONFIG_DSSCOMP) && (defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER)) + DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd2; + psFlipCmd2 = (DISPLAYCLASS_FLIP_COMMAND2 *)pvData; + return ProcessFlipV2(hCmdCookie, + psDevInfo, + psFlipCmd2->ppsMemInfos, + psFlipCmd2->ui32NumMemInfos, + psFlipCmd2->pvPrivData, + psFlipCmd2->ui32PrivDataLength); +#else + BUG(); +#endif + } +} + +#if defined(CONFIG_DSSCOMP) + +static OMAPLFB_ERROR OMAPLFBInitIonOmap(OMAPLFB_DEVINFO *psDevInfo, + struct fb_info *psLINFBInfo, + OMAPLFB_FBINFO *psPVRFBInfo) +{ + int n; + int iMaxSwapChainBuffs; + int res; + int i, x, y, w; + ion_phys_addr_t phys; + size_t size; + struct tiler_view_t view; + + struct omap_ion_tiler_alloc_data sAllocData = { + .w = ALIGN(psLINFBInfo->var.xres, PAGE_SIZE / (psLINFBInfo->var.bits_per_pixel / 8)), + .h = psLINFBInfo->var.yres, + .fmt = psLINFBInfo->var.bits_per_pixel == 16 ? TILER_PIXEL_FMT_16BIT : TILER_PIXEL_FMT_32BIT, + .flags = 0, + .token = 0, + .out_align = PAGE_SIZE + }; + unsigned uiFBDevID = psDevInfo->uiFBDevID; + struct sgx_omaplfb_config *psFBPlatConfig = GetFBPlatConfig(uiFBDevID); + +#if defined(CONFIG_ION_OMAP) + gpsIONClient = ion_client_create(omap_ion_device, + 1 << ION_HEAP_TYPE_CARVEOUT | + 1 << OMAP_ION_HEAP_TYPE_TILER | + 1 << ION_HEAP_TYPE_SYSTEM, + "omaplfb"); + if (IS_ERR_OR_NULL(gpsIONClient)) + { + printk(KERN_ERR DRIVER_PREFIX + " %s: Could not create ion client\n", __FUNCTION__); + return OMAPLFB_ERROR_INIT_FAILURE; + } +#endif /* defined(CONFIG_ION_OMAP) */ + + if (!psFBPlatConfig->swap_chain_length) + { + /* Set a default swap chain length if it's not present in the platform data */ + iMaxSwapChainBuffs = 2; + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Swap chain length missing in " + "platform data, defaulting to %d\n", __FUNCTION__, psDevInfo->uiFBDevID, + iMaxSwapChainBuffs); + } + else + { + iMaxSwapChainBuffs = psFBPlatConfig->swap_chain_length; + } + + if (psFBPlatConfig->tiler2d_buffers < iMaxSwapChainBuffs) + { + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Trying to use %d tiler " + "buffers which is less than the swap chain length of %d, maximum " + "swap chain length will be set to %d\n", __FUNCTION__, psDevInfo->uiFBDevID, + psFBPlatConfig->tiler2d_buffers, iMaxSwapChainBuffs, psFBPlatConfig->tiler2d_buffers); + iMaxSwapChainBuffs = psFBPlatConfig->tiler2d_buffers; + } + + psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = iMaxSwapChainBuffs; + n = psFBPlatConfig->tiler2d_buffers; + + printk(KERN_DEBUG DRIVER_PREFIX + ": %s: Device %u: Requesting %d TILER 2D framebuffers\n", __FUNCTION__, uiFBDevID, n); + sAllocData.w *= n; + + psPVRFBInfo->uiBytesPerPixel = psLINFBInfo->var.bits_per_pixel >> 3; + psPVRFBInfo->bIs2D = OMAPLFB_TRUE; + res = omap_ion_nonsecure_tiler_alloc(gpsIONClient, &sAllocData); + if (res < 0) + { + printk(KERN_ERR DRIVER_PREFIX + " %s: Device %u: Could not allocate 2D framebuffer(%d)\n", __FUNCTION__, uiFBDevID, res); + return OMAPLFB_ERROR_INIT_FAILURE; + } + + ion_phys(gpsIONClient, sAllocData.handle, &phys, &size); + psPVRFBInfo->sSysAddr.uiAddr = phys; + psPVRFBInfo->sCPUVAddr = 0; + + psPVRFBInfo->ulWidth = psLINFBInfo->var.xres; + psPVRFBInfo->ulHeight = psLINFBInfo->var.yres; + psPVRFBInfo->ulByteStride = PAGE_ALIGN(psPVRFBInfo->ulWidth * psPVRFBInfo->uiBytesPerPixel); + psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride; + psPVRFBInfo->ulRoundedBufferSize = psPVRFBInfo->ulBufferSize; + w = psPVRFBInfo->ulByteStride >> PAGE_SHIFT; + + /* this is an "effective" FB size to get correct number of buffers */ + psPVRFBInfo->ulFBSize = sAllocData.h * n * psPVRFBInfo->ulByteStride; + psPVRFBInfo->psPageList = kzalloc(w * n * psPVRFBInfo->ulHeight * sizeof(*psPVRFBInfo->psPageList), GFP_KERNEL); + if (!psPVRFBInfo->psPageList) + { + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Could not allocate page list\n", __FUNCTION__, psDevInfo->uiFBDevID); + ion_free(gpsIONClient, sAllocData.handle); + return OMAPLFB_ERROR_INIT_FAILURE; + } + psPVRFBInfo->psIONHandle = sAllocData.handle; + + tilview_create(&view, phys, psDevInfo->sFBInfo.ulWidth, psDevInfo->sFBInfo.ulHeight); + for(i=0; i<n; i++) + { + for(y=0; y<psDevInfo->sFBInfo.ulHeight; y++) + { + for(x=0; x<w; x++) + { + psPVRFBInfo->psPageList[i * psDevInfo->sFBInfo.ulHeight * w + y * w + x].uiAddr = + phys + view.v_inc * y + ((x + i * w) << PAGE_SHIFT); + } + } + } + return OMAPLFB_OK; +} +#endif + +static OMAPLFB_ERROR OMAPLFBInitFBVRAM(OMAPLFB_DEVINFO *psDevInfo, + struct fb_info *psLINFBInfo, + OMAPLFB_FBINFO *psPVRFBInfo) +{ + struct sgx_omaplfb_config *psFBPlatConfig = GetFBPlatConfig(psDevInfo->uiFBDevID); + unsigned long FBSize = psLINFBInfo->fix.smem_len; + unsigned long ulLCM; + int iMaxSwapChainBuffs; + IMG_UINT32 ui32FBAvailableBuffs; + + /* Check if there is VRAM reserved for this FB */ + if (FBSize == 0 || psLINFBInfo->fix.line_length == 0) + { + return OMAPLFB_ERROR_INVALID_DEVICE; + } + + /* Fail to init this DC device if vram buffers are not set */ + if (!psFBPlatConfig->vram_buffers) + { + return OMAPLFB_ERROR_INVALID_PARAMS; + } + + if (!psFBPlatConfig->swap_chain_length) + { + /* Set a default swap chain length if it's not present in the platform data */ + iMaxSwapChainBuffs = 2; + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Swap chain length missing in " + "platform data, defaulting to %d\n", __FUNCTION__, psDevInfo->uiFBDevID, + iMaxSwapChainBuffs); + } + else + { + iMaxSwapChainBuffs = psFBPlatConfig->swap_chain_length; + } + + if (psFBPlatConfig->vram_buffers < iMaxSwapChainBuffs) + { + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Trying to use %d vram " + "buffers which is less than the swap chain length of %d, maximum " + "swap chain length will be set to %d\n", __FUNCTION__, psDevInfo->uiFBDevID, + psFBPlatConfig->vram_buffers, iMaxSwapChainBuffs, psFBPlatConfig->vram_buffers); + iMaxSwapChainBuffs = psFBPlatConfig->vram_buffers; + } + + ulLCM = LCM(psLINFBInfo->fix.line_length, OMAPLFB_PAGE_SIZE); + psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start; + psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base; + psPVRFBInfo->ulWidth = psLINFBInfo->var.xres; + psPVRFBInfo->ulHeight = psLINFBInfo->var.yres; + psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length; + psPVRFBInfo->ulFBSize = FBSize; + psPVRFBInfo->bIs2D = OMAPLFB_FALSE; + psPVRFBInfo->psPageList = IMG_NULL; + psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride; + psPVRFBInfo->ulRoundedBufferSize = RoundUpToMultiple(psPVRFBInfo->ulBufferSize, ulLCM); + ui32FBAvailableBuffs = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize); + + if (!ui32FBAvailableBuffs) + { + printk(KERN_ERR DRIVER_PREFIX " %s: Device %u: Not enough vram to init swap " + "chain buffers\n", __FUNCTION__, psDevInfo->uiFBDevID); + return OMAPLFB_ERROR_INIT_FAILURE; + } + else if (ui32FBAvailableBuffs < psFBPlatConfig->vram_buffers) + { + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Not enough vram to hold " + "%d buffers (available %d), swap chain length will be set to %d\n", + __FUNCTION__, psDevInfo->uiFBDevID, iMaxSwapChainBuffs, ui32FBAvailableBuffs, + ui32FBAvailableBuffs); + iMaxSwapChainBuffs = ui32FBAvailableBuffs; + } + else + { + iMaxSwapChainBuffs = psFBPlatConfig->vram_buffers; + } + + psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = iMaxSwapChainBuffs; + + printk(KERN_DEBUG DRIVER_PREFIX ": %s: Device %u: Using %d VRAM framebuffers\n", __FUNCTION__, + psDevInfo->uiFBDevID, iMaxSwapChainBuffs); + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: Framebuffer virtual width: %u\n", + psDevInfo->uiFBDevID, psLINFBInfo->var.xres_virtual)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: Framebuffer virtual height: %u\n", + psDevInfo->uiFBDevID, psLINFBInfo->var.yres_virtual)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: LCM of stride and page size: %lu\n", + psDevInfo->uiFBDevID, ulLCM)); + + return OMAPLFB_OK; +} + +static OMAPLFB_ERROR OMAPLFBInitFBDev(OMAPLFB_DEVINFO *psDevInfo) +{ + struct fb_info *psLINFBInfo; + struct module *psLINFBOwner; + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + OMAPLFB_ERROR eError = OMAPLFB_ERROR_GENERIC; + unsigned uiFBDevID = psDevInfo->uiFBDevID; + struct sgx_omaplfb_config *psFBPlatConfig; + + OMAPLFB_CONSOLE_LOCK(); + + psLINFBInfo = registered_fb[uiFBDevID]; + if (psLINFBInfo == NULL) + { + eError = OMAPLFB_ERROR_INVALID_DEVICE; + goto ErrorRelSem; + } + + psLINFBOwner = psLINFBInfo->fbops->owner; + if (!try_module_get(psLINFBOwner)) + { + printk(KERN_INFO DRIVER_PREFIX + ": %s: Device %u: Couldn't get framebuffer module\n", __FUNCTION__, uiFBDevID); + + goto ErrorRelSem; + } + + if (psLINFBInfo->fbops->fb_open != NULL) + { + int res; + + res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0); + if (res != 0) + { + printk(KERN_INFO DRIVER_PREFIX + " %s: Device %u: Couldn't open framebuffer(%d)\n", __FUNCTION__, uiFBDevID, res); + + goto ErrorModPut; + } + } + + psDevInfo->psLINFBInfo = psLINFBInfo; + + /* + * Abort registering this DC device if no platform data found. This + * shouldn't happen since the FB index must be valid at this point. + */ + psFBPlatConfig = GetFBPlatConfig(uiFBDevID); + if (!psFBPlatConfig) + { + eError = OMAPLFB_ERROR_INVALID_PARAMS; + goto ErrorModPut; + } + +#if defined(CONFIG_DSSCOMP) + if (psFBPlatConfig->tiler2d_buffers) + { + /* Use ION to create the flip chain buffers with TILER */ + eError = OMAPLFBInitIonOmap(psDevInfo, psLINFBInfo, psPVRFBInfo); + if (eError != OMAPLFB_OK) + { + goto ErrorModPut; + } + } + else +#endif + { + /* Fall back to allocate flip chain buffers with VRAM */ + eError = OMAPLFBInitFBVRAM(psDevInfo, psLINFBInfo, psPVRFBInfo); + if (eError != OMAPLFB_OK) + { + goto ErrorModPut; + } + } + + OMAPLFBPrintInfo(psDevInfo); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: Framebuffer physical address: %p\n", + psDevInfo->uiFBDevID, (void *)psPVRFBInfo->sSysAddr.uiAddr)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: Framebuffer virtual address: %p\n", + psDevInfo->uiFBDevID, (void *)psPVRFBInfo->sCPUVAddr)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: Framebuffer size: %lu\n", + psDevInfo->uiFBDevID, psPVRFBInfo->ulFBSize)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: Framebuffer width: %lu\n", + psDevInfo->uiFBDevID, psPVRFBInfo->ulWidth)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: Framebuffer height: %lu\n", + psDevInfo->uiFBDevID, psPVRFBInfo->ulHeight)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: Framebuffer stride: %lu\n", + psDevInfo->uiFBDevID, psPVRFBInfo->ulByteStride)); + + if(psLINFBInfo->var.bits_per_pixel == 16) + { + if((psLINFBInfo->var.red.length == 5) && + (psLINFBInfo->var.green.length == 6) && + (psLINFBInfo->var.blue.length == 5) && + (psLINFBInfo->var.red.offset == 11) && + (psLINFBInfo->var.green.offset == 5) && + (psLINFBInfo->var.blue.offset == 0) && + (psLINFBInfo->var.red.msb_right == 0)) + { + psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565; + } + else + { + printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); + } + } + else if(psLINFBInfo->var.bits_per_pixel == 32) + { + if((psLINFBInfo->var.red.length == 8) && + (psLINFBInfo->var.green.length == 8) && + (psLINFBInfo->var.blue.length == 8) && + (psLINFBInfo->var.red.offset == 16) && + (psLINFBInfo->var.green.offset == 8) && + (psLINFBInfo->var.blue.offset == 0) && + (psLINFBInfo->var.red.msb_right == 0)) + { + psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888; + } + else + { + printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); + } + } + else + { + printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); + } + + psDevInfo->sFBInfo.ulPhysicalWidthmm = + ((int)psLINFBInfo->var.width > 0) ? psLINFBInfo->var.width : 90; + + psDevInfo->sFBInfo.ulPhysicalHeightmm = + ((int)psLINFBInfo->var.height > 0) ? psLINFBInfo->var.height : 54; + + + psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr; + psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr; + + eError = OMAPLFB_OK; + goto ErrorRelSem; + +ErrorModPut: + module_put(psLINFBOwner); +ErrorRelSem: + OMAPLFB_CONSOLE_UNLOCK(); + + return eError; +} + +static void OMAPLFBDeInitFBDev(OMAPLFB_DEVINFO *psDevInfo) +{ + struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + struct module *psLINFBOwner; + + OMAPLFB_CONSOLE_LOCK(); + + psLINFBOwner = psLINFBInfo->fbops->owner; + +#if defined(CONFIG_DSSCOMP) + kfree(psPVRFBInfo->psPageList); + if (psPVRFBInfo->psIONHandle) + { + ion_free(gpsIONClient, psPVRFBInfo->psIONHandle); + } + if (psPVRFBInfo->psBltFBsIonHndl) + { + ion_free(gpsIONClient, psPVRFBInfo->psBltFBsIonHndl); + } + if (psPVRFBInfo->psBltFBsBvHndl) + { + int i; + for (i = 0; i < psPVRFBInfo->psBltFBsNo; i++) + { + if (psPVRFBInfo->psBltFBsBvHndl[i]) + { + kfree(psPVRFBInfo->psBltFBsBvHndl[i]); + } + } + kfree(psPVRFBInfo->psBltFBsBvHndl); + kfree(psPVRFBInfo->psBltFBsBvPhys); + } +#endif + if (psLINFBInfo->fbops->fb_release != NULL) + { + (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); + } + + module_put(psLINFBOwner); + + OMAPLFB_CONSOLE_UNLOCK(); +} + +static OMAPLFB_DEVINFO *OMAPLFBInitDev(unsigned uiFBDevID) +{ + PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; + IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2]; + OMAPLFB_DEVINFO *psDevInfo = NULL; + + + psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO)); + + if(psDevInfo == NULL) + { + printk(KERN_ERR DRIVER_PREFIX + ": %s: Device %u: Couldn't allocate device information structure\n", __FUNCTION__, uiFBDevID); + + goto ErrorExit; + } + + + memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO)); + + psDevInfo->uiFBDevID = uiFBDevID; + + + if(!(*gpfnGetPVRJTable)(&psDevInfo->sPVRJTable)) + { + goto ErrorFreeDevInfo; + } + + + if(OMAPLFBInitFBDev(psDevInfo) != OMAPLFB_OK) + { + + goto ErrorFreeDevInfo; + } + + if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers != 0) + { + psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1; + psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1; + } + + psDevInfo->sDisplayInfo.ui32PhysicalWidthmm = psDevInfo->sFBInfo.ulPhysicalWidthmm; + psDevInfo->sDisplayInfo.ui32PhysicalHeightmm = psDevInfo->sFBInfo.ulPhysicalHeightmm; + + strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); + + psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat; + psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth; + psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight; + psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride; + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: Maximum number of swap chain buffers: %u\n", + psDevInfo->uiFBDevID, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)); + + + psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr; + psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr; + psDevInfo->sSystemBuffer.psDevInfo = psDevInfo; + + OMAPLFBInitBufferForSwap(&psDevInfo->sSystemBuffer); + + + + psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE); + psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice; + psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice; + psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats; + psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims; + psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer; + psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo; + psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr; + psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain; + psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain; + psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect; + psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect; + psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey; + psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey; + psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers; + psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer; + psDevInfo->sDCJTable.pfnSetDCState = SetDCState; + + + if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice( + &psDevInfo->sDCJTable, + &psDevInfo->uiPVRDevID) != PVRSRV_OK) + { + printk(KERN_ERR DRIVER_PREFIX + ": %s: Device %u: PVR Services device registration failed\n", __FUNCTION__, uiFBDevID); + + goto ErrorDeInitFBDev; + } + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Device %u: PVR Device ID: %u\n", + psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); + + + pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; + + + aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; + if (gbBvInterfacePresent) + { + aui32SyncCountList[DC_FLIP_COMMAND][1] = 32; + } + else + { + aui32SyncCountList[DC_FLIP_COMMAND][1] = 10; + } + + + + + + if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiPVRDevID, + &pfnCmdProcList[0], + aui32SyncCountList, + OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) + { + printk(KERN_ERR DRIVER_PREFIX + ": %s: Device %u: Couldn't register command processing functions with PVR Services\n", __FUNCTION__, uiFBDevID); + goto ErrorUnregisterDevice; + } + + OMAPLFBCreateSwapChainLockInit(psDevInfo); + + OMAPLFBAtomicBoolInit(&psDevInfo->sBlanked, OMAPLFB_FALSE); + OMAPLFBAtomicIntInit(&psDevInfo->sBlankEvents, 0); + OMAPLFBAtomicBoolInit(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); +#if defined(CONFIG_HAS_EARLYSUSPEND) + OMAPLFBAtomicBoolInit(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); +#endif +#if defined(SUPPORT_DRI_DRM) + OMAPLFBAtomicBoolInit(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); +#endif + return psDevInfo; + +ErrorUnregisterDevice: + (void)psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID); +ErrorDeInitFBDev: + OMAPLFBDeInitFBDev(psDevInfo); +ErrorFreeDevInfo: + OMAPLFBFreeKernelMem(psDevInfo); +ErrorExit: + return NULL; +} + +#if defined(CONFIG_OMAPLFB) +int OMAPLFBRegisterPVRDriver(PFN_DC_GET_PVRJTABLE pfnFuncTable) +{ + gpfnGetPVRJTable = pfnFuncTable; + + if(OMAPLFBInit() != OMAPLFB_OK) + { + printk(KERN_ERR DRIVER_PREFIX + " %s: Could not create ion client\n", __FUNCTION__); + return -1; + } + return 0; +} +EXPORT_SYMBOL(OMAPLFBRegisterPVRDriver); +#endif + +OMAPLFB_ERROR OMAPLFBInit(void) +{ + unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); + unsigned i; + unsigned uiDevicesFound = 0; + +#if !defined(CONFIG_OMAPLFB) + if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &gpfnGetPVRJTable) != OMAPLFB_OK) + { + return OMAPLFB_ERROR_INIT_FAILURE; + } +#endif + + gbBvInterfacePresent = OMAPLFBInitBlt(); + + if (!gbBvInterfacePresent) + { + printk(KERN_INFO DRIVER_PREFIX "%s: Blitsville gc2d " + "not present, blits disabled\n", __func__); + } + for(i = uiMaxFBDevIDPlusOne; i-- != 0;) + { + OMAPLFB_DEVINFO *psDevInfo = OMAPLFBInitDev(i); + + if (psDevInfo != NULL) + { + + OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, psDevInfo); + uiDevicesFound++; + } + } + + return (uiDevicesFound != 0) ? OMAPLFB_OK : OMAPLFB_ERROR_INIT_FAILURE; +} + +static OMAPLFB_BOOL OMAPLFBDeInitDev(OMAPLFB_DEVINFO *psDevInfo) +{ + PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable = &psDevInfo->sPVRJTable; + + OMAPLFBCreateSwapChainLockDeInit(psDevInfo); + + OMAPLFBAtomicBoolDeInit(&psDevInfo->sBlanked); + OMAPLFBAtomicIntDeInit(&psDevInfo->sBlankEvents); + OMAPLFBAtomicBoolDeInit(&psDevInfo->sFlushCommands); +#if defined(CONFIG_HAS_EARLYSUSPEND) + OMAPLFBAtomicBoolDeInit(&psDevInfo->sEarlySuspendFlag); +#endif +#if defined(SUPPORT_DRI_DRM) + OMAPLFBAtomicBoolDeInit(&psDevInfo->sLeaveVT); +#endif + psPVRJTable = &psDevInfo->sPVRJTable; + + if (psPVRJTable->pfnPVRSRVRemoveCmdProcList (psDevInfo->uiPVRDevID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) + { + printk(KERN_ERR DRIVER_PREFIX + ": %s: Device %u: PVR Device %u: Couldn't unregister command processing functions\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); + return OMAPLFB_FALSE; + } + + + if (psPVRJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID) != PVRSRV_OK) + { + printk(KERN_ERR DRIVER_PREFIX + ": %s: Device %u: PVR Device %u: Couldn't remove device from PVR Services\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); + return OMAPLFB_FALSE; + } + + OMAPLFBDeInitFBDev(psDevInfo); + + OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, NULL); + + + OMAPLFBFreeKernelMem(psDevInfo); + + return OMAPLFB_TRUE; +} + +OMAPLFB_ERROR OMAPLFBDeInit(void) +{ + unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); + unsigned i; + OMAPLFB_BOOL bError = OMAPLFB_FALSE; + + for(i = 0; i < uiMaxFBDevIDPlusOne; i++) + { + OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); + + if (psDevInfo != NULL) + { + bError |= !OMAPLFBDeInitDev(psDevInfo); + } + } + + return (bError) ? OMAPLFB_ERROR_INIT_FAILURE : OMAPLFB_OK; +} + diff --git a/drivers/video/omap2/omaplfb/omaplfb_linux.c b/drivers/video/omap2/omaplfb/omaplfb_linux.c new file mode 100644 index 0000000..b4f2faa --- /dev/null +++ b/drivers/video/omap2/omaplfb/omaplfb_linux.c @@ -0,0 +1,1197 @@ +/********************************************************************** + * + * Copyright (C) Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. <gpl-support@imgtec.com> + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include <linux/version.h> + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) +#ifndef AUTOCONF_INCLUDED +#include <linux/config.h> +#endif +#endif + +#include <asm/atomic.h> + +#if defined(SUPPORT_DRI_DRM) +#include <drm/drmP.h> +#else +#include <linux/module.h> +#endif + +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/hardirq.h> +#include <linux/mutex.h> +#include <linux/workqueue.h> +#include <linux/fb.h> +#include <linux/console.h> +#include <linux/omapfb.h> +#include <linux/mutex.h> +#include <plat/sgx_omaplfb.h> + +#if defined(PVR_OMAPLFB_DRM_FB) +#include <plat/display.h> +#include <linux/omap_gpu.h> +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) +#define PVR_OMAPFB3_NEEDS_PLAT_VRFB_H +#endif + +#if defined(PVR_OMAPFB3_NEEDS_PLAT_VRFB_H) +#include <plat/vrfb.h> +#else +#if defined(PVR_OMAPFB3_NEEDS_MACH_VRFB_H) +#include <mach/vrfb.h> +#endif +#endif + +#if defined(DEBUG) +#define PVR_DEBUG DEBUG +#undef DEBUG +#endif +#include "../omapfb/omapfb.h" +#if defined(DEBUG) +#undef DEBUG +#endif +#if defined(PVR_DEBUG) +#define DEBUG PVR_DEBUG +#undef PVR_DEBUG +#endif +#endif + +#include "img_defs.h" +#include "servicesext.h" +#include "kerneldisplay.h" +#include "omaplfb.h" +#if defined(SUPPORT_DRI_DRM) +#include "pvr_drm.h" +#include "3rdparty_dc_drm_shared.h" +#endif + +#if !defined(PVR_LINUX_USING_WORKQUEUES) +#error "PVR_LINUX_USING_WORKQUEUES must be defined" +#endif + +MODULE_SUPPORTED_DEVICE(DEVNAME); + +#if !defined(PVR_OMAPLFB_DRM_FB) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) +#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_driver *drv = (dev) != NULL ? (dev)->driver : NULL +#define OMAP_DSS_MANAGER(man, dev) struct omap_overlay_manager *man = (dev) != NULL ? (dev)->manager : NULL +#define WAIT_FOR_VSYNC(man) ((man)->wait_for_vsync) +#else +#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_device *drv = (dev) +#define OMAP_DSS_MANAGER(man, dev) struct omap_dss_device *man = (dev) +#define WAIT_FOR_VSYNC(man) ((man)->wait_vsync) +#endif +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) +#define OMAP_FB_UPDATE_MODE +#define OMAP_UPDATE_MODE omapfb_update_mode +#define OMAP_UPDATE_MODE_AUTO OMAPFB_AUTO_UPDATE +#define OMAP_UPDATE_MODE_MANUAL OMAPFB_MANUAL_UPDATE +#define OMAP_UPDATE_MODE_DISABLED OMAPFB_UPDATE_DISABLED +#else +#define OMAP_UPDATE_MODE omap_dss_update_mode +#define OMAP_UPDATE_MODE_AUTO OMAP_DSS_UPDATE_AUTO +#define OMAP_UPDATE_MODE_MANUAL OMAP_DSS_UPDATE_MANUAL +#define OMAP_UPDATE_MODE_DISABLED OMAP_DSS_UPDATE_DISABLED +#endif + +static int debug; +module_param(debug, int, 0644); /* For future use */ + +static struct sgx_omaplfb_platform_data *gplatdata; + +void *OMAPLFBAllocKernelMem(unsigned long ulSize) +{ + return kmalloc(ulSize, GFP_KERNEL); +} + +void OMAPLFBFreeKernelMem(void *pvMem) +{ + kfree(pvMem); +} + +void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo) +{ + mutex_init(&psDevInfo->sCreateSwapChainMutex); +} + +void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo) +{ + mutex_destroy(&psDevInfo->sCreateSwapChainMutex); +} + +void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo) +{ + mutex_lock(&psDevInfo->sCreateSwapChainMutex); +} + +void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo) +{ + mutex_unlock(&psDevInfo->sCreateSwapChainMutex); +} + +void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) +{ + atomic_set(psAtomic, (int)bVal); +} + +void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic) +{ +} + +void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) +{ + atomic_set(psAtomic, (int)bVal); +} + +OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic) +{ + return (OMAPLFB_BOOL)atomic_read(psAtomic); +} + +void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) +{ + atomic_set(psAtomic, iVal); +} + +void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic) +{ +} + +void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) +{ + atomic_set(psAtomic, iVal); +} + +int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic) +{ + return atomic_read(psAtomic); +} + +void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic) +{ + atomic_inc(psAtomic); +} + +#if !defined(CONFIG_OMAPLFB) +OMAPLFB_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable) +{ + if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0) + { + return (OMAPLFB_ERROR_INVALID_PARAMS); + } + + + *ppfnFuncTable = PVRGetDisplayClassJTable; + + return (OMAPLFB_OK); +} +#endif + +void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer) +{ + int res = queue_work(psSwapChain->psWorkQueue, &psBuffer->sWork); + + if (res == 0) + { + printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Buffer already on work queue\n", __FUNCTION__, psSwapChain->uiFBDevID); + } +} + +static void WorkQueueHandler(struct work_struct *psWork) +{ + OMAPLFB_BUFFER *psBuffer = container_of(psWork, OMAPLFB_BUFFER, sWork); + + OMAPLFBSwapHandler(psBuffer); +} + +OMAPLFB_ERROR OMAPLFBCreateSwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + + psSwapChain->psWorkQueue = alloc_ordered_workqueue(DEVNAME, WQ_FREEZABLE | WQ_MEM_RECLAIM); +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) + psSwapChain->psWorkQueue = create_freezable_workqueue(DEVNAME); +#else + + psSwapChain->psWorkQueue = __create_workqueue(DEVNAME, 1, 1, 1); +#endif +#endif + if (psSwapChain->psWorkQueue == NULL) + { + printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Couldn't create workqueue\n", __FUNCTION__, psSwapChain->uiFBDevID); + + return (OMAPLFB_ERROR_INIT_FAILURE); + } + + return (OMAPLFB_OK); +} + +void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer) +{ + INIT_WORK(&psBuffer->sWork, WorkQueueHandler); +} + +void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) +{ + destroy_workqueue(psSwapChain->psWorkQueue); +} + +#if defined(CONFIG_DSSCOMP) +#include <video/dsscomp.h> +#include <plat/dsscomp.h> +#include <linux/omapfb.h> +#endif + +void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer) +{ + struct fb_var_screeninfo sFBVar; + int res; + unsigned long ulYResVirtual; + + OMAPLFB_CONSOLE_LOCK(); + + sFBVar = psDevInfo->psLINFBInfo->var; + + sFBVar.xoffset = 0; + sFBVar.yoffset = psBuffer->ulYOffset; + + ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres; + + +#if defined(CONFIG_DSSCOMP) + { + /* + * If using DSSCOMP, we need to use dsscomp queuing for normal + * framebuffer updates, so that previously used overlays get + * automatically disabled, and manager gets dirtied. We can + * do that because DSSCOMP takes ownership of all pipelines on + * a manager. + */ + struct fb_fix_screeninfo sFBFix = psDevInfo->psLINFBInfo->fix; + struct dsscomp_setup_dispc_data d = { + .num_ovls = 1, + .num_mgrs = 1, + .mgrs[0].alpha_blending = 1, + .ovls[0] = { + .cfg = { + .win.w = sFBVar.xres, + .win.h = sFBVar.yres, + .crop.x = sFBVar.xoffset, + .crop.y = sFBVar.yoffset, + .crop.w = sFBVar.xres, + .crop.h = sFBVar.yres, + .width = sFBVar.xres_virtual, + .height = sFBVar.yres_virtual, + .stride = sFBFix.line_length, + .enabled = 1, + .global_alpha = 255, + }, + }, + }; + /* do not map buffer into TILER1D as it is contiguous */ + struct tiler_pa_info *pas[] = { NULL }; + + d.ovls[0].ba = sFBFix.smem_start; + omapfb_mode_to_dss_mode(&sFBVar, &d.ovls[0].cfg.color_mode); + + res = dsscomp_gralloc_queue(&d, pas, true, NULL, NULL); + } +#else +#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) + + if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual) +#endif + { + sFBVar.xres_virtual = sFBVar.xres; + sFBVar.yres_virtual = ulYResVirtual; + + sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; + + res = fb_set_var(psDevInfo->psLINFBInfo, &sFBVar); + if (res != 0) + { + printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_set_var failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); + } + } +#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) + else + { + res = fb_pan_display(psDevInfo->psLINFBInfo, &sFBVar); + if (res != 0) + { + printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_pan_display failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); + } + } +#endif +#endif + OMAPLFB_CONSOLE_UNLOCK(); +} + +#if !defined(PVR_OMAPLFB_DRM_FB) || defined(DEBUG) +static OMAPLFB_BOOL OMAPLFBValidUpdateMode(enum OMAP_UPDATE_MODE eMode) +{ + switch (eMode) + { + case OMAP_UPDATE_MODE_AUTO: + case OMAP_UPDATE_MODE_MANUAL: + case OMAP_UPDATE_MODE_DISABLED: + return OMAPLFB_TRUE; + default: + break; + } + + return OMAPLFB_FALSE; +} + +static OMAPLFB_UPDATE_MODE OMAPLFBFromUpdateMode(enum OMAP_UPDATE_MODE eMode) +{ + switch (eMode) + { + case OMAP_UPDATE_MODE_AUTO: + return OMAPLFB_UPDATE_MODE_AUTO; + case OMAP_UPDATE_MODE_MANUAL: + return OMAPLFB_UPDATE_MODE_MANUAL; + case OMAP_UPDATE_MODE_DISABLED: + return OMAPLFB_UPDATE_MODE_DISABLED; + default: + break; + } + + return OMAPLFB_UPDATE_MODE_UNDEFINED; +} +#endif + +static OMAPLFB_BOOL OMAPLFBValidateUpdateMode(OMAPLFB_UPDATE_MODE eMode) +{ + switch(eMode) + { + case OMAPLFB_UPDATE_MODE_AUTO: + case OMAPLFB_UPDATE_MODE_MANUAL: + case OMAPLFB_UPDATE_MODE_DISABLED: + return OMAPLFB_TRUE; + default: + break; + } + + return OMAPLFB_FALSE; +} + +static enum OMAP_UPDATE_MODE OMAPLFBToUpdateMode(OMAPLFB_UPDATE_MODE eMode) +{ + switch(eMode) + { + case OMAPLFB_UPDATE_MODE_AUTO: + return OMAP_UPDATE_MODE_AUTO; + case OMAPLFB_UPDATE_MODE_MANUAL: + return OMAP_UPDATE_MODE_MANUAL; + case OMAPLFB_UPDATE_MODE_DISABLED: + return OMAP_UPDATE_MODE_DISABLED; + default: + break; + } + + return -1; +} + +#if defined(DEBUG) +static const char *OMAPLFBUpdateModeToString(OMAPLFB_UPDATE_MODE eMode) +{ + switch(eMode) + { + case OMAPLFB_UPDATE_MODE_AUTO: + return "Auto Update Mode"; + case OMAPLFB_UPDATE_MODE_MANUAL: + return "Manual Update Mode"; + case OMAPLFB_UPDATE_MODE_DISABLED: + return "Update Mode Disabled"; + case OMAPLFB_UPDATE_MODE_UNDEFINED: + return "Update Mode Undefined"; + default: + break; + } + + return "Unknown Update Mode"; +} + +static const char *OMAPLFBDSSUpdateModeToString(enum OMAP_UPDATE_MODE eMode) +{ + if (!OMAPLFBValidUpdateMode(eMode)) + { + return "Unknown Update Mode"; + } + + return OMAPLFBUpdateModeToString(OMAPLFBFromUpdateMode(eMode)); +} + +void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo) +{ +#if defined(PVR_OMAPLFB_DRM_FB) + struct drm_connector *psConnector; + unsigned uConnectors; + unsigned uConnector; + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: DRM framebuffer\n", psDevInfo->uiFBDevID)); + + for (psConnector = NULL, uConnectors = 0; + (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) + { + uConnectors++; + } + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Number of screens (DRM connectors): %u\n", psDevInfo->uiFBDevID, uConnectors)); + + if (uConnectors == 0) + { + return; + } + + for (psConnector = NULL, uConnector = 0; + (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; uConnector++) + { + enum OMAP_UPDATE_MODE eMode = omap_connector_get_update_mode(psConnector); + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Screen %u: %s (%d)\n", psDevInfo->uiFBDevID, uConnector, OMAPLFBDSSUpdateModeToString(eMode), (int)eMode)); + + } +#else + OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: non-DRM framebuffer\n", psDevInfo->uiFBDevID)); + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: %s\n", psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); +#endif +} +#endif + +#if defined(PVR_OMAPLFB_DRM_FB) +OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) +{ + struct drm_connector *psConnector; + OMAPLFB_UPDATE_MODE eMode = OMAPLFB_UPDATE_MODE_UNDEFINED; + + + for (psConnector = NULL; + (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) + { + switch(omap_connector_get_update_mode(psConnector)) + { + case OMAP_DSS_UPDATE_MANUAL: + eMode = OMAPLFB_UPDATE_MODE_MANUAL; + break; + case OMAP_DSS_UPDATE_DISABLED: + if (eMode == OMAPLFB_UPDATE_MODE_UNDEFINED) + { + eMode = OMAPLFB_UPDATE_MODE_DISABLED; + } + break; + case OMAP_DSS_UPDATE_AUTO: + + default: + + if (eMode != OMAPLFB_UPDATE_MODE_MANUAL) + { + eMode = OMAPLFB_UPDATE_MODE_AUTO; + } + break; + } + } + + return eMode; +} + +OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode) +{ + struct drm_connector *psConnector; + enum OMAP_UPDATE_MODE eDSSMode; + OMAPLFB_BOOL bSuccess = OMAPLFB_FALSE; + OMAPLFB_BOOL bFailure = OMAPLFB_FALSE; + + if (!OMAPLFBValidateUpdateMode(eMode)) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); + return OMAPLFB_FALSE; + } + eDSSMode = OMAPLFBToUpdateMode(eMode); + + for (psConnector = NULL; + (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) + { + int iRes = omap_connector_set_update_mode(psConnector, eDSSMode); + OMAPLFB_BOOL bRes = (iRes == 0); + + + bSuccess |= bRes; + bFailure |= !bRes; + } + + if (!bFailure) + { + if (!bSuccess) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No screens\n", __FUNCTION__, psDevInfo->uiFBDevID)); + } + + return OMAPLFB_TRUE; + } + + if (!bSuccess) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for any screen\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); + return OMAPLFB_FALSE; + } + + if (eMode == OMAPLFB_UPDATE_MODE_AUTO) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for all screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); + return OMAPLFB_FALSE; + } + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: %s set for some screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); + + return OMAPLFB_TRUE; +} + +#elif defined(OMAP_FB_UPDATE_MODE) + +OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) +{ + enum OMAP_UPDATE_MODE eMode; + + omapfb_get_update_mode(psDevInfo->psLINFBInfo, &eMode); + + if (!OMAPLFBValidUpdateMode(eMode)) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); + } + + return OMAPLFBFromUpdateMode(eMode); +} + +OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode) +{ + enum OMAP_UPDATE_MODE eUpdateMode; + int res; + + if (!OMAPLFBValidateUpdateMode(eMode)) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); + return OMAPLFB_FALSE; + } + + res = omapfb_set_update_mode(psDevInfo->psLINFBInfo, eUpdateMode); + + if (res != 0) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: set_update_mode (%s) failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eUpdateMode), res)); + } + + return (res == 0); +} + +#else + +OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) +{ + struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); + OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); + + enum OMAP_UPDATE_MODE eMode; + + if (psDSSDrv == NULL) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No DSS device\n", __FUNCTION__, psDevInfo->uiFBDevID)); + return OMAPLFB_UPDATE_MODE_UNDEFINED; + } + + if (psDSSDrv->get_update_mode == NULL) + { + if (strcmp(psDSSDev->name, "hdmi") == 0) + { + return OMAPLFB_UPDATE_MODE_AUTO; + } + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No get_update_mode function\n", __FUNCTION__, psDevInfo->uiFBDevID)); + return OMAPLFB_UPDATE_MODE_UNDEFINED; + } + + eMode = psDSSDrv->get_update_mode(psDSSDev); + + if (!OMAPLFBValidUpdateMode(eMode)) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); + } + + return OMAPLFBFromUpdateMode(eMode); +} + +OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode) +{ + struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); + OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); + enum OMAP_UPDATE_MODE eUpdateMode; + int res; + + if (psDSSDrv == NULL || psDSSDrv->set_update_mode == NULL) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Can't set update mode\n", __FUNCTION__, psDevInfo->uiFBDevID)); + return OMAPLFB_FALSE; + } + + if (!OMAPLFBValidateUpdateMode(eMode)) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); + return OMAPLFB_FALSE; + } + + eUpdateMode = OMAPLFBToUpdateMode(eMode); + + res = psDSSDrv->set_update_mode(psDSSDev, eUpdateMode); + + if (res != 0) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: set_update_mode (%s) failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eUpdateMode), res)); + } + + return (res == 0); +} +#endif + +OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) +{ +#if defined(PVR_OMAPLFB_DRM_FB) + struct drm_connector *psConnector; + + for (psConnector = NULL; + (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) + { + (void) omap_encoder_wait_for_vsync(psConnector->encoder); + } + + return OMAPLFB_TRUE; +#else + struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); + OMAP_DSS_MANAGER(psDSSMan, psDSSDev); + + if (psDSSMan != NULL && WAIT_FOR_VSYNC(psDSSMan) != NULL) + { + int res = WAIT_FOR_VSYNC(psDSSMan)(psDSSMan); + if (res != 0) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Wait for vsync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); + return OMAPLFB_FALSE; + } + } + + return OMAPLFB_TRUE; +#endif +} + +OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo) +{ +#if defined(PVR_OMAPLFB_DRM_FB) + struct drm_connector *psConnector; + + for (psConnector = NULL; + (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; ) + { + + if (omap_connector_sync(psConnector) != 0) + { + (void) omap_encoder_wait_for_vsync(psConnector->encoder); + } + } + + return OMAPLFB_TRUE; +#else + struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); + OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); + + if (psDSSDrv != NULL && psDSSDrv->sync != NULL) + { + int res = psDSSDrv->sync(psDSSDev); + if (res != 0) + { + printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Sync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); + return OMAPLFB_FALSE; + } + } + + return OMAPLFB_TRUE; +#endif +} + +OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo) +{ + OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); + + switch(eMode) + { + case OMAPLFB_UPDATE_MODE_AUTO: + case OMAPLFB_UPDATE_MODE_MANUAL: + return OMAPLFBManualSync(psDevInfo); + default: + break; + } + + return OMAPLFB_TRUE; +} + +static int OMAPLFBFrameBufferEvents(struct notifier_block *psNotif, + unsigned long event, void *data) +{ + OMAPLFB_DEVINFO *psDevInfo; + struct fb_event *psFBEvent = (struct fb_event *)data; + struct fb_info *psFBInfo = psFBEvent->info; + OMAPLFB_BOOL bBlanked; + + + if (event != FB_EVENT_BLANK) + { + return 0; + } + + bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? OMAPLFB_TRUE: OMAPLFB_FALSE; + + psDevInfo = OMAPLFBGetDevInfoPtr(psFBInfo->node); + +#if 0 + if (psDevInfo != NULL) + { + if (bBlanked) + { + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); + } + else + { + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unblank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); + } + } + else + { + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank/Unblank event for unknown framebuffer\n", __FUNCTION__, psFBInfo->node)); + } +#endif + + if (psDevInfo != NULL) + { + OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, bBlanked); + OMAPLFBAtomicIntInc(&psDevInfo->sBlankEvents); + } + + return 0; +} + +OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) +{ + int res; + + OMAPLFB_CONSOLE_LOCK(); + res = fb_blank(psDevInfo->psLINFBInfo, 0); + OMAPLFB_CONSOLE_UNLOCK(); + if (res != 0 && res != -EINVAL) + { + printk(KERN_ERR DRIVER_PREFIX + ": %s: Device %u: fb_blank failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); + return (OMAPLFB_ERROR_GENERIC); + } + + return (OMAPLFB_OK); +} + +#ifdef CONFIG_HAS_EARLYSUSPEND + +static void OMAPLFBBlankDisplay(OMAPLFB_DEVINFO *psDevInfo) +{ + OMAPLFB_CONSOLE_LOCK(); + fb_blank(psDevInfo->psLINFBInfo, 1); + OMAPLFB_CONSOLE_UNLOCK(); +} + +static void OMAPLFBEarlySuspendHandler(struct early_suspend *h) +{ + unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); + unsigned i; + + for (i=0; i < uiMaxFBDevIDPlusOne; i++) + { + OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); + + if (psDevInfo != NULL) + { + OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_TRUE); + OMAPLFBBlankDisplay(psDevInfo); + } + } +} + +static void OMAPLFBEarlyResumeHandler(struct early_suspend *h) +{ + unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); + unsigned i; + + for (i=0; i < uiMaxFBDevIDPlusOne; i++) + { + OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); + + if (psDevInfo != NULL) + { + OMAPLFBUnblankDisplay(psDevInfo); + OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); + } + } +} + +#endif + +OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) +{ + int res; + OMAPLFB_ERROR eError; + + + memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); + + psDevInfo->sLINNotifBlock.notifier_call = OMAPLFBFrameBufferEvents; + + OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); + OMAPLFBAtomicIntSet(&psDevInfo->sBlankEvents, 0); + + res = fb_register_client(&psDevInfo->sLINNotifBlock); + if (res != 0) + { + printk(KERN_ERR DRIVER_PREFIX + ": %s: Device %u: fb_register_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); + + return (OMAPLFB_ERROR_GENERIC); + } + + eError = OMAPLFBUnblankDisplay(psDevInfo); + if (eError != OMAPLFB_OK) + { + printk(KERN_ERR DRIVER_PREFIX + ": %s: Device %u: UnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError); + return eError; + } + +#ifdef CONFIG_HAS_EARLYSUSPEND + psDevInfo->sEarlySuspend.suspend = OMAPLFBEarlySuspendHandler; + psDevInfo->sEarlySuspend.resume = OMAPLFBEarlyResumeHandler; + psDevInfo->sEarlySuspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1; + register_early_suspend(&psDevInfo->sEarlySuspend); +#endif + + return (OMAPLFB_OK); +} + +OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) +{ + int res; + +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&psDevInfo->sEarlySuspend); +#endif + + + res = fb_unregister_client(&psDevInfo->sLINNotifBlock); + if (res != 0) + { + printk(KERN_ERR DRIVER_PREFIX + ": %s: Device %u: fb_unregister_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); + return (OMAPLFB_ERROR_GENERIC); + } + + OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); + + return (OMAPLFB_OK); +} + +#if defined(SUPPORT_DRI_DRM) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL) +static OMAPLFB_DEVINFO *OMAPLFBPVRDevIDToDevInfo(unsigned uiPVRDevID) +{ + unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); + unsigned i; + + for (i=0; i < uiMaxFBDevIDPlusOne; i++) + { + OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); + + if (psDevInfo->uiPVRDevID == uiPVRDevID) + { + return psDevInfo; + } + } + + printk(KERN_ERR DRIVER_PREFIX + ": %s: PVR Device %u: Couldn't find device\n", __FUNCTION__, uiPVRDevID); + + return NULL; +} + +int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(struct drm_device unref__ *dev, void *arg, struct drm_file unref__ *pFile) +{ + uint32_t *puiArgs; + uint32_t uiCmd; + unsigned uiPVRDevID; + int ret = 0; + OMAPLFB_DEVINFO *psDevInfo; + + if (arg == NULL) + { + return -EFAULT; + } + + puiArgs = (uint32_t *)arg; + uiCmd = puiArgs[PVR_DRM_DISP_ARG_CMD]; + uiPVRDevID = puiArgs[PVR_DRM_DISP_ARG_DEV]; + + psDevInfo = OMAPLFBPVRDevIDToDevInfo(uiPVRDevID); + if (psDevInfo == NULL) + { + return -EINVAL; + } + + + switch (uiCmd) + { + case PVR_DRM_DISP_CMD_LEAVE_VT: + case PVR_DRM_DISP_CMD_ENTER_VT: + { + OMAPLFB_BOOL bLeaveVT = (uiCmd == PVR_DRM_DISP_CMD_LEAVE_VT); + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: %s\n", + __FUNCTION__, uiPVRDevID, + bLeaveVT ? "Leave VT" : "Enter VT")); + + OMAPLFBCreateSwapChainLock(psDevInfo); + + OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, bLeaveVT); + if (psDevInfo->psSwapChain != NULL) + { + flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); + + if (bLeaveVT) + { + OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); + (void) OMAPLFBCheckModeAndSync(psDevInfo); + } + } + + OMAPLFBCreateSwapChainUnLock(psDevInfo); + (void) OMAPLFBUnblankDisplay(psDevInfo); + break; + } + case PVR_DRM_DISP_CMD_ON: + case PVR_DRM_DISP_CMD_STANDBY: + case PVR_DRM_DISP_CMD_SUSPEND: + case PVR_DRM_DISP_CMD_OFF: + { + int iFBMode; +#if defined(DEBUG) + { + const char *pszMode; + switch(uiCmd) + { + case PVR_DRM_DISP_CMD_ON: + pszMode = "On"; + break; + case PVR_DRM_DISP_CMD_STANDBY: + pszMode = "Standby"; + break; + case PVR_DRM_DISP_CMD_SUSPEND: + pszMode = "Suspend"; + break; + case PVR_DRM_DISP_CMD_OFF: + pszMode = "Off"; + break; + default: + pszMode = "(Unknown Mode)"; + break; + } + printk(KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: Display %s\n", + __FUNCTION__, uiPVRDevID, pszMode); + } +#endif + switch(uiCmd) + { + case PVR_DRM_DISP_CMD_ON: + iFBMode = FB_BLANK_UNBLANK; + break; + case PVR_DRM_DISP_CMD_STANDBY: + iFBMode = FB_BLANK_HSYNC_SUSPEND; + break; + case PVR_DRM_DISP_CMD_SUSPEND: + iFBMode = FB_BLANK_VSYNC_SUSPEND; + break; + case PVR_DRM_DISP_CMD_OFF: + iFBMode = FB_BLANK_POWERDOWN; + break; + default: + return -EINVAL; + } + + OMAPLFBCreateSwapChainLock(psDevInfo); + + if (psDevInfo->psSwapChain != NULL) + { + flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); + } + + OMAPLFB_CONSOLE_LOCK(); + ret = fb_blank(psDevInfo->psLINFBInfo, iFBMode); + OMAPLFB_CONSOLE_UNLOCK(); + + OMAPLFBCreateSwapChainUnLock(psDevInfo); + + break; + } + default: + { + ret = -EINVAL; + break; + } + } + + return ret; +} +#endif + +#if defined(SUPPORT_DRI_DRM) +struct sgx_omaplfb_config *GetFBPlatConfig(int fbix) +{ + return NULL; +} +#else +struct sgx_omaplfb_config *GetFBPlatConfig(int fbix) +{ + if (fbix >= gplatdata->num_configs) + { + WARN(1, "Invalid FB device index"); + return NULL; + } + return &gplatdata->configs[fbix]; +} + +static int omaplfb_probe(struct platform_device *pdev) +{ + struct omaplfb_device *odev = kzalloc(sizeof(*odev), GFP_KERNEL); + + if (!odev) + return -ENOMEM; + + odev->dev = &pdev->dev; + platform_set_drvdata(pdev, odev); + gplatdata = (struct sgx_omaplfb_platform_data *)odev->dev->platform_data; + + if (!gplatdata) + { + WARN(1, "Platform data is null"); + return -ENODEV; + } + +#if !defined(CONFIG_OMAPLFB) + if(OMAPLFBInit() != OMAPLFB_OK) + { + dev_err(&pdev->dev, "failed to probe omaplfb\n"); + kfree(odev); + return -ENODEV; + } +#endif + + return 0; +} + +static int omaplfb_remove(struct platform_device *pdev) +{ + struct omaplfb_device *odev; + + odev = platform_get_drvdata(pdev); + + if(OMAPLFBDeInit() != OMAPLFB_OK) + { + dev_err(&pdev->dev, "failed to remove omaplfb\n"); + } + + gplatdata = NULL; + kfree(odev); + return 0; +} + +static struct platform_driver omaplfb_driver = { + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, + .probe = omaplfb_probe, + .remove = omaplfb_remove, +}; +#endif + +#if defined(SUPPORT_DRI_DRM) +int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev) +#else +static int __init OMAPLFB_Init(void) +#endif +{ +#if defined(SUPPORT_DRI_DRM) + if(OMAPLFBInit() != OMAPLFB_OK) + { + printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBInit failed\n", __FUNCTION__); + return -ENODEV; + } +#else + if (platform_driver_register(&omaplfb_driver)) + { + printk(KERN_ERR DRIVER_PREFIX ": %s: failed to register platform driver\n", __FUNCTION__); + return -ENODEV; + } +#endif + return 0; +} + +#if defined(SUPPORT_DRI_DRM) +void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev) +#else +static void __exit OMAPLFB_Cleanup(void) +#endif +{ +#if defined(SUPPORT_DRI_DRM) + if(OMAPLFBDeInit() != OMAPLFB_OK) + { + printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBDeInit failed\n", __FUNCTION__); + return -ENODEV; + } +#else + platform_driver_unregister(&omaplfb_driver); +#endif +} + +#if !defined(SUPPORT_DRI_DRM) +late_initcall(OMAPLFB_Init); +module_exit(OMAPLFB_Cleanup); +#endif diff --git a/drivers/video/omap2/omaplfb/servicesext.h b/drivers/video/omap2/omaplfb/servicesext.h new file mode 100644 index 0000000..62261ed --- /dev/null +++ b/drivers/video/omap2/omaplfb/servicesext.h @@ -0,0 +1,966 @@ +/*************************************************************************/ /*! +@Title Services definitions required by external drivers +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Provides services data structures, defines and prototypes + required by external drivers. +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ + +#if !defined (__SERVICESEXT_H__) +#define __SERVICESEXT_H__ + +/* + * Lock buffer read/write flags + */ +#define PVRSRV_LOCKFLG_READONLY (1) /*!< The locking process will only read the locked surface */ + +/*! + ***************************************************************************** + * Error values + * + * NOTE: If you change this, make sure you update the error texts in + * services4/include/pvrsrv_errors.h to match. + * + *****************************************************************************/ +typedef enum _PVRSRV_ERROR_ +{ + PVRSRV_OK = 0, + PVRSRV_ERROR_OUT_OF_MEMORY, + PVRSRV_ERROR_TOO_FEW_BUFFERS, + PVRSRV_ERROR_INVALID_PARAMS, + PVRSRV_ERROR_INIT_FAILURE, + PVRSRV_ERROR_CANT_REGISTER_CALLBACK, + PVRSRV_ERROR_INVALID_DEVICE, + PVRSRV_ERROR_NOT_OWNER, + PVRSRV_ERROR_BAD_MAPPING, + PVRSRV_ERROR_TIMEOUT, + PVRSRV_ERROR_FLIP_CHAIN_EXISTS, + PVRSRV_ERROR_INVALID_SWAPINTERVAL, + PVRSRV_ERROR_SCENE_INVALID, + PVRSRV_ERROR_STREAM_ERROR, + PVRSRV_ERROR_FAILED_DEPENDENCIES, + PVRSRV_ERROR_CMD_NOT_PROCESSED, + PVRSRV_ERROR_CMD_TOO_BIG, + PVRSRV_ERROR_DEVICE_REGISTER_FAILED, + PVRSRV_ERROR_TOOMANYBUFFERS, + PVRSRV_ERROR_NOT_SUPPORTED, + PVRSRV_ERROR_PROCESSING_BLOCKED, + + PVRSRV_ERROR_CANNOT_FLUSH_QUEUE, + PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE, + PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS, + PVRSRV_ERROR_RETRY, + + PVRSRV_ERROR_DDK_VERSION_MISMATCH, + PVRSRV_ERROR_BUILD_MISMATCH, + PVRSRV_ERROR_CORE_REVISION_MISMATCH, + + PVRSRV_ERROR_UPLOAD_TOO_BIG, + + PVRSRV_ERROR_INVALID_FLAGS, + PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS, + + PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY, + PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR, + PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED, + + PVRSRV_ERROR_BRIDGE_CALL_FAILED, + PVRSRV_ERROR_IOCTL_CALL_FAILED, + + PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND, + PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND, + PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT, + + PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND, + PVRSRV_ERROR_PCI_CALL_FAILED, + PVRSRV_ERROR_PCI_REGION_TOO_SMALL, + PVRSRV_ERROR_PCI_REGION_UNAVAILABLE, + PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH, + + PVRSRV_ERROR_REGISTER_BASE_NOT_SET, + + PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE, + + PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM, + PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY, + PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC, + PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR, + + PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY, + PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY, + + PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES, + PVRSRV_ERROR_FAILED_TO_FREE_PAGES, + PVRSRV_ERROR_FAILED_TO_COPY_PAGES, + PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES, + PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES, + PVRSRV_ERROR_STILL_MAPPED, + PVRSRV_ERROR_MAPPING_NOT_FOUND, + PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT, + PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE, + + PVRSRV_ERROR_INVALID_SEGMENT_BLOCK, + PVRSRV_ERROR_INVALID_SGXDEVDATA, + PVRSRV_ERROR_INVALID_DEVINFO, + PVRSRV_ERROR_INVALID_MEMINFO, + PVRSRV_ERROR_INVALID_MISCINFO, + PVRSRV_ERROR_UNKNOWN_IOCTL, + PVRSRV_ERROR_INVALID_CONTEXT, + PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT, + PVRSRV_ERROR_INVALID_HEAP, + PVRSRV_ERROR_INVALID_KERNELINFO, + PVRSRV_ERROR_UNKNOWN_POWER_STATE, + PVRSRV_ERROR_INVALID_HANDLE_TYPE, + PVRSRV_ERROR_INVALID_WRAP_TYPE, + PVRSRV_ERROR_INVALID_PHYS_ADDR, + PVRSRV_ERROR_INVALID_CPU_ADDR, + PVRSRV_ERROR_INVALID_HEAPINFO, + PVRSRV_ERROR_INVALID_PERPROC, + PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO, + PVRSRV_ERROR_INVALID_MAP_REQUEST, + PVRSRV_ERROR_INVALID_UNMAP_REQUEST, + PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP, + PVRSRV_ERROR_MAPPING_STILL_IN_USE, + + PVRSRV_ERROR_EXCEEDED_HW_LIMITS, + PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED, + + PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA, + PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT, + PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT, + PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT, + PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT, + PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD, + PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD, + PVRSRV_ERROR_THREAD_READ_ERROR, + PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER, + PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR, + PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR, + PVRSRV_ERROR_ISR_ALREADY_INSTALLED, + PVRSRV_ERROR_ISR_NOT_INSTALLED, + PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT, + PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO, + PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT, + PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES, + PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT, + PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE, + PVRSRV_ERROR_UNABLE_TO_CLOSE_HANDLE, + + PVRSRV_ERROR_INVALID_CCB_COMMAND, + + PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE, + PVRSRV_ERROR_INVALID_LOCK_ID, + PVRSRV_ERROR_RESOURCE_NOT_LOCKED, + + PVRSRV_ERROR_FLIP_FAILED, + PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED, + + PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE, + + PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED, + PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG, + PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG, + PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG, + + PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID, + + PVRSRV_ERROR_BLIT_SETUP_FAILED, + + PVRSRV_ERROR_PDUMP_NOT_AVAILABLE, + PVRSRV_ERROR_PDUMP_BUFFER_FULL, + PVRSRV_ERROR_PDUMP_BUF_OVERFLOW, + PVRSRV_ERROR_PDUMP_NOT_ACTIVE, + PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES, + + PVRSRV_ERROR_MUTEX_DESTROY_FAILED, + PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR, + + PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE, + PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND, + + PVRSRV_ERROR_PROCESS_NOT_INITIALISED, + PVRSRV_ERROR_PROCESS_NOT_FOUND, + PVRSRV_ERROR_SRV_CONNECT_FAILED, + PVRSRV_ERROR_SRV_DISCONNECT_FAILED, + PVRSRV_ERROR_DEINT_PHASE_FAILED, + PVRSRV_ERROR_INIT2_PHASE_FAILED, + + PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE, + + PVRSRV_ERROR_NO_DC_DEVICES_FOUND, + PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE, + PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE, + PVRSRV_ERROR_NO_DEVICEDATA_FOUND, + PVRSRV_ERROR_NO_DEVICENODE_FOUND, + PVRSRV_ERROR_NO_CLIENTNODE_FOUND, + PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE, + + PVRSRV_ERROR_UNABLE_TO_INIT_TASK, + PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK, + PVRSRV_ERROR_UNABLE_TO_KILL_TASK, + + PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER, + PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER, + PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER, + + PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT, + PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION, + + PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE, + PVRSRV_ERROR_HANDLE_NOT_ALLOCATED, + PVRSRV_ERROR_HANDLE_TYPE_MISMATCH, + PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE, + PVRSRV_ERROR_HANDLE_NOT_SHAREABLE, + PVRSRV_ERROR_HANDLE_NOT_FOUND, + PVRSRV_ERROR_INVALID_SUBHANDLE, + PVRSRV_ERROR_HANDLE_BATCH_IN_USE, + PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE, + + PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE, + PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED, + + PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE, + PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP, + + PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE, + + PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE, + PVRSRV_ERROR_INVALID_DEVICEID, + PVRSRV_ERROR_DEVICEID_NOT_FOUND, + + PVRSRV_ERROR_MEMORY_TEST_FAILED, + PVRSRV_ERROR_CPUPADDR_TEST_FAILED, + PVRSRV_ERROR_COPY_TEST_FAILED, + + PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED, + + PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK, + PVRSRV_ERROR_CLOCK_REQUEST_FAILED, + PVRSRV_ERROR_DISABLE_CLOCK_FAILURE, + PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE, + PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE, + PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK, + PVRSRV_ERROR_UNABLE_TO_GET_CLOCK, + PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK, + PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK, + + PVRSRV_ERROR_UNKNOWN_SGL_ERROR, + + PVRSRV_ERROR_SYSTEM_POWER_CHANGE_FAILURE, + PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE, + + PVRSRV_ERROR_BAD_SYNC_STATE, + + PVRSRV_ERROR_CACHEOP_FAILED, + + PVRSRV_ERROR_CACHE_INVALIDATE_FAILED, + + PVRSRV_ERROR_FORCE_I32 = 0x7fffffff + +} PVRSRV_ERROR; + + +/*! + ***************************************************************************** + * List of known device classes. + *****************************************************************************/ +typedef enum _PVRSRV_DEVICE_CLASS_ +{ + PVRSRV_DEVICE_CLASS_3D = 0 , + PVRSRV_DEVICE_CLASS_DISPLAY = 1 , + PVRSRV_DEVICE_CLASS_BUFFER = 2 , + PVRSRV_DEVICE_CLASS_VIDEO = 3 , + + PVRSRV_DEVICE_CLASS_FORCE_I32 = 0x7fffffff + +} PVRSRV_DEVICE_CLASS; + + +/*! + ***************************************************************************** + * States for power management + *****************************************************************************/ +typedef enum _PVRSRV_SYS_POWER_STATE_ +{ + PVRSRV_SYS_POWER_STATE_Unspecified = -1, /*!< Unspecified : Uninitialised */ + PVRSRV_SYS_POWER_STATE_D0 = 0, /*!< On */ + PVRSRV_SYS_POWER_STATE_D1 = 1, /*!< User Idle */ + PVRSRV_SYS_POWER_STATE_D2 = 2, /*!< System Idle / sleep */ + PVRSRV_SYS_POWER_STATE_D3 = 3, /*!< Suspend / Hibernate */ + PVRSRV_SYS_POWER_STATE_D4 = 4, /*!< shutdown */ + + PVRSRV_SYS_POWER_STATE_FORCE_I32 = 0x7fffffff + +} PVRSRV_SYS_POWER_STATE, *PPVRSRV_SYS_POWER_STATE; + + +typedef enum _PVRSRV_DEV_POWER_STATE_ +{ + PVRSRV_DEV_POWER_STATE_DEFAULT = -1, /*!< Default state for the device */ + PVRSRV_DEV_POWER_STATE_ON = 0, /*!< Running */ + PVRSRV_DEV_POWER_STATE_IDLE = 1, /*!< Powered but operation paused */ + PVRSRV_DEV_POWER_STATE_OFF = 2, /*!< Unpowered */ + + PVRSRV_DEV_POWER_STATE_FORCE_I32 = 0x7fffffff + +} PVRSRV_DEV_POWER_STATE, *PPVRSRV_DEV_POWER_STATE; /* PRQA S 3205 */ + + +/* Power transition handler prototypes */ +typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE hDevHandle, + PVRSRV_DEV_POWER_STATE eNewPowerState, + PVRSRV_DEV_POWER_STATE eCurrentPowerState); +typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE hDevHandle, + PVRSRV_DEV_POWER_STATE eNewPowerState, + PVRSRV_DEV_POWER_STATE eCurrentPowerState); + +/* Clock speed handler prototypes */ +typedef PVRSRV_ERROR (*PFN_PRE_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle, + IMG_BOOL bIdleDevice, + PVRSRV_DEV_POWER_STATE eCurrentPowerState); +typedef PVRSRV_ERROR (*PFN_POST_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle, + IMG_BOOL bIdleDevice, + PVRSRV_DEV_POWER_STATE eCurrentPowerState); + + +/***************************************************************************** + * Enumeration of all possible pixel types. Where applicable, Ordering of name + * is in reverse order of memory bytes (i.e. as a word in little endian). + * e.g. A8R8G8B8 is in memory as 4 bytes in order: BB GG RR AA + * + * NOTE: When modifying this structure please update the client driver format + * tables located in %WORKROOT%/eurasia/codegen/pixfmts using the tool + * located in %WORKROOT%/eurasia/tools/intern/TextureFormatParser. + * + *****************************************************************************/ +typedef enum _PVRSRV_PIXEL_FORMAT_ { + /* Basic types */ + PVRSRV_PIXEL_FORMAT_UNKNOWN = 0, + PVRSRV_PIXEL_FORMAT_RGB565 = 1, + PVRSRV_PIXEL_FORMAT_RGB555 = 2, + PVRSRV_PIXEL_FORMAT_RGB888 = 3, /*!< 24bit */ + PVRSRV_PIXEL_FORMAT_BGR888 = 4, /*!< 24bit */ + PVRSRV_PIXEL_FORMAT_GREY_SCALE = 8, + PVRSRV_PIXEL_FORMAT_PAL12 = 13, + PVRSRV_PIXEL_FORMAT_PAL8 = 14, + PVRSRV_PIXEL_FORMAT_PAL4 = 15, + PVRSRV_PIXEL_FORMAT_PAL2 = 16, + PVRSRV_PIXEL_FORMAT_PAL1 = 17, + PVRSRV_PIXEL_FORMAT_ARGB1555 = 18, + PVRSRV_PIXEL_FORMAT_ARGB4444 = 19, + PVRSRV_PIXEL_FORMAT_ARGB8888 = 20, + PVRSRV_PIXEL_FORMAT_ABGR8888 = 21, + PVRSRV_PIXEL_FORMAT_YV12 = 22, + PVRSRV_PIXEL_FORMAT_I420 = 23, + PVRSRV_PIXEL_FORMAT_IMC2 = 25, + PVRSRV_PIXEL_FORMAT_XRGB8888 = 26, + PVRSRV_PIXEL_FORMAT_XBGR8888 = 27, + PVRSRV_PIXEL_FORMAT_BGRA8888 = 28, + PVRSRV_PIXEL_FORMAT_XRGB4444 = 29, + PVRSRV_PIXEL_FORMAT_ARGB8332 = 30, + PVRSRV_PIXEL_FORMAT_A2RGB10 = 31, /*!< 32bpp, 10 bits for R, G, B, 2 bits for A */ + PVRSRV_PIXEL_FORMAT_A2BGR10 = 32, /*!< 32bpp, 10 bits for B, G, R, 2 bits for A */ + PVRSRV_PIXEL_FORMAT_P8 = 33, + PVRSRV_PIXEL_FORMAT_L8 = 34, + PVRSRV_PIXEL_FORMAT_A8L8 = 35, + PVRSRV_PIXEL_FORMAT_A4L4 = 36, + PVRSRV_PIXEL_FORMAT_L16 = 37, + PVRSRV_PIXEL_FORMAT_L6V5U5 = 38, + PVRSRV_PIXEL_FORMAT_V8U8 = 39, + PVRSRV_PIXEL_FORMAT_V16U16 = 40, + PVRSRV_PIXEL_FORMAT_QWVU8888 = 41, + PVRSRV_PIXEL_FORMAT_XLVU8888 = 42, + PVRSRV_PIXEL_FORMAT_QWVU16 = 43, + PVRSRV_PIXEL_FORMAT_D16 = 44, + PVRSRV_PIXEL_FORMAT_D24S8 = 45, + PVRSRV_PIXEL_FORMAT_D24X8 = 46, + + /* Added to ensure TQ build */ + PVRSRV_PIXEL_FORMAT_ABGR16 = 47, + PVRSRV_PIXEL_FORMAT_ABGR16F = 48, + PVRSRV_PIXEL_FORMAT_ABGR32 = 49, + PVRSRV_PIXEL_FORMAT_ABGR32F = 50, + PVRSRV_PIXEL_FORMAT_B10GR11 = 51, + PVRSRV_PIXEL_FORMAT_GR88 = 52, + PVRSRV_PIXEL_FORMAT_BGR32 = 53, + PVRSRV_PIXEL_FORMAT_GR32 = 54, + PVRSRV_PIXEL_FORMAT_E5BGR9 = 55, + + /* reserved types */ + PVRSRV_PIXEL_FORMAT_RESERVED1 = 56, + PVRSRV_PIXEL_FORMAT_RESERVED2 = 57, + PVRSRV_PIXEL_FORMAT_RESERVED3 = 58, + PVRSRV_PIXEL_FORMAT_RESERVED4 = 59, + PVRSRV_PIXEL_FORMAT_RESERVED5 = 60, + + /* RGB space packed formats */ + PVRSRV_PIXEL_FORMAT_R8G8_B8G8 = 61, + PVRSRV_PIXEL_FORMAT_G8R8_G8B8 = 62, + + /* YUV space planar formats */ + PVRSRV_PIXEL_FORMAT_NV11 = 63, + PVRSRV_PIXEL_FORMAT_NV12 = 64, + + /* YUV space packed formats */ + PVRSRV_PIXEL_FORMAT_YUY2 = 65, + PVRSRV_PIXEL_FORMAT_YUV420 = 66, + PVRSRV_PIXEL_FORMAT_YUV444 = 67, + PVRSRV_PIXEL_FORMAT_VUY444 = 68, + PVRSRV_PIXEL_FORMAT_YUYV = 69, + PVRSRV_PIXEL_FORMAT_YVYU = 70, + PVRSRV_PIXEL_FORMAT_UYVY = 71, + PVRSRV_PIXEL_FORMAT_VYUY = 72, + + PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY = 73, /*!< See http://www.fourcc.org/yuv.php#UYVY */ + PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV = 74, /*!< See http://www.fourcc.org/yuv.php#YUYV */ + PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU = 75, /*!< See http://www.fourcc.org/yuv.php#YVYU */ + PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY = 76, /*!< No fourcc.org link */ + PVRSRV_PIXEL_FORMAT_FOURCC_ORG_AYUV = 77, /*!< See http://www.fourcc.org/yuv.php#AYUV */ + + /* 4 component, 32 bits per component types */ + PVRSRV_PIXEL_FORMAT_A32B32G32R32 = 78, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_A32B32G32R32F = 79, /*!< float type */ + PVRSRV_PIXEL_FORMAT_A32B32G32R32_UINT = 80, /*!< uint type */ + PVRSRV_PIXEL_FORMAT_A32B32G32R32_SINT = 81, /*!< sint type */ + + /* 3 component, 32 bits per component types */ + PVRSRV_PIXEL_FORMAT_B32G32R32 = 82, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_B32G32R32F = 83, /*!< float data */ + PVRSRV_PIXEL_FORMAT_B32G32R32_UINT = 84, /*!< uint data */ + PVRSRV_PIXEL_FORMAT_B32G32R32_SINT = 85, /*!< signed int data */ + + /* 2 component, 32 bits per component types */ + PVRSRV_PIXEL_FORMAT_G32R32 = 86, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_G32R32F = 87, /*!< float */ + PVRSRV_PIXEL_FORMAT_G32R32_UINT = 88, /*!< uint */ + PVRSRV_PIXEL_FORMAT_G32R32_SINT = 89, /*!< signed int */ + + /* 1 component, 32 bits per component types */ + PVRSRV_PIXEL_FORMAT_D32F = 90, /*!< float depth */ + PVRSRV_PIXEL_FORMAT_R32 = 91, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_R32F = 92, /*!< float type */ + PVRSRV_PIXEL_FORMAT_R32_UINT = 93, /*!< unsigned int type */ + PVRSRV_PIXEL_FORMAT_R32_SINT = 94, /*!< signed int type */ + + /* 4 component, 16 bits per component types */ + PVRSRV_PIXEL_FORMAT_A16B16G16R16 = 95, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_A16B16G16R16F = 96, /*!< type float */ + PVRSRV_PIXEL_FORMAT_A16B16G16R16_SINT = 97, /*!< signed ints */ + PVRSRV_PIXEL_FORMAT_A16B16G16R16_SNORM = 98, /*!< signed normalised int */ + PVRSRV_PIXEL_FORMAT_A16B16G16R16_UINT = 99, /*!< unsigned ints */ + PVRSRV_PIXEL_FORMAT_A16B16G16R16_UNORM = 100, /*!< normalised unsigned int */ + + /* 2 component, 16 bits per component types */ + PVRSRV_PIXEL_FORMAT_G16R16 = 101, /*!< unspecified type */ + PVRSRV_PIXEL_FORMAT_G16R16F = 102, /*!< float type */ + PVRSRV_PIXEL_FORMAT_G16R16_UINT = 103, /*!< unsigned int type */ + PVRSRV_PIXEL_FORMAT_G16R16_UNORM = 104, /*!< unsigned normalised */ + PVRSRV_PIXEL_FORMAT_G16R16_SINT = 105, /*!< signed int */ + PVRSRV_PIXEL_FORMAT_G16R16_SNORM = 106, /*!< signed normalised */ + + /* 1 component, 16 bits per component types */ + PVRSRV_PIXEL_FORMAT_R16 = 107, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_R16F = 108, /*!< float type */ + PVRSRV_PIXEL_FORMAT_R16_UINT = 109, /*!< unsigned int type */ + PVRSRV_PIXEL_FORMAT_R16_UNORM = 110, /*!< unsigned normalised int type */ + PVRSRV_PIXEL_FORMAT_R16_SINT = 111, /*!< signed int type */ + PVRSRV_PIXEL_FORMAT_R16_SNORM = 112, /*!< signed normalised int type */ + + /* 4 component, 8 bits per component types */ + PVRSRV_PIXEL_FORMAT_X8R8G8B8 = 113, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM = 114, /*!< normalised unsigned int */ + PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM_SRGB = 115, /*!< normalised uint with sRGB */ + + PVRSRV_PIXEL_FORMAT_A8R8G8B8 = 116, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM = 117, /*!< normalised unsigned int */ + PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM_SRGB = 118, /*!< normalised uint with sRGB */ + + PVRSRV_PIXEL_FORMAT_A8B8G8R8 = 119, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_A8B8G8R8_UINT = 120, /*!< unsigned int */ + PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM = 121, /*!< normalised unsigned int */ + PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM_SRGB = 122, /*!< normalised unsigned int */ + PVRSRV_PIXEL_FORMAT_A8B8G8R8_SINT = 123, /*!< signed int */ + PVRSRV_PIXEL_FORMAT_A8B8G8R8_SNORM = 124, /*!< normalised signed int */ + + /* 2 component, 8 bits per component types */ + PVRSRV_PIXEL_FORMAT_G8R8 = 125, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_G8R8_UINT = 126, /*!< unsigned int type */ + PVRSRV_PIXEL_FORMAT_G8R8_UNORM = 127, /*!< unsigned int normalised */ + PVRSRV_PIXEL_FORMAT_G8R8_SINT = 128, /*!< signed int type */ + PVRSRV_PIXEL_FORMAT_G8R8_SNORM = 129, /*!< signed int normalised */ + + /* 1 component, 8 bits per component types */ + PVRSRV_PIXEL_FORMAT_A8 = 130, /*!< type unspecified, alpha channel */ + PVRSRV_PIXEL_FORMAT_R8 = 131, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_R8_UINT = 132, /*!< unsigned int */ + PVRSRV_PIXEL_FORMAT_R8_UNORM = 133, /*!< unsigned normalised int */ + PVRSRV_PIXEL_FORMAT_R8_SINT = 134, /*!< signed int */ + PVRSRV_PIXEL_FORMAT_R8_SNORM = 135, /*!< signed normalised int */ + + /* A2RGB10 types */ + PVRSRV_PIXEL_FORMAT_A2B10G10R10 = 136, /*!< Type unspecified */ + PVRSRV_PIXEL_FORMAT_A2B10G10R10_UNORM = 137, /*!< normalised unsigned int */ + PVRSRV_PIXEL_FORMAT_A2B10G10R10_UINT = 138, /*!< unsigned int */ + + /* F11F11F10 types */ + PVRSRV_PIXEL_FORMAT_B10G11R11 = 139, /*!< type unspecified */ + PVRSRV_PIXEL_FORMAT_B10G11R11F = 140, /*!< float type */ + + /* esoteric types */ + PVRSRV_PIXEL_FORMAT_X24G8R32 = 141, /*!< 64 bit, type unspecified (Usually typed to D32S8 style) */ + PVRSRV_PIXEL_FORMAT_G8R24 = 142, /*!< 32 bit, type unspecified (Usually typed to D24S8 style) */ + PVRSRV_PIXEL_FORMAT_X8R24 = 143, + PVRSRV_PIXEL_FORMAT_E5B9G9R9 = 144, /*!< 32 bit, shared exponent (RGBE). */ + PVRSRV_PIXEL_FORMAT_R1 = 145, /*!< 1 bit monochrome */ + + PVRSRV_PIXEL_FORMAT_RESERVED6 = 146, + PVRSRV_PIXEL_FORMAT_RESERVED7 = 147, + PVRSRV_PIXEL_FORMAT_RESERVED8 = 148, + PVRSRV_PIXEL_FORMAT_RESERVED9 = 149, + PVRSRV_PIXEL_FORMAT_RESERVED10 = 150, + PVRSRV_PIXEL_FORMAT_RESERVED11 = 151, + PVRSRV_PIXEL_FORMAT_RESERVED12 = 152, + PVRSRV_PIXEL_FORMAT_RESERVED13 = 153, + PVRSRV_PIXEL_FORMAT_RESERVED14 = 154, + PVRSRV_PIXEL_FORMAT_RESERVED15 = 155, + PVRSRV_PIXEL_FORMAT_RESERVED16 = 156, + PVRSRV_PIXEL_FORMAT_RESERVED17 = 157, + PVRSRV_PIXEL_FORMAT_RESERVED18 = 158, + PVRSRV_PIXEL_FORMAT_RESERVED19 = 159, + PVRSRV_PIXEL_FORMAT_RESERVED20 = 160, + + /* DXLegacy vertex types */ + PVRSRV_PIXEL_FORMAT_UBYTE4 = 161, /*!< 4 channels, 1 byte per channel, normalised */ + PVRSRV_PIXEL_FORMAT_SHORT4 = 162, /*!< 4 signed channels, 16 bits each, unnormalised */ + PVRSRV_PIXEL_FORMAT_SHORT4N = 163, /*!< 4 signed channels, 16 bits each, normalised */ + PVRSRV_PIXEL_FORMAT_USHORT4N = 164, /*!< 4 unsigned channels, 16 bits each, normalised */ + PVRSRV_PIXEL_FORMAT_SHORT2N = 165, /*!< 2 signed channels, 16 bits each, normalised */ + PVRSRV_PIXEL_FORMAT_SHORT2 = 166, /*!< 2 signed channels, 16 bits each, unnormalised */ + PVRSRV_PIXEL_FORMAT_USHORT2N = 167, /*!< 2 unsigned channels, 16 bits each, normalised */ + PVRSRV_PIXEL_FORMAT_UDEC3 = 168, /*!< 3 10-bit channels, unnormalised, unsigned*/ + PVRSRV_PIXEL_FORMAT_DEC3N = 169, /*!< 3 10-bit channels, signed normalised */ + PVRSRV_PIXEL_FORMAT_F16_2 = 170, /*!< 2 F16 channels */ + PVRSRV_PIXEL_FORMAT_F16_4 = 171, /*!< 4 F16 channels */ + + /* misc float types */ + PVRSRV_PIXEL_FORMAT_L_F16 = 172, + PVRSRV_PIXEL_FORMAT_L_F16_REP = 173, + PVRSRV_PIXEL_FORMAT_L_F16_A_F16 = 174, + PVRSRV_PIXEL_FORMAT_A_F16 = 175, + PVRSRV_PIXEL_FORMAT_B16G16R16F = 176, + + PVRSRV_PIXEL_FORMAT_L_F32 = 177, + PVRSRV_PIXEL_FORMAT_A_F32 = 178, + PVRSRV_PIXEL_FORMAT_L_F32_A_F32 = 179, + + /* powervr types */ + PVRSRV_PIXEL_FORMAT_PVRTC2 = 180, + PVRSRV_PIXEL_FORMAT_PVRTC4 = 181, + PVRSRV_PIXEL_FORMAT_PVRTCII2 = 182, + PVRSRV_PIXEL_FORMAT_PVRTCII4 = 183, + PVRSRV_PIXEL_FORMAT_PVRTCIII = 184, + PVRSRV_PIXEL_FORMAT_PVRO8 = 185, + PVRSRV_PIXEL_FORMAT_PVRO88 = 186, + PVRSRV_PIXEL_FORMAT_PT1 = 187, + PVRSRV_PIXEL_FORMAT_PT2 = 188, + PVRSRV_PIXEL_FORMAT_PT4 = 189, + PVRSRV_PIXEL_FORMAT_PT8 = 190, + PVRSRV_PIXEL_FORMAT_PTW = 191, + PVRSRV_PIXEL_FORMAT_PTB = 192, + PVRSRV_PIXEL_FORMAT_MONO8 = 193, + PVRSRV_PIXEL_FORMAT_MONO16 = 194, + + /* additional YUV types */ + PVRSRV_PIXEL_FORMAT_C0_YUYV = 195, + PVRSRV_PIXEL_FORMAT_C0_UYVY = 196, + PVRSRV_PIXEL_FORMAT_C0_YVYU = 197, + PVRSRV_PIXEL_FORMAT_C0_VYUY = 198, + PVRSRV_PIXEL_FORMAT_C1_YUYV = 199, + PVRSRV_PIXEL_FORMAT_C1_UYVY = 200, + PVRSRV_PIXEL_FORMAT_C1_YVYU = 201, + PVRSRV_PIXEL_FORMAT_C1_VYUY = 202, + + /* planar YUV types */ + PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_UV = 203, + PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_VU = 204, + PVRSRV_PIXEL_FORMAT_C0_YUV420_3P = 205, + PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_UV = 206, + PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_VU = 207, + PVRSRV_PIXEL_FORMAT_C1_YUV420_3P = 208, + + PVRSRV_PIXEL_FORMAT_A2B10G10R10F = 209, + PVRSRV_PIXEL_FORMAT_B8G8R8_SINT = 210, + PVRSRV_PIXEL_FORMAT_PVRF32SIGNMASK = 211, + + PVRSRV_PIXEL_FORMAT_ABGR4444 = 212, + PVRSRV_PIXEL_FORMAT_ABGR1555 = 213, + PVRSRV_PIXEL_FORMAT_BGR565 = 214, + + /* 4k aligned planar YUV */ + PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_UV = 215, + PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_VU = 216, + PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_UV = 217, + PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_VU = 218, + PVRSRV_PIXEL_FORMAT_P208 = 219, + PVRSRV_PIXEL_FORMAT_A8P8 = 220, + + PVRSRV_PIXEL_FORMAT_A4 = 221, + PVRSRV_PIXEL_FORMAT_AYUV8888 = 222, + PVRSRV_PIXEL_FORMAT_RAW256 = 223, + PVRSRV_PIXEL_FORMAT_RAW512 = 224, + PVRSRV_PIXEL_FORMAT_RAW1024 = 225, + + PVRSRV_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff + +} PVRSRV_PIXEL_FORMAT; + +/*! + ***************************************************************************** + * Enumeration of possible alpha types. + *****************************************************************************/ +typedef enum _PVRSRV_ALPHA_FORMAT_ { + PVRSRV_ALPHA_FORMAT_UNKNOWN = 0x00000000, + PVRSRV_ALPHA_FORMAT_PRE = 0x00000001, + PVRSRV_ALPHA_FORMAT_NONPRE = 0x00000002, + PVRSRV_ALPHA_FORMAT_MASK = 0x0000000F, +} PVRSRV_ALPHA_FORMAT; + +/*! + ***************************************************************************** + * Enumeration of possible alpha types. + *****************************************************************************/ +typedef enum _PVRSRV_COLOURSPACE_FORMAT_ { + PVRSRV_COLOURSPACE_FORMAT_UNKNOWN = 0x00000000, + PVRSRV_COLOURSPACE_FORMAT_LINEAR = 0x00010000, + PVRSRV_COLOURSPACE_FORMAT_NONLINEAR = 0x00020000, + PVRSRV_COLOURSPACE_FORMAT_MASK = 0x000F0000, +} PVRSRV_COLOURSPACE_FORMAT; + + +/* + * Drawable orientation (in degrees clockwise). + * Opposite sense from WSEGL. + */ +typedef enum _PVRSRV_ROTATION_ { + PVRSRV_ROTATE_0 = 0, + PVRSRV_ROTATE_90 = 1, + PVRSRV_ROTATE_180 = 2, + PVRSRV_ROTATE_270 = 3, + PVRSRV_FLIP_Y + +} PVRSRV_ROTATION; + +/*! + * Flags for DisplayClassCreateSwapChain. + */ +#define PVRSRV_CREATE_SWAPCHAIN_SHARED (1<<0) +#define PVRSRV_CREATE_SWAPCHAIN_QUERY (1<<1) +#define PVRSRV_CREATE_SWAPCHAIN_OEMOVERLAY (1<<2) + +/*! + ***************************************************************************** + * Structure providing implementation details for serialisation and + * synchronisation of operations. This is the fundamental unit on which operations + * are synced, and would typically be included in any data structures that require + * serialised accesses etc. e.g. MEM_INFO structures + * + *****************************************************************************/ +/* + Sync Data to be shared/mapped between user/kernel +*/ +typedef struct _PVRSRV_SYNC_DATA_ +{ + /* CPU accessible WriteOp Info */ + IMG_UINT32 ui32WriteOpsPending; + volatile IMG_UINT32 ui32WriteOpsComplete; + + /* CPU accessible ReadOp Info */ + IMG_UINT32 ui32ReadOpsPending; + volatile IMG_UINT32 ui32ReadOpsComplete; + + /* CPU accessible ReadOp2 Info */ + IMG_UINT32 ui32ReadOps2Pending; + volatile IMG_UINT32 ui32ReadOps2Complete; + + /* pdump specific value */ + IMG_UINT32 ui32LastOpDumpVal; + IMG_UINT32 ui32LastReadOpDumpVal; + + /* Last write oprtation on this sync */ + IMG_UINT64 ui64LastWrite; + +} PVRSRV_SYNC_DATA; + +/* + Client Sync Info structure +*/ +typedef struct _PVRSRV_CLIENT_SYNC_INFO_ +{ + /* mapping of the kernel sync data */ + PVRSRV_SYNC_DATA *psSyncData; + + /* Device accessible WriteOp Info */ + IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; + + /* Device accessible ReadOp Info */ + IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; + + /* Device accessible ReadOp2 Info */ + IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr; + + /* handle to client mapping data (OS specific) */ +#if defined (SUPPORT_SID_INTERFACE) + IMG_SID hMappingInfo; + + /* handle to kernel sync info */ + IMG_SID hKernelSyncInfo; +#else + IMG_HANDLE hMappingInfo; + + /* handle to kernel sync info */ + IMG_HANDLE hKernelSyncInfo; +#endif + +} PVRSRV_CLIENT_SYNC_INFO, *PPVRSRV_CLIENT_SYNC_INFO; + +/*! + ***************************************************************************** + * Resource locking structure + *****************************************************************************/ +typedef struct PVRSRV_RESOURCE_TAG +{ + volatile IMG_UINT32 ui32Lock; + IMG_UINT32 ui32ID; +}PVRSRV_RESOURCE; +typedef PVRSRV_RESOURCE PVRSRV_RES_HANDLE; + + +/* command complete callback pfn prototype */ +typedef IMG_VOID (*PFN_CMD_COMPLETE) (IMG_HANDLE); +typedef IMG_VOID (**PPFN_CMD_COMPLETE) (IMG_HANDLE); + +/* private command handler prototype */ +typedef IMG_BOOL (*PFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*); +typedef IMG_BOOL (**PPFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*); + + +/* + rectangle structure required by Lock API +*/ +typedef struct _IMG_RECT_ +{ + IMG_INT32 x0; + IMG_INT32 y0; + IMG_INT32 x1; + IMG_INT32 y1; +}IMG_RECT; + +typedef struct _IMG_RECT_16_ +{ + IMG_INT16 x0; + IMG_INT16 y0; + IMG_INT16 x1; + IMG_INT16 y1; +}IMG_RECT_16; + + +/* common pfn between BC/DC */ +typedef PVRSRV_ERROR (*PFN_GET_BUFFER_ADDR)(IMG_HANDLE, + IMG_HANDLE, + IMG_SYS_PHYADDR**, + IMG_SIZE_T*, + IMG_VOID**, + IMG_HANDLE*, + IMG_BOOL*, + IMG_UINT32*); + + +/* + Display dimension structure definition +*/ +typedef struct DISPLAY_DIMS_TAG +{ + IMG_UINT32 ui32ByteStride; + IMG_UINT32 ui32Width; + IMG_UINT32 ui32Height; +} DISPLAY_DIMS; + + +/* + Display format structure definition +*/ +typedef struct DISPLAY_FORMAT_TAG +{ + /* pixel format type */ + PVRSRV_PIXEL_FORMAT pixelformat; +} DISPLAY_FORMAT; + +/* + Display Surface Attributes structure definition +*/ +typedef struct DISPLAY_SURF_ATTRIBUTES_TAG +{ + /* pixel format type */ + PVRSRV_PIXEL_FORMAT pixelformat; + /* dimensions information structure array */ + DISPLAY_DIMS sDims; +} DISPLAY_SURF_ATTRIBUTES; + + +/* + Display Mode information structure definition +*/ +typedef struct DISPLAY_MODE_INFO_TAG +{ + /* pixel format type */ + PVRSRV_PIXEL_FORMAT pixelformat; + /* dimensions information structure array */ + DISPLAY_DIMS sDims; + /* refresh rate of the display */ + IMG_UINT32 ui32RefreshHZ; + /* OEM specific flags */ + IMG_UINT32 ui32OEMFlags; +} DISPLAY_MODE_INFO; + + + +#define MAX_DISPLAY_NAME_SIZE (50) /* arbitrary choice! */ + +/* + Display info structure definition +*/ +typedef struct DISPLAY_INFO_TAG +{ + /* max swapchains supported */ + IMG_UINT32 ui32MaxSwapChains; + /* max buffers in a swapchain */ + IMG_UINT32 ui32MaxSwapChainBuffers; + /* min swap interval supported */ + IMG_UINT32 ui32MinSwapInterval; + /* max swap interval supported */ + IMG_UINT32 ui32MaxSwapInterval; + /* physical dimensions of the display required for DPI calc. */ + IMG_UINT32 ui32PhysicalWidthmm; + IMG_UINT32 ui32PhysicalHeightmm; + /* display name */ + IMG_CHAR szDisplayName[MAX_DISPLAY_NAME_SIZE]; +#if defined(SUPPORT_HW_CURSOR) + /* cursor dimensions */ + IMG_UINT16 ui32CursorWidth; + IMG_UINT16 ui32CursorHeight; +#endif +} DISPLAY_INFO; + +typedef struct ACCESS_INFO_TAG +{ + IMG_UINT32 ui32Size; + IMG_UINT32 ui32FBPhysBaseAddress; + IMG_UINT32 ui32FBMemAvailable; /* size of usable FB memory */ + IMG_UINT32 ui32SysPhysBaseAddress; + IMG_UINT32 ui32SysSize; + IMG_UINT32 ui32DevIRQ; +}ACCESS_INFO; + + + +#if defined(PDUMP_SUSPEND_IS_PER_THREAD) +/** Present only on WinMobile 6.5 */ + +typedef struct { + IMG_UINT32 threadId; + IMG_INT suspendCount; +} PVRSRV_THREAD_SUSPEND_COUNT; + +#define PVRSRV_PDUMP_SUSPEND_Q_NAME "PVRSRVPDumpSuspendMsgQ" +#define PVRSRV_PDUMP_SUSPEND_Q_LENGTH 8 + +#endif /* defined(PDUMP_SUSPEND_IS_PER_THREAD) */ + + +/*! + ***************************************************************************** + * This structure is used for OS independent registry (profile) access + *****************************************************************************/ +typedef struct _PVRSRV_REGISTRY_INFO_ +{ + IMG_UINT32 ui32DevCookie; + IMG_PCHAR pszKey; + IMG_PCHAR pszValue; + IMG_PCHAR pszBuf; + IMG_UINT32 ui32BufSize; +} PVRSRV_REGISTRY_INFO, *PPVRSRV_REGISTRY_INFO; + + +PVRSRV_ERROR IMG_CALLCONV PVRSRVReadRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo); +PVRSRV_ERROR IMG_CALLCONV PVRSRVWriteRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo); + + +#define PVRSRV_BC_FLAGS_YUVCSC_CONFORMANT_RANGE (0 << 0) +#define PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE (1 << 0) + +#define PVRSRV_BC_FLAGS_YUVCSC_BT601 (0 << 1) +#define PVRSRV_BC_FLAGS_YUVCSC_BT709 (1 << 1) + +#define MAX_BUFFER_DEVICE_NAME_SIZE (50) /* arbitrary choice! */ + +/* buffer information structure */ +typedef struct BUFFER_INFO_TAG +{ + IMG_UINT32 ui32BufferCount; + IMG_UINT32 ui32BufferDeviceID; + PVRSRV_PIXEL_FORMAT pixelformat; + IMG_UINT32 ui32ByteStride; + IMG_UINT32 ui32Width; + IMG_UINT32 ui32Height; + IMG_UINT32 ui32Flags; + IMG_CHAR szDeviceName[MAX_BUFFER_DEVICE_NAME_SIZE]; +} BUFFER_INFO; + +typedef enum _OVERLAY_DEINTERLACE_MODE_ +{ + WEAVE=0x0, + BOB_ODD, + BOB_EVEN, + BOB_EVEN_NONINTERLEAVED +} OVERLAY_DEINTERLACE_MODE; + +#endif /* __SERVICESEXT_H__ */ +/***************************************************************************** + End of file (servicesext.h) +*****************************************************************************/ |