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