linux-omap 2.6.27: sync powervr code with latest code drop from TI
authorKoen Kooi <koen@openembedded.org>
Tue, 6 Jan 2009 10:44:24 +0000 (11:44 +0100)
committerKoen Kooi <koen@openembedded.org>
Tue, 6 Jan 2009 14:44:11 +0000 (15:44 +0100)
packages/linux/linux-omap-2.6.27/beagleboard/defconfig
packages/linux/linux-omap-2.6.27/pvr/nokia-TI.diff [new file with mode: 0644]
packages/linux/linux-omap_2.6.27.bb

index 8380a20..afcd728 100644 (file)
@@ -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 (file)
index 0000000..a4aca1e
--- /dev/null
@@ -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       \
index bc12d9d..602bbf3 100644 (file)
@@ -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 \
 "