diff options
author | Koen Kooi <koen@openembedded.org> | 2009-01-06 11:44:24 +0100 |
---|---|---|
committer | Koen Kooi <koen@openembedded.org> | 2009-01-06 15:44:11 +0100 |
commit | 62a428f0266e0d41f73c3fead9fd448bb67899ab (patch) | |
tree | fecc68ef63d9e330fe97920b223cdea56383be05 | |
parent | c03e405d58f713364c4a812016a024821fdc59f9 (diff) |
linux-omap 2.6.27: sync powervr code with latest code drop from TI
-rw-r--r-- | packages/linux/linux-omap-2.6.27/beagleboard/defconfig | 13 | ||||
-rw-r--r-- | packages/linux/linux-omap-2.6.27/pvr/nokia-TI.diff | 8798 | ||||
-rw-r--r-- | packages/linux/linux-omap_2.6.27.bb | 1 |
3 files changed, 8806 insertions, 6 deletions
diff --git a/packages/linux/linux-omap-2.6.27/beagleboard/defconfig b/packages/linux/linux-omap-2.6.27/beagleboard/defconfig index 8380a200bf..afcd72891d 100644 --- a/packages/linux/linux-omap-2.6.27/beagleboard/defconfig +++ b/packages/linux/linux-omap-2.6.27/beagleboard/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.27-omap1 -# Sun Jan 4 17:13:56 2009 +# Tue Jan 6 10:27:42 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -630,9 +630,10 @@ CONFIG_SCSI_PROC_FS=y CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_CHR_DEV_SG=m -# CONFIG_CHR_DEV_SCH is not set +CONFIG_CHR_DEV_SCH=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -648,11 +649,11 @@ CONFIG_SCSI_WAIT_SCAN=m # # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_SAS_LIBSAS is not set # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set +CONFIG_ISCSI_TCP=m # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_ATA is not set @@ -1563,7 +1564,7 @@ CONFIG_USB_LED=m # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set +CONFIG_USB_TEST=m # CONFIG_USB_ISIGHTFW is not set CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set diff --git a/packages/linux/linux-omap-2.6.27/pvr/nokia-TI.diff b/packages/linux/linux-omap-2.6.27/pvr/nokia-TI.diff new file mode 100644 index 0000000000..a4aca1e524 --- /dev/null +++ b/packages/linux/linux-omap-2.6.27/pvr/nokia-TI.diff @@ -0,0 +1,8798 @@ + include4/img_types.h | 5 + include4/pdumpdefs.h | 1 + include4/pvrmodule.h | 31 + include4/pvrversion.h | 8 + include4/services.h | 46 + include4/servicesext.h | 6 + include4/sgxapi_km.h | 65 + services4/3rdparty/bufferclass_example/bufferclass_example.c | 32 + services4/3rdparty/bufferclass_example/bufferclass_example.h | 25 + services4/3rdparty/bufferclass_example/bufferclass_example_linux.c | 20 + services4/3rdparty/bufferclass_example/bufferclass_example_private.c | 76 - + services4/3rdparty/bufferclass_example/kbuild/Makefile | 40 + services4/3rdparty/dc_omap3430_linux/kbuild/Makefile | 39 + services4/3rdparty/dc_omap3430_linux/omaplfb.h | 7 + services4/3rdparty/dc_omap3430_linux/omaplfb_displayclass.c | 60 + services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c | 52 + services4/include/pvr_bridge.h | 26 + services4/include/servicesint.h | 17 + services4/include/sgx_bridge.h | 95 + + services4/include/sgx_bridge_km.h | 139 - + services4/include/sgxinfo.h | 347 ++-- + services4/srvkm/Makefile | 68 + services4/srvkm/bridged/bridged_pvr_bridge.c | 732 ++++++++- + services4/srvkm/common/deviceclass.c | 6 + services4/srvkm/common/devicemem.c | 3 + services4/srvkm/common/handle.c | 58 + services4/srvkm/common/power.c | 15 + services4/srvkm/common/pvrsrv.c | 151 +- + services4/srvkm/common/queue.c | 4 + services4/srvkm/common/resman.c | 13 + services4/srvkm/devices/sgx/mmu.c | 2 + services4/srvkm/devices/sgx/mmu.h | 2 + services4/srvkm/devices/sgx/pb.c | 37 + services4/srvkm/devices/sgx/sgx2dcore.c | 21 + services4/srvkm/devices/sgx/sgx_bridge_km.h | 158 ++ + services4/srvkm/devices/sgx/sgxinfokm.h | 146 + + services4/srvkm/devices/sgx/sgxinit.c | 734 ++-------- + services4/srvkm/devices/sgx/sgxkick.c | 327 +++- + services4/srvkm/devices/sgx/sgxreset.c | 330 ++++ + services4/srvkm/devices/sgx/sgxtransfer.c | 312 ++++ + services4/srvkm/devices/sgx/sgxutils.c | 459 +++--- + services4/srvkm/devices/sgx/sgxutils.h | 28 + services4/srvkm/env/linux/env_data.h | 8 + services4/srvkm/env/linux/event.c | 221 +++ + services4/srvkm/env/linux/event.h | 32 + services4/srvkm/env/linux/kbuild/Makefile | 81 + + services4/srvkm/env/linux/mm.c | 8 + services4/srvkm/env/linux/module.c | 342 +++- + services4/srvkm/env/linux/osfunc.c | 347 +++- + services4/srvkm/env/linux/pdump.c | 13 + services4/srvkm/env/linux/proc.c | 17 + services4/srvkm/env/linux/pvr_debug.c | 2 + services4/srvkm/hwdefs/sgxdefs.h | 4 + services4/srvkm/hwdefs/sgxerrata.h | 9 + services4/srvkm/hwdefs/sgxfeaturedefs.h | 11 + services4/srvkm/include/device.h | 35 + services4/srvkm/include/handle.h | 10 + services4/srvkm/include/osfunc.h | 32 + services4/srvkm/include/pdump_km.h | 2 + services4/srvkm/include/resman.h | 5 + services4/srvkm/include/srvkm.h | 4 + services4/system/include/syscommon.h | 2 + services4/system/omap3430/sysconfig.c | 24 + services4/system/omap3430/sysconfig.h | 7 + services4/system/omap3430/sysutils.c | 2 + 65 files changed, 4286 insertions(+), 1675 deletions(-) + + +diff -Nurd git/drivers/gpu/pvr/include4/img_types.h git/drivers/gpu/pvr/include4/img_types.h +--- git/drivers/gpu/pvr/include4/img_types.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/include4/img_types.h 2008-12-18 15:47:29.000000000 +0100 +@@ -43,7 +43,10 @@ + typedef signed long IMG_INT32, *IMG_PINT32; + + #if defined(LINUX) +- ++#if !defined(USE_CODE) ++ typedef unsigned long long IMG_UINT64, *IMG_PUINT64; ++ typedef long long IMG_INT64, *IMG_PINT64; ++#endif + #else + + #error("define an OS") +diff -Nurd git/drivers/gpu/pvr/include4/pdumpdefs.h git/drivers/gpu/pvr/include4/pdumpdefs.h +--- git/drivers/gpu/pvr/include4/pdumpdefs.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/include4/pdumpdefs.h 2008-12-18 15:47:29.000000000 +0100 +@@ -73,6 +73,7 @@ + PVRSRV_PDUMP_MEM_FORMAT_RESERVED = 1, + PVRSRV_PDUMP_MEM_FORMAT_TILED = 8, + PVRSRV_PDUMP_MEM_FORMAT_TWIDDLED = 9, ++ PVRSRV_PDUMP_MEM_FORMAT_HYBRID = 10, + + PVRSRV_PDUMP_MEM_FORMAT_FORCE_I32 = 0x7fffffff + } PDUMP_MEM_FORMAT; +diff -Nurd git/drivers/gpu/pvr/include4/pvrmodule.h git/drivers/gpu/pvr/include4/pvrmodule.h +--- git/drivers/gpu/pvr/include4/pvrmodule.h 1970-01-01 01:00:00.000000000 +0100 ++++ git/drivers/gpu/pvr/include4/pvrmodule.h 2008-12-18 15:47:29.000000000 +0100 +@@ -0,0 +1,31 @@ ++/********************************************************************** ++ * ++ * Copyright(c) 2008 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 _PVRMODULE_H_ ++#define _PVRMODULE_H_ ++MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>"); ++MODULE_LICENSE("GPL"); ++#endif +diff -Nurd git/drivers/gpu/pvr/include4/pvrversion.h git/drivers/gpu/pvr/include4/pvrversion.h +--- git/drivers/gpu/pvr/include4/pvrversion.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/include4/pvrversion.h 2008-12-18 15:47:29.000000000 +0100 +@@ -28,10 +28,10 @@ + #define _PVRVERSION_H_ + + #define PVRVERSION_MAJ 1 +-#define PVRVERSION_MIN 1 +-#define PVRVERSION_BRANCH 11 +-#define PVRVERSION_BUILD 970 +-#define PVRVERSION_STRING "1.1.11.970" ++#define PVRVERSION_MIN 2 ++#define PVRVERSION_BRANCH 12 ++#define PVRVERSION_BUILD 838 ++#define PVRVERSION_STRING "1.2.12.838" + + #endif + +diff -Nurd git/drivers/gpu/pvr/include4/servicesext.h git/drivers/gpu/pvr/include4/servicesext.h +--- git/drivers/gpu/pvr/include4/servicesext.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/include4/servicesext.h 2008-12-18 15:47:29.000000000 +0100 +@@ -150,6 +150,8 @@ + PVRSRV_PIXEL_FORMAT_V8U8, + PVRSRV_PIXEL_FORMAT_V16U16, + PVRSRV_PIXEL_FORMAT_QWVU8888, ++ PVRSRV_PIXEL_FORMAT_XLVU8888, ++ PVRSRV_PIXEL_FORMAT_QWVU16, + PVRSRV_PIXEL_FORMAT_D16, + PVRSRV_PIXEL_FORMAT_D24S8, + PVRSRV_PIXEL_FORMAT_D24X8, +@@ -159,7 +161,9 @@ + PVRSRV_PIXEL_FORMAT_YUY2, + PVRSRV_PIXEL_FORMAT_DXT23, + PVRSRV_PIXEL_FORMAT_DXT45, +- PVRSRV_PIXEL_FORMAT_G32R32F, ++ PVRSRV_PIXEL_FORMAT_G32R32F, ++ PVRSRV_PIXEL_FORMAT_NV11, ++ PVRSRV_PIXEL_FORMAT_NV12, + + PVRSRV_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff, + } PVRSRV_PIXEL_FORMAT; +diff -Nurd git/drivers/gpu/pvr/include4/services.h git/drivers/gpu/pvr/include4/services.h +--- git/drivers/gpu/pvr/include4/services.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/include4/services.h 2008-12-18 15:47:29.000000000 +0100 +@@ -36,16 +36,14 @@ + #include "pdumpdefs.h" + + +-#if defined(SERVICES4) + #define IMG_CONST const +-#else +-#define IMG_CONST +-#endif + + #define PVRSRV_MAX_CMD_SIZE 1024 + + #define PVRSRV_MAX_DEVICES 16 + ++#define EVENTOBJNAME_MAXLENGTH (50) ++ + #define PVRSRV_MEM_READ (1<<0) + #define PVRSRV_MEM_WRITE (1<<1) + #define PVRSRV_MEM_CACHE_CONSISTENT (1<<2) +@@ -90,6 +88,7 @@ + #define PVRSRV_MISC_INFO_TIMER_PRESENT (1<<0) + #define PVRSRV_MISC_INFO_CLOCKGATE_PRESENT (1<<1) + #define PVRSRV_MISC_INFO_MEMSTATS_PRESENT (1<<2) ++#define PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT (1<<3) + + #define PVRSRV_PDUMP_MAX_FILENAME_SIZE 20 + #define PVRSRV_PDUMP_MAX_COMMENT_SIZE 200 +@@ -133,7 +132,8 @@ + IMG_OPENGLES2 = 0x00000003, + IMG_D3DM = 0x00000004, + IMG_SRV_UM = 0x00000005, +- IMG_OPENVG = 0x00000006 ++ IMG_OPENVG = 0x00000006, ++ IMG_SRVCLIENT = 0x00000007, + + } IMG_MODULE_ID; + +@@ -202,10 +202,8 @@ + + IMG_PVOID pvLinAddr; + +-#if defined(SERVICES4) + + IMG_PVOID pvLinAddrKM; +-#endif + + + IMG_DEV_VIRTADDR sDevVAddr; +@@ -294,6 +292,14 @@ + + } PVRSRV_DEVICE_IDENTIFIER; + ++typedef struct _PVRSRV_EVENTOBJECT_ ++{ ++ ++ IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH]; ++ ++ IMG_HANDLE hOSEventKM; ++ ++} PVRSRV_EVENTOBJECT; + + typedef struct _PVRSRV_MISC_INFO_ + { +@@ -313,9 +319,14 @@ + IMG_UINT32 ui32MemoryStrLen; + + ++ PVRSRV_EVENTOBJECT sGlobalEventObject; ++ IMG_HANDLE hOSGlobalEvent; ++ ++ + + } PVRSRV_MISC_INFO; + ++ + IMG_IMPORT + PVRSRV_ERROR IMG_CALLCONV PVRSRVConnect(PVRSRV_CONNECTION *psConnection); + +@@ -335,7 +346,7 @@ + PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo); + + IMG_IMPORT +-PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseMiscInfo (PVRSRV_MISC_INFO *psMiscInfo); ++PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo); + + #if 1 + IMG_IMPORT +@@ -348,7 +359,9 @@ + #endif + + IMG_IMPORT +-PVRSRV_ERROR PollForValue (volatile IMG_UINT32 *pui32LinMemAddr, ++PVRSRV_ERROR PollForValue ( PVRSRV_CONNECTION *psConnection, ++ IMG_HANDLE hOSEvent, ++ volatile IMG_UINT32 *pui32LinMemAddr, + IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Waitus, +@@ -631,21 +644,18 @@ + IMG_UINT32 ui32RegValue, + IMG_UINT32 ui32Flags); + +-#ifdef SERVICES4 + IMG_IMPORT + PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPolWithFlags(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32RegAddr, + IMG_UINT32 ui32RegValue, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Flags); +-#endif + IMG_IMPORT + PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPol(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32RegAddr, + IMG_UINT32 ui32RegValue, + IMG_UINT32 ui32Mask); + +-#ifdef SERVICES4 + IMG_IMPORT + PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDReg(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32RegAddr, +@@ -655,7 +665,6 @@ + PVRSRV_CLIENT_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_DEV_PHYADDR sPDDevPAddr); +-#endif + + IMG_IMPORT + PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPages(IMG_CONST PVRSRV_CONNECTION *psConnection, +@@ -676,7 +685,6 @@ + IMG_CONST IMG_CHAR *pszComment, + IMG_BOOL bContinuous); + +-#if defined(SERVICES4) + IMG_IMPORT + PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentf(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_BOOL bContinuous, +@@ -686,7 +694,6 @@ + PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentWithFlagsf(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32Flags, + IMG_CONST IMG_CHAR *pszFormat, ...); +-#endif + + IMG_IMPORT + PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpDriverInfo(IMG_CONST PVRSRV_CONNECTION *psConnection, +@@ -718,7 +725,7 @@ + IMG_UINT32 ui32Size, + IMG_UINT32 ui32PDumpFlags); + +-#ifdef SERVICES4 ++ + IMG_IMPORT + IMG_BOOL IMG_CALLCONV PVRSRVPDumpIsCapturingTest(IMG_CONST PVRSRV_CONNECTION *psConnection); + +@@ -726,7 +733,6 @@ + PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCycleCountRegRead(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32RegOffset, + IMG_BOOL bLastFrame); +-#endif + + IMG_IMPORT IMG_HANDLE PVRSRVLoadLibrary(IMG_CHAR *pszLibraryName); + IMG_IMPORT PVRSRV_ERROR PVRSRVUnloadLibrary(IMG_HANDLE hExtDrv); +@@ -777,9 +783,9 @@ + IMG_PVOID PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_UINT32 ui32NewSize, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); + #endif + +-PVRSRV_ERROR PVRSRVEventObjectWait(PVRSRV_CONNECTION *psConnection, +- IMG_HANDLE hOSEvent, +- IMG_UINT32 ui32MSTimeout); ++IMG_IMPORT ++PVRSRV_ERROR PVRSRVEventObjectWait(PVRSRV_CONNECTION * psConnection, ++ IMG_HANDLE hOSEvent); + + #define TIME_NOT_PASSED_UINT32(a,b,c) ((a - b) < c) + +diff -Nurd git/drivers/gpu/pvr/include4/sgxapi_km.h git/drivers/gpu/pvr/include4/sgxapi_km.h +--- git/drivers/gpu/pvr/include4/sgxapi_km.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/include4/sgxapi_km.h 2008-12-18 15:47:29.000000000 +0100 +@@ -32,6 +32,7 @@ + #endif + + #include "sgxdefs.h" ++ + #if defined(__linux__) && !defined(USE_CODE) + #if defined(__KERNEL__) + #include <asm/unistd.h> +@@ -64,6 +65,8 @@ + #define SGX_MAX_TA_STATUS_VALS 32 + #define SGX_MAX_3D_STATUS_VALS 2 + ++#define SGX_MAX_SRC_SYNCS 4 ++ + #define PFLAGS_POWERDOWN 0x00000001 + #define PFLAGS_POWERUP 0x00000002 + +@@ -75,11 +78,60 @@ + IMG_SYS_PHYADDR sPhysBase; + }SGX_SLAVE_PORT; + ++#ifdef SUPPORT_SGX_HWPERF ++ ++#define PVRSRV_SGX_HWPERF_CBSIZE 0x100 ++ ++#define PVRSRV_SGX_HWPERF_INVALID 1 ++#define PVRSRV_SGX_HWPERF_TRANSFER 2 ++#define PVRSRV_SGX_HWPERF_TA 3 ++#define PVRSRV_SGX_HWPERF_3D 4 ++ ++#define PVRSRV_SGX_HWPERF_ON 0x40 ++ ++ ++typedef struct _PVRSRV_SGX_HWPERF_CBDATA_ ++{ ++ IMG_UINT32 ui32FrameNo; ++ IMG_UINT32 ui32Type; ++ IMG_UINT32 ui32StartTimeWraps; ++ IMG_UINT32 ui32StartTime; ++ IMG_UINT32 ui32EndTimeWraps; ++ IMG_UINT32 ui32EndTime; ++ IMG_UINT32 ui32ClockSpeed; ++ IMG_UINT32 ui32TimeMax; ++} PVRSRV_SGX_HWPERF_CBDATA; ++ ++typedef struct _PVRSRV_SGX_HWPERF_CB_ ++{ ++ IMG_UINT32 ui32Woff; ++ IMG_UINT32 ui32Roff; ++ PVRSRV_SGX_HWPERF_CBDATA psHWPerfCBData[PVRSRV_SGX_HWPERF_CBSIZE]; ++} PVRSRV_SGX_HWPERF_CB; ++ ++ ++typedef struct _SGX_MISC_INFO_HWPERF_RETRIEVE_CB ++{ ++ PVRSRV_SGX_HWPERF_CBDATA* psHWPerfData; ++ IMG_UINT32 ui32ArraySize; ++ IMG_UINT32 ui32DataCount; ++ IMG_UINT32 ui32Time; ++} SGX_MISC_INFO_HWPERF_RETRIEVE_CB; ++#endif ++ ++ + typedef enum _SGX_MISC_INFO_REQUEST_ + { ++ SGX_MISC_INFO_REQUEST_CLOCKSPEED = 0, ++#ifdef SUPPORT_SGX_HWPERF ++ SGX_MISC_INFO_REQUEST_HWPERF_CB_ON, ++ SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF, ++ SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB, ++#endif + SGX_MISC_INFO_REQUEST_FORCE_I16 = 0x7fff + } SGX_MISC_INFO_REQUEST; + ++ + typedef struct _SGX_MISC_INFO_ + { + SGX_MISC_INFO_REQUEST eRequest; +@@ -87,6 +139,10 @@ + union + { + IMG_UINT32 reserved; ++ IMG_UINT32 ui32SGXClockSpeed; ++#ifdef SUPPORT_SGX_HWPERF ++ SGX_MISC_INFO_HWPERF_RETRIEVE_CB sRetrieveCB; ++#endif + } uData; + } SGX_MISC_INFO; + +@@ -162,6 +218,15 @@ + } PVR3DIF4_KICKTA_PDUMP, *PPVR3DIF4_KICKTA_PDUMP; + #endif + ++#if defined(TRANSFER_QUEUE) ++#if defined(SGX_FEATURE_2D_HARDWARE) ++#define SGX_MAX_2D_BLIT_CMD_SIZE 26 ++#define SGX_MAX_2D_SRC_SYNC_OPS 3 ++#endif ++#define SGX_MAX_TRANSFER_STATUS_VALS 64 ++#define SGX_MAX_TRANSFER_SYNC_OPS 5 ++#endif ++ + #if defined (__cplusplus) + } + #endif +diff -Nurd git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example.c git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example.c +--- git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example.c 2008-12-18 15:47:29.000000000 +0100 +@@ -197,11 +197,27 @@ + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + ++ ++ ++ psDevInfo->sBufferInfo.pixelformat = BC_EXAMPLE_PIXELFORMAT; ++ psDevInfo->sBufferInfo.ui32Width = BC_EXAMPLE_WIDTH; ++ psDevInfo->sBufferInfo.ui32Height = BC_EXAMPLE_HEIGHT; ++ psDevInfo->sBufferInfo.ui32ByteStride = BC_EXAMPLE_STRIDE; ++ psDevInfo->sBufferInfo.ui32BufferDeviceID = BC_EXAMPLE_DEVICEID; ++ psDevInfo->sBufferInfo.ui32Flags = PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE | PVRSRV_BC_FLAGS_YUVCSC_BT601; ++ + for(i=0; i < BC_EXAMPLE_NUM_BUFFERS; i++) + { ++ IMG_UINT32 ui32Size = BC_EXAMPLE_HEIGHT * BC_EXAMPLE_STRIDE; ++ ++ if(psDevInfo->sBufferInfo.pixelformat == PVRSRV_PIXEL_FORMAT_YUV420) ++ { ++ ++ ui32Size += ((BC_EXAMPLE_STRIDE >> 1) * (BC_EXAMPLE_HEIGHT >> 1) << 1); ++ } + + +- if (AllocContigMemory(BC_EXAMPLE_HEIGHT * BC_EXAMPLE_STRIDE, ++ if (AllocContigMemory(ui32Size, + &psDevInfo->psSystemBuffer[i].hMemHandle, + &psDevInfo->psSystemBuffer[i].sCPUVAddr, + &sSystemBufferCPUPAddr) != PVRSRV_OK) +@@ -211,12 +227,14 @@ + + psDevInfo->ui32NumBuffers++; + +- psDevInfo->psSystemBuffer[i].ui32Size = BC_EXAMPLE_HEIGHT * BC_EXAMPLE_STRIDE; ++ psDevInfo->psSystemBuffer[i].ui32Size = ui32Size; + psDevInfo->psSystemBuffer[i].sSysAddr = CpuPAddrToSysPAddr(sSystemBufferCPUPAddr); + psDevInfo->psSystemBuffer[i].sPageAlignSysAddr.uiAddr = (psDevInfo->psSystemBuffer[i].sSysAddr.uiAddr & 0xFFFFF000); + psDevInfo->psSystemBuffer[i].psSyncData = IMG_NULL; + } + ++ psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ui32NumBuffers; ++ + + + psDevInfo->sBCJTable.ui32TableSize = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE); +@@ -234,16 +252,6 @@ + { + return PVRSRV_ERROR_DEVICE_REGISTER_FAILED; + } +- +- +- +- psDevInfo->sBufferInfo.pixelformat = BC_EXAMPLE_PIXELFORMAT; +- psDevInfo->sBufferInfo.ui32Width = BC_EXAMPLE_WIDTH; +- psDevInfo->sBufferInfo.ui32Height = BC_EXAMPLE_HEIGHT; +- psDevInfo->sBufferInfo.ui32ByteStride = BC_EXAMPLE_STRIDE; +- psDevInfo->sBufferInfo.ui32BufferDeviceID = BC_EXAMPLE_DEVICEID; +- psDevInfo->sBufferInfo.ui32Flags = PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE | PVRSRV_BC_FLAGS_YUVCSC_BT601; +- psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ui32NumBuffers; + } + + +diff -Nurd git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example.h git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example.h +--- git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example.h 2008-12-18 15:47:29.000000000 +0100 +@@ -39,11 +39,32 @@ + + #define BC_EXAMPLE_NUM_BUFFERS 3 + +-#define BC_EXAMPLE_WIDTH (160) ++#define YUV420 1 ++#ifdef YUV420 ++ ++#define BC_EXAMPLE_WIDTH (320) + #define BC_EXAMPLE_HEIGHT (160) +-#define BC_EXAMPLE_STRIDE (160*2) ++#define BC_EXAMPLE_STRIDE (320) ++#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_YUV420) ++ ++#else ++#ifdef YUV422 ++ ++#define BC_EXAMPLE_WIDTH (320) ++#define BC_EXAMPLE_HEIGHT (160) ++#define BC_EXAMPLE_STRIDE (320*2) + #define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_YVYU) + ++#else ++ ++#define BC_EXAMPLE_WIDTH (320) ++#define BC_EXAMPLE_HEIGHT (160) ++#define BC_EXAMPLE_STRIDE (320*2) ++#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_RGB565) ++ ++#endif ++#endif ++ + #define BC_EXAMPLE_DEVICEID 0 + + +diff -Nurd git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c +--- git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c 2008-12-18 15:47:29.000000000 +0100 +@@ -38,11 +38,10 @@ + + #include "bufferclass_example.h" + #include "bufferclass_example_linux.h" ++#include "pvrmodule.h" + + #define DEVNAME "bc_example" + +-MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>"); +-MODULE_LICENSE("GPL"); + MODULE_SUPPORTED_DEVICE(DEVNAME); + + int BC_Example_Bridge(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +@@ -259,22 +258,11 @@ + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } +- else +- { +- IMG_VOID *pvPage; +- IMG_VOID *pvEnd = pvLinAddr + ui32Size; +- +- for(pvPage = pvLinAddr; pvPage < pvEnd; pvPage += PAGE_SIZE) +- { +- SetPageReserved(virt_to_page(pvPage)); +- } + +- pPhysAddr->uiAddr = dma; +- *pLinAddr = pvLinAddr; ++ pPhysAddr->uiAddr = dma; ++ *pLinAddr = pvLinAddr; + +- return PVRSRV_OK; +- } +- return PVRSRV_ERROR_OUT_OF_MEMORY; ++ return PVRSRV_OK; + #endif + } + +diff -Nurd git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example_private.c git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example_private.c +--- git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example_private.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/bufferclass_example_private.c 2008-12-18 15:47:29.000000000 +0100 +@@ -26,6 +26,43 @@ + + #include "bufferclass_example.h" + ++void FillYUV420Image(void *pvDest, int width, int height, int bytestride) ++{ ++ static int iPhase = 0; ++ int i, j; ++ unsigned char u,v,y; ++ unsigned char *pui8y = (unsigned char *)pvDest; ++ unsigned short *pui16uv; ++ unsigned int count = 0; ++ ++ for(j=0;j<height;j++) ++ { ++ for(i=0;i<width;i++) ++ { ++ y = (((i+iPhase)>>6)%(2)==0)? 0x7f:0x00; ++ ++ pui8y[count++] = y; ++ } ++ } ++ ++ pui16uv = (unsigned short *)((unsigned char *)pvDest + (width * height)); ++ count = 0; ++ ++ for(j=0;j<height;j+=2) ++ { ++ for(i=0;i<width;i+=2) ++ { ++ u = (j<(height/2))? ((i<(width/2))? 0xFF:0x33) : ((i<(width/2))? 0x33:0xAA); ++ v = (j<(height/2))? ((i<(width/2))? 0xAC:0x0) : ((i<(width/2))? 0x03:0xEE); ++ ++ ++ pui16uv[count++] = (v << 8) | u; ++ ++ } ++ } ++ ++ iPhase++; ++} + + void FillYUV422Image(void *pvDest, int width, int height, int bytestride) + { +@@ -37,12 +74,12 @@ + + for(y=0;y<height;y++) + { +- for(x=0;x<width >> 1;x++) ++ for(x=0;x<width;x+=2) + { +- u = (y<(height/2))? ((x<(width/4))? 0xFF:0x33) : ((x<(width/4))? 0x33:0xAA); +- v = (y<(height/2))? ((x<(width/4))? 0xAA:0x0) : ((x<(width/4))? 0x03:0xEE); ++ u = (y<(height/2))? ((x<(width/2))? 0xFF:0x33) : ((x<(width/2))? 0x33:0xAA); ++ v = (y<(height/2))? ((x<(width/2))? 0xAA:0x0) : ((x<(width/2))? 0x03:0xEE); + +- y0 = y1 = (((x+iPhase)>>4)%(2)==0)? 0x7f:0x00; ++ y0 = y1 = (((x+iPhase)>>6)%(2)==0)? 0x7f:0x00; + + + pui32yuv[count++] = (y1 << 24) | (v << 16) | (y0 << 8) | u; +@@ -115,19 +152,36 @@ + + psSyncData = psBuffer->psSyncData; + +- + if(psSyncData) + { ++ ++ if(psSyncData->ui32ReadOpsPending != psSyncData->ui32ReadOpsComplete) ++ { ++ return -1; ++ } ++ ++ + psSyncData->ui32WriteOpsPending++; + } + +- if(psBufferInfo->pixelformat == PVRSRV_PIXEL_FORMAT_RGB565) +- { +- FillRGB565Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); +- } +- else ++ switch(psBufferInfo->pixelformat) + { +- FillYUV422Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); ++ case PVRSRV_PIXEL_FORMAT_RGB565: ++ default: ++ { ++ FillRGB565Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); ++ break; ++ } ++ case PVRSRV_PIXEL_FORMAT_YVYU: ++ { ++ FillYUV422Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); ++ break; ++ } ++ case PVRSRV_PIXEL_FORMAT_YUV420: ++ { ++ FillYUV420Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); ++ break; ++ } + } + + +diff -Nurd git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/kbuild/Makefile git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/kbuild/Makefile +--- git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/kbuild/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/bufferclass_example/kbuild/Makefile 2008-12-18 15:47:29.000000000 +0100 +@@ -0,0 +1,40 @@ ++# ++# Copyright(c) 2008 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 ++# ++# ++# ++ ++MODULE = bc_example ++ ++INCLUDES = -I$(EURASIAROOT)/include4 \ ++ -I$(EURASIAROOT)/services4/include \ ++ -I$(EURASIAROOT)/services4/system/$(PVR_SYSTEM) \ ++ -I$(EURASIAROOT)/services4/system/include \ ++ ++SOURCES = ../bufferclass_example.c \ ++ ../bufferclass_example_linux.c \ ++ ../bufferclass_example_private.c ++ ++ ++ ++ +diff -Nurd git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/kbuild/Makefile git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/kbuild/Makefile +--- git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/kbuild/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/kbuild/Makefile 2008-12-18 15:47:29.000000000 +0100 +@@ -0,0 +1,39 @@ ++# ++# Copyright(c) 2008 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 ++# ++# ++# ++ ++MODULE = omaplfb ++ ++INCLUDES = -I$(EURASIAROOT)/include4 \ ++ -I$(EURASIAROOT)/services4/include \ ++ -I$(EURASIAROOT)/services4/system/$(PVR_SYSTEM) \ ++ -I$(EURASIAROOT)/services4/system/include \ ++ ++SOURCES = ../omaplfb_displayclass.c \ ++ ../omaplfb_linux.c ++ ++ ++ ++ +diff -Nurd git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb_displayclass.c git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb_displayclass.c +--- git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb_displayclass.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb_displayclass.c 2008-12-18 15:47:29.000000000 +0100 +@@ -41,6 +41,7 @@ + #define DISPLAY_DEVICE_NAME "PowerVR OMAP Linux Display Driver" + + #define DRIVER_PREFIX "omaplfb" ++//extern int omap2_disp_get_output_dev(int); + + static IMG_VOID *gpvAnchor; + +@@ -57,8 +58,6 @@ + PVR_POWER_STATE eCurrentPowerState); + #endif + +-extern void omap_dispc_set_plane_base(int plane, IMG_UINT32 phys_addr); +- + static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = IMG_NULL; + + static OMAPLFB_DEVINFO * GetAnchorPtr(IMG_VOID) +@@ -124,28 +123,53 @@ + static PVRSRV_ERROR Flip(OMAPLFB_SWAPCHAIN *psSwapChain, + IMG_UINT32 aPhyAddr) + { +- if (1 /* omap2_disp_get_output_dev(OMAP2_GRAPHICS) == OMAP2_OUTPUT_LCD */) ++ IMG_UINT32 control; ++ OMAPLFB_DEVINFO *psDevInfo; ++ ++ psDevInfo = GetAnchorPtr(); ++ ++ if (1) //omap2_disp_get_output_dev(OMAP2_GRAPHICS) == OMAP2_OUTPUT_LCD) + { +- omap_dispc_set_plane_base(0, aPhyAddr); ++ OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_GFX_BA0, aPhyAddr); ++ ++ OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_GFX_BA1, aPhyAddr); ++ ++ control = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_CONTROL); ++ control |= OMAP_CONTROL_GOLCD; ++ OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_CONTROL, control); ++ + return PVRSRV_OK; + } + else +- if (0 /*omap2_disp_get_output_dev(OMAP2_GRAPHICS) == OMAP2_OUTPUT_TV*/) ++ if (0) //omap2_disp_get_output_dev(OMAP2_GRAPHICS) == OMAP2_OUTPUT_TV) + { +- omap_dispc_set_plane_base(0, aPhyAddr); ++ OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_GFX_BA0, aPhyAddr); ++ OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_GFX_BA1, aPhyAddr + psDevInfo->sFBInfo.ui32ByteStride); ++ ++ control = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_CONTROL); ++ control |= OMAP_CONTROL_GODIGITAL; ++ OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_CONTROL, control); ++ + return PVRSRV_OK; + } +- ++ + return PVRSRV_ERROR_INVALID_PARAMS; + } + + static IMG_VOID EnableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) + { +- ++ ++ IMG_UINT32 ui32InterruptEnable = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_IRQENABLE); ++ ui32InterruptEnable |= OMAPLCD_INTMASK_VSYNC; ++ OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_IRQENABLE, ui32InterruptEnable ); + } + + static IMG_VOID DisableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) + { ++ ++ IMG_UINT32 ui32InterruptEnable = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_IRQENABLE); ++ ui32InterruptEnable &= ~(OMAPLCD_INTMASK_VSYNC); ++ OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_IRQENABLE, ui32InterruptEnable); + } + + static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID, +@@ -169,6 +193,7 @@ + #endif + ); + ++ + memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); + + psDevInfo->sLINNotifBlock.notifier_call = FrameBufferEvents; +@@ -363,6 +388,7 @@ + PVR_UNREFERENCED_PARAMETER(ui32OEMFlags); + PVR_UNREFERENCED_PARAMETER(pui32SwapChainID); + ++ + if(!hDevice + || !psDstSurfAttrib + || !psSrcSurfAttrib +@@ -399,6 +425,7 @@ + || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width + || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) + { ++ + return PVRSRV_ERROR_INVALID_PARAMS; + } + +@@ -407,6 +434,7 @@ + || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width + || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) + { ++ + return PVRSRV_ERROR_INVALID_PARAMS; + } + +@@ -467,12 +495,21 @@ + } + + ++ psSwapChain->pvRegs = ioremap(psDevInfo->psLINFBInfo->fix.mmio_start, psDevInfo->psLINFBInfo->fix.mmio_len); ++ ++ if (psSwapChain->pvRegs == IMG_NULL) ++ { ++ printk(KERN_WARNING DRIVER_PREFIX ": Couldn't map registers needed for flipping\n"); ++ goto ErrorFreeVSyncItems; ++ } ++ ++ + unblank_display(psDevInfo); + + if (OMAPLFBInstallVSyncISR(psSwapChain) != PVRSRV_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": ISR handler failed to register\n"); +- goto ErrorFreeVSyncItems; ++ goto ErrorUnmapRegisters; + } + + EnableVSyncInterrupt(psSwapChain); +@@ -485,6 +522,8 @@ + + return PVRSRV_OK; + ++ErrorUnmapRegisters: ++ iounmap(psSwapChain->pvRegs); + ErrorFreeVSyncItems: + OMAPLFBFreeKernelMem(psVSyncFlips); + ErrorFreeBuffers: +@@ -590,6 +629,9 @@ + } + + ++ iounmap(psSwapChain->pvRegs); ++ ++ + OMAPLFBFreeKernelMem(psSwapChain->psVSyncFlips); + OMAPLFBFreeKernelMem(psSwapChain->psBuffer); + OMAPLFBFreeKernelMem(psSwapChain); +diff -Nurd git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb.h git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb.h +--- git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb.h 2008-12-18 15:47:29.000000000 +0100 +@@ -121,6 +121,9 @@ + IMG_UINT32 ui32RemoveIndex; + + ++ IMG_VOID *pvRegs; ++ ++ + PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable; + } OMAPLFB_SWAPCHAIN; + +@@ -194,8 +197,8 @@ + + IMG_VOID *OMAPLFBAllocKernelMem(IMG_UINT32 ui32Size); + IMG_VOID OMAPLFBFreeKernelMem(IMG_VOID *pvMem); +-IMG_VOID OMAPLFBWriteReg(OMAPLFB_SWAPCHAIN *psSwapChain, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value); +-IMG_UINT32 OMAPLFBReadReg(OMAPLFB_SWAPCHAIN *psSwapChain, IMG_UINT32 ui32Offset); ++IMG_VOID OMAPLFBVSyncWriteReg(OMAPLFB_SWAPCHAIN *psSwapChain, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value); ++IMG_UINT32 OMAPLFBVSyncReadReg(OMAPLFB_SWAPCHAIN *psSwapChain, IMG_UINT32 ui32Offset); + PVRSRV_ERROR OMAPLFBGetLibFuncAddr(IMG_CHAR *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable); + PVRSRV_ERROR OMAPLFBInstallVSyncISR (OMAPLFB_SWAPCHAIN *psSwapChain); + PVRSRV_ERROR OMAPLFBUninstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain); +diff -Nurd git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c +--- git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c 2008-12-18 15:47:29.000000000 +0100 +@@ -101,28 +100,57 @@ + } + + static void +-OMAPLFBVSyncISR(void *arg) ++OMAPLFBVSyncISR(void *arg, struct pt_regs *regs) + { +- (void) OMAPLFBVSyncIHandler((OMAPLFB_SWAPCHAIN *)arg); ++ OMAPLFB_SWAPCHAIN *psSwapChain= (OMAPLFB_SWAPCHAIN *)arg; ++ ++ (void) OMAPLFBVSyncIHandler(psSwapChain); + } + +-#define DISPC_IRQ_VSYNC 0x0002 +- + PVRSRV_ERROR OMAPLFBInstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain) + { + +- if (omap_dispc_request_irq(DISPC_IRQ_VSYNC, OMAPLFBVSyncISR, psSwapChain) != 0) +- return PVRSRV_ERROR_OUT_OF_MEMORY; /* not worth a proper mapping */ +- ++ if (1) //omap2_disp_get_output_dev(OMAP2_GRAPHICS) == OMAP2_OUTPUT_LCD) ++ { ++ if (omap_dispc_request_irq(DISPC_IRQ_VSYNC, OMAPLFBVSyncISR, ++ psSwapChain) != 0) ++ { ++ printk("request OMAPLCD IRQ failed"); ++ return PVRSRV_ERROR_INIT_FAILURE; ++ } ++ } ++ else ++ if (0) //omap2_disp_get_output_dev(OMAP2_GRAPHICS) == OMAP2_OUTPUT_TV) ++ { ++ if (omap_dispc_request_irq(DISPC_IRQSTATUS_EVSYNC_EVEN|DISPC_IRQSTATUS_EVSYNC_ODD, OMAPLFBVSyncISR, psSwapChain) != 0) ++ { ++ printk("request OMAPLCD IRQ failed"); ++ return PVRSRV_ERROR_INIT_FAILURE; ++ } ++ } ++ + return PVRSRV_OK; + } + + + PVRSRV_ERROR OMAPLFBUninstallVSyncISR (OMAPLFB_SWAPCHAIN *psSwapChain) + { +- omap_dispc_free_irq(DISPC_IRQ_VSYNC, OMAPLFBVSyncISR, psSwapChain); ++ omap_dispc_free_irq(DISPC_IRQ_VSYNC, OMAPLFBVSyncISR, psSwapChain); ++ ++ return PVRSRV_OK; ++} + +- return PVRSRV_OK; ++IMG_VOID OMAPLFBVSyncWriteReg(OMAPLFB_SWAPCHAIN *psSwapChain, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) ++{ ++ IMG_VOID *pvRegAddr = (IMG_VOID *)((IMG_UINT8 *)psSwapChain->pvRegs + ui32Offset); ++ ++ ++ writel(ui32Value, pvRegAddr); ++} ++ ++IMG_UINT32 OMAPLFBVSyncReadReg(OMAPLFB_SWAPCHAIN *psSwapChain, IMG_UINT32 ui32Offset) ++{ ++ return readl((IMG_UINT8 *)psSwapChain->pvRegs + ui32Offset); + } + + module_init(OMAPLFB_Init); +diff -Nurd git/drivers/gpu/pvr/services4/include/pvr_bridge.h git/drivers/gpu/pvr/services4/include/pvr_bridge.h +--- git/drivers/gpu/pvr/services4/include/pvr_bridge.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/include/pvr_bridge.h 2008-12-18 15:47:29.000000000 +0100 +@@ -202,14 +202,14 @@ + + #define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST (PVRSRV_BRIDGE_INITSRV_CMD_LAST+1) + #define PVRSRV_BRIDGE_EVENT_OBJECT_WAIT PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+0) +-#define PVRSRV_BRIDGE_EVENT_OBJECT_CONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+1) +-#define PVRSRV_BRIDGE_EVENT_OBJECT_DISCONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2) ++#define PVRSRV_BRIDGE_EVENT_OBJECT_OPEN PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+1) ++#define PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2) + #define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2) + + #define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST+1) + + +-#define PVRSRV_KERNAL_MODE_CLIENT 1 ++#define PVRSRV_KERNEL_MODE_CLIENT 1 + + typedef struct PVRSRV_BRIDGE_RETURN_TAG + { +@@ -716,7 +716,7 @@ + typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR_TAG + { + IMG_UINT32 ui32BridgeFlags; +- IMG_HANDLE *hKernelMemInfo; ++ IMG_HANDLE hKernelMemInfo; + IMG_UINT32 ui32Offset; + IMG_DEV_PHYADDR sPDDevPAddr; + }PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR; +@@ -1302,9 +1302,25 @@ + { + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hOSEventKM; +- IMG_UINT32 ui32MSTimeout; + } PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT; + ++typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN_TAG ++{ ++ PVRSRV_EVENTOBJECT sEventObject; ++} PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN; ++ ++typedef struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN_TAG ++{ ++ IMG_HANDLE hOSEvent; ++ PVRSRV_ERROR eError; ++} PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN; ++ ++typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE_TAG ++{ ++ PVRSRV_EVENTOBJECT sEventObject; ++ IMG_HANDLE hOSEventKM; ++} PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE; ++ + #if defined (__cplusplus) + } + #endif +diff -Nurd git/drivers/gpu/pvr/services4/include/servicesint.h git/drivers/gpu/pvr/services4/include/servicesint.h +--- git/drivers/gpu/pvr/services4/include/servicesint.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/include/servicesint.h 2008-12-18 15:47:29.000000000 +0100 +@@ -38,16 +38,6 @@ + + #define DRIVERNAME_MAXLENGTH (100) + +-#define EVENTOBJNAME_MAXLENGTH (50) +- +- +-typedef struct _PVRSRV_EVENTOBJECT_ +-{ +- +- IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH]; +- +- IMG_HANDLE hOSEventKM; +-} PVRSRV_EVENTOBJECT; + + + typedef struct _PVRSRV_KERNEL_MEM_INFO_ +@@ -93,6 +83,13 @@ + + } PVRSRV_KERNEL_SYNC_INFO; + ++typedef struct _PVRSRV_DEVICE_SYNC_OBJECT_ ++{ ++ IMG_UINT32 ui32ReadOpPendingVal; ++ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; ++ IMG_UINT32 ui32WriteOpPendingVal; ++ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; ++} PVRSRV_DEVICE_SYNC_OBJECT; + + typedef struct _PVRSRV_SYNC_OBJECT + { +diff -Nurd git/drivers/gpu/pvr/services4/include/sgx_bridge.h git/drivers/gpu/pvr/services4/include/sgx_bridge.h +--- git/drivers/gpu/pvr/services4/include/sgx_bridge.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/include/sgx_bridge.h 2008-12-18 15:47:29.000000000 +0100 +@@ -70,8 +70,16 @@ + #define PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+20) + #define PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+21) + #define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+22) ++#if defined(SGX_FEATURE_2D_HARDWARE) ++#define PVRSRV_BRIDGE_SGX_SUBMIT2D PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+23) ++#define PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+24) ++#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+25) ++#endif ++#define PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+26) ++#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+27) ++#define PVRSRV_BRIDGE_SGX_READ_HWPERF_COUNTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+28) + +-#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+22) ++#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+28) + + + typedef struct PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR +@@ -161,8 +169,18 @@ + { + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; +- IMG_DEV_VIRTADDR sHWRenderContextDevVAddr; ++ PVRSRV_TRANSFER_SGX_KICK sKick; + }PVRSRV_BRIDGE_IN_SUBMITTRANSFER; ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++ ++typedef struct PVRSRV_BRIDGE_IN_SUBMIT2D_TAG ++{ ++ IMG_UINT32 ui32BridgeFlags; ++ IMG_HANDLE hDevCookie; ++ PVRSRV_2D_SGX_KICK sKick; ++} PVRSRV_BRIDGE_IN_SUBMIT2D; ++#endif + #endif + + +@@ -330,6 +348,33 @@ + IMG_HANDLE hHWRenderContext; + }PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT; + ++typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG ++{ ++ IMG_UINT32 ui32BridgeFlags; ++ IMG_HANDLE hDevCookie; ++ IMG_HANDLE hHWRenderContext; ++}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT; ++ ++typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG ++{ ++ IMG_UINT32 ui32BridgeFlags; ++ IMG_HANDLE hDevCookie; ++ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; ++}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT; ++ ++typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG ++{ ++ PVRSRV_ERROR eError; ++ IMG_HANDLE hHWTransferContext; ++}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT; ++ ++typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT_TAG ++{ ++ IMG_UINT32 ui32BridgeFlags; ++ IMG_HANDLE hDevCookie; ++ IMG_HANDLE hHWTransferContext; ++}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT; ++ + typedef struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET_TAG + { + IMG_UINT32 ui32BridgeFlags; +@@ -337,18 +382,54 @@ + IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr; + }PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET; + +-typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT_TAG + { + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; +- IMG_HANDLE hHWRenderContext; +-}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT; ++ IMG_DEV_VIRTADDR sHW2DContextDevVAddr; ++}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT; ++ ++typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG ++{ ++ PVRSRV_ERROR eError; ++ IMG_HANDLE hHW2DContext; ++}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT; ++ ++typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT_TAG ++{ ++ IMG_UINT32 ui32BridgeFlags; ++ IMG_HANDLE hDevCookie; ++ IMG_HANDLE hHW2DContext; ++}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT; + +- +-#if defined(SGX_FEATURE_2D_HARDWARE) + #define SGX2D_MAX_BLT_CMD_SIZ 256 + #endif + ++ ++typedef struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_COUNTERS_TAG ++{ ++ IMG_UINT32 ui32BridgeFlags; ++ IMG_HANDLE hDevCookie; ++ IMG_UINT32 ui32PerfReg; ++ IMG_BOOL bNewPerf; ++ IMG_UINT32 ui32NewPerf; ++ IMG_UINT32 ui32NewPerfReset; ++ IMG_UINT32 ui32PerfCountersReg; ++} PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_COUNTERS; ++ ++typedef struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_COUNTERS_TAG ++{ ++ PVRSRV_ERROR eError; ++ IMG_UINT32 ui32OldPerf; ++ IMG_UINT32 aui32Counters[PVRSRV_SGX_HWPERF_NUM_COUNTERS]; ++ IMG_UINT32 ui32KickTACounter; ++ IMG_UINT32 ui32KickTARenderCounter; ++ IMG_UINT32 ui32CPUTime; ++ IMG_UINT32 ui32SGXTime; ++} PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_COUNTERS; ++ + #if defined (__cplusplus) + } + #endif +diff -Nurd git/drivers/gpu/pvr/services4/include/sgx_bridge_km.h git/drivers/gpu/pvr/services4/include/sgx_bridge_km.h +--- git/drivers/gpu/pvr/services4/include/sgx_bridge_km.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/include/sgx_bridge_km.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,139 +0,0 @@ +-/********************************************************************** +- * +- * Copyright(c) 2008 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 +- * +- ******************************************************************************/ +- +-#if !defined(__SGX_BRIDGE_KM_H__) +-#define __SGX_BRIDGE_KM_H__ +- +-#include "sgxapi_km.h" +-#include "sgxinfo.h" +-#include "sgxinfokm.h" +-#include "sgx_bridge.h" +-#include "pvr_bridge.h" +-#include "perproc.h" +- +-#if defined (__cplusplus) +-extern "C" { +-#endif +- +-IMG_IMPORT +-PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, +- IMG_DEV_VIRTADDR sHWRenderContextDevVAddr); +- +-IMG_IMPORT +-PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, +- PVR3DIF4_CCB_KICK *psCCBKick); +- +-IMG_IMPORT +-PVRSRV_ERROR SGXGetPhysPageAddrKM(IMG_HANDLE hDevMemHeap, +- IMG_DEV_VIRTADDR sDevVAddr, +- IMG_DEV_PHYADDR *pDevPAddr, +- IMG_CPU_PHYADDR *pCpuPAddr); +- +-IMG_IMPORT +-PVRSRV_ERROR IMG_CALLCONV SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie, +- IMG_HANDLE hDevMemContext, +- IMG_DEV_PHYADDR *psPDDevPAddr); +- +-IMG_IMPORT +-PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, +- PVR3DIF4_CLIENT_INFO* psClientInfo); +- +-IMG_IMPORT +-PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, +- SGX_MISC_INFO *psMiscInfo); +- +-#if defined(SGX_FEATURE_2D_HARDWARE) +-IMG_IMPORT +-PVRSRV_ERROR SGX2DQueueBlitKM(PVRSRV_SGXDEV_INFO *psDevInfo, +- PVRSRV_KERNEL_SYNC_INFO *psDstSync, +- IMG_UINT32 ui32NumSrcSyncs, +- PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[], +- IMG_UINT32 ui32DataByteSize, +- IMG_UINT32 *pui32BltData); +- +-#if defined(SGX2D_DIRECT_BLITS) +-IMG_IMPORT +-PVRSRV_ERROR SGX2DDirectBlitKM(PVRSRV_SGXDEV_INFO *psDevInfo, +- IMG_UINT32 ui32DataByteSize, +- IMG_UINT32 *pui32BltData); +-#endif +-#endif +- +-#if defined(SGX_FEATURE_2D_HARDWARE) || defined(PVR2D_ALT_2DHW) +-IMG_IMPORT +-PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo, +- PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, +- IMG_BOOL bWaitForComplete); +-#endif +- +-IMG_IMPORT +-PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, +- SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo); +- +-IMG_IMPORT +-PVRSRV_ERROR DevInitSGXPart2KM(PVRSRV_PER_PROCESS_DATA *psPerProc, +- IMG_HANDLE hDevHandle, +- SGX_BRIDGE_INIT_INFO *psInitInfo); +- +-IMG_IMPORT PVRSRV_ERROR +-SGXFindSharedPBDescKM(IMG_HANDLE hDevCookie, +- IMG_UINT32 ui32TotalPBSize, +- IMG_HANDLE *phSharedPBDesc, +- PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo, +- PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo, +- PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo, +- PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos, +- IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount); +- +-IMG_IMPORT PVRSRV_ERROR +-SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc); +- +-IMG_IMPORT PVRSRV_ERROR +-SGXAddSharedPBDescKM(IMG_HANDLE hDevCookie, +- PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo, +- PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo, +- PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo, +- IMG_UINT32 ui32TotalPBSize, +- IMG_HANDLE *phSharedPBDesc, +- PVRSRV_KERNEL_MEM_INFO **psSharedPBDescSubKernelMemInfos, +- IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount); +- +- +-IMG_IMPORT PVRSRV_ERROR +-SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie, +- PVR3DIF4_INTERNAL_DEVINFO *psSGXInternalDevInfo); +- +- +-#if defined(SGX_FEATURE_2D_HARDWARE) +-#define SGX2D_MAX_BLT_CMD_SIZ 256 +-#endif +- +-#if defined (__cplusplus) +-} +-#endif +- +-#endif +- +diff -Nurd git/drivers/gpu/pvr/services4/include/sgxinfo.h git/drivers/gpu/pvr/services4/include/sgxinfo.h +--- git/drivers/gpu/pvr/services4/include/sgxinfo.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/include/sgxinfo.h 2008-12-18 15:47:29.000000000 +0100 +@@ -59,11 +59,16 @@ + #if defined(SGX_SUPPORT_HWPROFILING) + IMG_HANDLE hKernelHWProfilingMemInfo; + #endif ++#if defined(SUPPORT_SGX_HWPERF) ++ IMG_HANDLE hKernelHWPerfCBMemInfo; ++#endif + + IMG_UINT32 ui32EDMTaskReg0; + IMG_UINT32 ui32EDMTaskReg1; + +- IMG_UINT32 ui32ClockGateMask; ++ IMG_UINT32 ui32ClkGateCtl; ++ IMG_UINT32 ui32ClkGateCtl2; ++ IMG_UINT32 ui32ClkGateStatusMask; + + IMG_UINT32 ui32CacheControl; + +@@ -111,11 +116,13 @@ + #define PVRSRV_CCBFLAGS_RASTERCMD 0x1 + #define PVRSRV_CCBFLAGS_TRANSFERCMD 0x2 + #define PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD 0x3 ++#if defined(SGX_FEATURE_2D_HARDWARE) ++#define PVRSRV_CCBFLAGS_2DCMD 0x4 ++#endif + + #define PVRSRV_KICKFLAG_RENDER 0x1 + #define PVRSRV_KICKFLAG_PIXEL 0x2 + +- + #define SGX_BIF_INVALIDATE_PTCACHE 0x1 + #define SGX_BIF_INVALIDATE_PDCACHE 0x2 + +@@ -125,25 +132,40 @@ + PVRSRV_SGX_COMMAND_TYPE eCommand; + PVRSRV_SGX_COMMAND sCommand; + IMG_HANDLE hCCBKernelMemInfo; +- IMG_HANDLE hDstKernelSyncInfo; +- IMG_UINT32 ui32DstReadOpsPendingOffset; +- IMG_UINT32 ui32DstWriteOpsPendingOffset; ++ IMG_HANDLE hRenderSurfSyncInfo; ++ + IMG_UINT32 ui32NumTAStatusVals; +- IMG_UINT32 aui32TAStatusValueOffset[SGX_MAX_TA_STATUS_VALS]; + IMG_HANDLE ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS]; + + IMG_UINT32 ui32Num3DStatusVals; +- IMG_UINT32 aui323DStatusValueOffset[SGX_MAX_3D_STATUS_VALS]; + IMG_HANDLE ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS]; +-#ifdef NO_HARDWARE +- IMG_BOOL bTerminate; +- IMG_HANDLE hUpdateDstKernelSyncInfo; ++ ++ IMG_BOOL bFirstKickOrResume; ++#if (defined(NO_HARDWARE) || defined(PDUMP)) ++ IMG_BOOL bTerminateOrAbort; ++#endif ++ IMG_UINT32 ui32KickFlags; ++ ++ ++ IMG_UINT32 ui32CCBOffset; ++ ++ ++ IMG_UINT32 ui32NumSrcSyncs; ++ IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS]; ++ ++ ++ IMG_BOOL bTADependency; ++ IMG_HANDLE hTA3DSyncInfo; ++ ++ IMG_HANDLE hTASyncInfo; ++ IMG_HANDLE h3DSyncInfo; ++#if defined(NO_HARDWARE) + IMG_UINT32 ui32WriteOpsPendingVal; + #endif +- IMG_UINT32 ui32KickFlags; + } PVR3DIF4_CCB_KICK; + + ++ + typedef struct _PVRSRV_SGX_HOST_CTL_ + { + +@@ -158,163 +180,25 @@ + IMG_UINT32 ui32ResManFlags; + IMG_DEV_VIRTADDR sResManCleanupData; + ++ + IMG_DEV_VIRTADDR sTAHWPBDesc; + IMG_DEV_VIRTADDR s3DHWPBDesc; ++ IMG_DEV_VIRTADDR sHostHWPBDesc; + +-} PVRSRV_SGX_HOST_CTL; +- +- +-#if defined(SUPPORT_HW_RECOVERY) +-typedef struct _SGX_INIT_SCRIPT_DATA +-{ +- IMG_UINT32 asHWRecoveryData[SGX_MAX_DEV_DATA]; +-} SGX_INIT_SCRIPT_DATA; +-#endif +- +-typedef struct _PVRSRV_SGXDEV_INFO_ +-{ +- PVRSRV_DEVICE_TYPE eDeviceType; +- PVRSRV_DEVICE_CLASS eDeviceClass; +- +- IMG_UINT8 ui8VersionMajor; +- IMG_UINT8 ui8VersionMinor; +- IMG_UINT32 ui32CoreConfig; +- IMG_UINT32 ui32CoreFlags; +- +- +- IMG_PVOID pvRegsBaseKM; +- +- +- +- IMG_HANDLE hRegMapping; +- +- +- IMG_SYS_PHYADDR sRegsPhysBase; +- +- IMG_UINT32 ui32RegSize; +- +- +- IMG_UINT32 ui32CoreClockSpeed; +- +-#if defined(SGX_FEATURE_2D_HARDWARE) +- +- SGX_SLAVE_PORT s2DSlavePortKM; +- +- +- PVRSRV_RESOURCE s2DSlaveportResource; +- +- +- IMG_UINT32 ui322DFifoSize; +- IMG_UINT32 ui322DFifoOffset; +- +- IMG_HANDLE h2DCmdCookie; +- +- IMG_HANDLE h2DQueue; +- IMG_BOOL b2DHWRecoveryInProgress; +- IMG_BOOL b2DHWRecoveryEndPending; +- IMG_UINT32 ui322DCompletedBlits; +- IMG_BOOL b2DLockupSuspected; +-#endif +- +- +- IMG_VOID *psStubPBDescListKM; +- +- +- +- IMG_DEV_PHYADDR sKernelPDDevPAddr; +- +- IMG_VOID *pvDeviceMemoryHeap; +- PPVRSRV_KERNEL_MEM_INFO psKernelCCBMemInfo; +- PVRSRV_SGX_KERNEL_CCB *psKernelCCB; +- PPVRSRV_SGX_CCB_INFO psKernelCCBInfo; +- PPVRSRV_KERNEL_MEM_INFO psKernelCCBCtlMemInfo; +- PVRSRV_SGX_CCB_CTL *psKernelCCBCtl; +- PPVRSRV_KERNEL_MEM_INFO psKernelCCBEventKickerMemInfo; +- IMG_UINT32 *pui32KernelCCBEventKicker; +- IMG_UINT32 ui32TAKickAddress; +- IMG_UINT32 ui32TexLoadKickAddress; +- IMG_UINT32 ui32VideoHandlerAddress; +-#if defined(SGX_SUPPORT_HWPROFILING) +- PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo; +-#endif +- +- +- IMG_UINT32 ui32ClientRefCount; +- +- +- IMG_UINT32 ui32CacheControl; +- +- +- +- +- IMG_VOID *pvMMUContextList; +- +- +- IMG_BOOL bForcePTOff; +- +- IMG_UINT32 ui32EDMTaskReg0; +- IMG_UINT32 ui32EDMTaskReg1; +- +- IMG_UINT32 ui32ClockGateMask; +- SGX_INIT_SCRIPTS sScripts; +-#if defined(SUPPORT_HW_RECOVERY) +- SGX_INIT_SCRIPT_DATA sScriptData; +-#endif +- +- IMG_HANDLE hBIFResetPDOSMemHandle; +- IMG_DEV_PHYADDR sBIFResetPDDevPAddr; +- IMG_DEV_PHYADDR sBIFResetPTDevPAddr; +- IMG_DEV_PHYADDR sBIFResetPageDevPAddr; +- IMG_UINT32 *pui32BIFResetPD; +- IMG_UINT32 *pui32BIFResetPT; +- +- +- +-#if defined(SUPPORT_HW_RECOVERY) +- +- IMG_HANDLE hTimer; +- +- IMG_UINT32 ui32TimeStamp; +-#endif +- +- +- IMG_UINT32 ui32NumResets; +- +- PVRSRV_KERNEL_MEM_INFO *psKernelSGXHostCtlMemInfo; +- PVRSRV_SGX_HOST_CTL *psSGXHostCtl; +- +- IMG_UINT32 ui32Flags; +- +- +- IMG_UINT32 ui32RegFlags; +- +- #if defined(PDUMP) +- PVRSRV_SGX_PDUMP_CONTEXT sPDContext; +- #endif ++ IMG_UINT32 ui32NumActivePowerEvents; + +-#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) +- +- IMG_VOID *pvDummyPTPageCpuVAddr; +- IMG_DEV_PHYADDR sDummyPTDevPAddr; +- IMG_HANDLE hDummyPTPageOSMemHandle; +- IMG_VOID *pvDummyDataPageCpuVAddr; +- IMG_DEV_PHYADDR sDummyDataDevPAddr; +- IMG_HANDLE hDummyDataPageOSMemHandle; ++#if defined(SUPPORT_SGX_HWPERF) ++ IMG_UINT32 ui32HWPerfFlags; + #endif + +- IMG_UINT32 asSGXDevData[SGX_MAX_DEV_DATA]; + +-#if defined(SUPPORT_SGX_EVENT_OBJECT) +- PVRSRV_EVENTOBJECT *psSGXEventObject; +-#endif ++ ++ IMG_UINT32 ui32TimeWraps; ++} PVRSRV_SGX_HOST_CTL; + +-} PVRSRV_SGXDEV_INFO; + + typedef struct _PVR3DIF4_CLIENT_INFO_ + { +- IMG_VOID *pvRegsBase; +- IMG_HANDLE hBlockMapping; +- SGX_SLAVE_PORT s2DSlavePort; + IMG_UINT32 ui32ProcessID; + IMG_VOID *pvProcess; + PVRSRV_MISC_INFO sMiscInfo; +@@ -330,13 +214,9 @@ + typedef struct _PVR3DIF4_INTERNAL_DEVINFO_ + { + IMG_UINT32 ui32Flags; +- IMG_BOOL bTimerEnable; + IMG_HANDLE hCtlKernelMemInfoHandle; + IMG_BOOL bForcePTOff; + IMG_UINT32 ui32RegFlags; +-#if defined(SUPPORT_SGX_EVENT_OBJECT) +- IMG_HANDLE hOSEvent; +-#endif + } PVR3DIF4_INTERNAL_DEVINFO; + + typedef struct _PVRSRV_SGX_SHARED_CCB_ +@@ -371,5 +251,150 @@ + #endif + }PVRSRV_SGX_CCB; + ++typedef struct _CTL_STATUS_ ++{ ++ IMG_DEV_VIRTADDR sStatusDevAddr; ++ IMG_UINT32 ui32StatusValue; ++} CTL_STATUS, *PCTL_STATUS; ++ ++#if defined(TRANSFER_QUEUE) ++#define SGXTQ_MAX_STATUS 5 ++typedef struct _PVR3DIF4_CMDTA_SHARED_ ++{ ++ IMG_UINT32 ui32NumTAStatusVals; ++ IMG_UINT32 ui32Num3DStatusVals; ++ ++ ++ IMG_UINT32 ui32WriteOpsPendingVal; ++ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; ++ IMG_UINT32 ui32ReadOpsPendingVal; ++ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; ++ ++ ++ IMG_UINT32 ui32TQSyncWriteOpsPendingVal; ++ IMG_DEV_VIRTADDR sTQSyncWriteOpsCompleteDevVAddr; ++ IMG_UINT32 ui32TQSyncReadOpsPendingVal; ++ IMG_DEV_VIRTADDR sTQSyncReadOpsCompleteDevVAddr; ++ ++ ++ IMG_UINT32 ui323DTQSyncWriteOpsPendingVal; ++ IMG_DEV_VIRTADDR s3DTQSyncWriteOpsCompleteDevVAddr; ++ IMG_UINT32 ui323DTQSyncReadOpsPendingVal; ++ IMG_DEV_VIRTADDR s3DTQSyncReadOpsCompleteDevVAddr; ++ ++ ++ IMG_UINT32 ui32NumSrcSyncs; ++ PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS]; ++ ++ CTL_STATUS sCtlTAStatusInfo[SGX_MAX_TA_STATUS_VALS]; ++ CTL_STATUS sCtl3DStatusInfo[SGX_MAX_3D_STATUS_VALS]; ++ ++ PVRSRV_DEVICE_SYNC_OBJECT sTA3DDependancy; ++ ++} PVR3DIF4_CMDTA_SHARED; ++ ++typedef struct _PVR3DIF4_TRANSFERCMD_SHARED_ ++{ ++ ++ ++ IMG_UINT32 ui32SrcReadOpPendingVal; ++ IMG_DEV_VIRTADDR sSrcReadOpsCompleteDevAddr; ++ ++ IMG_UINT32 ui32SrcWriteOpPendingVal; ++ IMG_DEV_VIRTADDR sSrcWriteOpsCompleteDevAddr; ++ ++ ++ ++ IMG_UINT32 ui32DstReadOpPendingVal; ++ IMG_DEV_VIRTADDR sDstReadOpsCompleteDevAddr; ++ ++ IMG_UINT32 ui32DstWriteOpPendingVal; ++ IMG_DEV_VIRTADDR sDstWriteOpsCompleteDevAddr; ++ ++ ++ IMG_UINT32 ui32TASyncWriteOpsPendingVal; ++ IMG_DEV_VIRTADDR sTASyncWriteOpsCompleteDevVAddr; ++ IMG_UINT32 ui32TASyncReadOpsPendingVal; ++ IMG_DEV_VIRTADDR sTASyncReadOpsCompleteDevVAddr; ++ ++ ++ IMG_UINT32 ui323DSyncWriteOpsPendingVal; ++ IMG_DEV_VIRTADDR s3DSyncWriteOpsCompleteDevVAddr; ++ IMG_UINT32 ui323DSyncReadOpsPendingVal; ++ IMG_DEV_VIRTADDR s3DSyncReadOpsCompleteDevVAddr; ++ ++ IMG_UINT32 ui32NumStatusVals; ++ CTL_STATUS sCtlStatusInfo[SGXTQ_MAX_STATUS]; ++ ++ IMG_UINT32 ui32NumSrcSync; ++ IMG_UINT32 ui32NumDstSync; ++ ++ IMG_DEV_VIRTADDR sSrcWriteOpsDevVAddr[SGX_MAX_TRANSFER_SYNC_OPS]; ++ IMG_DEV_VIRTADDR sSrcReadOpsDevVAddr[SGX_MAX_TRANSFER_SYNC_OPS]; ++ ++ IMG_DEV_VIRTADDR sDstWriteOpsDevVAddr[SGX_MAX_TRANSFER_SYNC_OPS]; ++ IMG_DEV_VIRTADDR sDstReadOpsDevVAddr[SGX_MAX_TRANSFER_SYNC_OPS]; ++} PVR3DIF4_TRANSFERCMD_SHARED, *PPVR3DIF4_TRANSFERCMD_SHARED; ++ ++typedef struct _PVRSRV_TRANSFER_SGX_KICK_ ++{ ++ IMG_HANDLE hCCBMemInfo; ++ IMG_UINT32 ui32SharedCmdCCBOffset; ++ ++ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; ++ ++ IMG_HANDLE hTASyncInfo; ++ IMG_HANDLE h3DSyncInfo; ++ ++ IMG_UINT32 ui32NumSrcSync; ++ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS]; ++ ++ IMG_UINT32 ui32NumDstSync; ++ IMG_HANDLE ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS]; ++ ++ IMG_UINT32 ui32StatusFirstSync; ++} PVRSRV_TRANSFER_SGX_KICK, *PPVRSRV_TRANSFER_SGX_KICK; ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++typedef struct _PVR3DIF4_2DCMD_SHARED_ { ++ ++ IMG_UINT32 ui32NumSrcSync; ++ PVRSRV_DEVICE_SYNC_OBJECT sSrcSyncData[SGX_MAX_2D_SRC_SYNC_OPS]; ++ ++ ++ PVRSRV_DEVICE_SYNC_OBJECT sDstSyncData; ++ ++ ++ PVRSRV_DEVICE_SYNC_OBJECT sTASyncData; ++ ++ ++ PVRSRV_DEVICE_SYNC_OBJECT s3DSyncData; ++} PVR3DIF4_2DCMD_SHARED, *PPVR3DIF4_2DCMD_SHARED; ++ ++typedef struct _PVRSRV_2D_SGX_KICK_ ++{ ++ IMG_HANDLE hCCBMemInfo; ++ IMG_UINT32 ui32SharedCmdCCBOffset; ++ ++ IMG_DEV_VIRTADDR sHW2DContextDevVAddr; ++ ++ IMG_UINT32 ui32NumSrcSync; ++ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS]; ++ ++ ++ IMG_HANDLE hDstSyncInfo; ++ ++ ++ IMG_HANDLE hTASyncInfo; ++ ++ ++ IMG_HANDLE h3DSyncInfo; ++ ++} PVRSRV_2D_SGX_KICK, *PPVRSRV_2D_SGX_KICK; ++#endif ++#endif ++ ++#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 9 ++ + + #endif +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c git/drivers/gpu/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c +--- git/drivers/gpu/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c 2008-12-18 15:47:29.000000000 +0100 +@@ -44,7 +44,6 @@ + #include "bridged_pvr_bridge.h" + #include "env_data.h" + +- + #if defined (__linux__) + #include "mmap.h" + #else +@@ -66,7 +65,7 @@ + + static IMG_BOOL gbInitServerRunning = IMG_FALSE; + static IMG_BOOL gbInitServerRan = IMG_FALSE; +-static IMG_BOOL gbInitServerSuccessful = IMG_FALSE; ++static IMG_BOOL gbInitSuccessful = IMG_FALSE; + + PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT]; + +@@ -446,7 +445,13 @@ + } + + +- ++#if defined(OS_PVRSRV_ALLOC_DEVICE_MEM_BW) ++int ++PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN, ++ PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc); ++#else + static int + PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN, +@@ -512,7 +517,7 @@ + psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; + psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; + psAllocDeviceMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize; +- psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = IMG_NULL; ++ psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle; + + psAllocDeviceMemOUT->eError = + PVRSRVAllocHandle(psPerProc->psHandleBase, +@@ -568,6 +573,7 @@ + return 0; + } + ++#endif + + static int + PVRSRVFreeDeviceMemBW(IMG_UINT32 ui32BridgeID, +@@ -1547,12 +1553,12 @@ + return 0; + } + +- if(psDoKickIN->sCCBKick.hDstKernelSyncInfo != IMG_NULL) ++ if(psDoKickIN->sCCBKick.hTA3DSyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, +- &psDoKickIN->sCCBKick.hDstKernelSyncInfo, +- psDoKickIN->sCCBKick.hDstKernelSyncInfo, ++ &psDoKickIN->sCCBKick.hTA3DSyncInfo, ++ psDoKickIN->sCCBKick.hTA3DSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) +@@ -1561,13 +1567,12 @@ + } + } + +-#if defined (NO_HARDWARE) +- if(psDoKickIN->sCCBKick.hUpdateDstKernelSyncInfo != IMG_NULL) ++ if(psDoKickIN->sCCBKick.hTASyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, +- &psDoKickIN->sCCBKick.hUpdateDstKernelSyncInfo, +- psDoKickIN->sCCBKick.hUpdateDstKernelSyncInfo, ++ &psDoKickIN->sCCBKick.hTASyncInfo, ++ psDoKickIN->sCCBKick.hTASyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) +@@ -1575,7 +1580,46 @@ + return 0; + } + } +-#endif ++ ++ if(psDoKickIN->sCCBKick.h3DSyncInfo != IMG_NULL) ++ { ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psDoKickIN->sCCBKick.h3DSyncInfo, ++ psDoKickIN->sCCBKick.h3DSyncInfo, ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ } ++ ++ ++ if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS) ++ { ++ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; ++ return 0; ++ } ++ for(i=0; i<psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++) ++ { ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i], ++ psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i], ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ } ++ ++ if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS) ++ { ++ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; ++ return 0; ++ } + for (i = 0; i < psDoKickIN->sCCBKick.ui32NumTAStatusVals; i++) + { + psRetOUT->eError = +@@ -1590,6 +1634,11 @@ + } + } + ++ if (psDoKickIN->sCCBKick.ui32Num3DStatusVals > SGX_MAX_3D_STATUS_VALS) ++ { ++ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; ++ return 0; ++ } + for(i = 0; i < psDoKickIN->sCCBKick.ui32Num3DStatusVals; i++) + { + psRetOUT->eError = +@@ -1604,6 +1653,20 @@ + } + } + ++ if(psDoKickIN->sCCBKick.hRenderSurfSyncInfo != IMG_NULL) ++ { ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psDoKickIN->sCCBKick.hRenderSurfSyncInfo, ++ psDoKickIN->sCCBKick.hRenderSurfSyncInfo, ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ } ++ + psRetOUT->eError = + SGXDoKickKM(hDevCookieInt, + &psDoKickIN->sCCBKick); +@@ -1620,51 +1683,119 @@ + PVRSRV_PER_PROCESS_DATA *psPerProc) + { + IMG_HANDLE hDevCookieInt; ++ PVRSRV_TRANSFER_SGX_KICK *psKick; ++ IMG_UINT32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMITTRANSFER); + PVR_UNREFERENCED_PARAMETER(ui32BridgeID); + ++ psKick = &psSubmitTransferIN->sKick; ++ + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSubmitTransferIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); +- + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = +- SGXSubmitTransferKM(hDevCookieInt, +- psSubmitTransferIN->sHWRenderContextDevVAddr); ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->hCCBMemInfo, ++ psKick->hCCBMemInfo, ++ PVRSRV_HANDLE_TYPE_MEM_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ if (psKick->hTASyncInfo != IMG_NULL) ++ { ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->hTASyncInfo, ++ psKick->hTASyncInfo, ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ } ++ ++ if (psKick->h3DSyncInfo != IMG_NULL) ++ { ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->h3DSyncInfo, ++ psKick->h3DSyncInfo, ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ } ++ ++ if (psKick->ui32NumSrcSync > SGX_MAX_TRANSFER_SYNC_OPS) ++ { ++ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; ++ return 0; ++ } ++ for (i = 0; i < psKick->ui32NumSrcSync; i++) ++ { ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->ahSrcSyncInfo[i], ++ psKick->ahSrcSyncInfo[i], ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ } ++ ++ if (psKick->ui32NumDstSync > SGX_MAX_TRANSFER_SYNC_OPS) ++ { ++ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; ++ return 0; ++ } ++ for (i = 0; i < psKick->ui32NumDstSync; i++) ++ { ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->ahDstSyncInfo[i], ++ psKick->ahDstSyncInfo[i], ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ } ++ ++ psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick); + + return 0; + } +-#endif + ++#if defined(SGX_FEATURE_2D_HARDWARE) + static int +-SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID, +- PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN, +- PVRSRV_BRIDGE_RETURN *psRetOUT, +- PVRSRV_PER_PROCESS_DATA *psPerProc) ++SGXSubmit2DBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_SUBMIT2D *psSubmit2DIN, ++ PVRSRV_BRIDGE_RETURN *psRetOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) + { + IMG_HANDLE hDevCookieInt; +- PVRSRV_SGXDEV_INFO *psDevInfo; +- SGX_MISC_INFO *psMiscInfo; +- +- +- PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETMISCINFO); ++ PVRSRV_2D_SGX_KICK *psKick; ++ IMG_UINT32 i; + +- +- psMiscInfo = +- (SGX_MISC_INFO *)((IMG_UINT8 *)psSGXGetMiscInfoIN +- + sizeof(PVRSRV_BRIDGE_IN_SGXGETMISCINFO)); ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMIT2D); ++ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); + + psRetOUT->eError = +- PVRSRVLookupHandle(psPerProc->psHandleBase, +- &hDevCookieInt, +- psSGXGetMiscInfoIN->hDevCookie, ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &hDevCookieInt, ++ psSubmit2DIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psRetOUT->eError != PVRSRV_OK) +@@ -1672,45 +1803,156 @@ + return 0; + } + +- psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; ++ psKick = &psSubmit2DIN->sKick; + +- if(CopyFromUserWrapper(psPerProc, +- ui32BridgeID, +- psMiscInfo, +- psSGXGetMiscInfoIN->psMiscInfo, +- sizeof(SGX_MISC_INFO)) != PVRSRV_OK) ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->hCCBMemInfo, ++ psKick->hCCBMemInfo, ++ PVRSRV_HANDLE_TYPE_MEM_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) + { +- return -EFAULT; ++ return 0; + } + +- switch(psMiscInfo->eRequest) ++ if (psKick->hTASyncInfo != IMG_NULL) + { +- default: +- break; ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->hTASyncInfo, ++ psKick->hTASyncInfo, ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } + } + +- +- psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, psMiscInfo); ++ if (psKick->h3DSyncInfo != IMG_NULL) ++ { ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->h3DSyncInfo, ++ psKick->h3DSyncInfo, ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ } + +- +- switch(psMiscInfo->eRequest) ++ if (psKick->ui32NumSrcSync > SGX_MAX_2D_SRC_SYNC_OPS) + { +- default: +- break; ++ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; ++ return 0; ++ } ++ for (i = 0; i < psKick->ui32NumSrcSync; i++) ++ { ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->ahSrcSyncInfo[i], ++ psKick->ahSrcSyncInfo[i], ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } + } + +- if(CopyToUserWrapper(psPerProc, +- ui32BridgeID, +- psSGXGetMiscInfoIN->psMiscInfo, +- psMiscInfo, +- sizeof(SGX_MISC_INFO)) != PVRSRV_OK) ++ if (psKick->hDstSyncInfo != IMG_NULL) + { +- return -EFAULT; ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psKick->hDstSyncInfo, ++ psKick->hDstSyncInfo, ++ PVRSRV_HANDLE_TYPE_SYNC_INFO); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } + } + ++ psRetOUT->eError = ++ SGXSubmit2DKM(hDevCookieInt, psKick); ++ ++ return 0; ++} ++#endif ++ ++#endif ++ ++static int ++SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN, ++ PVRSRV_BRIDGE_RETURN *psRetOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) ++{ ++ IMG_HANDLE hDevCookieInt; ++ PVRSRV_SGXDEV_INFO *psDevInfo; ++ SGX_MISC_INFO *psMiscInfo; ++ ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, ++ PVRSRV_BRIDGE_SGX_GETMISCINFO); ++ ++ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &hDevCookieInt, ++ psSGXGetMiscInfoIN->hDevCookie, ++ PVRSRV_HANDLE_TYPE_DEV_NODE); ++ ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE*)hDevCookieInt)->pvDevice; ++ ++ psMiscInfo = psSGXGetMiscInfoIN->psMiscInfo; ++ psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, psMiscInfo); ++ + return 0; + } + ++#if defined(SUPPORT_SGX_HWPERF) ++static int ++SGXReadHWPerfCountersBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_COUNTERS *psSGXReadHWPerfCountersIN, ++ PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_COUNTERS *psSGXReadHWPerfCountersOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) ++{ ++ IMG_HANDLE hDevCookieInt; ++ PVRSRV_SGXDEV_INFO *psDevInfo; ++ ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_READ_HWPERF_COUNTERS); ++ ++ psSGXReadHWPerfCountersOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &hDevCookieInt, ++ psSGXReadHWPerfCountersIN->hDevCookie, ++ PVRSRV_HANDLE_TYPE_DEV_NODE); ++ ++ if(psSGXReadHWPerfCountersOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ psDevInfo = ((PVRSRV_DEVICE_NODE*)hDevCookieInt)->pvDevice; ++ ++ psSGXReadHWPerfCountersOUT->eError = SGXReadHWPerfCountersKM(psDevInfo, ++ psSGXReadHWPerfCountersIN->ui32PerfReg, ++ &psSGXReadHWPerfCountersOUT->ui32OldPerf, ++ psSGXReadHWPerfCountersIN->bNewPerf, ++ psSGXReadHWPerfCountersIN->ui32NewPerf, ++ psSGXReadHWPerfCountersIN->ui32NewPerfReset, ++ psSGXReadHWPerfCountersIN->ui32PerfCountersReg, ++ &psSGXReadHWPerfCountersOUT->aui32Counters[0], ++ &psSGXReadHWPerfCountersOUT->ui32KickTACounter, ++ &psSGXReadHWPerfCountersOUT->ui32KickTARenderCounter, ++ &psSGXReadHWPerfCountersOUT->ui32CPUTime, ++ &psSGXReadHWPerfCountersOUT->ui32SGXTime); ++ ++ return 0; ++} ++#endif ++ + static int + PVRSRVInitSrvConnectBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, +@@ -1752,15 +1994,13 @@ + return 0; + } + +- PDUMPENDINITPHASE(); +- +- gbInitServerSuccessful = psInitSrvDisconnectIN->bInitSuccesful; +- + psPerProc->bInitProcess = IMG_FALSE; + gbInitServerRunning = IMG_FALSE; + gbInitServerRan = IMG_TRUE; + +- psRetOUT->eError = PVRSRV_OK; ++ psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful); ++ ++ gbInitSuccessful = (IMG_BOOL)(((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful))); + + return 0; + } +@@ -1772,15 +2012,99 @@ + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) + { ++ IMG_HANDLE hOSEventKM; ++ + PVR_UNREFERENCED_PARAMETER(psPerProc); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT); + +- psRetOUT->eError = OSEventObjectWait(psEventObjectWaitIN->hOSEventKM, psEventObjectWaitIN->ui32MSTimeout); ++ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &hOSEventKM, ++ psEventObjectWaitIN->hOSEventKM, ++ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); ++ ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ psRetOUT->eError = OSEventObjectWait(hOSEventKM); ++ ++ return 0; ++} ++ ++static int ++PVRSRVEventObjectOpenBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN, ++ PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) ++{ ++ ++ PVR_UNREFERENCED_PARAMETER(psPerProc); ++ ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN); ++ ++ psEventObjectOpenOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psEventObjectOpenIN->sEventObject.hOSEventKM, ++ psEventObjectOpenIN->sEventObject.hOSEventKM, ++ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); ++ ++ if(psEventObjectOpenOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ psEventObjectOpenOUT->eError = OSEventObjectOpen(&psEventObjectOpenIN->sEventObject, &psEventObjectOpenOUT->hOSEvent); ++ ++ if(psEventObjectOpenOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ psEventObjectOpenOUT->eError = ++ PVRSRVAllocHandle(psPerProc->psHandleBase, ++ &psEventObjectOpenOUT->hOSEvent, ++ psEventObjectOpenOUT->hOSEvent, ++ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, ++ PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + return 0; + } ++static int ++PVRSRVEventObjectCloseBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN, ++ PVRSRV_BRIDGE_RETURN *psRetOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) ++{ ++ IMG_HANDLE hOSEventKM; ++ ++ PVR_UNREFERENCED_PARAMETER(psPerProc); ++ ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE); ++ ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &psEventObjectCloseIN->sEventObject.hOSEventKM, ++ psEventObjectCloseIN->sEventObject.hOSEventKM, ++ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, ++ &hOSEventKM, ++ psEventObjectCloseIN->hOSEventKM, ++ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); + ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ psRetOUT->eError = OSEventObjectClose(&psEventObjectCloseIN->sEventObject, hOSEventKM); ++ ++ return 0; ++} + + static int + SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID, +@@ -1847,6 +2171,13 @@ + bLookupFailed |= (eError != PVRSRV_OK); + #endif + ++#if defined(SUPPORT_SGX_HWPERF) ++ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &hDummy, ++ psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo, ++ PVRSRV_HANDLE_TYPE_MEM_INFO); ++ bLookupFailed |= (eError != PVRSRV_OK); ++#endif + + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) +@@ -1907,6 +2238,13 @@ + bReleaseFailed |= (eError != PVRSRV_OK); + #endif + ++#if defined(SUPPORT_SGX_HWPERF) ++ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, ++ &psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo, ++ psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo, ++ PVRSRV_HANDLE_TYPE_MEM_INFO); ++ bReleaseFailed |= (eError != PVRSRV_OK); ++#endif + + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) +@@ -1950,6 +2288,10 @@ + bDissociateFailed |= (eError != PVRSRV_OK); + #endif + ++#if defined(SUPPORT_SGX_HWPERF) ++ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo); ++ bDissociateFailed |= (eError != PVRSRV_OK); ++#endif + + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) +@@ -2005,7 +2347,6 @@ + PVRSRV_PER_PROCESS_DATA *psPerProc) + { + IMG_HANDLE hDevCookieInt; +- PVRSRV_SGXDEV_INFO *psDevInfo; + IMG_HANDLE hHWRenderContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT); +@@ -2020,10 +2361,8 @@ + return 0; + } + +- psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; +- + hHWRenderContextInt = +- SGXRegisterHWRenderContextKM(psDevInfo, ++ SGXRegisterHWRenderContextKM(hDevCookieInt, + &psSGXRegHWRenderContextIN->sHWRenderContextDevVAddr); + + if (hHWRenderContextInt == IMG_NULL) +@@ -2043,54 +2382,180 @@ + } + + static int +-SGXFlushHWRenderTargetBW(IMG_UINT32 ui32BridgeID, +- PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET *psSGXFlushHWRenderTargetIN, +- PVRSRV_BRIDGE_RETURN *psRetOUT, +- PVRSRV_PER_PROCESS_DATA *psPerProc) ++SGXUnregisterHWRenderContextBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT *psSGXUnregHWRenderContextIN, ++ PVRSRV_BRIDGE_RETURN *psRetOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) + { +- IMG_HANDLE hDevCookieInt; +- PVRSRV_SGXDEV_INFO *psDevInfo; +- +- PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET); ++ IMG_HANDLE hHWRenderContextInt; ++ ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT); + + psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &hHWRenderContextInt, ++ psSGXUnregHWRenderContextIN->hHWRenderContext, ++ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ psRetOUT->eError = ++ PVRSRVReleaseHandle(psPerProc->psHandleBase, ++ psSGXUnregHWRenderContextIN->hHWRenderContext, ++ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); ++ ++ return 0; ++} ++ ++static int ++SGXRegisterHWTransferContextBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextIN, ++ PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) ++{ ++ IMG_HANDLE hDevCookieInt; ++ IMG_HANDLE hHWTransferContextInt; ++ ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT); ++ ++ psSGXRegHWTransferContextOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, +- psSGXFlushHWRenderTargetIN->hDevCookie, ++ psSGXRegHWTransferContextIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); ++ if(psSGXRegHWTransferContextOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ hHWTransferContextInt = ++ SGXRegisterHWTransferContextKM(hDevCookieInt, ++ &psSGXRegHWTransferContextIN->sHWTransferContextDevVAddr); ++ ++ if (hHWTransferContextInt == IMG_NULL) ++ { ++ psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_GENERIC; ++ return 0; ++ } ++ ++ psSGXRegHWTransferContextOUT->eError = ++ PVRSRVAllocHandle(psPerProc->psHandleBase, ++ &psSGXRegHWTransferContextOUT->hHWTransferContext, ++ hHWTransferContextInt, ++ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT, ++ PVRSRV_HANDLE_ALLOC_FLAG_NONE); ++ ++ return 0; ++} ++ ++static int ++SGXUnregisterHWTransferContextBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT *psSGXUnregHWTransferContextIN, ++ PVRSRV_BRIDGE_RETURN *psRetOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) ++{ ++ IMG_HANDLE hHWTransferContextInt; ++ ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT); ++ ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &hHWTransferContextInt, ++ psSGXUnregHWTransferContextIN->hHWTransferContext, ++ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + ++ psRetOUT->eError = SGXUnregisterHWTransferContextKM(hHWTransferContextInt); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ psRetOUT->eError = ++ PVRSRVReleaseHandle(psPerProc->psHandleBase, ++ psSGXUnregHWTransferContextIN->hHWTransferContext, ++ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); ++ ++ return 0; ++} ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++static int ++SGXRegisterHW2DContextBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextIN, ++ PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) ++{ ++ IMG_HANDLE hDevCookieInt; ++ PVRSRV_SGXDEV_INFO *psDevInfo; ++ IMG_HANDLE hHW2DContextInt; ++ ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT); ++ ++ psSGXRegHW2DContextOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &hDevCookieInt, ++ psSGXRegHW2DContextIN->hDevCookie, ++ PVRSRV_HANDLE_TYPE_DEV_NODE); ++ if(psSGXRegHW2DContextOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ + psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; + +- SGXFlushHWRenderTargetKM(psDevInfo, psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr); ++ hHW2DContextInt = ++ SGXRegisterHW2DContextKM(hDevCookieInt, ++ &psSGXRegHW2DContextIN->sHW2DContextDevVAddr); ++ ++ if (hHW2DContextInt == IMG_NULL) ++ { ++ psSGXRegHW2DContextOUT->eError = PVRSRV_ERROR_GENERIC; ++ return 0; ++ } ++ ++ psSGXRegHW2DContextOUT->eError = ++ PVRSRVAllocHandle(psPerProc->psHandleBase, ++ &psSGXRegHW2DContextOUT->hHW2DContext, ++ hHW2DContextInt, ++ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT, ++ PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + return 0; + } + + static int +-SGXUnregisterHWRenderContextBW(IMG_UINT32 ui32BridgeID, +- PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT *psSGXUnregHWRenderContextIN, ++SGXUnregisterHW2DContextBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT *psSGXUnregHW2DContextIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) + { +- IMG_HANDLE hHWRenderContextInt; ++ IMG_HANDLE hHW2DContextInt; + +- PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT); ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, +- &hHWRenderContextInt, +- psSGXUnregHWRenderContextIN->hHWRenderContext, +- PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); ++ &hHW2DContextInt, ++ psSGXUnregHW2DContextIN->hHW2DContext, ++ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + +- psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt); ++ psRetOUT->eError = SGXUnregisterHW2DContextKM(hHW2DContextInt); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; +@@ -2098,11 +2563,37 @@ + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, +- psSGXUnregHWRenderContextIN->hHWRenderContext, +- PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); ++ psSGXUnregHW2DContextIN->hHW2DContext, ++ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT); + + return 0; + } ++#endif ++ ++static int ++SGXFlushHWRenderTargetBW(IMG_UINT32 ui32BridgeID, ++ PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET *psSGXFlushHWRenderTargetIN, ++ PVRSRV_BRIDGE_RETURN *psRetOUT, ++ PVRSRV_PER_PROCESS_DATA *psPerProc) ++{ ++ IMG_HANDLE hDevCookieInt; ++ ++ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET); ++ ++ psRetOUT->eError = ++ PVRSRVLookupHandle(psPerProc->psHandleBase, ++ &hDevCookieInt, ++ psSGXFlushHWRenderTargetIN->hDevCookie, ++ PVRSRV_HANDLE_TYPE_DEV_NODE); ++ if(psRetOUT->eError != PVRSRV_OK) ++ { ++ return 0; ++ } ++ ++ SGXFlushHWRenderTargetKM(hDevCookieInt, psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr); ++ ++ return 0; ++} + + #if defined(SGX_FEATURE_2D_HARDWARE) + +@@ -2679,16 +3170,63 @@ + PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) + { ++ PVRSRV_ERROR eError; ++ + PVR_UNREFERENCED_PARAMETER(psPerProc); +- + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO); + + OSMemCopy(&psGetMiscInfoOUT->sMiscInfo, + &psGetMiscInfoIN->sMiscInfo, + sizeof(PVRSRV_MISC_INFO)); + +- psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoIN->sMiscInfo); +- psGetMiscInfoOUT->sMiscInfo = psGetMiscInfoIN->sMiscInfo; ++ if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) ++ { ++ ++ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ++ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen, ++ (IMG_VOID **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0); ++ if(eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Out of memory")); ++ return -EFAULT; ++ } ++ ++ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo); ++ ++ ++ eError = CopyToUserWrapper(psPerProc, ui32BridgeID, ++ psGetMiscInfoIN->sMiscInfo.pszMemoryStr, ++ psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, ++ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen); ++ ++ ++ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ++ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen, ++ (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0); ++ ++ ++ psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr; ++ ++ if(eError != PVRSRV_OK) ++ { ++ ++ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user")); ++ return -EFAULT; ++ } ++ } ++ else ++ { ++ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo); ++ } ++ ++ if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) ++ { ++ psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase, ++ &psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM, ++ psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM, ++ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, ++ PVRSRV_HANDLE_ALLOC_FLAG_SHARED); ++ } + + return 0; + } +@@ -3526,6 +4064,7 @@ + psKernelMemInfo->ui32Flags; + psAllocSharedSysMemOUT->sClientMemInfo.ui32AllocSize = + psKernelMemInfo->ui32AllocSize; ++ psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle; + psAllocSharedSysMemOUT->eError = + PVRSRVAllocHandle(psPerProc->psHandleBase, + &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo, +@@ -3641,7 +4180,7 @@ + psKernelMemInfo->ui32Flags; + psMapMemInfoMemOUT->sClientMemInfo.ui32AllocSize = + psKernelMemInfo->ui32AllocSize; +- psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = IMG_NULL; ++ psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle; + psMapMemInfoMemOUT->eError = + PVRSRVAllocSubHandle(psPerProc->psHandleBase, + &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo, +@@ -3972,6 +4511,8 @@ + + + SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT, PVRSRVEventObjectWaitBW); ++ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN, PVRSRVEventObjectOpenBW); ++ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, PVRSRVEventObjectCloseBW); + + + #if defined(SUPPORT_SGX1) +@@ -4009,7 +4550,18 @@ + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT, SGXRegisterHWRenderContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET, SGXFlushHWRenderTargetBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT, SGXUnregisterHWRenderContextBW); +- ++#if defined(SGX_FEATURE_2D_HARDWARE) ++#if defined(TRANSFER_QUEUE) ++ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMIT2D, SGXSubmit2DBW); ++#endif ++ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT, SGXRegisterHW2DContextBW); ++ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT, SGXUnregisterHW2DContextBW); ++#endif ++ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT, SGXRegisterHWTransferContextBW); ++ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT, SGXUnregisterHWTransferContextBW); ++#endif ++#if defined(SUPPORT_SGX_HWPERF) ++ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_COUNTERS, SGXReadHWPerfCountersBW); + #endif + + +@@ -4059,7 +4611,7 @@ + { + if(gbInitServerRan) + { +- if(!gbInitServerSuccessful) ++ if(!gbInitSuccessful) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed. Driver unusable.", + __FUNCTION__)); +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/common/deviceclass.c git/drivers/gpu/pvr/services4/srvkm/common/deviceclass.c +--- git/drivers/gpu/pvr/services4/srvkm/common/deviceclass.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/common/deviceclass.c 2008-12-18 15:47:29.000000000 +0100 +@@ -24,7 +24,6 @@ + * + ******************************************************************************/ + +-#include <linux/module.h> + #include "services_headers.h" + #include "buffer_manager.h" + #include "kernelbuffer.h" +@@ -1128,7 +1127,8 @@ + + + apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo; +- if(psBuffer->psSwapChain->psLastFlipBuffer) ++ if(psBuffer->psSwapChain->psLastFlipBuffer && ++ psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) + { + apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; + ui32NumSrcSyncs++; +@@ -1389,7 +1389,7 @@ + } + + +-IMG_VOID PVRSRVSetDCState(IMG_UINT32 ui32State) ++IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State) + { + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DEVICE_NODE *psDeviceNode; +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/common/devicemem.c git/drivers/gpu/pvr/services4/srvkm/common/devicemem.c +--- git/drivers/gpu/pvr/services4/srvkm/common/devicemem.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/common/devicemem.c 2008-12-18 15:47:29.000000000 +0100 +@@ -422,7 +422,8 @@ + BM_HEAP *psBMHeap; + IMG_HANDLE hDevMemContext; + +- if (!hDevMemHeap) ++ if (!hDevMemHeap || ++ (ui32Size == 0)) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/common/handle.c git/drivers/gpu/pvr/services4/srvkm/common/handle.c +--- git/drivers/gpu/pvr/services4/srvkm/common/handle.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/common/handle.c 2008-12-18 15:47:29.000000000 +0100 +@@ -25,6 +25,10 @@ + ******************************************************************************/ + + #ifdef PVR_SECURE_HANDLES ++#ifdef __linux__ ++#include <linux/vmalloc.h> ++#endif ++ + #include <stddef.h> + + #include "services_headers.h" +@@ -36,6 +40,8 @@ + #define HANDLE_BLOCK_SIZE 256 + #endif + ++#define HANDLE_LARGE_BLOCK_SIZE 1024 ++ + #define HANDLE_HASH_TAB_INIT_SIZE 32 + + #define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount) +@@ -100,13 +106,13 @@ + { + IMG_BOOL bIsEmpty; + +- bIsEmpty = (psList->ui32Next == ui32Index); ++ bIsEmpty = (IMG_BOOL)(psList->ui32Next == ui32Index); + + #ifdef DEBUG + { + IMG_BOOL bIsEmpty2; + +- bIsEmpty2 = (psList->ui32Prev == ui32Index); ++ bIsEmpty2 = (IMG_BOOL)(psList->ui32Prev == ui32Index); + PVR_ASSERT(bIsEmpty == bIsEmpty2); + } + #endif +@@ -114,6 +120,7 @@ + return bIsEmpty; + } + ++#ifdef DEBUG + #ifdef INLINE_IS_PRAGMA + #pragma inline(NoChildren) + #endif +@@ -143,6 +150,7 @@ + } + return IMG_FALSE; + } ++#endif + + #ifdef INLINE_IS_PRAGMA + #pragma inline(ParentHandle) +@@ -328,6 +336,14 @@ + + if (psBase->psHandleArray != IMG_NULL) + { ++#ifdef __linux__ ++ if (psBase->bVmallocUsed) ++ { ++ vfree(psBase->psHandleArray); ++ psBase->psHandleArray = IMG_NULL; ++ return PVRSRV_OK; ++ } ++#endif + eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + psBase->ui32TotalHandCount * sizeof(struct sHandle), + psBase->psHandleArray, +@@ -363,6 +379,7 @@ + + PVR_ASSERT(hHandle != IMG_NULL); + PVR_ASSERT(hHandle == INDEX_TO_HANDLE(psBase, ui32Index)); ++ PVR_UNREFERENCED_PARAMETER(hHandle); + } + + +@@ -495,22 +512,46 @@ + return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey); + } + ++#define NEW_HANDLE_ARRAY_SIZE(psBase, handleNumberIncrement) \ ++ (((psBase)->ui32TotalHandCount + (handleNumberIncrement)) * \ ++ sizeof(struct sHandle)) ++ + static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase) + { + struct sHandle *psNewHandleArray; + IMG_HANDLE hNewHandBlockAlloc; + PVRSRV_ERROR eError; + struct sHandle *psHandle; ++ IMG_UINT32 ui32HandleNumberIncrement = HANDLE_BLOCK_SIZE; ++ IMG_UINT32 ui32NewHandleArraySize = NEW_HANDLE_ARRAY_SIZE(psBase, ui32HandleNumberIncrement); ++#ifdef __linux__ ++ IMG_BOOL bVmallocUsed = IMG_FALSE; ++#endif + + + eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, +- (psBase->ui32TotalHandCount + HANDLE_BLOCK_SIZE) * sizeof(struct sHandle), ++ ui32NewHandleArraySize, + (IMG_PVOID *)&psNewHandleArray, + &hNewHandBlockAlloc); + if (eError != PVRSRV_OK) + { ++#ifdef __linux__ ++ PVR_TRACE(("IncreaseHandleArraySize: OSAllocMem failed (%d), trying vmalloc", eError)); ++ ++ ui32HandleNumberIncrement = HANDLE_LARGE_BLOCK_SIZE; ++ ui32NewHandleArraySize = NEW_HANDLE_ARRAY_SIZE(psBase, ui32HandleNumberIncrement); ++ ++ psNewHandleArray = vmalloc(ui32NewHandleArraySize); ++ if (psNewHandleArray == IMG_NULL) ++ { ++ PVR_TRACE(("IncreaseHandleArraySize: vmalloc failed")); ++ return PVRSRV_ERROR_OUT_OF_MEMORY; ++ } ++ bVmallocUsed = IMG_TRUE; ++#else + PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: Couldn't allocate new handle array (%d)", eError)); + return eError; ++#endif + } + + +@@ -521,7 +562,7 @@ + + + for(psHandle = psNewHandleArray + psBase->ui32TotalHandCount; +- psHandle < psNewHandleArray + psBase->ui32TotalHandCount + HANDLE_BLOCK_SIZE; ++ psHandle < psNewHandleArray + psBase->ui32TotalHandCount + ui32HandleNumberIncrement; + psHandle++) + { + psHandle->eType = PVRSRV_HANDLE_TYPE_NONE; +@@ -538,15 +579,18 @@ + + psBase->psHandleArray = psNewHandleArray; + psBase->hHandBlockAlloc = hNewHandBlockAlloc; ++#ifdef __linux__ ++ psBase->bVmallocUsed = bVmallocUsed; ++#endif + + + PVR_ASSERT(psBase->ui32FreeHandCount == 0); +- psBase->ui32FreeHandCount = HANDLE_BLOCK_SIZE; ++ psBase->ui32FreeHandCount = ui32HandleNumberIncrement; + + PVR_ASSERT(psBase->ui32FirstFreeIndex == 0); + psBase->ui32FirstFreeIndex = psBase->ui32TotalHandCount; + +- psBase->ui32TotalHandCount += HANDLE_BLOCK_SIZE; ++ psBase->ui32TotalHandCount += ui32HandleNumberIncrement; + + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); + psBase->ui32LastFreeIndexPlusOne = psBase->ui32TotalHandCount; +@@ -564,7 +608,7 @@ + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + +- PVR_ASSERT(psBase->psHashTab != NULL); ++ PVR_ASSERT(psBase->psHashTab != IMG_NULL); + + if (!(eFlag & PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) + { +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/common/power.c git/drivers/gpu/pvr/services4/srvkm/common/power.c +--- git/drivers/gpu/pvr/services4/srvkm/common/power.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/common/power.c 2008-12-18 15:47:29.000000000 +0100 +@@ -207,6 +207,21 @@ + } + + ++PVRSRV_ERROR PVRSRVSetDevicePowerStateCoreKM(IMG_UINT32 ui32DeviceIndex, ++ PVR_POWER_STATE eNewPowerState) ++{ ++ PVRSRV_ERROR eError; ++ eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); ++ if(eError != PVRSRV_OK) ++ { ++ return eError; ++ } ++ ++ eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); ++ return eError; ++} ++ ++ + IMG_EXPORT + PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/common/pvrsrv.c git/drivers/gpu/pvr/services4/srvkm/common/pvrsrv.c +--- git/drivers/gpu/pvr/services4/srvkm/common/pvrsrv.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/common/pvrsrv.c 2008-12-18 15:47:29.000000000 +0100 +@@ -28,6 +28,7 @@ + #include "buffer_manager.h" + #include "handle.h" + #include "perproc.h" ++#include "pdump_km.h" + + + #include "ra.h" +@@ -180,7 +181,7 @@ + } + + +-PVRSRV_ERROR PVRSRVInit(PSYS_DATA psSysData) ++PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData) + { + PVRSRV_ERROR eError; + +@@ -215,6 +216,20 @@ + gpsSysData->eCurrentPowerState = PVRSRV_POWER_STATE_D0; + gpsSysData->eFailedPowerState = PVRSRV_POWER_Unspecified; + ++ ++ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, ++ sizeof(PVRSRV_EVENTOBJECT) , ++ (IMG_VOID **)&psSysData->psGlobalEventObject, 0) != PVRSRV_OK) ++ { ++ ++ goto Error; ++ } ++ ++ if(OSEventObjectCreate("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK) ++ { ++ goto Error; ++ } ++ + return eError; + + Error: +@@ -224,12 +239,21 @@ + + + +-IMG_VOID PVRSRVDeInit(PSYS_DATA psSysData) ++IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData) + { + PVRSRV_ERROR eError; + + PVR_UNREFERENCED_PARAMETER(psSysData); + ++ ++ if(psSysData->psGlobalEventObject) ++ { ++ OSEventObjectDestroy(psSysData->psGlobalEventObject); ++ OSFreeMem( PVRSRV_OS_PAGEABLE_HEAP, ++ sizeof(PVRSRV_EVENTOBJECT) , ++ psSysData->psGlobalEventObject, 0); ++ } ++ + eError = PVRSRVHandleDeInit(); + if (eError != PVRSRV_OK) + { +@@ -246,10 +270,10 @@ + } + + +-PVRSRV_ERROR PVRSRVRegisterDevice(PSYS_DATA psSysData, +- PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*), +- IMG_UINT32 ui32SOCInterruptBit, +- IMG_UINT32 *pui32DeviceIndex) ++PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData, ++ PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*), ++ IMG_UINT32 ui32SOCInterruptBit, ++ IMG_UINT32 *pui32DeviceIndex) + { + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode; +@@ -342,6 +366,61 @@ + } + } + ++ ++ ++ ++ eError = PVRSRVResManConnect(RESMAN_KERNEL_PROCESSID, IMG_TRUE); ++ if (eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call")); ++ return eError; ++ } ++ ++ return PVRSRV_OK; ++} ++ ++ ++PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful) ++{ ++ PVRSRV_DEVICE_NODE *psDeviceNode; ++ SYS_DATA *psSysData; ++ PVRSRV_ERROR eError; ++ ++ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem")); ++ ++ eError = SysAcquireData(&psSysData); ++ if(eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed to get SysData")); ++ return(eError); ++ } ++ ++ if (bInitSuccessful) ++ { ++ eError = SysFinalise(); ++ if (eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError)); ++ return eError; ++ } ++ ++ ++ psDeviceNode = psSysData->psDeviceNodeList; ++ while (psDeviceNode) ++ { ++ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, ++ PVRSRV_POWER_Unspecified, ++ KERNEL_ID, IMG_FALSE); ++ if (eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex)); ++ } ++ psDeviceNode = psDeviceNode->psNext; ++ } ++ } ++ ++ PDUMPENDINITPHASE(); ++ + return PVRSRV_OK; + } + +@@ -408,7 +487,7 @@ + } + + +-PVRSRV_ERROR PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex) ++PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex) + { + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_DEVICE_NODE **ppsDevNode; +@@ -441,10 +520,6 @@ + + + +- +-#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) +- +- + eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex, + PVRSRV_POWER_STATE_D3, + KERNEL_ID, +@@ -454,7 +529,16 @@ + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call")); + return eError; + } +-#endif ++ ++ ++ ++ ++ eError = PVRSRVResManConnect(RESMAN_KERNEL_PROCESSID, IMG_FALSE); ++ if (eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVResManConnect call")); ++ return eError; ++ } + + + +@@ -481,11 +565,11 @@ + + + IMG_EXPORT +-PVRSRV_ERROR PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr, +- IMG_UINT32 ui32Value, +- IMG_UINT32 ui32Mask, +- IMG_UINT32 ui32Waitus, +- IMG_UINT32 ui32Tries) ++PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr, ++ IMG_UINT32 ui32Value, ++ IMG_UINT32 ui32Mask, ++ IMG_UINT32 ui32Waitus, ++ IMG_UINT32 ui32Tries) + { + IMG_BOOL bStart = IMG_FALSE; + IMG_UINT32 uiStart = 0, uiCurrent=0, uiMaxTime; +@@ -585,7 +669,8 @@ + + if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT + |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT +- |PVRSRV_MISC_INFO_MEMSTATS_PRESENT)) ++ |PVRSRV_MISC_INFO_MEMSTATS_PRESENT ++ |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags")); + return PVRSRV_ERROR_INVALID_PARAMS; +@@ -719,13 +804,20 @@ + i32Count = OSSNPrintf(pszStr, 100, "\n\0"); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + } ++ ++ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) ++ && psSysData->psGlobalEventObject) ++ { ++ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT; ++ psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject; ++ } + + return PVRSRV_OK; + } + + +-PVRSRV_ERROR PVRSRVGetFBStatsKM(IMG_UINT32 *pui32Total, +- IMG_UINT32 *pui32Available) ++PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFBStatsKM(IMG_UINT32 *pui32Total, ++ IMG_UINT32 *pui32Available) + { + IMG_UINT32 ui32Total = 0, i = 0; + IMG_UINT32 ui32Available = 0; +@@ -746,7 +838,7 @@ + } + + +-IMG_BOOL PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode) ++IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode) + { + SYS_DATA *psSysData; + IMG_BOOL bStatus = IMG_FALSE; +@@ -776,7 +868,7 @@ + } + + +-IMG_BOOL PVRSRVSystemLISR(IMG_VOID *pvSysData) ++IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData) + { + SYS_DATA *psSysData = pvSysData; + IMG_BOOL bStatus = IMG_FALSE; +@@ -826,7 +918,7 @@ + } + + +-IMG_VOID PVRSRVMISR(IMG_VOID *pvSysData) ++IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData) + { + SYS_DATA *psSysData = pvSysData; + PVRSRV_DEVICE_NODE *psDeviceNode; +@@ -853,10 +945,21 @@ + { + PVRSRVProcessQueues(ISR_ID, IMG_FALSE); + } ++ ++ ++ if (psSysData->psGlobalEventObject) ++ { ++ IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM; ++ if(hOSEventKM) ++ { ++ OSEventObjectSignal(hOSEventKM); ++ } ++ } + } + + +-PVRSRV_ERROR PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_UINT32 *puiBufSize, IMG_BOOL bSave) ++PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, ++ IMG_UINT32 *puiBufSize, IMG_BOOL bSave) + { + IMG_UINT32 uiBytesSaved = 0; + IMG_PVOID pvLocalMemCPUVAddr; +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/common/queue.c git/drivers/gpu/pvr/services4/srvkm/common/queue.c +--- git/drivers/gpu/pvr/services4/srvkm/common/queue.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/common/queue.c 2008-12-18 15:47:29.000000000 +0100 +@@ -760,14 +760,10 @@ + + PVRSRVCommandCompleteCallbacks(); + +-#if defined(SYS_USING_INTERRUPTS) + if(bScheduleMISR) + { + OSScheduleMISR(psSysData); + } +-#else +- PVR_UNREFERENCED_PARAMETER(bScheduleMISR); +-#endif + } + + +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/common/resman.c git/drivers/gpu/pvr/services4/srvkm/common/resman.c +--- git/drivers/gpu/pvr/services4/srvkm/common/resman.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/common/resman.c 2008-12-18 15:47:29.000000000 +0100 +@@ -145,6 +141,10 @@ + + case RESMAN_TYPE_HW_RENDER_CONTEXT: + return "HW Render Context Resource"; ++ case RESMAN_TYPE_HW_TRANSFER_CONTEXT: ++ return "HW Transfer Context Resource"; ++ case RESMAN_TYPE_HW_2D_CONTEXT: ++ return "HW 2D Context Resource"; + case RESMAN_TYPE_SHARED_PB_DESC: + return "Shared Parameter Buffer Description Resource"; + +@@ -378,7 +378,12 @@ + FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE); + + ++ FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE); ++ ++ + FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE); ++ FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE); ++ FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE); + +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/mmu.c git/drivers/gpu/pvr/services4/srvkm/devices/sgx/mmu.c +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/mmu.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/mmu.c 2008-12-18 15:47:29.000000000 +0100 +@@ -1966,6 +1966,8 @@ + } + + ++ ++ + #if PAGE_TEST + static void PageTest(void* pMem, IMG_DEV_PHYADDR sDevPAddr) + { +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/mmu.h git/drivers/gpu/pvr/services4/srvkm/devices/sgx/mmu.h +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/mmu.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/mmu.h 2008-12-18 15:47:29.000000000 +0100 +@@ -27,6 +27,8 @@ + #ifndef _MMU_H_ + #define _MMU_H_ + ++#include "sgxinfokm.h" ++ + PVRSRV_ERROR + MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr); + +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/pb.c git/drivers/gpu/pvr/services4/srvkm/devices/sgx/pb.c +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/pb.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/pb.c 2008-12-18 15:47:29.000000000 +0100 +@@ -56,11 +56,26 @@ + + psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; + ++ ++ ++ ++#if defined(FIXME) + for(psStubPBDesc = psSGXDevInfo->psStubPBDescListKM; + psStubPBDesc != IMG_NULL; + psStubPBDesc = psStubPBDesc->psNext) + { + if(psStubPBDesc->ui32TotalPBSize == ui32TotalPBSize) ++#else ++ psStubPBDesc = psSGXDevInfo->psStubPBDescListKM; ++ if (psStubPBDesc != IMG_NULL) ++ { ++ if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) ++ { ++ PVR_DPF((PVR_DBG_ERROR, ++ "SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored", ++ ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize)); ++ } ++#endif + { + IMG_UINT32 i; + PRESMAN_ITEM psResItem; +@@ -125,20 +140,6 @@ + return eError; + } + +-IMG_VOID ResetPBs(PVRSRV_SGXDEV_INFO* psSGXDevInfo) +-{ +- PVRSRV_STUB_PBDESC **ppsStubPBDesc; +- +- for(ppsStubPBDesc = (PVRSRV_STUB_PBDESC **)&psSGXDevInfo->psStubPBDescListKM; +- *ppsStubPBDesc != IMG_NULL; +- ppsStubPBDesc = &(*ppsStubPBDesc)->psNext) +- { +- PVRSRV_STUB_PBDESC *psStubPBDesc = *ppsStubPBDesc; +- IMG_UINT32* pui32Flags = (IMG_UINT32*)psStubPBDesc->psHWPBDescKernelMemInfo->pvLinAddrKM; +- *pui32Flags |= 1; +- } +-} +- + + static PVRSRV_ERROR + SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn) +@@ -266,7 +267,7 @@ + { + PVR_DPF((PVR_DBG_ERROR, + "SGXAddSharedPBDescKM: " +- "Failed to register exisitng shared " ++ "Failed to register existing shared " + "PBDesc with the resource manager")); + goto NoAddKeepPB; + } +@@ -301,7 +302,7 @@ + } + + +- psStubPBDesc->ppsSubKernelMemInfos=IMG_NULL; ++ psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL; + + if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO *) +@@ -395,8 +396,10 @@ + } + + NoAddKeepPB: +- for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++) ++ for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) ++ { + PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i], IMG_FALSE); ++ } + + PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookie, psStubPBDesc->psHWPBDescKernelMemInfo, IMG_FALSE); +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgx2dcore.c git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgx2dcore.c +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgx2dcore.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgx2dcore.c 2008-12-18 15:47:29.000000000 +0100 +@@ -27,12 +27,15 @@ + #include "sgxdefs.h" + #include "services_headers.h" + #include "sgxinfo.h" ++#include "sgxinfokm.h" + + #if defined(SGX_FEATURE_2D_HARDWARE) + + #include "sgx2dcore.h" + +-#define SGX2D_FLUSH_BH (0xF0000000) ++#define SGX2D_FLUSH_BH 0xF0000000 ++#define SGX2D_FENCE_BH 0x70000000 ++ + #define SGX2D_QUEUED_BLIT_PAD 4 + + #define SGX2D_COMMAND_QUEUE_SIZE 1024 +@@ -521,7 +524,7 @@ + + if (hCmdCookie != IMG_NULL) + { +- PVRSRVCommandCompleteKM(hCmdCookie, IMG_FALSE); ++ PVRSRVCommandCompleteKM(hCmdCookie, IMG_TRUE); + } + + PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DHandle2DComplete: Exit")); +@@ -723,7 +726,7 @@ + + SGX2DWriteSlavePortBatch(psDevInfo, pui32BltData, ui32DataByteSize); + +- SGX2DWriteSlavePort(psDevInfo, EURASIA2D_FENCE_BH); ++ SGX2DWriteSlavePort(psDevInfo, SGX2D_FENCE_BH); + } + } + +@@ -817,6 +820,18 @@ + + PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending.")); + ++#if defined(DEBUG) ++ { ++ PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; ++ ++ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: %p, Syncdata: %p", psSyncInfo, psSyncData)); ++ ++ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Read ops complete: %d, Read ops pending: %d", psSyncData->ui32ReadOpsComplete, psSyncData->ui32ReadOpsPending)); ++ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Write ops complete: %d, Write ops pending: %d", psSyncData->ui32WriteOpsComplete, psSyncData->ui32WriteOpsPending)); ++ ++ } ++#endif ++ + return PVRSRV_ERROR_TIMEOUT; + } + #endif +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h 1970-01-01 01:00:00.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h 2008-12-18 15:47:29.000000000 +0100 +@@ -0,0 +1,158 @@ ++/********************************************************************** ++ * ++ * Copyright(c) 2008 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 ++ * ++ ******************************************************************************/ ++ ++#if !defined(__SGX_BRIDGE_KM_H__) ++#define __SGX_BRIDGE_KM_H__ ++ ++#include "sgxapi_km.h" ++#include "sgxinfo.h" ++#include "sgxinfokm.h" ++#include "sgx_bridge.h" ++#include "pvr_bridge.h" ++#include "perproc.h" ++ ++#if defined (__cplusplus) ++extern "C" { ++#endif ++ ++IMG_IMPORT ++PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick); ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick); ++#endif ++ ++IMG_IMPORT ++PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, ++ PVR3DIF4_CCB_KICK *psCCBKick); ++ ++IMG_IMPORT ++PVRSRV_ERROR SGXGetPhysPageAddrKM(IMG_HANDLE hDevMemHeap, ++ IMG_DEV_VIRTADDR sDevVAddr, ++ IMG_DEV_PHYADDR *pDevPAddr, ++ IMG_CPU_PHYADDR *pCpuPAddr); ++ ++IMG_IMPORT ++PVRSRV_ERROR IMG_CALLCONV SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie, ++ IMG_HANDLE hDevMemContext, ++ IMG_DEV_PHYADDR *psPDDevPAddr); ++ ++IMG_IMPORT ++PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, ++ PVR3DIF4_CLIENT_INFO* psClientInfo); ++ ++IMG_IMPORT ++PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, ++ SGX_MISC_INFO *psMiscInfo); ++ ++#if defined(SUPPORT_SGX_HWPERF) ++IMG_IMPORT ++PVRSRV_ERROR SGXReadHWPerfCountersKM(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_UINT32 ui32PerfReg, ++ IMG_UINT32 *pui32OldPerf, ++ IMG_BOOL bNewPerf, ++ IMG_UINT32 ui32NewPerf, ++ IMG_UINT32 ui32NewPerfReset, ++ IMG_UINT32 ui32PerfCountersReg, ++ IMG_UINT32 *pui32Counters, ++ IMG_UINT32 *pui32KickTACounter, ++ IMG_UINT32 *pui32KickTARenderCounter, ++ IMG_UINT32 *pui32CPUTime, ++ IMG_UINT32 *pui32SGXTime); ++#endif ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++IMG_IMPORT ++PVRSRV_ERROR SGX2DQueueBlitKM(PVRSRV_SGXDEV_INFO *psDevInfo, ++ PVRSRV_KERNEL_SYNC_INFO *psDstSync, ++ IMG_UINT32 ui32NumSrcSyncs, ++ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[], ++ IMG_UINT32 ui32DataByteSize, ++ IMG_UINT32 *pui32BltData); ++ ++#if defined(SGX2D_DIRECT_BLITS) ++IMG_IMPORT ++PVRSRV_ERROR SGX2DDirectBlitKM(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_UINT32 ui32DataByteSize, ++ IMG_UINT32 *pui32BltData); ++#endif ++#endif ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) || defined(PVR2D_ALT_2DHW) ++IMG_IMPORT ++PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo, ++ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, ++ IMG_BOOL bWaitForComplete); ++#endif ++ ++IMG_IMPORT ++PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, ++ SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo); ++ ++IMG_IMPORT ++PVRSRV_ERROR DevInitSGXPart2KM(PVRSRV_PER_PROCESS_DATA *psPerProc, ++ IMG_HANDLE hDevHandle, ++ SGX_BRIDGE_INIT_INFO *psInitInfo); ++ ++IMG_IMPORT PVRSRV_ERROR ++SGXFindSharedPBDescKM(IMG_HANDLE hDevCookie, ++ IMG_UINT32 ui32TotalPBSize, ++ IMG_HANDLE *phSharedPBDesc, ++ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo, ++ PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo, ++ PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo, ++ PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos, ++ IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount); ++ ++IMG_IMPORT PVRSRV_ERROR ++SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc); ++ ++IMG_IMPORT PVRSRV_ERROR ++SGXAddSharedPBDescKM(IMG_HANDLE hDevCookie, ++ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo, ++ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo, ++ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo, ++ IMG_UINT32 ui32TotalPBSize, ++ IMG_HANDLE *phSharedPBDesc, ++ PVRSRV_KERNEL_MEM_INFO **psSharedPBDescSubKernelMemInfos, ++ IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount); ++ ++ ++IMG_IMPORT PVRSRV_ERROR ++SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie, ++ PVR3DIF4_INTERNAL_DEVINFO *psSGXInternalDevInfo); ++ ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++#define SGX2D_MAX_BLT_CMD_SIZ 256 ++#endif ++ ++#if defined (__cplusplus) ++} ++#endif ++ ++#endif ++ +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxinfokm.h git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxinfokm.h +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxinfokm.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxinfokm.h 2008-12-18 15:47:29.000000000 +0100 +@@ -45,14 +45,152 @@ + + #define PVRSRV_USSE_EDM_RESMAN_CLEANUP_RT_REQUEST 0x01 + #define PVRSRV_USSE_EDM_RESMAN_CLEANUP_RC_REQUEST 0x02 +-#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE 0x04 +-#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPD 0x10 +-#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPT 0x20 ++#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_TC_REQUEST 0x04 ++#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_2DC_REQUEST 0x08 ++#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE 0x10 ++#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPD 0x20 ++#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPT 0x40 ++ ++typedef struct _PVRSRV_SGXDEV_INFO_ ++{ ++ PVRSRV_DEVICE_TYPE eDeviceType; ++ PVRSRV_DEVICE_CLASS eDeviceClass; ++ ++ IMG_UINT8 ui8VersionMajor; ++ IMG_UINT8 ui8VersionMinor; ++ IMG_UINT32 ui32CoreConfig; ++ IMG_UINT32 ui32CoreFlags; ++ ++ ++ IMG_PVOID pvRegsBaseKM; ++ ++ ++ ++ IMG_HANDLE hRegMapping; ++ ++ ++ IMG_SYS_PHYADDR sRegsPhysBase; ++ ++ IMG_UINT32 ui32RegSize; ++ ++ ++ IMG_UINT32 ui32CoreClockSpeed; ++ IMG_UINT32 ui32uKernelTimerClock; ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++ ++ SGX_SLAVE_PORT s2DSlavePortKM; ++ ++ ++ PVRSRV_RESOURCE s2DSlaveportResource; ++ ++ ++ IMG_UINT32 ui322DFifoSize; ++ IMG_UINT32 ui322DFifoOffset; ++ ++ IMG_HANDLE h2DCmdCookie; ++ ++ IMG_HANDLE h2DQueue; ++ IMG_BOOL b2DHWRecoveryInProgress; ++ IMG_BOOL b2DHWRecoveryEndPending; ++ IMG_UINT32 ui322DCompletedBlits; ++ IMG_BOOL b2DLockupSuspected; ++#endif ++ ++ ++ IMG_VOID *psStubPBDescListKM; ++ ++ ++ ++ IMG_DEV_PHYADDR sKernelPDDevPAddr; ++ ++ IMG_VOID *pvDeviceMemoryHeap; ++ PPVRSRV_KERNEL_MEM_INFO psKernelCCBMemInfo; ++ PVRSRV_SGX_KERNEL_CCB *psKernelCCB; ++ PPVRSRV_SGX_CCB_INFO psKernelCCBInfo; ++ PPVRSRV_KERNEL_MEM_INFO psKernelCCBCtlMemInfo; ++ PVRSRV_SGX_CCB_CTL *psKernelCCBCtl; ++ PPVRSRV_KERNEL_MEM_INFO psKernelCCBEventKickerMemInfo; ++ IMG_UINT32 *pui32KernelCCBEventKicker; ++ IMG_UINT32 ui32TAKickAddress; ++ IMG_UINT32 ui32TexLoadKickAddress; ++ IMG_UINT32 ui32VideoHandlerAddress; ++#if defined(SGX_SUPPORT_HWPROFILING) ++ PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo; ++#endif ++ IMG_UINT32 ui32KickTACounter; ++ IMG_UINT32 ui32KickTARenderCounter; ++#if defined(SUPPORT_SGX_HWPERF) ++ PPVRSRV_KERNEL_MEM_INFO psKernelHWPerfCBMemInfo; ++#endif + ++ ++ IMG_UINT32 ui32ClientRefCount; + ++ ++ IMG_UINT32 ui32CacheControl; + ++ + + ++ IMG_VOID *pvMMUContextList; ++ ++ ++ IMG_BOOL bForcePTOff; ++ ++ IMG_UINT32 ui32EDMTaskReg0; ++ IMG_UINT32 ui32EDMTaskReg1; ++ ++ IMG_UINT32 ui32ClkGateCtl; ++ IMG_UINT32 ui32ClkGateCtl2; ++ IMG_UINT32 ui32ClkGateStatusMask; ++ SGX_INIT_SCRIPTS sScripts; ++ ++ ++ IMG_HANDLE hBIFResetPDOSMemHandle; ++ IMG_DEV_PHYADDR sBIFResetPDDevPAddr; ++ IMG_DEV_PHYADDR sBIFResetPTDevPAddr; ++ IMG_DEV_PHYADDR sBIFResetPageDevPAddr; ++ IMG_UINT32 *pui32BIFResetPD; ++ IMG_UINT32 *pui32BIFResetPT; ++ ++ ++#if defined(SUPPORT_HW_RECOVERY) ++ ++ IMG_HANDLE hTimer; ++ ++ IMG_UINT32 ui32TimeStamp; ++#endif ++ ++ ++ IMG_UINT32 ui32NumResets; ++ ++ PVRSRV_KERNEL_MEM_INFO *psKernelSGXHostCtlMemInfo; ++ PVRSRV_SGX_HOST_CTL *psSGXHostCtl; ++ ++ IMG_UINT32 ui32Flags; ++ ++ ++ IMG_UINT32 ui32RegFlags; ++ ++ #if defined(PDUMP) ++ PVRSRV_SGX_PDUMP_CONTEXT sPDContext; ++ #endif ++ ++#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) ++ ++ IMG_VOID *pvDummyPTPageCpuVAddr; ++ IMG_DEV_PHYADDR sDummyPTDevPAddr; ++ IMG_HANDLE hDummyPTPageOSMemHandle; ++ IMG_VOID *pvDummyDataPageCpuVAddr; ++ IMG_DEV_PHYADDR sDummyDataDevPAddr; ++ IMG_HANDLE hDummyDataPageOSMemHandle; ++#endif ++ ++ IMG_UINT32 asSGXDevData[SGX_MAX_DEV_DATA]; ++ ++} PVRSRV_SGXDEV_INFO; ++ + + typedef struct _SGX_TIMING_INFORMATION_ + { +@@ -122,10 +260,8 @@ + + PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode); + +- + IMG_VOID SGXOSTimer(IMG_VOID *pvData); + +-IMG_VOID ResetPBs(PVRSRV_SGXDEV_INFO *psDevInfo); + #if defined(NO_HARDWARE) + static INLINE IMG_VOID NoHardwareGenerateEvent(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_UINT32 ui32StatusRegister, +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxinit.c git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxinit.c +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxinit.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxinit.c 2008-12-18 15:47:29.000000000 +0100 +@@ -54,23 +54,16 @@ + #endif + + IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData); +-IMG_VOID SGXScheduleProcessQueues(IMG_VOID *pvData); + + IMG_UINT32 gui32EventStatusServicesByISR = 0; + +-static IMG_VOID ResetSGX(PVRSRV_SGXDEV_INFO *psDevInfo, +- IMG_UINT32 ui32PDUMPFlags); ++IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_UINT32 ui32PDUMPFlags); + +-PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, +- IMG_BOOL bHardwareRecovery); ++static PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_BOOL bHardwareRecovery); + PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie); + +-#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) +-#define SGX_BIF_DIR_LIST_INDEX_EDM 15 +-#define SGX_BIF_DIR_LIST_REG_EDM EUR_CR_BIF_DIR_LIST_BASE15 +-#else +-#define SGX_BIF_DIR_LIST_REG_EDM EUR_CR_BIF_DIR_LIST_BASE0 +-#endif + + static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode) + { +@@ -116,6 +109,9 @@ + #if defined(SGX_SUPPORT_HWPROFILING) + psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo; + #endif ++#if defined(SUPPORT_SGX_HWPERF) ++ psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo; ++#endif + + + +@@ -124,7 +120,7 @@ + (IMG_VOID **)&psKernelCCBInfo, 0); + if (eError != PVRSRV_OK) + { +- PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to alloc memory")); ++ PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory")); + goto failed_allockernelccb; + } + +@@ -151,7 +147,9 @@ + + psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0; + psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1; +- psDevInfo->ui32ClockGateMask = psInitInfo->ui32ClockGateMask; ++ psDevInfo->ui32ClkGateCtl = psInitInfo->ui32ClkGateCtl; ++ psDevInfo->ui32ClkGateCtl2 = psInitInfo->ui32ClkGateCtl2; ++ psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask; + + + +@@ -183,10 +181,20 @@ + if (eNewPowerState == PVRSRV_POWER_STATE_D3) + { + PVRSRV_SGX_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; +- #if defined (SGX_FEATURE_AUTOCLOCKGATING) && (!defined(NO_HARDWARE) || defined(PDUMP)) +- IMG_UINT32 ui32ClockMask = psDevInfo->ui32ClockGateMask; ++ ++ #if defined (SGX_FEATURE_AUTOCLOCKGATING) && (!defined(NO_HARDWARE) || defined(PDUMP)) ++ IMG_UINT32 ui32ClockMask = psDevInfo->ui32ClkGateStatusMask; + #endif + ++#if defined(SUPPORT_HW_RECOVERY) ++ ++ if (OSDisableTimer(psDevInfo->hTimer) != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to disable timer")); ++ return PVRSRV_ERROR_GENERIC; ++ } ++#endif ++ + + psSGXHostCtl->ui32PowManFlags |= PVRSRV_USSE_EDM_POWMAN_POWEROFF_REQUEST; + +@@ -202,7 +210,7 @@ + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT) != PVRSRV_OK) + { +- PVR_DPF((PVR_DBG_ERROR,"Wait for chip power off failed.")); ++ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for chip power off failed.")); + } + #endif + +@@ -229,7 +237,7 @@ + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT) != PVRSRV_OK) + { +- PVR_DPF((PVR_DBG_ERROR,"Wait for chip idle failed.")); ++ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for chip idle failed.")); + } + #endif + PDUMPREGPOL(EUR_CR_CLKGATESTATUS, 0, ui32ClockMask); +@@ -278,6 +286,14 @@ + PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXInitialise failed")); + return eError; + } ++#if defined(SUPPORT_HW_RECOVERY) ++ eError = OSEnableTimer(psDevInfo->hTimer); ++ if (eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState : Failed to enable host timer")); ++ return PVRSRV_ERROR_GENERIC; ++ } ++#endif + } + + PVR_DPF((PVR_DBG_WARNING, +@@ -288,8 +304,6 @@ + return PVRSRV_OK; + } + +-#define SCRIPT_DATA(pData, offset, type) (*((type *)(((char *)pData) + offset))) +-#define SCRIPT_DATA_UI32(pData, offset) SCRIPT_DATA(pData, offset, IMG_UINT32) + + static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands) + { +@@ -333,14 +347,18 @@ + return PVRSRV_ERROR_GENERIC;; + } + +-PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, +- IMG_BOOL bHardwareRecovery) ++static PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_BOOL bHardwareRecovery) + { + PVRSRV_ERROR eError; + IMG_UINT32 ui32ReadOffset, ui32WriteOffset; + + +- ResetSGX(psDevInfo, PDUMP_FLAGS_CONTINUOUS); ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL, psDevInfo->ui32ClkGateCtl); ++ PDUMPREGWITHFLAGS(EUR_CR_CLKGATECTL, psDevInfo->ui32ClkGateCtl, PDUMP_FLAGS_CONTINUOUS); ++ ++ ++ SGXReset(psDevInfo, PDUMP_FLAGS_CONTINUOUS); + + + *psDevInfo->pui32KernelCCBEventKicker = 0; +@@ -381,12 +399,14 @@ + 0, + PVRSRV_USSE_EDM_INTERRUPT_HWR, + MAX_HW_TIME_US/WAIT_TRY_COUNT, +- WAIT_TRY_COUNT) != PVRSRV_OK) ++ 1000) != PVRSRV_OK) + { +- PVR_DPF((PVR_DBG_ERROR, "HWRecoveryResetSGXEDM: Wait for uKernel HW Recovery failed")); ++ PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel HW Recovery failed")); ++ return PVRSRV_ERROR_RETRY; + } + } + ++ + + + +@@ -426,259 +446,6 @@ + } + + +-static IMG_VOID ResetSGXSleep(PVRSRV_SGXDEV_INFO *psDevInfo, +- IMG_UINT32 ui32PDUMPFlags, +- IMG_BOOL bPDump) +-{ +-#if !defined(PDUMP) +- PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); +-#endif +- +- +- OSWaitus(1000 * 1000000 / psDevInfo->ui32CoreClockSpeed); +- if (bPDump) +- { +- PDUMPIDLWITHFLAGS(1000, ui32PDUMPFlags); +- } +-} +- +- +-static IMG_VOID ResetSGX(PVRSRV_SGXDEV_INFO *psDevInfo, +- IMG_UINT32 ui32PDUMPFlags) +-{ +- IMG_UINT32 ui32RegVal; +- +- const IMG_UINT32 ui32SoftResetRegVal = +- #ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK +- EUR_CR_SOFT_RESET_TWOD_RESET_MASK | +- #endif +- EUR_CR_SOFT_RESET_DPM_RESET_MASK | +- EUR_CR_SOFT_RESET_TA_RESET_MASK | +- EUR_CR_SOFT_RESET_USE_RESET_MASK | +- EUR_CR_SOFT_RESET_ISP_RESET_MASK | +- EUR_CR_SOFT_RESET_TSP_RESET_MASK; +- +- const IMG_UINT32 ui32BifInvalDCVal = EUR_CR_BIF_CTRL_INVALDC_MASK; +- +- const IMG_UINT32 ui32BifFaultMask = +- EUR_CR_BIF_INT_STAT_FAULT_MASK; +- +-#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) +- IMG_UINT32 ui32BIFCtrl; +-#if defined(EUR_CR_BIF_MEM_ARB_CONFIG) +- IMG_UINT32 ui32BIFMemArb; +-#endif +-#endif +- +-#ifndef PDUMP +- PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); +-#endif +- +- psDevInfo->ui32NumResets++; +- +- PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX reset sequence\r\n"); +- +-#if defined(FIX_HW_BRN_23944) +- +- ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); +- +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +- +- ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); +- if (ui32RegVal & ui32BifFaultMask) +- { +- +- ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK | EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); +- +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +- +- ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); +- +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +- } +-#endif +- +- +- ui32RegVal = ui32SoftResetRegVal | EUR_CR_SOFT_RESET_BIF_RESET_MASK; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); +- +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +- +- +- +-#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) +- ui32RegVal = 0; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags); +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags); +- +-#if defined(EUR_CR_BIF_MEM_ARB_CONFIG) +- +- +- ui32BIFMemArb = (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT) | +- (7UL << EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT) | +- (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT); +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_ARB_CONFIG, ui32BIFMemArb); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_MEM_ARB_CONFIG, ui32BIFMemArb, ui32PDUMPFlags); +-#endif +-#endif +- +- +- +- +- +- +- +- ui32RegVal = psDevInfo->sBIFResetPDDevPAddr.uiAddr; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); +- +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); +- +- +- ui32RegVal = ui32SoftResetRegVal; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); +- +- +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BifInvalDCVal); +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); +- ui32RegVal = 0; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); +- +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +- +- +- +- +- for (;;) +- { +- IMG_UINT32 ui32BifIntStat = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); +- IMG_DEV_VIRTADDR sBifFault; +- IMG_UINT32 ui32PDIndex, ui32PTIndex; +- +- if ((ui32BifIntStat & ui32BifFaultMask) == 0) +- { +- break; +- } +- +- +- +- +- +- +- +- sBifFault.uiAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT); +- PVR_DPF((PVR_DBG_WARNING, "ResetSGX: Page fault 0x%x/0x%x", ui32BifIntStat, sBifFault.uiAddr)); +- ui32PDIndex = sBifFault.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); +- ui32PTIndex = (sBifFault.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; +- +- +- ui32RegVal = ui32SoftResetRegVal | EUR_CR_SOFT_RESET_BIF_RESET_MASK; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); +- +- +- psDevInfo->pui32BIFResetPD[ui32PDIndex] = psDevInfo->sBIFResetPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; +- psDevInfo->pui32BIFResetPT[ui32PTIndex] = psDevInfo->sBIFResetPageDevPAddr.uiAddr | SGX_MMU_PTE_VALID; +- +- +- ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32RegVal); +- ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2); +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32RegVal); +- +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); +- +- +- ui32RegVal = ui32SoftResetRegVal; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); +- +- +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BifInvalDCVal); +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); +- ui32RegVal = 0; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); +- +- +- psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0; +- psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0; +- } +- +- +- +- +-#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) +- +- ui32BIFCtrl = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT); +-#ifdef SGX_FEATURE_2D_HARDWARE +- +- ui32BIFCtrl |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT); +-#endif +-#if defined(FIX_HW_BRN_23410) +- +- ui32BIFCtrl |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT); +-#endif +- +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32BIFCtrl); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32BIFCtrl, ui32PDUMPFlags); +-#endif +- +- +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_BIF_DIR_LIST_REG_EDM, psDevInfo->sKernelPDDevPAddr.uiAddr); +- PDUMPPDREGWITHFLAGS(SGX_BIF_DIR_LIST_REG_EDM, psDevInfo->sKernelPDDevPAddr.uiAddr, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); +- +-#ifdef SGX_FEATURE_2D_HARDWARE +- +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags); +-#endif +- +-#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) +- +- ui32RegVal = ui32SoftResetRegVal | EUR_CR_SOFT_RESET_BIF_RESET_MASK; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +- +- ui32RegVal = ui32SoftResetRegVal; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +-#endif +- +- +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BifInvalDCVal); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32BifInvalDCVal, ui32PDUMPFlags); +- +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +- +- ui32RegVal = 0; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); +- +- PVR_DPF((PVR_DBG_WARNING,"Soft Reset of SGX")); +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +- +- +- ui32RegVal = 0; +- OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); +- PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); +- +- +- ResetSGXSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); +- +- PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n"); +-} +- + static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode) + { + PVRSRV_SGXDEV_INFO *psDevInfo; +@@ -730,6 +497,7 @@ + + psDevInfo->sKernelPDDevPAddr = sPDDevPAddr; + ++ + + for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++) + { +@@ -759,25 +527,6 @@ + return PVRSRV_ERROR_GENERIC; + } + +-#if defined(SUPPORT_SGX_EVENT_OBJECT) +- +- if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, +- sizeof(PVRSRV_EVENTOBJECT) , +- (IMG_VOID **)&psDevInfo->psSGXEventObject, 0) != PVRSRV_OK) +- { +- +- PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for event object")); +- return (PVRSRV_ERROR_OUT_OF_MEMORY); +- } +- +- if(OSEventObjectCreate("PVRSRV_EVENTOBJECT_SGX", psDevInfo->psSGXEventObject) != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to create event object")); +- return (PVRSRV_ERROR_OUT_OF_MEMORY); +- +- } +-#endif +- + return PVRSRV_OK; + } + +@@ -816,9 +565,10 @@ + + + psDevInfo->ui32CoreClockSpeed = psSGXTimingInfo->ui32CoreClockSpeed; ++ psDevInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq; + + +- psInitInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq; ++ psInitInfo->ui32uKernelTimerClock = psDevInfo->ui32uKernelTimerClock; + #if defined(SUPPORT_HW_RECOVERY) + psInitInfo->ui32HWRecoverySampleRate = psSGXTimingInfo->ui32uKernelFreq / psSGXTimingInfo->ui32HWRecoveryFreq; + #endif +@@ -970,7 +720,6 @@ + #endif + + +- + + + OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB)); +@@ -983,27 +732,16 @@ + PDUMPCOMMENT("Kernel CCB Event Kicker"); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); + +- ++#if defined(SUPPORT_HW_RECOVERY) + +- eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, +- PVRSRV_POWER_Unspecified, +- KERNEL_ID, IMG_FALSE); +- if (eError != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed PVRSRVSetDevicePowerStateKM call")); +- return eError; +- } + +-#if defined(SUPPORT_HW_RECOVERY) ++ ++ psDevInfo->hTimer = OSAddTimer(SGXOSTimer, psDeviceNode, ++ 1000 * 50 / psSGXDeviceMap->sTimingInfo.ui32uKernelFreq); ++ if(psDevInfo->hTimer == IMG_NULL) + { +- SGX_TIMING_INFORMATION* psSGXTimingInfo = & psSGXDeviceMap->sTimingInfo; +- +- psDevInfo->hTimer = OSAddTimer(SGXOSTimer, psDeviceNode, 1000 * 50 / psSGXTimingInfo->ui32uKernelFreq); +- if(psDevInfo->hTimer == IMG_NULL) +- { +- PVR_DPF((PVR_DBG_ERROR,"OSAddTimer : Failed to register timer callback function")); +- return PVRSRV_ERROR_GENERIC; +- } ++ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM : Failed to register timer callback function")); ++ return PVRSRV_ERROR_GENERIC; + } + #endif + +@@ -1030,38 +768,17 @@ + } + + #if defined(SUPPORT_HW_RECOVERY) +- +- if(psDevInfo->hTimer) +- { +- eError = OSRemoveTimer (psDevInfo->hTimer); +- if (eError != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer")); +- return eError; +- } +- } +-#endif +- +- MMU_BIFResetPDFree(psDevInfo); +- +- +- +- +- +- +- +- +-#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) +- +- eError = SGXDeinitialise((IMG_HANDLE)psDevInfo); ++ eError = OSRemoveTimer(psDevInfo->hTimer); + if (eError != PVRSRV_OK) + { +- PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: SGXDeinitialise failed")); +- return eError; ++ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer")); ++ return eError; + } ++ psDevInfo->hTimer = IMG_NULL; + #endif + + ++ MMU_BIFResetPDFree(psDevInfo); + + + +@@ -1146,23 +863,14 @@ + #endif + + +-#if defined(SUPPORT_SGX_EVENT_OBJECT) +- +- if(psDevInfo->psSGXEventObject) +- { +- OSEventObjectDestroy(psDevInfo->psSGXEventObject); +- OSFreeMem( PVRSRV_OS_PAGEABLE_HEAP, +- sizeof(PVRSRV_EVENTOBJECT) , +- psDevInfo->psSGXEventObject, 0); +- } +-#endif + + + OSFreePages(PVRSRV_OS_PAGEABLE_HEAP|PVRSRV_HAP_MULTI_PROCESS, + sizeof(PVRSRV_SGXDEV_INFO), + psDevInfo, + hDevInfoOSMemHandle); +- ++ psDeviceNode->pvDevice = IMG_NULL; ++ + if (psDeviceMemoryHeap != IMG_NULL) + { + +@@ -1178,47 +886,17 @@ + + + +-IMG_VOID HWRecoveryResetSGX (PVRSRV_SGXDEV_INFO *psDevInfo, +- IMG_UINT32 ui32Component, +- IMG_UINT32 ui32CallerID) +-{ +- PVRSRV_ERROR eError; +- +- PVR_UNREFERENCED_PARAMETER(ui32Component); +- PVR_UNREFERENCED_PARAMETER(ui32CallerID); +- +- +- PVR_DPF((PVR_DBG_ERROR, "HWRecoveryResetSGX: SGX Hardware Recovery triggered")); +- +- +- PDUMPSUSPEND(); +- +- +- ResetPBs(psDevInfo); +- +- +- eError = SGXInitialise(psDevInfo, IMG_TRUE); +- if (eError != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError)); +- } +- +- +- PDUMPRESUME(); +-} +- +- +-IMG_VOID HWRecoveryResetSGXEDM (PVRSRV_DEVICE_NODE *psDeviceNode, +- IMG_UINT32 ui32Component, ++#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY) ++static IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, ++ IMG_UINT32 ui32Component, + IMG_UINT32 ui32CallerID) + { + PVRSRV_ERROR eError; + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + PVRSRV_SGX_HOST_CTL *psSGXHostCtl = (PVRSRV_SGX_HOST_CTL *)psDevInfo->psSGXHostCtl; + +-#if defined(SGX_FEATURE_2D_HARDWARE) +- SGX2DHWRecoveryStart(psDevInfo); +-#endif ++ PVR_UNREFERENCED_PARAMETER(ui32Component); ++ + + + eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); +@@ -1227,15 +905,32 @@ + + + +- PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGXEDM: Power transition in progress")); ++ PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress")); + return; + } + + psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR; + ++ PVR_DPF((PVR_DBG_ERROR, "HWRecoveryResetSGX: SGX Hardware Recovery triggered")); + +- HWRecoveryResetSGX(psDevInfo, ui32Component, ui32CallerID); ++ ++ ++ PDUMPSUSPEND(); + ++ ++ do ++ { ++ eError = SGXInitialise(psDevInfo, IMG_TRUE); ++ } ++ while (eError == PVRSRV_ERROR_RETRY); ++ if (eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError)); ++ } ++ ++ ++ PDUMPRESUME(); ++ + PVRSRVPowerUnlock(ui32CallerID); + + +@@ -1244,11 +939,9 @@ + + + PVRSRVProcessQueues(ui32CallerID, IMG_TRUE); +- +-#if defined(SGX_FEATURE_2D_HARDWARE) +- SGX2DHWRecoveryEnd(psDevInfo); +-#endif + } ++#endif ++ + + #if defined(SUPPORT_HW_RECOVERY) + IMG_VOID SGXOSTimer(IMG_VOID *pvData) +@@ -1261,10 +954,6 @@ + IMG_UINT32 ui32CurrentEDMTasks; + IMG_BOOL bLockup = IMG_FALSE; + IMG_BOOL bPoweredDown; +-#if defined(SGX_FEATURE_2D_HARDWARE) +- IMG_UINT32 ui322DCompletedBlits = 0; +- IMG_BOOL b2DCoreIsBusy; +-#endif + + + psDevInfo->ui32TimeStamp++; +@@ -1305,42 +994,6 @@ + } + } + +-#if defined(SGX_FEATURE_2D_HARDWARE) +- if (!bPoweredDown) +- { +- ui322DCompletedBlits = psDevInfo->ui322DCompletedBlits; +- psDevInfo->ui322DCompletedBlits = SGX2DCompletedBlits(psDevInfo); +- } +- +- if (!bLockup && !bPoweredDown) +- { +- b2DCoreIsBusy = SGX2DIsBusy(psDevInfo); +- +- if (b2DCoreIsBusy && ui322DCompletedBlits == psDevInfo->ui322DCompletedBlits) +- { +- if (psDevInfo->b2DLockupSuspected) +- { +- PVR_DPF((PVR_DBG_ERROR, "SGXTimer() detects 2D lockup (%d blits completed)", psDevInfo->ui322DCompletedBlits)); +- bLockup = IMG_TRUE; +- psDevInfo->b2DLockupSuspected = IMG_FALSE; +- } +- else +- { +- +- psDevInfo->b2DLockupSuspected = IMG_TRUE; +- } +- } +- else +- { +- psDevInfo->b2DLockupSuspected = IMG_FALSE; +- } +- } +- else +- { +- psDevInfo->b2DLockupSuspected = IMG_FALSE; +- } +-#endif +- + if (bLockup) + { + PVRSRV_SGX_HOST_CTL *psSGXHostCtl = (PVRSRV_SGX_HOST_CTL *)psDevInfo->psSGXHostCtl; +@@ -1349,7 +1002,7 @@ + psSGXHostCtl->ui32HostDetectedLockups ++; + + +- HWRecoveryResetSGXEDM(psDeviceNode, 0, KERNEL_ID); ++ HWRecoveryResetSGX(psDeviceNode, 0, KERNEL_ID); + } + } + #endif +@@ -1394,14 +1047,6 @@ + ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK; + } + +-#if defined(SGX_FEATURE_2D_HARDWARE) +- if (ui32EventStatus & EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK) +- { +- ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK; +- SGX2DHandle2DComplete(psDevInfo); +- } +-#endif +- + if (ui32EventClear) + { + bInterruptProcessed = IMG_TRUE; +@@ -1420,7 +1065,6 @@ + + IMG_VOID SGX_MISRHandler (IMG_VOID *pvData) + { +- PVRSRV_ERROR eError = PVRSRV_OK; + PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + PVRSRV_SGX_HOST_CTL *psSGXHostCtl = (PVRSRV_SGX_HOST_CTL *)psDevInfo->psSGXHostCtl; +@@ -1428,64 +1072,12 @@ + if ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) && + !(psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR)) + { +- HWRecoveryResetSGXEDM(psDeviceNode, 0, ISR_ID); ++ HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID); + } + +- if ((eError == PVRSRV_OK) && +- (psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) && +- !(psSGXHostCtl->ui32PowManFlags & PVRSRV_USSE_EDM_POWMAN_POWEROFF_REQUEST)) +- { +- +- + #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) +- { +- +- +- PDUMPSUSPEND(); +- +- eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, +- PVRSRV_POWER_STATE_D3, +- ISR_ID, IMG_FALSE); +- if (eError == PVRSRV_OK) +- { +- if ((*(volatile IMG_UINT32 *)(&psSGXHostCtl->ui32PowManFlags) +- & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0) +- { +- +- +- +- psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; +- } +- } +- else if (eError == PVRSRV_ERROR_RETRY) +- { +- +- +- eError = PVRSRV_OK; +- } +- +- +- PDUMPRESUME(); +- } ++ SGXTestActivePowerEvent(psDeviceNode, ISR_ID); + #endif +- } +- +-#if defined(SUPPORT_SGX_EVENT_OBJECT) +- if (psDevInfo->psSGXEventObject) +- { +- PVRSRV_EVENTOBJECT *psEventObject = psDevInfo->psSGXEventObject; +- if(psEventObject->hOSEventKM) +- { +- OSEventObjectSignal(psEventObject->hOSEventKM); +- } +- } +- +-#endif +- +- if (eError != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR, "SGX_MISRHandler error:%lu", eError)); +- } + } + #endif + +@@ -1494,7 +1086,6 @@ + { + DEVICE_MEMORY_INFO *psDevMemoryInfo; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; +- IMG_BOOL bSharedPB = IMG_TRUE; + + + psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE; +@@ -1684,13 +1275,8 @@ + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].pszName = "CacheCoherent"; + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].pszBSName = "CacheCoherent BS"; +-#if defined(SGX535) + + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; +-#else +- +- psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; +-#endif + + + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32HeapID = HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID); +@@ -1698,32 +1284,23 @@ + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32HeapSize = SGX_3DPARAMETERS_HEAP_SIZE; + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].pszName = "3DParameters"; + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].pszBSName = "3DParameters BS"; +- +- +- if(bSharedPB) +- { +- psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE +- | PVRSRV_MEM_RAM_BACKED_ALLOCATION +-#if 0 +- | PVRSRV_HAP_KERNEL_ONLY; ++#if defined(SUPPORT_PERCONTEXT_PB) ++ psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE ++ | PVRSRV_MEM_RAM_BACKED_ALLOCATION ++ | PVRSRV_HAP_SINGLE_PROCESS; ++ psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + #else +- | PVRSRV_HAP_MULTI_PROCESS; +-#endif +- psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; +- } +- else +- { +- psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE +- | PVRSRV_MEM_RAM_BACKED_ALLOCATION +- | PVRSRV_HAP_SINGLE_PROCESS; +- psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; +- } ++ psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE ++ | PVRSRV_MEM_RAM_BACKED_ALLOCATION ++ | PVRSRV_HAP_MULTI_PROCESS; ++ psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; ++#endif + + + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_GENERAL_MAPPING_HEAP_ID); + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE; + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE; +- psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_SINGLE_PROCESS; ++ psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].pszName = "GeneralMapping"; + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].pszBSName = "GeneralMapping BS"; + +@@ -1767,23 +1344,7 @@ + + + psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); +-#if defined(SGX_FEATURE_2D_HARDWARE) +- psClientInfo->s2DSlavePort = psDevInfo->s2DSlavePortKM; +-#endif +- psClientInfo->pvRegsBase = psDevInfo->pvRegsBaseKM; + +-#if defined(SUPPORT_SGX_EVENT_OBJECT) +- if (psDevInfo->psSGXEventObject) +- { +- PVRSRV_EVENTOBJECT *psEventObject = psDevInfo->psSGXEventObject; +- psClientInfo->hOSEventKM = psEventObject->hOSEventKM; +- } +- else +- { +- psClientInfo->hOSEventKM = IMG_NULL; +- } +-#endif +- + + + OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData)); +@@ -1792,13 +1353,48 @@ + return PVRSRV_OK; + } + ++ + IMG_EXPORT +-PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_MISC_INFO *psMiscInfo) ++PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, ++ SGX_MISC_INFO *psMiscInfo) + { +- PVR_UNREFERENCED_PARAMETER(psDevInfo); +- + switch(psMiscInfo->eRequest) + { ++ case SGX_MISC_INFO_REQUEST_CLOCKSPEED: ++ { ++ psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed; ++ return PVRSRV_OK; ++ } ++#ifdef SUPPORT_SGX_HWPERF ++ case SGX_MISC_INFO_REQUEST_HWPERF_CB_ON: ++ { ++ psDevInfo->psSGXHostCtl->ui32HWPerfFlags |= PVRSRV_SGX_HWPERF_ON; ++ return PVRSRV_OK; ++ } ++ case SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF: ++ { ++ psDevInfo->psSGXHostCtl->ui32HWPerfFlags &= ~PVRSRV_SGX_HWPERF_ON; ++ return PVRSRV_OK; ++ } ++ case SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB: ++ { ++ SGX_MISC_INFO_HWPERF_RETRIEVE_CB* psRetrieve = &psMiscInfo->uData.sRetrieveCB; ++ PVRSRV_SGX_HWPERF_CB* psHWPerfCB = (PVRSRV_SGX_HWPERF_CB*)psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; ++ IMG_UINT i = 0; ++ ++ for (; psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < psRetrieve->ui32ArraySize; i++) ++ { ++ PVRSRV_SGX_HWPERF_CBDATA* psData = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff]; ++ OSMemCopy(&psRetrieve->psHWPerfData[i], psData, sizeof(PVRSRV_SGX_HWPERF_CBDATA)); ++ psRetrieve->psHWPerfData[i].ui32ClockSpeed = psDevInfo->ui32CoreClockSpeed; ++ psRetrieve->psHWPerfData[i].ui32TimeMax = psDevInfo->ui32uKernelTimerClock; ++ psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (PVRSRV_SGX_HWPERF_CBSIZE - 1); ++ } ++ psRetrieve->ui32DataCount = i; ++ psRetrieve->ui32Time = OSClockus(); ++ return PVRSRV_OK; ++ } ++#endif + default: + { + +@@ -1807,3 +1403,55 @@ + } + } + ++ ++#if defined(SUPPORT_SGX_HWPERF) ++IMG_EXPORT ++PVRSRV_ERROR SGXReadHWPerfCountersKM(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_UINT32 ui32PerfReg, ++ IMG_UINT32 *pui32OldPerf, ++ IMG_BOOL bNewPerf, ++ IMG_UINT32 ui32NewPerf, ++ IMG_UINT32 ui32NewPerfReset, ++ IMG_UINT32 ui32PerfCountersReg, ++ IMG_UINT32 *pui32Counters, ++ IMG_UINT32 *pui32KickTACounter, ++ IMG_UINT32 *pui32KickTARenderCounter, ++ IMG_UINT32 *pui32CPUTime, ++ IMG_UINT32 *pui32SGXTime) ++{ ++ IMG_UINT32 i; ++ ++ ++ ++ { ++ *pui32OldPerf = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32PerfReg); ++ ++ for (i = 0; i < 9; ++i) ++ { ++ pui32Counters[i] = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32PerfCountersReg + (i * 4)); ++ } ++ ++ *pui32KickTACounter = psDevInfo->ui32KickTACounter; ++ *pui32KickTARenderCounter = psDevInfo->ui32KickTARenderCounter; ++ ++ *pui32CPUTime = OSClockus(); ++ *pui32SGXTime = psDevInfo->psSGXHostCtl->ui32TimeWraps; ++ } ++ ++ ++ ++ if (bNewPerf) ++ { ++ if(ui32NewPerfReset != 0) ++ { ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32PerfReg, ui32NewPerf | ui32NewPerfReset); ++ } ++ ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32PerfReg, ui32NewPerf); ++ } ++ ++ return PVRSRV_OK; ++} ++#endif ++ ++ +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxkick.c git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxkick.c +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxkick.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxkick.c 2008-12-18 15:47:29.000000000 +0100 +@@ -24,11 +24,13 @@ + * + ******************************************************************************/ + ++#include <stddef.h> + #include "services_headers.h" + #include "sgxinfo.h" + #include "sgxinfokm.h" + #if defined (PDUMP) + #include "sgxapi_km.h" ++#include "pdump_km.h" + #endif + #include "sgx_bridge_km.h" + #include "osfunc.h" +@@ -36,92 +38,241 @@ + #include "sgxutils.h" + + ++#define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psCCBKick, offset) \ ++ ((psCCBKick)->offset + sizeof(type) < (psCCBMemInfo)->ui32AllocSize) ++ + #define CCB_DATA_FROM_OFFSET(type, psCCBMemInfo, psCCBKick, offset) \ + ((type *)(((char *)(psCCBMemInfo)->pvLinAddrKM) + \ + (psCCBKick)->offset)) + +-#define CCB_OFFSET_IS_VALID(psCCBMemInfo, psCCBKick, offset) \ +- ((psCCBKick)->offset < (psCCBMemInfo)->ui32AllocSize) +- + IMG_EXPORT + PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, PVR3DIF4_CCB_KICK *psCCBKick) + { + PVRSRV_ERROR eError; + PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; + PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo; +- IMG_UINT32 *pui32DstReadOpsPendingVal; +- IMG_UINT32 *pui32DstWriteOpsPendingVal; ++ PVR3DIF4_CMDTA_SHARED *psTACmd; + IMG_UINT32 i; ++#if defined(SUPPORT_SGX_HWPERF) ++ PVRSRV_DEVICE_NODE *psDeviceNode; ++ PVRSRV_SGXDEV_INFO *psDevInfo; + ++ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; ++ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; ++#endif + +-#if defined(NO_HARDWARE) +- pui32DstReadOpsPendingVal = IMG_NULL; +- pui32DstWriteOpsPendingVal = IMG_NULL; ++#if defined(SUPPORT_SGX_HWPERF) ++ if (psCCBKick->bKickRender) ++ { ++ ++psDevInfo->ui32KickTARenderCounter; ++ } ++ ++psDevInfo->ui32KickTACounter; + #endif + +- if (psCCBKick->hDstKernelSyncInfo != IMG_NULL) ++ if (!CCB_OFFSET_IS_VALID(PVR3DIF4_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset)) + { +- +- if (!CCB_OFFSET_IS_VALID(psCCBMemInfo, psCCBKick, ui32DstReadOpsPendingOffset) || !CCB_OFFSET_IS_VALID(psCCBMemInfo, psCCBKick, ui32DstWriteOpsPendingOffset)) ++ return PVRSRV_ERROR_INVALID_PARAMS; ++ } ++ psTACmd = CCB_DATA_FROM_OFFSET(PVR3DIF4_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset); ++ ++ ++ if (psCCBKick->hTA3DSyncInfo) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; ++ psTACmd->sTA3DDependancy.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ ++ psTACmd->sTA3DDependancy.ui32WriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ ++ if (psCCBKick->bTADependency) + { +- PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: ui32DstReadOpsPendingOffset or ui32DstWriteOpsPendingOffset out of range")); ++ psSyncInfo->psSyncData->ui32WriteOpsPending++; + } +- else +- { +- psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->hDstKernelSyncInfo; +- pui32DstReadOpsPendingVal = CCB_DATA_FROM_OFFSET(IMG_UINT32, psCCBMemInfo, psCCBKick, ui32DstReadOpsPendingOffset); +- pui32DstWriteOpsPendingVal = CCB_DATA_FROM_OFFSET(IMG_UINT32, psCCBMemInfo, psCCBKick, ui32DstWriteOpsPendingOffset); ++ } + +- *pui32DstReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; +- *pui32DstWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; +- } ++ if (psCCBKick->hTASyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; + ++ psTACmd->sTQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ psTACmd->sTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ ++ psTACmd->ui32TQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; ++ psTACmd->ui32TQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + ++ if (psCCBKick->h3DSyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; ++ ++ psTACmd->s3DTQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ ++ psTACmd->ui323DTQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; ++ psTACmd->ui323DTQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ } ++ ++ psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals; + if (psCCBKick->ui32NumTAStatusVals != 0) + { + + for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) + { +- if (CCB_OFFSET_IS_VALID(psCCBMemInfo, psCCBKick, aui32TAStatusValueOffset[i])) +- { +- IMG_UINT32 *pui32TAStatusValue = CCB_DATA_FROM_OFFSET(IMG_UINT32, psCCBMemInfo, psCCBKick, aui32TAStatusValueOffset[i]); +- psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; + +- *pui32TAStatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; +- } +- else +- { +- PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: aui32TAStatusValueOffset[%d] out of range", i)); +- } ++ psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ ++ psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; + } + } + ++ psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals; + if (psCCBKick->ui32Num3DStatusVals != 0) + { + + for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) + { +- if (CCB_OFFSET_IS_VALID(psCCBMemInfo, psCCBKick, aui323DStatusValueOffset[i])) +- { +- IMG_UINT32 *pui323DStatusValue = CCB_DATA_FROM_OFFSET(IMG_UINT32, psCCBMemInfo, psCCBKick, aui323DStatusValueOffset[i]); +- psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; + +- *pui323DStatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; +- } +- else ++ psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ ++ psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ } ++ } ++ ++ ++ psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs; ++ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; ++ ++ psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ ++ ++ psTACmd->asSrcSyncs[i].ui32ReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; ++ ++ psTACmd->asSrcSyncs[i].ui32WriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ ++ } ++ ++ if (psCCBKick->bFirstKickOrResume && psCCBKick->hRenderSurfSyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->hRenderSurfSyncInfo; ++ psTACmd->sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ psTACmd->sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ ++ psTACmd->ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ psTACmd->ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ++ ++ ++#if defined(PDUMP) ++ if (PDumpIsCaptureFrameKM()) ++ { ++ if (psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) + { +- PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: aui323DStatusValueOffset[%d] out of range", i)); ++ ++ PDUMPCOMMENT("Init render surface last op\r\n"); ++ ++ PDUMPMEM(IMG_NULL, ++ psSyncInfo->psSyncDataMemInfoKM, ++ 0, ++ sizeof(PVRSRV_SYNC_DATA), ++ 0, ++ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); ++ ++ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, ++ psSyncInfo->psSyncDataMemInfoKM, ++ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), ++ sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), ++ 0, ++ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + } ++ ++ psSyncInfo->psSyncData->ui32LastOpDumpVal++; + } ++#endif + } + ++#if defined(PDUMP) ++ if (PDumpIsCaptureFrameKM()) ++ { ++ PDUMPCOMMENT("Shared part of TA command\r\n"); ++ ++ PDUMPMEM(IMG_NULL, psCCBMemInfo, psCCBKick->ui32CCBOffset, sizeof(PVR3DIF4_CMDTA_SHARED), 0, MAKEUNIQUETAG(psCCBMemInfo)); ++ ++ if (psCCBKick->hRenderSurfSyncInfo != IMG_NULL) ++ { ++ IMG_UINT32 ui32HackValue; ++ ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hRenderSurfSyncInfo; ++ ui32HackValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; ++ ++ PDUMPCOMMENT("Hack render surface last op in TA cmd\r\n"); ++ ++ PDUMPMEM(&ui32HackValue, ++ psCCBMemInfo, ++ psCCBKick->ui32CCBOffset + offsetof(PVR3DIF4_CMDTA_SHARED, ui32WriteOpsPendingVal), ++ sizeof(IMG_UINT32), ++ 0, ++ MAKEUNIQUETAG(psCCBMemInfo)); ++ ++ ui32HackValue = 0; ++ PDUMPCOMMENT("Hack render surface read op in TA cmd\r\n"); ++ ++ PDUMPMEM(&ui32HackValue, ++ psCCBMemInfo, ++ psCCBKick->ui32CCBOffset + offsetof(PVR3DIF4_CMDTA_SHARED, sReadOpsCompleteDevVAddr), ++ sizeof(IMG_UINT32), ++ 0, ++ MAKEUNIQUETAG(psCCBMemInfo)); ++ } ++ ++ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; ++ ++ PDUMPCOMMENT("Hack TA status value in TA cmd\r\n"); ++ ++ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, ++ psCCBMemInfo, ++ psCCBKick->ui32CCBOffset + offsetof(PVR3DIF4_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue), ++ sizeof(IMG_UINT32), ++ 0, ++ MAKEUNIQUETAG(psCCBMemInfo)); ++ } ++ ++ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; ++ ++ PDUMPCOMMENT("Hack 3D status value in TA cmd\r\n"); ++ ++ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, ++ psCCBMemInfo, ++ psCCBKick->ui32CCBOffset + offsetof(PVR3DIF4_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue), ++ sizeof(IMG_UINT32), ++ 0, ++ MAKEUNIQUETAG(psCCBMemInfo)); ++ } ++ } ++#endif ++ + eError = SGXScheduleCCBCommandKM(hDevHandle, psCCBKick->eCommand, &psCCBKick->sCommand, KERNEL_ID); + if (eError == PVRSRV_ERROR_RETRY) + { +- +- psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->hDstKernelSyncInfo; +- psSyncInfo->psSyncData->ui32WriteOpsPending--; ++ if (psCCBKick->bFirstKickOrResume && psCCBKick->hRenderSurfSyncInfo != IMG_NULL) ++ { ++ ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->hRenderSurfSyncInfo; ++ psSyncInfo->psSyncData->ui32WriteOpsPending--; ++ } ++ ++ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; ++ psSyncInfo->psSyncData->ui32ReadOpsPending--; ++ } ++ + return eError; + } + else if (PVRSRV_OK != eError) +@@ -132,70 +283,66 @@ + + + #if defined(NO_HARDWARE) +- if (psCCBKick->ui32NumTAStatusVals != 0) +- { +- +- for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) +- { +- if (CCB_OFFSET_IS_VALID(psCCBMemInfo, psCCBKick, aui32TAStatusValueOffset[i])) +- { +- IMG_UINT32 *pui32TAStatusValue = CCB_DATA_FROM_OFFSET(IMG_UINT32, psCCBMemInfo, psCCBKick, aui32TAStatusValueOffset[i]); +- psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; +- +- psSyncInfo->psSyncData->ui32ReadOpsComplete = *pui32TAStatusValue; +- } +- } +- } + +- if (psCCBKick->bTerminate) ++ if (psCCBKick->hTA3DSyncInfo) + { +- if (psCCBKick->hUpdateDstKernelSyncInfo != IMG_NULL) ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; ++ ++ if (psCCBKick->bTADependency) + { +- psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hUpdateDstKernelSyncInfo; +- psSyncInfo->psSyncData->ui32WriteOpsComplete = ((pui32DstWriteOpsPendingVal != IMG_NULL) ? *pui32DstWriteOpsPendingVal : psCCBKick->ui32WriteOpsPendingVal) + 1; ++ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; + } ++ } + +- if (psCCBKick->ui32Num3DStatusVals != 0) +- { +- +- for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) +- { +- if (CCB_OFFSET_IS_VALID(psCCBMemInfo, psCCBKick, aui323DStatusValueOffset[i])) +- { +- IMG_UINT32 *pui323DStatusValue = CCB_DATA_FROM_OFFSET(IMG_UINT32, psCCBMemInfo, psCCBKick, aui323DStatusValueOffset[i]); +- psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; ++ if (psCCBKick->hTASyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; + +- psSyncInfo->psSyncData->ui32ReadOpsComplete = *pui323DStatusValue; +- } +- } +- } ++ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; + } +-#endif + +- return eError; +-} ++ if (psCCBKick->h3DSyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; + ++ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ } + +-IMG_VOID SGXScheduleProcessQueues(PVRSRV_DEVICE_NODE *psDeviceNode) +-{ +- PVRSRV_ERROR eError; +- PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; +- PVRSRV_SGX_HOST_CTL *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; +- IMG_UINT32 ui32PowManFlags; +- PVRSRV_SGX_COMMAND sCommand = {0}; ++ ++ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; + +- ui32PowManFlags = psHostCtl->ui32PowManFlags; +- if ((ui32PowManFlags & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0) ++ psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; ++ } ++ ++ ++ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) + { +- +- return; ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; ++ ++ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ + } + +- sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD; +- eError = SGXScheduleCCBCommandKM(psDeviceNode, PVRSRV_SGX_COMMAND_EDM_KICK, &sCommand, ISR_ID); +- if (eError != PVRSRV_OK) ++ if (psCCBKick->bTerminateOrAbort) + { +- PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueues failed to schedule CCB command: %lu", eError)); ++ if (psCCBKick->hRenderSurfSyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hRenderSurfSyncInfo; ++ psSyncInfo->psSyncData->ui32WriteOpsComplete = psCCBKick->bFirstKickOrResume ? psSyncInfo->psSyncData->ui32WriteOpsPending : (psCCBKick->ui32WriteOpsPendingVal + 1); ++ } ++ ++ ++ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; ++ ++ psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; ++ } + } ++#endif ++ ++ return eError; + } + +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxreset.c git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxreset.c +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxreset.c 1970-01-01 01:00:00.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxreset.c 2008-12-18 15:47:29.000000000 +0100 +@@ -0,0 +1,330 @@ ++/********************************************************************** ++ * ++ * Copyright(c) 2008 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 "sgxdefs.h" ++#include "sgxmmu.h" ++#include "services_headers.h" ++#include "sgxinfokm.h" ++#include "sgxconfig.h" ++ ++#include "pdump_km.h" ++ ++ ++#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) ++#define SGX_BIF_DIR_LIST_INDEX_EDM 15 ++#define SGX_BIF_DIR_LIST_REG_EDM EUR_CR_BIF_DIR_LIST_BASE15 ++#else ++#define SGX_BIF_DIR_LIST_REG_EDM EUR_CR_BIF_DIR_LIST_BASE0 ++#endif ++ ++ ++static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_BOOL bResetBIF, ++ IMG_UINT32 ui32PDUMPFlags, ++ IMG_BOOL bPDump) ++{ ++ IMG_UINT32 ui32SoftResetRegVal = ++ #ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK ++ EUR_CR_SOFT_RESET_TWOD_RESET_MASK | ++ #endif ++ EUR_CR_SOFT_RESET_DPM_RESET_MASK | ++ EUR_CR_SOFT_RESET_TA_RESET_MASK | ++ EUR_CR_SOFT_RESET_USE_RESET_MASK | ++ EUR_CR_SOFT_RESET_ISP_RESET_MASK | ++ EUR_CR_SOFT_RESET_TSP_RESET_MASK; ++ ++#if !defined(PDUMP) ++ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); ++#endif ++ ++ if (bResetBIF) ++ { ++ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_BIF_RESET_MASK; ++ } ++ ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32SoftResetRegVal); ++ if (bPDump) ++ { ++ PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags); ++ } ++} ++ ++ ++static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_UINT32 ui32PDUMPFlags, ++ IMG_BOOL bPDump) ++{ ++#if !defined(PDUMP) ++ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); ++#endif ++ ++ ++ OSWaitus(1000 * 1000000 / psDevInfo->ui32CoreClockSpeed); ++ if (bPDump) ++ { ++ PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags); ++#if defined(PDUMP) ++ PDumpRegRead(EUR_CR_SOFT_RESET, ui32PDUMPFlags); ++#endif ++ } ++ ++ ++ ++} ++ ++ ++static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_UINT32 ui32PDUMPFlags, ++ IMG_BOOL bPDump) ++{ ++ IMG_UINT32 ui32RegVal; ++ ++ ++ ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK; ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); ++ if (bPDump) ++ { ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); ++ } ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump); ++ ++ ui32RegVal = 0; ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); ++ if (bPDump) ++ { ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); ++ } ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump); ++ ++#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) ++ { ++ ++ ++ ++ if (PollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + EUR_CR_BIF_MEM_REQ_STAT), ++ 0, ++ EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ++ MAX_HW_TIME_US/WAIT_TRY_COUNT, ++ WAIT_TRY_COUNT) != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR,"Wait for DC invalidate failed.")); ++ } ++ ++ if (bPDump) ++ { ++ PDUMPREGPOLWITHFLAGS(EUR_CR_BIF_MEM_REQ_STAT, 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ui32PDUMPFlags); ++ } ++ } ++#endif ++} ++ ++ ++IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, ++ IMG_UINT32 ui32PDUMPFlags) ++{ ++ IMG_UINT32 ui32RegVal; ++ ++ const IMG_UINT32 ui32BifFaultMask = ++ EUR_CR_BIF_INT_STAT_FAULT_MASK; ++ ++#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) ++ IMG_UINT32 ui32BIFCtrl; ++#if defined(EUR_CR_BIF_MEM_ARB_CONFIG) ++ IMG_UINT32 ui32BIFMemArb; ++#endif ++#endif ++ ++#ifndef PDUMP ++ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); ++#endif ++ ++ psDevInfo->ui32NumResets++; ++ ++ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX reset sequence\r\n"); ++ ++#if defined(FIX_HW_BRN_23944) ++ ++ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); ++ ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ++ ++ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); ++ if (ui32RegVal & ui32BifFaultMask) ++ { ++ ++ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK | EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK; ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); ++ ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ++ ++ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); ++ ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ++ } ++#endif ++ ++ ++ SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE); ++ ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ++ ++ ++ ++#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) ++ ui32RegVal = 0; ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal); ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags); ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal); ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags); ++ ++#if defined(EUR_CR_BIF_MEM_ARB_CONFIG) ++ ++ ++ ui32BIFMemArb = (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT) | ++ (7UL << EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT) | ++ (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT); ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_ARB_CONFIG, ui32BIFMemArb); ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_MEM_ARB_CONFIG, ui32BIFMemArb, ui32PDUMPFlags); ++#endif ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ui32RegVal = psDevInfo->sBIFResetPDDevPAddr.uiAddr; ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); ++ ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); ++ ++ ++ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE); ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); ++ ++ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE); ++ ++ ++ ++ for (;;) ++ { ++ IMG_UINT32 ui32BifIntStat = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); ++ IMG_DEV_VIRTADDR sBifFault; ++ IMG_UINT32 ui32PDIndex, ui32PTIndex; ++ ++ if ((ui32BifIntStat & ui32BifFaultMask) == 0) ++ { ++ break; ++ } ++ ++ ++ ++ ++ sBifFault.uiAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT); ++ PVR_DPF((PVR_DBG_WARNING, "SGXReset: Page fault 0x%x/0x%x", ui32BifIntStat, sBifFault.uiAddr)); ++ ui32PDIndex = sBifFault.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); ++ ui32PTIndex = (sBifFault.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; ++ ++ ++ SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_FALSE); ++ ++ ++ psDevInfo->pui32BIFResetPD[ui32PDIndex] = psDevInfo->sBIFResetPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; ++ psDevInfo->pui32BIFResetPT[ui32PTIndex] = psDevInfo->sBIFResetPageDevPAddr.uiAddr | SGX_MMU_PTE_VALID; ++ ++ ++ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32RegVal); ++ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2); ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32RegVal); ++ ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); ++ ++ ++ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_FALSE); ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); ++ ++ ++ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE); ++ ++ ++ psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0; ++ psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0; ++ } ++ ++ ++ ++ ++#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) ++ ++ ui32BIFCtrl = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT); ++#ifdef SGX_FEATURE_2D_HARDWARE ++ ++ ui32BIFCtrl |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT); ++#endif ++#if defined(FIX_HW_BRN_23410) ++ ++ ui32BIFCtrl |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT); ++#endif ++ ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32BIFCtrl); ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32BIFCtrl, ui32PDUMPFlags); ++#endif ++ ++ ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_BIF_DIR_LIST_REG_EDM, psDevInfo->sKernelPDDevPAddr.uiAddr); ++ PDUMPPDREGWITHFLAGS(SGX_BIF_DIR_LIST_REG_EDM, psDevInfo->sKernelPDDevPAddr.uiAddr, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); ++ ++#ifdef SGX_FEATURE_2D_HARDWARE ++ ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE); ++ PDUMPREGWITHFLAGS(EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags); ++#endif ++ ++ ++ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ++ ++ PVR_DPF((PVR_DBG_WARNING,"Soft Reset of SGX")); ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ++ ++ ++ ui32RegVal = 0; ++ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); ++ PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); ++ ++ ++ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ++ ++ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n"); ++} ++ ++ +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxtransfer.c git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxtransfer.c +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxtransfer.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxtransfer.c 2008-12-18 15:47:29.000000000 +0100 +@@ -43,16 +43,314 @@ + #include "pvr_debug.h" + #include "sgxutils.h" + +-IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, +- IMG_DEV_VIRTADDR sHWRenderContextDevVAddr) +- ++#define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psKick, offset) \ ++ ((psKick)->offset + sizeof(type) < (psCCBMemInfo)->ui32AllocSize) ++ ++#define CCB_DATA_FROM_OFFSET(type, psCCBMemInfo, psKick, offset) \ ++ ((type *)(((char *)(psCCBMemInfo)->pvLinAddrKM) + \ ++ (psKick)->offset)) ++ ++IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick) + { ++ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; + PVRSRV_SGX_COMMAND sCommand = {0}; ++ PVR3DIF4_TRANSFERCMD_SHARED *psTransferCmd; ++ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; ++ IMG_UINT32 i; ++ PVRSRV_ERROR eError; ++ ++ if (!CCB_OFFSET_IS_VALID(PVR3DIF4_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) ++ { ++ return PVRSRV_ERROR_INVALID_PARAMS; ++ } ++ psTransferCmd = CCB_DATA_FROM_OFFSET(PVR3DIF4_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); ++ ++ if (psTransferCmd->ui32NumStatusVals > SGXTQ_MAX_STATUS) ++ { ++ return PVRSRV_ERROR_INVALID_PARAMS; ++ } ++ ++ if (psKick->ui32StatusFirstSync + ++ (psKick->ui32NumSrcSync ? (psKick->ui32NumSrcSync - 1) : 0) + ++ (psKick->ui32NumDstSync ? (psKick->ui32NumDstSync - 1) : 0) > ++ psTransferCmd->ui32NumStatusVals) ++ { ++ return PVRSRV_ERROR_INVALID_PARAMS; ++ } ++ ++ if (psKick->hTASyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; ++ ++ psTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ++ psTransferCmd->ui32TASyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ ++ psTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ psTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ } ++ else ++ { ++ psTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0; ++ psTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0; ++ } ++ ++ if (psKick->h3DSyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; ++ ++ psTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ++ psTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ ++ psTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ psTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ } ++ else ++ { ++ psTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0; ++ psTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0; ++ } + +- sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD; +- sCommand.ui32Data[1] = sHWRenderContextDevVAddr.uiAddr; + +- return SGXScheduleCCBCommandKM(hDevHandle, PVRSRV_SGX_COMMAND_EDM_KICK, &sCommand, KERNEL_ID); ++ psTransferCmd->ui32NumSrcSync = psKick->ui32NumSrcSync; ++ psTransferCmd->ui32NumDstSync = psKick->ui32NumDstSync; ++ ++ ++ if(psKick->ui32NumSrcSync > 0) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0]; ++ ++ psTransferCmd->ui32SrcWriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ psTransferCmd->ui32SrcReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ ++ psTransferCmd->sSrcWriteOpsCompleteDevAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ psTransferCmd->sSrcReadOpsCompleteDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ } ++ if(psKick->ui32NumDstSync > 0) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; ++ ++ psTransferCmd->ui32DstWriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ psTransferCmd->ui32DstReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ ++ psTransferCmd->sDstWriteOpsCompleteDevAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ psTransferCmd->sDstReadOpsCompleteDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ } ++ ++ ++ if (psKick->ui32NumSrcSync > 0) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0]; ++ psSyncInfo->psSyncData->ui32ReadOpsPending++; ++ ++ } ++ if (psKick->ui32NumDstSync > 0) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; ++ psSyncInfo->psSyncData->ui32WriteOpsPending++; ++ } ++ ++ ++ if (psKick->ui32NumSrcSync > 1) ++ { ++ for(i = 1; i < psKick->ui32NumSrcSync; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; ++ ++ psTransferCmd->sCtlStatusInfo[psKick->ui32StatusFirstSync].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending++; ++ ++ psTransferCmd->sCtlStatusInfo[psKick->ui32StatusFirstSync].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ ++ psKick->ui32StatusFirstSync++; ++ } ++ } ++ ++ if (psKick->ui32NumDstSync > 1) ++ { ++ for(i = 1; i < psKick->ui32NumDstSync; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i]; ++ ++ psTransferCmd->sCtlStatusInfo[psKick->ui32StatusFirstSync].ui32StatusValue = psSyncInfo->psSyncData->ui32WriteOpsPending++; ++ ++ psTransferCmd->sCtlStatusInfo[psKick->ui32StatusFirstSync].sStatusDevAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ ++ psKick->ui32StatusFirstSync++; ++ } ++ } ++ ++#if defined(PDUMP) ++ PDUMPCOMMENT("Shared part of transfer command\r\n"); ++ PDUMPMEM(IMG_NULL, ++ psCCBMemInfo, ++ psKick->ui32SharedCmdCCBOffset, ++ sizeof(PVR3DIF4_TRANSFERCMD_SHARED), ++ 0, ++ MAKEUNIQUETAG(psCCBMemInfo)); ++#endif ++ ++ sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD; ++ sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr; ++ ++ eError = SGXScheduleCCBCommandKM(hDevHandle, PVRSRV_SGX_COMMAND_EDM_KICK, &sCommand, KERNEL_ID); ++ ++#if defined(NO_HARDWARE) ++ ++ for(i = 0; i < psKick->ui32NumSrcSync; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; ++ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ } ++ ++ for(i = 0; i < psKick->ui32NumDstSync; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i]; ++ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ ++ } ++ ++ if (psKick->hTASyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; ++ ++ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ } ++ ++ if (psKick->h3DSyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; ++ ++ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ } ++#endif ++ ++ return eError; + } + +-#endif ++#if defined(SGX_FEATURE_2D_HARDWARE) ++IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick) ++ ++{ ++ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; ++ PVRSRV_SGX_COMMAND sCommand = {0}; ++ PVR3DIF4_2DCMD_SHARED *ps2DCmd; ++ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; ++ IMG_BOOL bDstSyncDone = IMG_FALSE; ++ PVRSRV_ERROR eError; ++ IMG_UINT32 i; ++ ++ if (!CCB_OFFSET_IS_VALID(PVR3DIF4_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) ++ { ++ return PVRSRV_ERROR_INVALID_PARAMS; ++ } ++ ps2DCmd = CCB_DATA_FROM_OFFSET(PVR3DIF4_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); ++ ++ OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd)); ++ ++ ++ if (psKick->hTASyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; ++ ++ ps2DCmd->sTASyncData.ui32WriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ++ ps2DCmd->sTASyncData.ui32ReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ ++ ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ } ++ ++ ++ if (psKick->h3DSyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; ++ ++ ps2DCmd->s3DSyncData.ui32WriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ++ ps2DCmd->s3DSyncData.ui32ReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ ++ ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ } ++ ++ ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync; ++ for (i = 0; i < psKick->ui32NumSrcSync; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; ++ if (psSyncInfo == (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo) ++ { ++ ps2DCmd->sSrcSyncData[i].ui32WriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ ps2DCmd->sSrcSyncData[i].ui32ReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ ++ ps2DCmd->sDstSyncData.ui32WriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ++ ps2DCmd->sDstSyncData.ui32ReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; ++ ++ bDstSyncDone = IMG_TRUE; ++ } ++ else ++ { ++ ps2DCmd->sSrcSyncData[i].ui32WriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ ps2DCmd->sSrcSyncData[i].ui32ReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; ++ } ++ ++ ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ } ++ ++ if (psKick->hDstSyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo; ++ ++ if (!bDstSyncDone) ++ { ++ ps2DCmd->sDstSyncData.ui32WriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ++ ps2DCmd->sDstSyncData.ui32ReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ } ++ ++ ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ++ ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ++ } ++ ++#if defined(PDUMP) ++ ++ PDUMPCOMMENT("Shared part of 2D command\r\n"); ++ PDUMPMEM(IMG_NULL, ++ psCCBMemInfo, ++ psKick->ui32SharedCmdCCBOffset, ++ sizeof(PVR3DIF4_2DCMD_SHARED), ++ 0, ++ MAKEUNIQUETAG(psCCBMemInfo)); ++#endif ++ ++ sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_2DCMD; ++ sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr; ++ ++ eError = SGXScheduleCCBCommandKM(hDevHandle, PVRSRV_SGX_COMMAND_EDM_KICK, &sCommand, KERNEL_ID); ++ ++#if defined(NO_HARDWARE) ++ ++ for(i = 0; i < psKick->ui32NumSrcSync; i++) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; ++ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; ++ } ++ ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo; ++ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ ++ if (psKick->hTASyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; ++ ++ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ } ++ ++ if (psKick->h3DSyncInfo != IMG_NULL) ++ { ++ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; ++ ++ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; ++ } ++#endif ++ ++ return eError; ++} ++#endif ++#endif +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxutils.c git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxutils.c +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxutils.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxutils.c 2008-12-18 15:47:29.000000000 +0100 +@@ -46,6 +46,79 @@ + #include <stdio.h> + #endif + ++#if defined(SYS_CUSTOM_POWERDOWN) ++PVRSRV_ERROR SysPowerDownMISR(IMG_UINT32 ui32DeviceIndex, IMG_UINT32 ui32CallerID); ++#endif ++ ++ ++#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) ++IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE *psDeviceNode, ++ IMG_UINT32 ui32CallerID) ++{ ++ PVRSRV_ERROR eError = PVRSRV_OK; ++ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; ++ PVRSRV_SGX_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; ++ ++ if ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) && ++ !(psSGXHostCtl->ui32PowManFlags & PVRSRV_USSE_EDM_POWMAN_POWEROFF_REQUEST)) ++ { ++ ++ ++ { ++ ++ PDUMPSUSPEND(); ++ ++#if defined(SYS_CUSTOM_POWERDOWN) ++ ++ ++ ++ eError = SysPowerDownMISR(psDeviceNode->sDevId.ui32DeviceIndex, ui32CallerID); ++#else ++ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, ++ PVRSRV_POWER_STATE_D3, ++ ui32CallerID, IMG_FALSE); ++ if (eError == PVRSRV_OK) ++ { ++ ++ psSGXHostCtl->ui32NumActivePowerEvents++; ++ ++ if ((*(volatile IMG_UINT32 *)(&psSGXHostCtl->ui32PowManFlags) ++ & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0) ++ { ++ ++ ++ ++ if (ui32CallerID == ISR_ID) ++ { ++ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; ++ } ++ else ++ { ++ SGXScheduleProcessQueues(psDeviceNode); ++ } ++ } ++ } ++#endif ++ if (eError == PVRSRV_ERROR_RETRY) ++ { ++ ++ ++ eError = PVRSRV_OK; ++ } ++ ++ ++ PDUMPRESUME(); ++ } ++ } ++ ++ if (eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%lu", eError)); ++ } ++} ++#endif ++ ++ + #ifdef INLINE_IS_PRAGMA + #pragma inline(SGXAcquireKernelCCBSlot) + #endif +@@ -255,147 +328,43 @@ + Exit: + PVRSRVPowerUnlock(ui32CallerID); + +- return eError; +-} +- +- +-#if 0 +-PVRSRV_ERROR CreateCCB(PVRSRV_SGXDEV_INFO *psSGXDevInfo, +- IMG_UINT32 ui32CCBSize, +- IMG_UINT32 ui32AllocGran, +- IMG_UINT32 ui32OverrunSize, +- IMG_HANDLE hDevMemHeap, +- PVRSRV_SGX_CCB **ppsCCB) +-{ +- PVRSRV_SGX_CCB *psCCB; +- +- PVR_UNREFERENCED_PARAMETER(psSGXDevInfo); +- +- psCCB = IMG_NULL; +- +- if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, +- sizeof(PVRSRV_SGX_CCB), +- (IMG_VOID **)&psCCB, +- IMG_NULL) != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR,"CreateCCB: psCCB alloc failed")); +- +- return PVRSRV_ERROR_OUT_OF_MEMORY; +- } +- +- +- psCCB->psCCBMemInfo = IMG_NULL; +- psCCB->psCCBCtlMemInfo = IMG_NULL; +- psCCB->pui32CCBLinAddr = IMG_NULL; +- psCCB->pui32WriteOffset = IMG_NULL; +- psCCB->pui32ReadOffset = IMG_NULL; +- +- #ifdef PDUMP +- psCCB->ui32CCBDumpWOff = 0; +- #endif +- +- +- if ( ui32CCBSize < 0x1000 ) ++#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) ++ if (ui32CallerID != ISR_ID) + { +- IMG_UINT32 i, ui32PowOfTwo; ++ + +- ui32PowOfTwo = 0x1000; + +- for (i = 12; i > 0; i--) +- { +- if (ui32CCBSize & ui32PowOfTwo) +- { +- break; +- } +- +- ui32PowOfTwo >>= 1; +- } +- +- if (ui32CCBSize & (ui32PowOfTwo - 1)) +- { +- ui32PowOfTwo <<= 1; +- } +- +- ui32AllocGran = ui32PowOfTwo; +- } +- else +- { +- ui32AllocGran = 0x1000; ++ SGXTestActivePowerEvent(psDeviceNode, ui32CallerID); + } ++#endif + +- +- if (PVRSRVAllocDeviceMemKM(IMG_NULL, +- hDevMemHeap, +- PVRSRV_MEM_READ | PVRSRV_MEM_WRITE | PVRSRV_MEM_EDM_PROTECT | PVRSRV_MEM_NO_SYNCOBJ, +- ui32CCBSize + ui32OverrunSize, +- ui32AllocGran, +- &psCCB->psCCBMemInfo) != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR,"CreateCCB: CCBMemInfo alloc failed")); +- +- goto ErrorExit; +- } ++ return eError; ++} + +- psCCB->pui32CCBLinAddr = psCCB->psCCBMemInfo->pvLinAddrKM; +- psCCB->sCCBDevAddr = psCCB->psCCBMemInfo->sDevVAddr; +- psCCB->ui32Size = ui32CCBSize; +- psCCB->ui32AllocGran = ui32AllocGran; ++IMG_VOID SGXScheduleProcessQueues(PVRSRV_DEVICE_NODE *psDeviceNode) ++{ ++ PVRSRV_ERROR eError; ++ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; ++ PVRSRV_SGX_HOST_CTL *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; ++ IMG_UINT32 ui32PowManFlags; ++ PVRSRV_SGX_COMMAND sCommand = {0}; + +- +- if (PVRSRVAllocDeviceMemKM(IMG_NULL, +- hDevMemHeap, +- PVRSRV_MEM_READ | PVRSRV_MEM_WRITE | PVRSRV_MEM_EDM_PROTECT | PVRSRV_MEM_NO_SYNCOBJ, +- sizeof(PVRSRV_SGX_CCB_CTL), +- 32, +- &psCCB->psCCBCtlMemInfo) != PVRSRV_OK) ++ ui32PowManFlags = psHostCtl->ui32PowManFlags; ++ if ((ui32PowManFlags & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0) + { +- PVR_DPF((PVR_DBG_ERROR,"CreateCCB: CCBCtlMemInfo alloc failed")); +- +- goto ErrorExit; ++ ++ return; + } + +- +- psCCB->pui32WriteOffset = &((PVRSRV_SGX_CCB_CTL *)psCCB->psCCBCtlMemInfo->pvLinAddrKM)->ui32WriteOffset; +- psCCB->pui32ReadOffset = &((PVRSRV_SGX_CCB_CTL *)psCCB->psCCBCtlMemInfo->pvLinAddrKM)->ui32ReadOffset; +- +- +- *psCCB->pui32WriteOffset = 0; +- *psCCB->pui32ReadOffset = 0; +- +- +- *ppsCCB = psCCB; +- +- return PVRSRV_OK; +- +-ErrorExit: +- +- +- if (psCCB->psCCBMemInfo) ++ sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD; ++ eError = SGXScheduleCCBCommandKM(psDeviceNode, PVRSRV_SGX_COMMAND_EDM_KICK, &sCommand, ISR_ID); ++ if (eError != PVRSRV_OK) + { +- PVRSRVFreeDeviceMemKM(IMG_NULL, psCCB->psCCBMemInfo, IMG_FALSE); ++ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueues failed to schedule CCB command: %lu", eError)); + } +- +- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psCCB, IMG_NULL); +- +- return PVRSRV_ERROR_OUT_OF_MEMORY; +-; + } + +-IMG_VOID DestroyCCB(PVRSRV_SGX_CCB *psCCB, IMG_UINT32 ui32PFlags) +-{ +- PVRSRVFreeDeviceMemKM(IMG_NULL, psCCB->psCCBMemInfo, IMG_FALSE); +- +- PVRSRVFreeDeviceMemKM(IMG_NULL, psCCB->psCCBCtlMemInfo, IMG_FALSE); + +- if (!(ui32PFlags & PFLAGS_POWERDOWN)) +- { +- if (psCCB) +- { +- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psCCB, IMG_NULL); +- } +- } +-} +-#endif + #if defined (PDUMP) + IMG_VOID DumpBufferArray(PPVR3DIF4_KICKTA_DUMP_BUFFER psBufferArray, + IMG_UINT32 ui32BufferArrayLength, +@@ -513,18 +482,6 @@ + psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff; + psSGXInternalDevInfo->ui32RegFlags = (IMG_BOOL)psDevInfo->ui32RegFlags; + +-#if defined(SUPPORT_SGX_EVENT_OBJECT) +- if (psDevInfo->psSGXEventObject) +- { +- PVRSRV_EVENTOBJECT *psEventObject = psDevInfo->psSGXEventObject; +- psSGXInternalDevInfo->hOSEvent = psEventObject->hOSEventKM; +- } +- else +- { +- psSGXInternalDevInfo->hOSEvent = IMG_NULL; +- } +-#endif +- + + psSGXInternalDevInfo->hCtlKernelMemInfoHandle = + (IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo; +@@ -532,11 +489,11 @@ + return PVRSRV_OK; + } + +-static IMG_VOID SGXCleanupRequest(PVRSRV_SGXDEV_INFO *psSGXDevInfo, ++static IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_DEV_VIRTADDR *psHWDataDevVAddr, +- IMG_BOOL bContextCleanup) ++ IMG_UINT32 ui32ResManRequestFlag) + { +- IMG_UINT32 ui32ResManRequestFlag = 0; ++ PVRSRV_SGXDEV_INFO *psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psSGXDevInfo->psKernelSGXHostCtlMemInfo; + PVRSRV_SGX_HOST_CTL *psSGXHostCtl = (PVRSRV_SGX_HOST_CTL *)psSGXHostCtlMemInfo->pvLinAddrKM; + IMG_UINT32 ui32PowManFlags; +@@ -554,25 +511,18 @@ + + if (psSGXDevInfo->ui32CacheControl & SGX_BIF_INVALIDATE_PDCACHE) + { +- ui32ResManRequestFlag |= PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPD; ++ psSGXHostCtl->ui32ResManFlags |= PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPD; + psSGXDevInfo->ui32CacheControl ^= SGX_BIF_INVALIDATE_PDCACHE; + } + if (psSGXDevInfo->ui32CacheControl & SGX_BIF_INVALIDATE_PTCACHE) + { +- ui32ResManRequestFlag |= PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPT; ++ psSGXHostCtl->ui32ResManFlags |= PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPT; + psSGXDevInfo->ui32CacheControl ^= SGX_BIF_INVALIDATE_PTCACHE; + } +- if (bContextCleanup) +- { +- ui32ResManRequestFlag |= PVRSRV_USSE_EDM_RESMAN_CLEANUP_RC_REQUEST; +- } +- else +- { +- ui32ResManRequestFlag |= PVRSRV_USSE_EDM_RESMAN_CLEANUP_RT_REQUEST; +- } +- ++ + + psSGXHostCtl->sResManCleanupData.uiAddr = psHWDataDevVAddr->uiAddr; ++ + psSGXHostCtl->ui32ResManFlags |= ui32ResManRequestFlag; + + +@@ -581,6 +531,9 @@ + PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(PVRSRV_SGX_HOST_CTL, ui32ResManFlags), sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, hUniqueTag); + + ++ SGXScheduleProcessQueues(psDeviceNode); ++ ++ + #if !defined(NO_HARDWARE) + if(PollForValueKM ((volatile IMG_UINT32 *)(&psSGXHostCtl->ui32ResManFlags), + PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE, +@@ -612,8 +565,8 @@ + + typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_ + { +- PVRSRV_SGXDEV_INFO *psDevInfo; +- IMG_DEV_VIRTADDR sHWDataDevVAddr; ++ PVRSRV_DEVICE_NODE *psDeviceNode; ++ IMG_DEV_VIRTADDR sHWRenderContextDevVAddr; + IMG_HANDLE hBlockAlloc; + PRESMAN_ITEM psResItem; + } SGX_HW_RENDER_CONTEXT_CLEANUP; +@@ -625,8 +578,8 @@ + PVR_UNREFERENCED_PARAMETER(ui32ProcessID); + PVR_UNREFERENCED_PARAMETER(ui32Param); + +- SGXCleanupRequest(psCleanup->psDevInfo, +- &psCleanup->sHWDataDevVAddr, IMG_TRUE); ++ SGXCleanupRequest(psCleanup->psDeviceNode, ++ &psCleanup->sHWRenderContextDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_RC_REQUEST); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), +@@ -636,8 +589,34 @@ + return PVRSRV_OK; + } + ++typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_ ++{ ++ PVRSRV_DEVICE_NODE *psDeviceNode; ++ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; ++ IMG_HANDLE hBlockAlloc; ++ PRESMAN_ITEM psResItem; ++} SGX_HW_TRANSFER_CONTEXT_CLEANUP; ++ ++static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_UINT32 ui32ProcessID, IMG_PVOID pvParam, IMG_UINT32 ui32Param) ++{ ++ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam; ++ ++ PVR_UNREFERENCED_PARAMETER(ui32ProcessID); ++ PVR_UNREFERENCED_PARAMETER(ui32Param); ++ ++ SGXCleanupRequest(psCleanup->psDeviceNode, ++ &psCleanup->sHWTransferContextDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_TC_REQUEST); ++ ++ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ++ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), ++ psCleanup, ++ psCleanup->hBlockAlloc); ++ ++ return PVRSRV_OK; ++} ++ + IMG_EXPORT +-IMG_HANDLE SGXRegisterHWRenderContextKM(PVRSRV_SGXDEV_INFO *psSGXDevInfo, IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr) ++IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode, IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr) + { + PVRSRV_ERROR eError; + IMG_HANDLE hBlockAlloc; +@@ -656,8 +635,8 @@ + } + + psCleanup->hBlockAlloc = hBlockAlloc; +- psCleanup->psDevInfo = psSGXDevInfo; +- psCleanup->sHWDataDevVAddr = *psHWRenderContextDevVAddr; ++ psCleanup->psDeviceNode = (PVRSRV_DEVICE_NODE *)psDeviceNode; ++ psCleanup->sHWRenderContextDevVAddr = *psHWRenderContextDevVAddr; + + psResItem = ResManRegisterRes(RESMAN_TYPE_HW_RENDER_CONTEXT, + (IMG_VOID *)psCleanup, +@@ -682,25 +661,173 @@ + } + + IMG_EXPORT +-IMG_VOID SGXFlushHWRenderTargetKM(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr) ++PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext) + { +- PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL); ++ PVRSRV_ERROR eError; ++ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; + +- SGXCleanupRequest(psDevInfo, &sHWRTDataSetDevVAddr, IMG_FALSE); ++ PVR_ASSERT(hHWRenderContext != IMG_NULL); ++ ++ psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext; ++ ++ eError = ResManFreeResByPtr(psCleanup->psResItem, IMG_TRUE); ++ ++ return eError; + } + + IMG_EXPORT +-PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext) ++IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode, IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr) + { + PVRSRV_ERROR eError; +- SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; ++ IMG_HANDLE hBlockAlloc; ++ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; ++ PRESMAN_ITEM psResItem; + +- PVR_ASSERT(hHWRenderContext != IMG_NULL); ++ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ++ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), ++ (IMG_VOID **)&psCleanup, ++ &hBlockAlloc); + +- psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext; ++ if (eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure")); ++ return IMG_NULL; ++ } ++ ++ psCleanup->hBlockAlloc = hBlockAlloc; ++ psCleanup->psDeviceNode = (PVRSRV_DEVICE_NODE *)psDeviceNode; ++ psCleanup->sHWTransferContextDevVAddr = *psHWTransferContextDevVAddr; ++ ++ psResItem = ResManRegisterRes(RESMAN_TYPE_HW_TRANSFER_CONTEXT, ++ (IMG_VOID *)psCleanup, ++ 0, ++ &SGXCleanupHWTransferContextCallback, ++ 0); ++ ++ if (psResItem == IMG_NULL) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed")); ++ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ++ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), ++ psCleanup, ++ psCleanup->hBlockAlloc); ++ ++ return IMG_NULL; ++ } ++ ++ psCleanup->psResItem = psResItem; ++ ++ return (IMG_HANDLE)psCleanup; ++} ++ ++IMG_EXPORT ++PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext) ++{ ++ PVRSRV_ERROR eError; ++ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; ++ ++ PVR_ASSERT(hHWTransferContext != IMG_NULL); ++ ++ psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext; ++ ++ eError = ResManFreeResByPtr(psCleanup->psResItem, IMG_TRUE); ++ ++ return eError; ++} ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_ ++{ ++ PVRSRV_DEVICE_NODE *psDeviceNode; ++ IMG_DEV_VIRTADDR sHW2DContextDevVAddr; ++ IMG_HANDLE hBlockAlloc; ++ PRESMAN_ITEM psResItem; ++} SGX_HW_2D_CONTEXT_CLEANUP; ++ ++static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_UINT32 ui32ProcessID, IMG_PVOID pvParam, IMG_UINT32 ui32Param) ++{ ++ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam; ++ ++ PVR_UNREFERENCED_PARAMETER(ui32ProcessID); ++ PVR_UNREFERENCED_PARAMETER(ui32Param); ++ ++ SGXCleanupRequest(psCleanup->psDeviceNode, ++ &psCleanup->sHW2DContextDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_2DC_REQUEST); ++ ++ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ++ sizeof(SGX_HW_2D_CONTEXT_CLEANUP), ++ psCleanup, ++ psCleanup->hBlockAlloc); ++ ++ return PVRSRV_OK; ++} ++ ++IMG_EXPORT ++IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode, IMG_DEV_VIRTADDR *psHW2DContextDevVAddr) ++{ ++ PVRSRV_ERROR eError; ++ IMG_HANDLE hBlockAlloc; ++ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; ++ PRESMAN_ITEM psResItem; ++ ++ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ++ sizeof(SGX_HW_2D_CONTEXT_CLEANUP), ++ (IMG_VOID **)&psCleanup, ++ &hBlockAlloc); ++ ++ if (eError != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure")); ++ return IMG_NULL; ++ } ++ ++ psCleanup->hBlockAlloc = hBlockAlloc; ++ psCleanup->psDeviceNode = (PVRSRV_DEVICE_NODE *)psDeviceNode; ++ psCleanup->sHW2DContextDevVAddr = *psHW2DContextDevVAddr; ++ ++ psResItem = ResManRegisterRes(RESMAN_TYPE_HW_2D_CONTEXT, ++ (IMG_VOID *)psCleanup, ++ 0, ++ &SGXCleanupHW2DContextCallback, ++ 0); ++ ++ if (psResItem == IMG_NULL) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed")); ++ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ++ sizeof(SGX_HW_2D_CONTEXT_CLEANUP), ++ psCleanup, ++ psCleanup->hBlockAlloc); ++ ++ return IMG_NULL; ++ } ++ ++ psCleanup->psResItem = psResItem; ++ ++ return (IMG_HANDLE)psCleanup; ++} ++ ++IMG_EXPORT ++PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext) ++{ ++ PVRSRV_ERROR eError; ++ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; ++ ++ PVR_ASSERT(hHW2DContext != IMG_NULL); ++ ++ psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)hHW2DContext; + + eError = ResManFreeResByPtr(psCleanup->psResItem, IMG_TRUE); + + return eError; + } ++#endif ++ ++IMG_EXPORT ++IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode, IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr) ++{ ++ PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL); ++ ++ SGXCleanupRequest((PVRSRV_DEVICE_NODE *)psDeviceNode, &sHWRTDataSetDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_RT_REQUEST); ++} + +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxutils.h git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxutils.h +--- git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxutils.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/devices/sgx/sgxutils.h 2008-12-18 15:47:29.000000000 +0100 +@@ -73,6 +73,13 @@ + IMG_BOOL bDumpPolls); + #endif + ++ ++#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) ++IMG_IMPORT ++IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE *psDeviceNode, ++ IMG_UINT32 ui32CallerID); ++#endif ++ + IMG_IMPORT + PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, + PVRSRV_SGX_COMMAND_TYPE eCommandType, +@@ -80,14 +87,31 @@ + IMG_UINT32 ui32CallerID); + + IMG_IMPORT ++IMG_VOID SGXScheduleProcessQueues(PVRSRV_DEVICE_NODE *psDeviceNode); ++ ++IMG_IMPORT + IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode); + + IMG_IMPORT +-IMG_HANDLE SGXRegisterHWRenderContextKM(PVRSRV_SGXDEV_INFO *psSGXDevInfo, IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr); ++IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psSGXDevInfo, IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr); + + IMG_IMPORT +-IMG_VOID SGXFlushHWRenderTargetKM(PVRSRV_SGXDEV_INFO *psSGXDevInfo, IMG_DEV_VIRTADDR psHWRTDataSetDevVAddr); ++IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psSGXDevInfo, IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr); ++ ++IMG_IMPORT ++IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psSGXDevInfo, IMG_DEV_VIRTADDR psHWRTDataSetDevVAddr); + + IMG_IMPORT + PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext); + ++IMG_IMPORT ++PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext); ++ ++#if defined(SGX_FEATURE_2D_HARDWARE) ++IMG_IMPORT ++IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psSGXDevInfo, IMG_DEV_VIRTADDR *psHW2DContextDevVAddr); ++ ++IMG_IMPORT ++PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext); ++#endif ++ +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/env_data.h git/drivers/gpu/pvr/services4/srvkm/env/linux/env_data.h +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/env_data.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/env_data.h 2008-12-18 15:47:29.000000000 +0100 +@@ -33,6 +33,12 @@ + #define PVRSRV_MAX_BRIDGE_IN_SIZE 0x1000 + #define PVRSRV_MAX_BRIDGE_OUT_SIZE 0x1000 + ++typedef struct _PVR_PCI_DEV_TAG ++{ ++ struct pci_dev *psPCIDev; ++ HOST_PCI_INIT_FLAGS ePCIFlags; ++ IMG_BOOL abPCIResourceInUse[DEVICE_COUNT_RESOURCE]; ++} PVR_PCI_DEV; + + typedef struct _ENV_DATA_TAG + { +@@ -43,8 +49,6 @@ + IMG_UINT32 ui32IRQ; + IMG_VOID *pvISRCookie; + struct tasklet_struct sMISRTasklet; +- struct pci_dev *psPCIDev; +- IMG_BOOL abPCIResourceInUse[DEVICE_COUNT_RESOURCE]; + } ENV_DATA; + + #endif +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/event.c git/drivers/gpu/pvr/services4/srvkm/env/linux/event.c +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/event.c 1970-01-01 01:00:00.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/event.c 2008-12-18 15:47:29.000000000 +0100 +@@ -0,0 +1,221 @@ ++/********************************************************************** ++ * ++ * Copyright(c) 2008 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 AUTOCONF_INCLUDED ++ #include <linux/config.h> ++#endif ++ ++#include <linux/version.h> ++#include <asm/io.h> ++#include <asm/page.h> ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) ++#include <asm/system.h> ++#endif ++#include <linux/mm.h> ++#include <linux/slab.h> ++#include <linux/vmalloc.h> ++#include <linux/delay.h> ++#include <linux/pci.h> ++ ++#include <linux/string.h> ++#include <linux/sched.h> ++#include <linux/interrupt.h> ++#include <asm/hardirq.h> ++#include <linux/timer.h> ++#include <linux/capability.h> ++#include <asm/uaccess.h> ++ ++#include "img_types.h" ++#include "services_headers.h" ++#include "mm.h" ++#include "pvrmmap.h" ++#include "mmap.h" ++#include "env_data.h" ++#include "proc.h" ++#include "mutex.h" ++ ++typedef struct PVRSRV_LINUX_EVENT_OBJECT_LIST_TAG ++{ ++ rwlock_t sLock; ++ struct list_head sList; ++ ++} PVRSRV_LINUX_EVENT_OBJECT_LIST; ++ ++ ++typedef struct PVRSRV_LINUX_EVENT_OBJECT_TAG ++{ ++ struct completion sCompletion; ++ struct list_head sList; ++ IMG_HANDLE hResItem; ++ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList; ++} PVRSRV_LINUX_EVENT_OBJECT; ++ ++PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList) ++{ ++ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList; ++ ++ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), ++ (IMG_VOID **)&psEvenObjectList, IMG_NULL) != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list")); ++ return PVRSRV_ERROR_OUT_OF_MEMORY; ++ } ++ ++ INIT_LIST_HEAD(&psEvenObjectList->sList); ++ ++ rwlock_init(&psEvenObjectList->sLock); ++ ++ *phEventObjectList = (IMG_HANDLE *) psEvenObjectList; ++ ++ return PVRSRV_OK; ++} ++ ++PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList) ++{ ++ ++ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList ; ++ ++ if(psEvenObjectList) ++ { ++ if (!list_empty(&psEvenObjectList->sList)) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty")); ++ return PVRSRV_ERROR_GENERIC; ++ } ++ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), psEvenObjectList, IMG_NULL); ++ } ++ return PVRSRV_OK; ++} ++ ++ ++PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject, IMG_BOOL bResManCallback) ++{ ++ if(hOSEventObjectList) ++ { ++ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; ++ if(hOSEventObject) ++ { ++ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject; ++ write_lock_bh(&psLinuxEventObjectList->sLock); ++ list_del(&psLinuxEventObject->sList); ++ write_unlock_bh(&psLinuxEventObjectList->sLock); ++ ++ ++ if(!bResManCallback && psLinuxEventObject->hResItem) ++ { ++ if(ResManFreeResByPtr(psLinuxEventObject->hResItem, IMG_FALSE) != PVRSRV_OK) ++ { ++ return PVRSRV_ERROR_GENERIC; ++ } ++ } ++ ++ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), psLinuxEventObject, IMG_NULL); ++ ++ return PVRSRV_OK; ++ } ++ } ++ return PVRSRV_ERROR_GENERIC; ++ ++} ++ ++static PVRSRV_ERROR LinuxEventObjectDeleteCallback(IMG_UINT32 ui32ProcessID, IMG_PVOID pvParam, IMG_UINT32 ui32Param) ++{ ++ if(pvParam) ++ { ++ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)pvParam; ++ if(psLinuxEventObject->psLinuxEventObjectList) ++ { ++ IMG_HANDLE hOSEventObjectList = (IMG_HANDLE)psLinuxEventObject->psLinuxEventObjectList; ++ return LinuxEventObjectDelete(hOSEventObjectList,(IMG_HANDLE) psLinuxEventObject, IMG_TRUE); ++ } ++ } ++ return PVRSRV_ERROR_GENERIC; ++} ++PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject) ++ { ++ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject; ++ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; ++ ++ ++ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), ++ (IMG_VOID **)&psLinuxEventObject, IMG_NULL) != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory ")); ++ return PVRSRV_ERROR_OUT_OF_MEMORY; ++ } ++ ++ INIT_LIST_HEAD(&psLinuxEventObject->sList); ++ ++ init_completion(&psLinuxEventObject->sCompletion); ++ ++ ++ psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList; ++ ++ psLinuxEventObject->hResItem = (IMG_HANDLE)ResManRegisterRes(RESMAN_TYPE_EVENT_OBJECT, ++ psLinuxEventObject, ++ 0, ++ &LinuxEventObjectDeleteCallback, ++ 0); ++ ++ write_lock_bh(&psLinuxEventObjectList->sLock); ++ list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList); ++ write_unlock_bh(&psLinuxEventObjectList->sLock); ++ ++ *phOSEventObject = psLinuxEventObject; ++ ++ return PVRSRV_OK; ++} ++ ++PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList) ++{ ++ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject; ++ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; ++ struct list_head *psListEntry, *psListEntryTemp, *psList; ++ psList = &psLinuxEventObjectList->sList; ++ ++ list_for_each_safe(psListEntry, psListEntryTemp, psList) ++ { ++ psLinuxEventObject = list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList); ++ complete(&psLinuxEventObject->sCompletion); ++ } ++ return PVRSRV_OK; ++ ++} ++ ++PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout) ++{ ++ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject; ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) ++ if(wait_for_completion_timeout(&psLinuxEventObject->sCompletion, msecs_to_jiffies(ui32MSTimeout)) == 0) ++ { ++ return PVRSRV_ERROR_TIMEOUT; ++ } ++#else ++ wait_for_completion(&psLinuxEventObject->sCompletion); ++#endif ++ return PVRSRV_OK; ++} +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/event.h git/drivers/gpu/pvr/services4/srvkm/env/linux/event.h +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/event.h 1970-01-01 01:00:00.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/event.h 2008-12-18 15:47:29.000000000 +0100 +@@ -0,0 +1,32 @@ ++/********************************************************************** ++ * ++ * Copyright(c) 2008 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 ++ * ++ ******************************************************************************/ ++ ++PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList); ++PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList); ++PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject); ++PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject, IMG_BOOL bResManCallback); ++PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList); ++PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout); +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/kbuild/Makefile git/drivers/gpu/pvr/services4/srvkm/env/linux/kbuild/Makefile +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/kbuild/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/kbuild/Makefile 2008-12-18 15:47:29.000000000 +0100 +@@ -0,0 +1,81 @@ ++# ++# Copyright(c) 2008 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 ++# ++# ++ ++# ++MODULE = pvrsrvkm ++ ++KBUILDROOT = ../../../.. ++ ++INCLUDES = -I$(EURASIAROOT)/include4 \ ++ -I$(EURASIAROOT)/services4/include \ ++ -I$(EURASIAROOT)/services4/srvkm/env/linux \ ++ -I$(EURASIAROOT)/services4/srvkm/include \ ++ -I$(EURASIAROOT)/services4/srvkm/bridged \ ++ -I$(EURASIAROOT)/services4/srvkm/devices/sgx \ ++ -I$(EURASIAROOT)/services4/system/$(PVR_SYSTEM) \ ++ -I$(EURASIAROOT)/services4/system/include ++ ++ ++SOURCES = $(KBUILDROOT)/srvkm/env/linux/osfunc.c \ ++ $(KBUILDROOT)/srvkm/env/linux/mmap.c \ ++ $(KBUILDROOT)/srvkm/env/linux/module.c \ ++ $(KBUILDROOT)/srvkm/env/linux/pdump.c \ ++ $(KBUILDROOT)/srvkm/env/linux/proc.c \ ++ $(KBUILDROOT)/srvkm/env/linux/pvr_bridge_k.c \ ++ $(KBUILDROOT)/srvkm/env/linux/pvr_debug.c \ ++ $(KBUILDROOT)/srvkm/env/linux/mm.c \ ++ $(KBUILDROOT)/srvkm/env/linux/mutex.c \ ++ $(KBUILDROOT)/srvkm/env/linux/event.c ++ ++SOURCES += $(KBUILDROOT)/srvkm/common/buffer_manager.c \ ++ $(KBUILDROOT)/srvkm/common/devicemem.c \ ++ $(KBUILDROOT)/srvkm/common/deviceclass.c \ ++ $(KBUILDROOT)/srvkm/common/handle.c \ ++ $(KBUILDROOT)/srvkm/common/hash.c \ ++ $(KBUILDROOT)/srvkm/common/metrics.c \ ++ $(KBUILDROOT)/srvkm/common/pvrsrv.c \ ++ $(KBUILDROOT)/srvkm/common/queue.c \ ++ $(KBUILDROOT)/srvkm/common/ra.c \ ++ $(KBUILDROOT)/srvkm/common/resman.c \ ++ $(KBUILDROOT)/srvkm/common/power.c \ ++ $(KBUILDROOT)/srvkm/common/mem.c \ ++ $(KBUILDROOT)/srvkm/bridged/bridged_pvr_bridge.c \ ++ $(KBUILDROOT)/srvkm/devices/sgx/sgxinit.c \ ++ $(KBUILDROOT)/srvkm/devices/sgx/sgxreset.c \ ++ $(KBUILDROOT)/srvkm/devices/sgx/sgxutils.c \ ++ $(KBUILDROOT)/srvkm/devices/sgx/sgxkick.c \ ++ $(KBUILDROOT)/srvkm/devices/sgx/sgxtransfer.c \ ++ $(KBUILDROOT)/srvkm/devices/sgx/mmu.c \ ++ $(KBUILDROOT)/srvkm/devices/sgx/pb.c \ ++ $(KBUILDROOT)/srvkm/common/perproc.c \ ++ $(KBUILDROOT)/../services4/system/$(PVR_SYSTEM)/sysconfig.c \ ++ $(KBUILDROOT)/../services4/system/$(PVR_SYSTEM)/sysutils.c \ ++ $(KBUILDROOT)/srvkm/devices/sgx/sgx2dcore.c ++ ++ ++INCLUDES += -I$(EURASIAROOT)/services4/srvkm/hwdefs ++ ++ ++ +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/mm.c git/drivers/gpu/pvr/services4/srvkm/env/linux/mm.c +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/mm.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/mm.c 2008-12-18 15:47:29.000000000 +0100 +@@ -37,6 +37,7 @@ + #endif + #include <linux/slab.h> + #include <linux/highmem.h> ++#include <linux/sched.h> + + #include "img_defs.h" + #include "services.h" +@@ -1078,7 +1079,11 @@ + #if defined(DEBUG_LINUX_SLAB_ALLOCATIONS) + ui32Flags |= SLAB_POISON|SLAB_RED_ZONE; + #endif ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) + return kmem_cache_create(pszName, Size, Align, ui32Flags, NULL); ++#else ++ return kmem_cache_create(pszName, Size, Align, ui32Flags, NULL, NULL); ++#endif + } + + +@@ -1445,9 +1450,6 @@ + const IMG_CHAR * + LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType) + { +- PVR_ASSERT(LINUX_MEM_AREA_TYPE_COUNT == 5); +- PVR_ASSERT(eMemAreaType < LINUX_MEM_AREA_TYPE_COUNT); +- + + switch(eMemAreaType) + { +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/module.c git/drivers/gpu/pvr/services4/srvkm/env/linux/module.c +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/module.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/module.c 2008-12-18 15:47:29.000000000 +0100 +@@ -25,7 +25,7 @@ + ******************************************************************************/ + + #ifndef AUTOCONF_INCLUDED +-// #include <linux/config.h> ++ #include <linux/config.h> + #endif + + #include <linux/init.h> +@@ -34,9 +34,19 @@ + #include <linux/version.h> + #include <linux/fs.h> + #include <linux/proc_fs.h> ++ + #if defined(LDM_PLATFORM) + #include <linux/platform_device.h> + #endif ++ ++#if defined(LDM_PCI) ++#include <linux/pci.h> ++#endif ++ ++#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) ++#include <asm/uaccess.h> ++#endif ++ + #include "img_defs.h" + #include "services.h" + #include "kerneldisplay.h" +@@ -51,15 +61,13 @@ + #include "handle.h" + #include "pvr_bridge_km.h" + #include "proc.h" +- ++#include "pvrmodule.h" + + #define CLASSNAME "powervr" + #define DRVNAME "pvrsrvkm" + #define DEVNAME "pvrsrvkm" + + +-MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>"); +-MODULE_LICENSE("GPL"); + MODULE_SUPPORTED_DEVICE(DEVNAME); + #ifdef DEBUG + static int debug = DBGPRIV_WARNING; +@@ -99,24 +107,75 @@ + }; + + ++#if defined(LDM_PLATFORM) || defined(LDM_PCI) ++ + #if defined(LDM_PLATFORM) +-static int PVRSRVDriverRemove(struct platform_device *device); +-static int PVRSRVDriverProbe(struct platform_device *device); +-static int PVRSRVDriverSuspend(struct platform_device *device, pm_message_t state); +-static void PVRSRVDriverShutdown(struct platform_device *device); +-static int PVRSRVDriverResume(struct platform_device *device); ++#define LDM_DEV struct platform_device ++#define LDM_DRV struct platform_driver ++#if defined(LDM_PCI) ++#undef LDM_PCI ++#endif ++#endif + +-static struct platform_driver powervr_driver = { ++#if defined(LDM_PCI) ++#define LDM_DEV struct pci_dev ++#define LDM_DRV struct pci_driver ++#endif ++ ++//static void PVRSRVClassDeviceRelease(struct class_device *class_device); ++ ++/*static struct class powervr_class = { ++ .name = CLASSNAME, ++ .release = PVRSRVClassDeviceRelease ++};*/ ++ ++#if defined(LDM_PLATFORM) ++static int PVRSRVDriverRemove(LDM_DEV *device); ++static int PVRSRVDriverProbe(LDM_DEV *device); ++#endif ++#if defined(LDM_PCI) ++static void PVRSRVDriverRemove(LDM_DEV *device); ++static int PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id); ++#endif ++static int PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state); ++static void PVRSRVDriverShutdown(LDM_DEV *device); ++static int PVRSRVDriverResume(LDM_DEV *device); ++ ++#if defined(LDM_PCI) ++struct pci_device_id powervr_id_table[] __devinitdata = { ++ { PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID2) }, ++ { 0 } ++}; ++ ++MODULE_DEVICE_TABLE(pci, powervr_id_table); ++#endif ++ ++static LDM_DRV powervr_driver = { ++#if defined(LDM_PLATFORM) + .driver = { +- .name = DEVNAME, ++ .name = DRVNAME, + }, ++#endif ++#if defined(LDM_PCI) ++ .name = DRVNAME, ++ .id_table = powervr_id_table, ++#endif + .probe = PVRSRVDriverProbe, ++#if defined(LDM_PLATFORM) + .remove = PVRSRVDriverRemove, ++#endif ++#if defined(LDM_PCI) ++ .remove = __devexit_p(PVRSRVDriverRemove), ++#endif + .suspend = PVRSRVDriverSuspend, + .resume = PVRSRVDriverResume, + .shutdown = PVRSRVDriverShutdown, + }; + ++LDM_DEV *gpsPVRLDMDev; ++ ++ ++#if defined(LDM_PLATFORM) + static void PVRSRVDeviceRelease(struct device *device); + + static struct platform_device powervr_device = { +@@ -126,18 +185,79 @@ + .release = PVRSRVDeviceRelease + } + }; ++#endif + + ++static ssize_t PVRSRVShowDev(struct class_device *pClassDevice, char *buf) ++{ ++ PVR_TRACE(("PVRSRVShowDev(pClassDevice=%p)", pClassDevice)); + +-static int PVRSRVDriverProbe(struct platform_device *pDevice) ++ return snprintf(buf, PAGE_SIZE, "%d:0\n", AssignedMajorNumber); ++} ++ ++//static CLASS_DEVICE_ATTR(dev, S_IRUGO, PVRSRVShowDev, NULL); ++ ++/*static void PVRSRVClassDeviceRelease(struct class_device *pClassDevice) ++{ ++ PVR_TRACE(("PVRSRVClassDeviceRelease(pClassDevice=%p)", pClassDevice)); ++ ++ kfree(pClassDevice); ++}*/ ++ ++#if defined(LDM_PLATFORM) ++static int PVRSRVDriverProbe(LDM_DEV *pDevice) ++#endif ++#if defined(LDM_PCI) ++static int __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id) ++#endif + { + SYS_DATA *psSysData; + PVRSRV_ERROR eError; ++ //struct class_device *pClassDevice; + int error; + +- PVR_DPF((PVR_DBG_WARNING, "PVRSRVDriverProbe(pDevice=%p)", pDevice)); ++ PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice)); + +- pDevice->dev.driver_data = NULL; ++ pDevice->dev.driver_data = NULL; ++ /*pClassDevice = kmalloc(sizeof(*pClassDevice), GFP_KERNEL); ++ ++ if (pClassDevice == IMG_NULL) ++ { ++ PVR_DPF((PVR_DBG_ERROR, ++ "PVRSRVDriverProbe(pDevice=%p): no memory for class device instance.", ++ pDevice)); ++ ++ return -ENOMEM; ++ } ++ ++ memset(pClassDevice, 0, sizeof(*pClassDevice)); ++ ++ pDevice->dev.driver_data = (void *)pClassDevice; ++ ++ ++ strncpy(pClassDevice->class_id, DEVNAME, BUS_ID_SIZE); ++ ++ pClassDevice->class = &powervr_class; ++ pClassDevice->dev = &pDevice->dev; ++ ++ ++ if ((error = class_device_register(pClassDevice)) != 0) ++ { ++ kfree(pClassDevice); ++ ++ PVR_DPF((PVR_DBG_ERROR, ++ "PVRSRVDriverProbe(pDevice=%p): class_device_register failed (%d)", ++ pDevice, error)); ++ return error; ++ } ++ ++ if ((error = class_device_create_file(pClassDevice, &class_device_attr_dev)) != 0) ++ { ++ PVR_DPF((PVR_DBG_ERROR, ++ "PVRSRVDriverProbe(pDevice=%p): class_device_create_file failed (%d)", ++ pDevice, error)); ++ return error; ++ }*/ + + #if 0 + +@@ -149,37 +269,34 @@ + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { ++ gpsPVRLDMDev = pDevice; ++ + if (SysInitialise() != PVRSRV_OK) + { + return -ENODEV; + } +- +- eError = PVRSRVResManConnect(RESMAN_KERNEL_PROCESSID, IMG_TRUE); +- if(eError != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR,"PVRSRVDriverProbe: Failed to connect to resource manager")); +- error = -ENODEV; +- } + } + + return 0; + } + + +-static int PVRSRVDriverRemove(struct platform_device *pDevice) ++#if defined (LDM_PLATFORM) ++static int PVRSRVDriverRemove(LDM_DEV *pDevice) ++#endif ++#if defined(LDM_PCI) ++static void __devexit PVRSRVDriverRemove(LDM_DEV *pDevice) ++#endif + { + SYS_DATA *psSysData; + +- PVR_DPF((PVR_DBG_WARNING, "PVRSRVDriverRemove(pDevice=%p)", pDevice)); ++ PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice)); + +- if(PVRSRVResManConnect(RESMAN_KERNEL_PROCESSID, IMG_FALSE) != PVRSRV_OK) +- { +- return -EINVAL; +- } +- + if (SysAcquireData(&psSysData) == PVRSRV_OK) + { + SysDeinitialise(psSysData); ++ ++ gpsPVRLDMDev = IMG_NULL; + } + + #if 0 +@@ -189,68 +306,131 @@ + } + #endif + ++ //class_device_unregister((struct class_device *)pDevice->dev.driver_data); ++ ++ ++ pDevice->dev.driver_data = 0; + ++ ++#if defined (LDM_PLATFORM) + return 0; ++#endif ++#if defined (LDM_PCI) ++ return; ++#endif + } + + +-static void PVRSRVDriverShutdown(struct platform_device *pDevice) ++static void PVRSRVDriverShutdown(LDM_DEV *pDevice) + { +- PVR_DPF((PVR_DBG_WARNING, "PVRSRVDriverShutdown(pDevice=%p)", pDevice)); ++ PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice)); + + (void) PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3); + } + + +-static int PVRSRVDriverSuspend(struct platform_device *pDevice, pm_message_t state) ++static int PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state) + { +- +- PVR_DPF((PVR_DBG_WARNING, +- "PVRSRVDriverSuspend(pDevice=%p)", +- pDevice)); ++#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)) ++ PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice)); + + if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3) != PVRSRV_OK) + { + return -EINVAL; + } +- ++#endif + return 0; + } + + +-static int PVRSRVDriverResume(struct platform_device *pDevice) ++static int PVRSRVDriverResume(LDM_DEV *pDevice) + { +- PVR_DPF((PVR_DBG_WARNING, "PVRSRVDriverResume(pDevice=%p)", pDevice)); ++#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)) ++ PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice)); + + if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) != PVRSRV_OK) + { + return -EINVAL; + } +- ++#endif + return 0; + } + + ++#if defined(LDM_PLATFORM) + static void PVRSRVDeviceRelease(struct device *pDevice) + { + PVR_DPF((PVR_DBG_WARNING, "PVRSRVDeviceRelease(pDevice=%p)", pDevice)); + } + #endif ++#endif ++ ++ ++#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) ++static IMG_UINT32 gPVRPowerLevel; ++ ++int PVRProcSetPowerLevel(struct file *file, const char *buffer, unsigned long count, void *data) ++{ ++ char data_buffer[2]; ++ IMG_UINT32 PVRPowerLevel; ++ ++ if (count != sizeof(data_buffer)) ++ { ++ return -EINVAL; ++ } ++ else ++ { ++ if (copy_from_user(data_buffer, buffer, count)) ++ return -EINVAL; ++ if (data_buffer[count - 1] != '\n') ++ return -EINVAL; ++ PVRPowerLevel = data_buffer[0] - '0'; ++ if (PVRPowerLevel != gPVRPowerLevel) ++ { ++ if (PVRPowerLevel != 0) ++ { ++ if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3) != PVRSRV_OK) ++ { ++ return -EINVAL; ++ } ++ } ++ else ++ { ++ if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) != PVRSRV_OK) ++ { ++ return -EINVAL; ++ } ++ } ++ ++ gPVRPowerLevel = PVRPowerLevel; ++ } ++ } ++ return (count); ++} ++ ++int PVRProcGetPowerLevel(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ if (off == 0) { ++ *start = (char *)1; ++ return printAppend(page, count, 0, "%lu\n", gPVRPowerLevel); ++ } ++ *eof = 1; ++ return 0; ++} ++#endif + + static int PVRSRVOpen(struct inode unref__ * pInode, struct file unref__ * pFile) + { + int Ret = 0; + +- PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVOpen")); +- +- LinuxLockMutex(&gPVRSRVLock); ++ LinuxLockMutex(&gPVRSRVLock); + + if (PVRSRVResManConnect(PVRSRVRESMAN_PROCESSID_FIND, IMG_TRUE) != PVRSRV_OK) + { + Ret = -ENOMEM; + } + +- LinuxUnLockMutex(&gPVRSRVLock); ++ LinuxUnLockMutex(&gPVRSRVLock); + + return Ret; + } +@@ -260,8 +440,6 @@ + { + int Ret = 0; + +- PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVRelease")); +- + if (PVRSRVResManConnect(PVRSRVRESMAN_PROCESSID_FIND, IMG_FALSE) != PVRSRV_OK) + { + Ret = -ENOMEM; +@@ -274,9 +452,12 @@ + static int __init PVRCore_Init(void) + { + int error; +-#if !defined(LDM_PLATFORM) ++#if !(defined(LDM_PLATFORM) || defined(LDM_PCI)) + PVRSRV_ERROR eError; +-#endif ++#endif ++ ++ PVR_TRACE(("PVRCore_Init")); ++ + + AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops); + +@@ -287,7 +468,7 @@ + return -EBUSY; + } + +- PVR_DPF((PVR_DBG_WARNING, "PVRCore_Init: major device %d", AssignedMajorNumber)); ++ PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber)); + + + if (CreateProcEntries ()) +@@ -313,9 +494,19 @@ + + PVRMMapInit(); + ++#if defined(LDM_PLATFORM) || defined(LDM_PCI) ++ /*if ((error = class_register(&powervr_class)) != 0) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register class (%d)", error)); ++ ++ goto init_failed; ++ }*/ ++ + #if defined(LDM_PLATFORM) + if ((error = platform_driver_register(&powervr_driver)) != 0) + { ++ //class_unregister(&powervr_class); ++ + PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error)); + + goto init_failed; +@@ -324,11 +515,25 @@ + if ((error = platform_device_register(&powervr_device)) != 0) + { + platform_driver_unregister(&powervr_driver); ++ //class_unregister(&powervr_class); + + PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error)); + + goto init_failed; + } ++#endif ++ ++#if defined(LDM_PCI) ++ if ((error = pci_register_driver(&powervr_driver)) != 0) ++ { ++ //class_unregister(&powervr_class); ++ ++ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error)); ++ ++ goto init_failed; ++ } ++#endif ++ + #else + + if ((eError = SysInitialise()) != PVRSRV_OK) +@@ -343,20 +548,12 @@ + #endif + goto init_failed; + } +- +- eError = PVRSRVResManConnect(RESMAN_KERNEL_PROCESSID, IMG_TRUE); +- if(eError != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR,"PVRCore_Init: Failed to connect to resource manager")); +- error = -ENODEV; +- goto init_failed; +- } + #endif ++ + return 0; + + init_failed: + +- (void) PVRSRVResManConnect(RESMAN_KERNEL_PROCESSID, IMG_FALSE); + PVRMMapCleanup(); + LinuxMMCleanup(); + RemoveProcEntries(); +@@ -370,23 +567,34 @@ + static void __exit PVRCore_Cleanup(void) + { + SYS_DATA *psSysData; +-#if !defined(LDM_PLATFORM) ++#if !(defined(LDM_PLATFORM) || defined (LDM_PCI)) + PVRSRV_ERROR eError; +-#endif ++#endif ++ ++ PVR_TRACE(("PVRCore_Cleanup")); + + SysAcquireData(&psSysData); +- unregister_chrdev(AssignedMajorNumber, DRVNAME); + ++ /*if (unregister_chrdev(AssignedMajorNumber, DRVNAME)) ++ { ++ PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber)); ++ }*/ ++ unregister_chrdev(AssignedMajorNumber, DRVNAME); ++ ++#if defined(LDM_PLATFORM) || defined(LDM_PCI) ++ ++#if defined(LDM_PCI) ++ pci_unregister_driver(&powervr_driver); ++#endif ++ + #if defined (LDM_PLATFORM) + platform_device_unregister(&powervr_device); + platform_driver_unregister(&powervr_driver); +-#else +- eError = PVRSRVResManConnect(RESMAN_KERNEL_PROCESSID, IMG_FALSE); +- if (eError != PVRSRV_OK) +- { +- PVR_DPF((PVR_DBG_ERROR,"KernelResManDisconnect: Failed to disconnect")); +- } ++#endif + ++ //class_unregister(&powervr_class); ++ ++#else + + SysDeinitialise(psSysData); + #endif +@@ -399,7 +607,7 @@ + + RemoveProcEntries(); + +- PVR_DPF((PVR_DBG_WARNING,"unloading")); ++ PVR_TRACE(("PVRCore_Cleanup: unloading")); + } + + module_init(PVRCore_Init); +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/osfunc.c git/drivers/gpu/pvr/services4/srvkm/env/linux/osfunc.c +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/osfunc.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/osfunc.c 2008-12-18 15:47:29.000000000 +0100 +@@ -56,6 +56,9 @@ + #include "env_data.h" + #include "proc.h" + #include "mutex.h" ++#include "event.h" ++ ++#define EVENT_OBJECT_TIMEOUT_MS (100) + + extern PVRSRV_LINUX_MUTEX gPVRSRVLock; + +@@ -411,9 +414,6 @@ + psEnvData->bLISRInstalled = IMG_FALSE; + + +- psEnvData->psPCIDev = NULL; +- +- + *ppvEnvSpecificData = psEnvData; + + return PVRSRV_OK; +@@ -426,7 +426,6 @@ + + PVR_ASSERT(!psEnvData->bMISRInstalled); + PVR_ASSERT(!psEnvData->bLISRInstalled); +- PVR_ASSERT(psEnvData->psPCIDev == NULL); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0x1000, psEnvData->pvBridgeData, IMG_NULL); + +@@ -1189,57 +1188,62 @@ + } + + #if defined(CONFIG_PCI) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) +-PVRSRV_ERROR OSPCIAcquireDev(IMG_VOID *pvSysData, IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags) ++ ++IMG_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags) + { +- SYS_DATA *psSysData = (SYS_DATA *)pvSysData; +- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; + int err; + IMG_UINT32 i; ++ PVR_PCI_DEV *psPVRPCI; + +- if (psEnvData->psPCIDev != NULL) +- { +- PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: A device has already been acquired")); +- return PVRSRV_ERROR_GENERIC; +- } ++ PVR_TRACE(("OSPCISetDev")); + +- psEnvData->psPCIDev = pci_get_device(ui16VendorID, ui16DeviceID, psEnvData->psPCIDev); +- if (psEnvData->psPCIDev == NULL) ++ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)&psPVRPCI, IMG_NULL) != PVRSRV_OK) + { +- PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't acquire device")); +- return PVRSRV_ERROR_GENERIC; ++ PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't allocate PVR PCI structure")); ++ return IMG_NULL; + } + +- err = pci_enable_device(psEnvData->psPCIDev); ++ psPVRPCI->psPCIDev = (struct pci_dev *)pvPCICookie; ++ psPVRPCI->ePCIFlags = eFlags; ++ ++ err = pci_enable_device(psPVRPCI->psPCIDev); + if (err != 0) + { +- PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't enable device (%d)", err)); +- return PVRSRV_ERROR_GENERIC; ++ PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't enable device (%d)", err)); ++ return IMG_NULL; + } + +- if (eFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) +- pci_set_master(psEnvData->psPCIDev); ++ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) ++ pci_set_master(psPVRPCI->psPCIDev); + + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + { +- psEnvData->abPCIResourceInUse[i] = IMG_FALSE; ++ psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE; + } + +- return PVRSRV_OK; ++ return (IMG_HANDLE)psPVRPCI; + } + +-PVRSRV_ERROR OSPCIIRQ(IMG_VOID *pvSysData, IMG_UINT32 *pui32IRQ) ++IMG_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags) + { +- SYS_DATA *psSysData = (SYS_DATA *)pvSysData; +- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; ++ struct pci_dev *psPCIDev; + +- if (psEnvData->psPCIDev == NULL) ++ psPCIDev = pci_get_device(ui16VendorID, ui16DeviceID, NULL); ++ if (psPCIDev == NULL) + { +- PVR_DPF((PVR_DBG_ERROR, "OSPCIIRQ: Device hasn't been acquired")); +- return PVRSRV_ERROR_GENERIC; ++ PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't acquire device")); ++ return IMG_NULL; + } + +- *pui32IRQ = psEnvData->psPCIDev->irq; ++ return OSPCISetDev((IMG_VOID *)psPCIDev, eFlags); ++} ++ ++PVRSRV_ERROR OSPCIIRQ(IMG_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ) ++{ ++ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; ++ ++ *pui32IRQ = psPVRPCI->psPCIDev->irq; + + return PVRSRV_OK; + } +@@ -1254,19 +1258,12 @@ + }; + + static IMG_UINT32 OSPCIAddrRangeFunc(enum HOST_PCI_ADDR_RANGE_FUNC eFunc, +- IMG_VOID *pvSysData, ++ IMG_HANDLE hPVRPCI, + IMG_UINT32 ui32Index + + ) + { +- SYS_DATA *psSysData = (SYS_DATA *)pvSysData; +- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; +- +- if (psEnvData->psPCIDev == NULL) +- { +- PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Device hasn't been acquired")); +- return 0; +- } ++ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; + + if (ui32Index >= DEVICE_COUNT_RESOURCE) + { +@@ -1278,32 +1275,32 @@ + switch (eFunc) + { + case HOST_PCI_ADDR_RANGE_FUNC_LEN: +- return pci_resource_len(psEnvData->psPCIDev, ui32Index); ++ return pci_resource_len(psPVRPCI->psPCIDev, ui32Index); + case HOST_PCI_ADDR_RANGE_FUNC_START: +- return pci_resource_start(psEnvData->psPCIDev, ui32Index); ++ return pci_resource_start(psPVRPCI->psPCIDev, ui32Index); + case HOST_PCI_ADDR_RANGE_FUNC_END: +- return pci_resource_end(psEnvData->psPCIDev, ui32Index); ++ return pci_resource_end(psPVRPCI->psPCIDev, ui32Index); + case HOST_PCI_ADDR_RANGE_FUNC_REQUEST: + { + + + #ifdef FIXME + int err; +- err = pci_request_region(psEnvData->psPCIDev, ui32Index, "PowerVR"); ++ err = pci_request_region(psPVRPCI->psPCIDev, ui32Index, "PowerVR"); + if (err != 0) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: pci_request_region_failed (%d)", err)); + return 0; + } + #endif +- psEnvData->abPCIResourceInUse[ui32Index] = IMG_TRUE; ++ psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_TRUE; + return 1; + } + case HOST_PCI_ADDR_RANGE_FUNC_RELEASE: +- if (psEnvData->abPCIResourceInUse[ui32Index]) ++ if (psPVRPCI->abPCIResourceInUse[ui32Index]) + { +- pci_release_region(psEnvData->psPCIDev, ui32Index); +- psEnvData->abPCIResourceInUse[ui32Index] = IMG_FALSE; ++ pci_release_region(psPVRPCI->psPCIDev, ui32Index); ++ psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_FALSE; + } + return 1; + default: +@@ -1314,62 +1311,160 @@ + return 0; + } + +-IMG_UINT32 OSPCIAddrRangeLen(IMG_VOID *pvSysData, IMG_UINT32 ui32Index) ++IMG_UINT32 OSPCIAddrRangeLen(IMG_HANDLE hPVRPCI, IMG_UINT32 ui32Index) + { +- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, pvSysData, ui32Index); ++ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index); + } + +-IMG_UINT32 OSPCIAddrRangeStart(IMG_VOID *pvSysData, IMG_UINT32 ui32Index) ++IMG_UINT32 OSPCIAddrRangeStart(IMG_HANDLE hPVRPCI, IMG_UINT32 ui32Index) + { +- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, pvSysData, ui32Index); ++ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index); + } + +-IMG_UINT32 OSPCIAddrRangeEnd(IMG_VOID *pvSysData, IMG_UINT32 ui32Index) ++IMG_UINT32 OSPCIAddrRangeEnd(IMG_HANDLE hPVRPCI, IMG_UINT32 ui32Index) + { +- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, pvSysData, ui32Index); ++ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index); + } + +-PVRSRV_ERROR OSPCIRequestAddrRange(IMG_VOID *pvSysData, +- IMG_UINT32 ui32Index +- +-) ++PVRSRV_ERROR OSPCIRequestAddrRange(IMG_HANDLE hPVRPCI, ++ IMG_UINT32 ui32Index) + { +- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, pvSysData, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK; ++ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK; + } + +-PVRSRV_ERROR OSPCIReleaseAddrRange(IMG_VOID *pvSysData, IMG_UINT32 ui32Index) ++PVRSRV_ERROR OSPCIReleaseAddrRange(IMG_HANDLE hPVRPCI, IMG_UINT32 ui32Index) + { +- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, pvSysData, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK; ++ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK; + } + +-PVRSRV_ERROR OSPCIReleaseDev(IMG_VOID *pvSysData) ++PVRSRV_ERROR OSPCIReleaseDev(IMG_HANDLE hPVRPCI) + { +- SYS_DATA *psSysData = (SYS_DATA *)pvSysData; +- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; ++ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; + int i; + +- if (psEnvData->psPCIDev == NULL) ++ PVR_TRACE(("OSPCIReleaseDev")); ++ ++ ++ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + { +- return PVRSRV_OK; ++ if (psPVRPCI->abPCIResourceInUse[i]) ++ { ++ PVR_TRACE(("OSPCIReleaseDev: Releasing Address range %d", i)); ++ pci_release_region(psPVRPCI->psPCIDev, i); ++ psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE; ++ } + } + ++ pci_disable_device(psPVRPCI->psPCIDev); ++ ++ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)psPVRPCI, IMG_NULL); ++ ++ return PVRSRV_OK; ++} ++ ++PVRSRV_ERROR OSPCISuspendDev(IMG_HANDLE hPVRPCI) ++{ ++ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; ++ int i; ++ int err; ++ ++ PVR_TRACE(("OSPCISuspendDev")); ++ + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + { +- if (psEnvData->abPCIResourceInUse[i]) ++ if (psPVRPCI->abPCIResourceInUse[i]) + { +- PVR_TRACE(("OSPCIReleaseDev: Releasing Address range %d", i)); +- pci_release_region(psEnvData->psPCIDev, i); +- psEnvData->abPCIResourceInUse[i] = IMG_FALSE; ++ pci_release_region(psPVRPCI->psPCIDev, i); + } + } + +- pci_disable_device(psEnvData->psPCIDev); ++ err = pci_save_state(psPVRPCI->psPCIDev); ++ if (err != 0) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_save_state_failed (%d)", err)); ++ return PVRSRV_ERROR_GENERIC; ++ } + +- psEnvData->psPCIDev = NULL; ++ pci_disable_device(psPVRPCI->psPCIDev); ++ ++ err = pci_set_power_state(psPVRPCI->psPCIDev, PCI_D3cold); ++ switch(err) ++ { ++ case 0: ++ break; ++ case -EIO: ++ PVR_DPF((PVR_DBG_WARNING, "OSPCISuspendDev: device doesn't support PCI PM")); ++ break; ++ case -EINVAL: ++ PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: can't enter requested power state")); ++ break; ++ default: ++ PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_set_power_state failed (%d)", err)); ++ break; ++ } + + return PVRSRV_OK; + } ++ ++PVRSRV_ERROR OSPCIResumeDev(IMG_HANDLE hPVRPCI) ++{ ++ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; ++ int err; ++ int i; ++ ++ PVR_TRACE(("OSPCIResumeDev")); ++ ++ err = pci_set_power_state(psPVRPCI->psPCIDev, PCI_D0); ++ switch(err) ++ { ++ case 0: ++ break; ++ case -EIO: ++ PVR_DPF((PVR_DBG_WARNING, "OSPCIResumeDev: device doesn't support PCI PM")); ++ break; ++ case -EINVAL: ++ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: can't enter requested power state")); ++ return PVRSRV_ERROR_GENERIC; ++ default: ++ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_set_power_state failed (%d)", err)); ++ return PVRSRV_ERROR_GENERIC; ++ } ++ ++ err = pci_restore_state(psPVRPCI->psPCIDev); ++ if (err != 0) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_restore_state failed (%d)", err)); ++ return PVRSRV_ERROR_GENERIC; ++ } ++ ++ err = pci_enable_device(psPVRPCI->psPCIDev); ++ if (err != 0) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: Couldn't enable device (%d)", err)); ++ return PVRSRV_ERROR_GENERIC; ++ } ++ ++ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) ++ pci_set_master(psPVRPCI->psPCIDev); ++ ++ ++ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) ++ { ++ if (psPVRPCI->abPCIResourceInUse[i]) ++ { ++ err = pci_request_region(psPVRPCI->psPCIDev, i, "PowerVR"); ++ if (err != 0) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err)); ++ } ++ } ++ ++ } ++ ++ return PVRSRV_OK; ++} ++ + #endif + + typedef struct TIMER_CALLBACK_DATA_TAG +@@ -1418,7 +1513,7 @@ + + psTimerCBData->pfnTimerFunc = pfnTimerFunc; + psTimerCBData->pvData = pvData; +- psTimerCBData->bActive = IMG_TRUE; ++ psTimerCBData->bActive = IMG_FALSE; + + + +@@ -1434,14 +1529,36 @@ + psTimerCBData->sTimer.data = (IMG_UINT32)psTimerCBData; + psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies; + ++ return (IMG_HANDLE)psTimerCBData; ++} ++ ++ ++PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer) ++{ ++ TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)hTimer; ++ ++ ++ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(TIMER_CALLBACK_DATA), psTimerCBData, IMG_NULL); ++ ++ return PVRSRV_OK; ++} ++ ++ ++PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer) ++{ ++ TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)hTimer; ++ ++ ++ psTimerCBData->bActive = IMG_TRUE; ++ + + add_timer(&psTimerCBData->sTimer); + +- return (IMG_HANDLE)psTimerCBData; ++ return PVRSRV_OK; + } + + +-PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer) ++PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer) + { + TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)hTimer; + +@@ -1451,21 +1568,17 @@ + + del_timer_sync(&psTimerCBData->sTimer); + +- +- OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(TIMER_CALLBACK_DATA), psTimerCBData, IMG_NULL); +- + return PVRSRV_OK; + } + + + PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT *psEventObject) + { ++ + PVRSRV_ERROR eError = PVRSRV_OK; + + if(psEventObject) + { +- struct completion *psCompletion; +- + if(pszName) + { + +@@ -1478,26 +1591,20 @@ + snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_%d", ui16NameIndex++); + } + +- +- if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, +- sizeof(struct completion), +- (IMG_VOID **)&psCompletion, IMG_NULL) != PVRSRV_OK) ++ if(LinuxEventObjectListCreate(&psEventObject->hOSEventKM) != PVRSRV_OK) + { +- PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: failed to allocate memory for completion variable")); +- return PVRSRV_ERROR_OUT_OF_MEMORY; ++ eError = PVRSRV_ERROR_OUT_OF_MEMORY; + } + +- init_completion(psCompletion); +- +- psEventObject->hOSEventKM = (IMG_HANDLE) psCompletion; + } + else + { + PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer")); +- eError = PVRSRV_ERROR_INVALID_PARAMS; ++ eError = PVRSRV_ERROR_GENERIC; + } + + return eError; ++ + } + + +@@ -1509,8 +1616,7 @@ + { + if(psEventObject->hOSEventKM) + { +- struct completion *psCompletion = (struct completion *) psEventObject->hOSEventKM; +- OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(struct completion), psCompletion, IMG_NULL); ++ LinuxEventObjectListDestroy(psEventObject->hOSEventKM); + } + else + { +@@ -1527,19 +1633,13 @@ + return eError; + } + +-PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM, IMG_UINT32 ui32MSTimeout) ++PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM) + { + PVRSRV_ERROR eError = PVRSRV_OK; + + if(hOSEventKM) + { +- LinuxUnLockMutex(&gPVRSRVLock); +-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) +- wait_for_completion_timeout((struct completion *)hOSEventKM, msecs_to_jiffies(ui32MSTimeout)); +-#else +- wait_for_completion((struct completion *)hOSEventKM); +-#endif +- LinuxLockMutex(&gPVRSRVLock); ++ eError = LinuxEventObjectWait(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS); + } + else + { +@@ -1550,13 +1650,60 @@ + return eError; + } + ++PVRSRV_ERROR OSEventObjectOpen(PVRSRV_EVENTOBJECT *psEventObject, ++ IMG_HANDLE *phOSEvent) ++{ ++ PVRSRV_ERROR eError = PVRSRV_OK; ++ ++ if(psEventObject) ++ { ++ if(LinuxEventObjectAdd(psEventObject->hOSEventKM, phOSEvent) != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed")); ++ eError = PVRSRV_ERROR_INVALID_PARAMS; ++ } ++ ++ } ++ else ++ { ++ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer")); ++ eError = PVRSRV_ERROR_INVALID_PARAMS; ++ } ++ ++ return eError; ++} ++ ++PVRSRV_ERROR OSEventObjectClose(PVRSRV_EVENTOBJECT *psEventObject, ++ IMG_HANDLE hOSEventKM) ++{ ++ PVRSRV_ERROR eError = PVRSRV_OK; ++ ++ if(psEventObject) ++ { ++ if(LinuxEventObjectDelete(psEventObject->hOSEventKM, hOSEventKM, IMG_FALSE) != PVRSRV_OK) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectDelete: failed")); ++ eError = PVRSRV_ERROR_INVALID_PARAMS; ++ } ++ ++ } ++ else ++ { ++ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: psEventObject is not a valid pointer")); ++ eError = PVRSRV_ERROR_INVALID_PARAMS; ++ } ++ ++ return eError; ++ ++} ++ + PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hOSEventKM) + { + PVRSRV_ERROR eError = PVRSRV_OK; + + if(hOSEventKM) + { +- complete_all((struct completion *) hOSEventKM); ++ eError = LinuxEventObjectSignal(hOSEventKM); + } + else + { +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/pdump.c git/drivers/gpu/pvr/services4/srvkm/env/linux/pdump.c +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/pdump.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/pdump.c 2008-12-18 15:47:29.000000000 +0100 +@@ -1205,15 +1205,14 @@ + { + ui32Written = DbgWrite(psStream, &pui8Data[ui32Off], ui32Count, ui32Flags); + +-#if 0 + + + + if (ui32Written == 0) + { +- ZwYieldExecution(); ++ OSReleaseThreadQuanta(); + } +-#endif ++ + if (ui32Written != 0xFFFFFFFF) + { + ui32Off += ui32Written; +@@ -1302,6 +1301,14 @@ + return bFrameDumped; + } + ++IMG_VOID PDumpRegRead(const IMG_UINT32 ui32RegOffset, IMG_UINT32 ui32Flags) ++{ ++ __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); ++ ++ snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "RDW :SGXREG:0x%lX\r\n", ui32RegOffset); ++ PDumpWriteString2(pszScript, ui32Flags); ++} ++ + IMG_VOID PDumpCycleCountRegRead(const IMG_UINT32 ui32RegOffset, IMG_BOOL bLastFrame) + { + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/proc.c git/drivers/gpu/pvr/services4/srvkm/env/linux/proc.c +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/proc.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/proc.c 2008-12-18 15:47:29.000000000 +0100 +@@ -46,6 +46,11 @@ + #ifdef DEBUG + int PVRDebugProcSetLevel(struct file *file, const char *buffer, unsigned long count, void *data); + int PVRDebugProcGetLevel(char *page, char **start, off_t off, int count, int *eof, void *data); ++ ++#ifdef PVR_MANUAL_POWER_CONTROL ++int PVRProcSetPowerLevel(struct file *file, const char *buffer, unsigned long count, void *data); ++int PVRProcGetPowerLevel(char *page, char **start, off_t off, int count, int *eof, void *data); ++#endif + #endif + + static struct proc_dir_entry * dir; +@@ -198,6 +203,15 @@ + + return -ENOMEM; + } ++ ++#ifdef PVR_MANUAL_POWER_CONTROL ++ if (CreateProcEntry("power_control", PVRProcGetPowerLevel, PVRProcSetPowerLevel, 0)) ++ { ++ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/pvr/power_control")); ++ ++ return -ENOMEM; ++ } ++#endif + #endif + + return 0; +@@ -219,6 +233,9 @@ + { + #ifdef DEBUG + RemoveProcEntry("debug_level"); ++#ifdef PVR_MANUAL_POWER_CONTROL ++ RemoveProcEntry("power_control"); ++#endif + #endif + RemoveProcEntry("queue"); + RemoveProcEntry("nodes"); +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/env/linux/pvr_debug.c git/drivers/gpu/pvr/services4/srvkm/env/linux/pvr_debug.c +--- git/drivers/gpu/pvr/services4/srvkm/env/linux/pvr_debug.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/env/linux/pvr_debug.c 2008-12-18 15:47:29.000000000 +0100 +@@ -161,7 +161,7 @@ + + void PVRDebugSetLevel(IMG_UINT32 uDebugLevel) + { +- printk(KERN_INFO "PVR: Setting Debug Level = 0x%x",(unsigned int)uDebugLevel); ++ printk(KERN_INFO "PVR: Setting Debug Level = 0x%x\n",(unsigned int)uDebugLevel); + + gPVRDebugLevel = uDebugLevel; + } +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxdefs.h git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxdefs.h +--- git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxdefs.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxdefs.h 2008-12-18 15:47:29.000000000 +0100 +@@ -33,12 +33,16 @@ + #if defined(SGX535) + #include "sgx535defs.h" + #else ++#if defined(SGX520) ++#include "sgx520defs.h" ++#else + #if defined(SGX535_V1_1) + #include "sgx535defs.h" + #else + #endif + #endif + #endif ++#endif + + #include "sgxerrata.h" + #include "sgxfeaturedefs.h" +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxerrata.h git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxerrata.h +--- git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxerrata.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxerrata.h 2008-12-18 15:47:29.000000000 +0100 +@@ -43,6 +43,8 @@ + #else + #if SGX_CORE_REV == 120 + #else ++ #if SGX_CORE_REV == 121 ++ #else + #if SGX_CORE_REV == SGX_CORE_REV_HEAD + + #else +@@ -51,6 +53,7 @@ + #endif + #endif + #endif ++ #endif + #endif + + #define SGX_CORE_DEFINED +@@ -69,16 +72,22 @@ + #define FIX_HW_BRN_23281 + #define FIX_HW_BRN_23410 + #define FIX_HW_BRN_22693 ++ #define FIX_HW_BRN_22997 ++ #define FIX_HW_BRN_23030 + #else + #if SGX_CORE_REV == 1111 + #define FIX_HW_BRN_23281 + #define FIX_HW_BRN_23410 + #define FIX_HW_BRN_22693 ++ #define FIX_HW_BRN_22997 ++ #define FIX_HW_BRN_23030 + #else + #if SGX_CORE_REV == 112 + #define FIX_HW_BRN_23281 + #define FIX_HW_BRN_23410 + #define FIX_HW_BRN_22693 ++ #define FIX_HW_BRN_22997 ++ #define FIX_HW_BRN_23030 + #else + #if SGX_CORE_REV == 113 + #define FIX_HW_BRN_23281 +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h +--- git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h 2008-12-18 15:47:29.000000000 +0100 +@@ -24,6 +24,12 @@ + * + ******************************************************************************/ + ++#if defined(SGX520) ++ #define SGX_CORE_FRIENDLY_NAME "SGX520" ++ #define SGX_CORE_ID SGX_CORE_ID_520 ++ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28) ++ #define SGX_FEATURE_AUTOCLOCKGATING ++#else + #if defined(SGX530) + #define SGX_CORE_FRIENDLY_NAME "SGX530" + #define SGX_CORE_ID SGX_CORE_ID_530 +@@ -36,8 +42,9 @@ + #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) + #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS + #define SGX_FEATURE_2D_HARDWARE +- #define SGX_FEATURE_AUTOCLOCKGATING +- ++ #define SGX_FEATURE_AUTOCLOCKGATING ++#else ++#endif + #endif + #endif + +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/include/device.h git/drivers/gpu/pvr/services4/srvkm/include/device.h +--- git/drivers/gpu/pvr/services4/srvkm/include/device.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/include/device.h 2008-12-18 15:47:29.000000000 +0100 +@@ -225,39 +225,40 @@ + struct _PVRSRV_DEVICE_NODE_ *psNext; + } PVRSRV_DEVICE_NODE; + +-PVRSRV_ERROR PVRSRVRegisterDevice(PSYS_DATA psSysData, +- PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*), +- IMG_UINT32 ui32SOCInterruptBit, +- IMG_UINT32 *pui32DeviceIndex ); ++PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData, ++ PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*), ++ IMG_UINT32 ui32SOCInterruptBit, ++ IMG_UINT32 *pui32DeviceIndex ); + +-PVRSRV_ERROR PVRSRVInitialiseDevice(IMG_UINT32 ui32DevIndex); ++PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice(IMG_UINT32 ui32DevIndex); ++PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful); + +-PVRSRV_ERROR PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex); ++PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex); + + #if !defined(USE_CODE) + +-IMG_IMPORT PVRSRV_ERROR PollForValueKM(volatile IMG_UINT32* pui32LinMemAddr, +- IMG_UINT32 ui32Value, +- IMG_UINT32 ui32Mask, +- IMG_UINT32 ui32Waitus, +- IMG_UINT32 ui32Tries); ++IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PollForValueKM(volatile IMG_UINT32* pui32LinMemAddr, ++ IMG_UINT32 ui32Value, ++ IMG_UINT32 ui32Mask, ++ IMG_UINT32 ui32Waitus, ++ IMG_UINT32 ui32Tries); + + #endif + + + #if defined (USING_ISR_INTERRUPTS) +-PVRSRV_ERROR PollForInterruptKM(IMG_UINT32 ui32Value, ++PVRSRV_ERROR IMG_CALLCONV PollForInterruptKM(IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Waitus, + IMG_UINT32 ui32Tries); + #endif + + +-PVRSRV_ERROR PVRSRVInit(PSYS_DATA psSysData); +-IMG_VOID PVRSRVDeInit(PSYS_DATA psSysData); +-IMG_BOOL PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode); +-IMG_BOOL PVRSRVSystemLISR(IMG_VOID *pvSysData); +-IMG_VOID PVRSRVMISR(IMG_VOID *pvSysData); ++PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData); ++IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData); ++IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode); ++IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData); ++IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData); + + #if defined(__cplusplus) + } +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/include/handle.h git/drivers/gpu/pvr/services4/srvkm/include/handle.h +--- git/drivers/gpu/pvr/services4/srvkm/include/handle.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/include/handle.h 2008-12-18 15:47:29.000000000 +0100 +@@ -50,10 +50,13 @@ + PVRSRV_HANDLE_TYPE_DISP_BUFFER, + PVRSRV_HANDLE_TYPE_BUF_BUFFER, + PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT, ++ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT, ++ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO, +- PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT ++ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, ++ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT + } PVRSRV_HANDLE_TYPE; + + typedef enum +@@ -126,6 +129,11 @@ + + + IMG_UINT32 ui32LastFreeIndexPlusOne; ++ ++#ifdef __linux__ ++ ++ IMG_BOOL bVmallocUsed; ++#endif + } PVRSRV_HANDLE_BASE; + + #ifdef PVR_SECURE_HANDLES +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/include/osfunc.h git/drivers/gpu/pvr/services4/srvkm/include/osfunc.h +--- git/drivers/gpu/pvr/services4/srvkm/include/osfunc.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/include/osfunc.h 2008-12-18 15:47:29.000000000 +0100 +@@ -148,14 +148,16 @@ + IMG_CHAR* OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc); + IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_UINT32 ui32Size, const IMG_CHAR *pszFormat, ...); + #define OSStringLength(pszString) strlen(pszString) +-PVRSRV_ERROR OSPowerManagerConnect(IMG_VOID); +-PVRSRV_ERROR OSPowerManagerDisconnect(IMG_VOID); + + PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, + PVRSRV_EVENTOBJECT *psEventObject); + PVRSRV_ERROR OSEventObjectDestroy(PVRSRV_EVENTOBJECT *psEventObject); + PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hOSEventKM); +-PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM, IMG_UINT32 ui32MSTimeout); ++PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM); ++PVRSRV_ERROR OSEventObjectOpen(PVRSRV_EVENTOBJECT *psEventObject, ++ IMG_HANDLE *phOSEvent); ++PVRSRV_ERROR OSEventObjectClose(PVRSRV_EVENTOBJECT *psEventObject, ++ IMG_HANDLE hOSEventKM); + + + PVRSRV_ERROR OSBaseAllocContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR *pLinAddr, IMG_CPU_PHYADDR *pPhysAddr); +@@ -203,6 +205,8 @@ + typedef IMG_VOID (*PFN_TIMER_FUNC)(IMG_VOID*); + IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout); + PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer); ++PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer); ++PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer); + + PVRSRV_ERROR OSGetSysMemSize(IMG_UINT32 *pui32Bytes); + +@@ -211,17 +215,17 @@ + HOST_PCI_INIT_FLAG_BUS_MASTER = 0x1, + HOST_PCI_INIT_FLAG_FORCE_I32 = 0x7fffffff + } HOST_PCI_INIT_FLAGS; +-PVRSRV_ERROR OSPCIAcquireDev(IMG_VOID *pvSysData, IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags); +-PVRSRV_ERROR OSPCISetDev(IMG_VOID *pvSysData, IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags); +-PVRSRV_ERROR OSPCIReleaseDev(IMG_VOID *pvSysData); +-PVRSRV_ERROR OSPCIIRQ(IMG_VOID *pvSysData, IMG_UINT32 *pui32IRQ); +-IMG_UINT32 OSPCIAddrRangeLen(IMG_VOID *pvSysData, IMG_UINT32 ui32Index); +-IMG_UINT32 OSPCIAddrRangeStart(IMG_VOID *pvSysData, IMG_UINT32 ui32Index); +-IMG_UINT32 OSPCIAddrRangeEnd(IMG_VOID *pvSysData, IMG_UINT32 ui32Index); +-PVRSRV_ERROR OSPCIRequestAddrRange(IMG_VOID *pvSysData, IMG_UINT32 ui32Index); +-PVRSRV_ERROR OSPCIReleaseAddrRange(IMG_VOID *pvSysData, IMG_UINT32 ui32Index); +-PVRSRV_ERROR OSPCISuspendDev(IMG_VOID *pvSysData); +-PVRSRV_ERROR OSPCIResumeDev(IMG_VOID *pvSysData); ++IMG_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags); ++IMG_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags); ++PVRSRV_ERROR OSPCIReleaseDev(IMG_HANDLE hPVRPCI); ++PVRSRV_ERROR OSPCIIRQ(IMG_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ); ++IMG_UINT32 OSPCIAddrRangeLen(IMG_HANDLE hPVRPCI, IMG_UINT32 ui32Index); ++IMG_UINT32 OSPCIAddrRangeStart(IMG_HANDLE hPVRPCI, IMG_UINT32 ui32Index); ++IMG_UINT32 OSPCIAddrRangeEnd(IMG_HANDLE hPVRPCI, IMG_UINT32 ui32Index); ++PVRSRV_ERROR OSPCIRequestAddrRange(IMG_HANDLE hPVRPCI, IMG_UINT32 ui32Index); ++PVRSRV_ERROR OSPCIReleaseAddrRange(IMG_HANDLE hPVRPCI, IMG_UINT32 ui32Index); ++PVRSRV_ERROR OSPCISuspendDev(IMG_HANDLE hPVRPCI); ++PVRSRV_ERROR OSPCIResumeDev(IMG_HANDLE hPVRPCI); + + PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData); + +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/include/pdump_km.h git/drivers/gpu/pvr/services4/srvkm/include/pdump_km.h +--- git/drivers/gpu/pvr/services4/srvkm/include/pdump_km.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/include/pdump_km.h 2008-12-18 15:47:29.000000000 +0100 +@@ -180,6 +180,8 @@ + void PDump3DSignatureRegisters(IMG_UINT32 ui32DumpFrameNum, + IMG_BOOL bLastFrame); + ++ IMG_VOID PDumpRegRead(const IMG_UINT32 dwRegOffset, IMG_UINT32 ui32Flags); ++ + IMG_VOID PDumpCycleCountRegRead(const IMG_UINT32 dwRegOffset, IMG_BOOL bLastFrame); + + void PDumpPerformanceCounterRegisters(IMG_UINT32 ui32DumpFrameNum, +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/include/resman.h git/drivers/gpu/pvr/services4/srvkm/include/resman.h +--- git/drivers/gpu/pvr/services4/srvkm/include/resman.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/include/resman.h 2008-12-18 15:47:29.000000000 +0100 +@@ -34,7 +34,9 @@ + enum { + + RESMAN_TYPE_SHARED_PB_DESC = 1, +- RESMAN_TYPE_HW_RENDER_CONTEXT, ++ RESMAN_TYPE_HW_RENDER_CONTEXT, ++ RESMAN_TYPE_HW_TRANSFER_CONTEXT, ++ RESMAN_TYPE_HW_2D_CONTEXT, + RESMAN_TYPE_TRANSFER_CONTEXT, + + +@@ -57,6 +59,7 @@ + RESMAN_TYPE_DEVICEMEM_WRAP, + RESMAN_TYPE_DEVICEMEM_ALLOCATION, + RESMAN_TYPE_RESOURCE_PERPROC_DATA, ++ RESMAN_TYPE_EVENT_OBJECT, + RESMAN_TYPE_SHARED_MEM_INFO, + + +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/include/srvkm.h git/drivers/gpu/pvr/services4/srvkm/include/srvkm.h +--- git/drivers/gpu/pvr/services4/srvkm/include/srvkm.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/include/srvkm.h 2008-12-18 15:47:29.000000000 +0100 +@@ -33,9 +33,9 @@ + #endif + + +-IMG_VOID PVRSRVSetDCState(IMG_UINT32 ui32State); ++IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State); + +-PVRSRV_ERROR PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_UINT32 *puiBufSize, IMG_BOOL bSave); ++PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_UINT32 *puiBufSize, IMG_BOOL bSave); + + #if defined (__cplusplus) + } +diff -Nurd git/drivers/gpu/pvr/services4/srvkm/Makefile git/drivers/gpu/pvr/services4/srvkm/Makefile +--- git/drivers/gpu/pvr/services4/srvkm/Makefile 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/srvkm/Makefile 1970-01-01 01:00:00.000000000 +0100 +@@ -1,68 +0,0 @@ +-# +-# Copyright(c) 2008 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 +-# +-# +- +-obj-y += env/linux/osfunc.o \ +- env/linux/mmap.o \ +- env/linux/mod.o \ +- env/linux/pdump.o \ +- env/linux/proc.o \ +- env/linux/pvr_bridge_k.o \ +- env/linux/pvr_debug.o \ +- env/linux/mm.o \ +- env/linux/mutex.o +- +-obj-y += common/buffer_manager.o \ +- common/devicemem.o \ +- common/deviceclass.o \ +- common/handle.o \ +- common/hash.o \ +- common/metrics.o \ +- common/pvrsrv.o \ +- common/queue.o \ +- common/ra.o \ +- common/resman.o \ +- common/power.o \ +- common/mem.o \ +- bridged/bridged_pvr_bridge.o \ +- devices/sgx/sgxinit.o \ +- devices/sgx/sgxutils.o \ +- devices/sgx/sgxkick.o \ +- devices/sgx/sgxtransfer.o \ +- devices/sgx/mmu.o \ +- devices/sgx/pb.o \ +- common/perproc.o \ +- ../system/$(CONFIG_PVR_SYSTEM)/sysconfig.o \ +- ../system/$(CONFIG_PVR_SYSTEM)/sysutils.o \ +- devices/sgx/sgx2dcore.o +- +-INCLUDES = -I$(src)/env/linux \ +- -I$(src)/include \ +- -I$(src)/bridged \ +- -I$(src)/devices/sgx \ +- -I$(src)/include \ +- -I$(src)/hwdefs +- +-ccflags-y += $(CONFIG_PVR_OPTS) $(INCLUDES) +- +diff -Nurd git/drivers/gpu/pvr/services4/system/include/syscommon.h git/drivers/gpu/pvr/services4/system/include/syscommon.h +--- git/drivers/gpu/pvr/services4/system/include/syscommon.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/system/include/syscommon.h 2008-12-18 15:47:29.000000000 +0100 +@@ -83,11 +83,13 @@ + RA_ARENA *apsLocalDevMemArena[SYS_MAX_LOCAL_DEVMEM_ARENAS]; + + IMG_CHAR *pszVersionString; ++ PVRSRV_EVENTOBJECT *psGlobalEventObject; + } SYS_DATA; + + + + PVRSRV_ERROR SysInitialise(IMG_VOID); ++PVRSRV_ERROR SysFinalise(IMG_VOID); + + IMG_UINT32 GetCPUTranslatedAddress(IMG_VOID); + +diff -Nurd git/drivers/gpu/pvr/services4/system/omap3430/sysconfig.c git/drivers/gpu/pvr/services4/system/omap3430/sysconfig.c +--- git/drivers/gpu/pvr/services4/system/omap3430/sysconfig.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/system/omap3430/sysconfig.c 2008-12-18 15:47:29.000000000 +0100 +@@ -360,8 +360,15 @@ + } + gsSysSpecificData.ui32SysSpecificData |= SYS_SPECIFIC_DATA_ENABLE_INITDEV; + ++ return PVRSRV_OK; ++} ++ + ++PVRSRV_ERROR SysFinalise(IMG_VOID) ++{ + #if defined(SYS_USING_INTERRUPTS) ++ PVRSRV_ERROR eError; ++ + eError = OSInstallMISR(gpsSysData); + if (eError != PVRSRV_OK) + { +@@ -388,12 +395,12 @@ + + gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase); + if (!gpsSysData->pszVersionString) +- { +- PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to create a system version string")); ++ { ++ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); + } + else + { +- PVR_DPF((PVR_DBG_WARNING, "SysInitialise: Version string: %s", gpsSysData->pszVersionString)); ++ PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString)); + } + + #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) +@@ -641,7 +648,7 @@ + } + gsSysSpecificData.ui32SysSpecificData &= ~SYS_SPECIFIC_DATA_ENABLE_LISR; + } +-#endif ++#endif + if (gsSysSpecificData.ui32SysSpecificData & SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS) + { + DisableSystemClocks(gpsSysData); +@@ -682,7 +689,7 @@ + } + gsSysSpecificData.ui32SysSpecificData |= SYS_SPECIFIC_DATA_ENABLE_LISR; + } +-#endif ++#endif + } + return eError; + } +@@ -706,7 +713,7 @@ + DisableSGXClocks(gpsSysData); + } + #else +- PVR_UNREFERENCED_PARAMETER(eNewPowerState); ++ PVR_UNREFERENCED_PARAMETER(eNewPowerState ); + #endif + return PVRSRV_OK; + } +@@ -718,12 +725,13 @@ + { + PVRSRV_ERROR eError = PVRSRV_OK; + ++ PVR_UNREFERENCED_PARAMETER(eNewPowerState); ++ + if (ui32DeviceIndex != gui32SGXDeviceID) + { + return eError; + } + +- PVR_UNREFERENCED_PARAMETER(eNewPowerState); + + #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eCurrentPowerState == PVRSRV_POWER_STATE_D3) +@@ -734,7 +742,7 @@ + #else + PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); + #endif +- ++ + return eError; + } + +diff -Nurd git/drivers/gpu/pvr/services4/system/omap3430/sysconfig.h git/drivers/gpu/pvr/services4/system/omap3430/sysconfig.h +--- git/drivers/gpu/pvr/services4/system/omap3430/sysconfig.h 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/system/omap3430/sysconfig.h 2008-12-18 15:47:29.000000000 +0100 +@@ -38,13 +38,6 @@ + + #define SYS_OMAP3430_SGX_IRQ 21 + +-#define SYS_OMAP3430_PM_REGS_SYS_PHYS_BASE 0x48306000 +-#define SYS_OMAP3430_PM_REGS_SIZE 0x1000 +- +-#define SYS_OMAP3430_CM_REGS_SYS_PHYS_BASE 0x48004000 +-#define SYS_OMAP3430_CM_REGS_SIZE 0x1000 +- +- + #define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088024 + #define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE 0x48088028 + #define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088040 +diff -Nurd git/drivers/gpu/pvr/services4/system/omap3430/sysutils.c git/drivers/gpu/pvr/services4/system/omap3430/sysutils.c +--- git/drivers/gpu/pvr/services4/system/omap3430/sysutils.c 2009-01-05 20:00:44.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/system/omap3430/sysutils.c 2008-12-18 15:47:29.000000000 +0100 +@@ -52,7 +52,7 @@ + return PVRSRV_OK; + } + +- PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Enabling SGX Clocks")); ++ PVR_TRACE(("EnableSGXClocks: Enabling SGX Clocks")); + + #if defined(__linux__) + if (psSysSpecData->psSGX_FCK == IMG_NULL) +--- /tmp/omaplfb_linux.c 2009-01-06 10:41:49.000000000 +0100 ++++ git/drivers/gpu/pvr/services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c 2009-01-06 10:42:41.000000000 +0100 +@@ -108,6 +108,8 @@ + (void) OMAPLFBVSyncIHandler(psSwapChain); + } + ++#define DISPC_IRQ_VSYNC 0x0002 ++ + PVRSRV_ERROR OMAPLFBInstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain) + { + +--- /tmp/Makefile 2009-01-06 11:32:47.000000000 +0100 ++++ git/drivers/gpu/pvr/Makefile 2009-01-06 11:39:06.000000000 +0100 +@@ -16,6 +16,7 @@ + services4/srvkm/env/linux/pvr_debug.o \ + services4/srvkm/env/linux/mm.o \ + services4/srvkm/env/linux/mutex.o \ ++ services4/srvkm/env/linux/event.o \ + services4/srvkm/common/buffer_manager.o \ + services4/srvkm/common/devicemem.o \ + services4/srvkm/common/deviceclass.o \ +@@ -30,6 +31,7 @@ + services4/srvkm/common/mem.o \ + services4/srvkm/bridged/bridged_pvr_bridge.o \ + services4/srvkm/devices/sgx/sgxinit.o \ ++ services4/srvkm/devices/sgx/sgxreset.o \ + services4/srvkm/devices/sgx/sgxutils.o \ + services4/srvkm/devices/sgx/sgxkick.o \ + services4/srvkm/devices/sgx/sgxtransfer.o \ diff --git a/packages/linux/linux-omap_2.6.27.bb b/packages/linux/linux-omap_2.6.27.bb index bc12d9da62..602bbf33ef 100644 --- a/packages/linux/linux-omap_2.6.27.bb +++ b/packages/linux/linux-omap_2.6.27.bb @@ -39,6 +39,7 @@ SRC_URI_append = " \ # file://openvz/openvz-2.6.27.diff;patch=1 \ file://pvr/pvr-add.patch;patch=1 \ file://pvr/dispc.patch;patch=1 \ + file://pvr/nokia-TI.diff;patch=1 \ file://sitecomwl168-support.diff;patch=1 \ " |