--- /dev/null
+++ b/drivers/staging/cdv/Kconfig
@@ -0,0 +1,51 @@
+#
+# Drm device configuration
+#
+# This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+#
+
+config DRM_INTEL_CDV
+	tristate "Intel CDV (load along with IMG driver)"
+	depends on DRM && PCI && !DRM_PSB_CDV
+	select FB_CFB_COPYAREA
+        select FB_CFB_FILLRECT
+        select FB_CFB_IMAGEBLIT
+        select DRM_KMS_HELPER
+        select DRM_TTM
+	select ACPI_VIDEO if ACPI
+	help
+          Choose this option if you have a Cedarview platform.
+          If M is selected the module will be called cedarview_gfx.
+
+choice 
+	prompt "Build IMG kernel service as "
+	depends on DRM_INTEL_CDV
+	default DRM_CDV_RELEASE
+
+config DRM_CDV_RELEASE
+	bool "Release"
+	depends on DRM_INTEL_CDV
+	help
+	  Build IMG kernel services as release version.
+
+config DRM_CDV_DEBUG
+	bool "Debug"
+	depends on DRM_INTEL_CDV
+	help
+	  Build IMG kernel services as debug version.	
+endchoice
+
+if DRM_CDV_DEBUG
+
+config DRM_PVR_PDUMP
+ 	bool "Enable PDump Debug"
+ 	help
+ 	  Build the PVR driver with PDUMP feature. At most cases it should be N.
+
+config DRM_PVR_TRACE
+	bool "Enable PVR Service Trace"
+	help
+	  Enable PVR service call trace. If unsure, it should be N.
+
+endif
diff --git a/drivers/staging/cdv/Makefile b/drivers/staging/cdv/Makefile
new file mode 100644
index 0000000..682cd49
--- /dev/null
+++ b/drivers/staging/cdv/Makefile
@@ -0,0 +1,200 @@
+# Makefile for the drm device driver.  This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+
+INCDIR=drivers/staging/cdv
+
+include_dirs := \
+	-I$(INCDIR)/pvr/include4 \
+        -I$(INCDIR)/pvr/services4/include \
+        -I$(INCDIR)/pvr/services4/include/env/linux \
+        -I$(INCDIR)/pvr/services4/srvkm/env/linux \
+        -I$(INCDIR)/pvr/services4/srvkm/include \
+        -I$(INCDIR)/pvr/services4/srvkm/bridged \
+	-I$(INCDIR)/pvr/services4/system/include \
+        -I$(INCDIR)/pvr/services4/srvkm/hwdefs \
+        -I$(INCDIR)/pvr/services4/srvkm/bridged/sgx \
+        -I$(INCDIR)/pvr/services4/srvkm/devices/sgx \
+        -I$(INCDIR)/ \
+        -I$(INCDIR)/drv \
+        -I$(INCDIR)/bc_video \
+        -I$(INCDIR)/imgv \
+	-Iinclude/linux \
+	-Iinclude/drm
+
+ 
+ccflags-y += $(include_dirs)
+
+ccflags-$(CONFIG_DRM_PVR_PDUMP) += -I$(INCDIR)/pvr/tools/intern/debug/client \
+			-I$(INCDIR)/pvr/tools/intern/debug/dbgdriv/common
+ccflags-y += -I$(INCDIR)/pvr/services4/system/unified -DSGX545 -DSUPPORT_SGX545 -DSGX_CORE_REV=10131
+
+
+ccflags-y += \
+	-Wall \
+	-Werror \
+	-DLINUX \
+	-DPVR_BUILD_DIR="\"pc_i686_cedarview_linux\"" \
+	-DSUPPORT_DRI_DRM \
+	-DSUPPORT_DRI_DRM_EXT \
+	-DSERVICES4 \
+	-D_XOPEN_SOURCE=600 \
+	-DPVR2D_VALIDATE_INPUT_PARAMS \
+	-DDISPLAY_CONTROLLER=mrstlfb \
+	-UDEBUG_LOG_PATH_TRUNCATE \
+	-DSUPPORT_SRVINIT \
+	-DSUPPORT_SGX \
+	-DSUPPORT_LINUX_X86_WRITECOMBINE \
+	-DTRANSFER_QUEUE \
+	-DSYS_USING_INTERRUPTS \
+	-DSUPPORT_HW_RECOVERY \
+	-DPVR_SECURE_HANDLES \
+	-DUSE_PTHREADS \
+	-DSUPPORT_SGX_EVENT_OBJECT \
+	-DSUPPORT_SGX_HWPERF \
+	-DSUPPORT_LINUX_X86_PAT \
+	-DPVR_PROC_USE_SEQ_FILE \
+	-DSUPPORT_CACHE_LINE_FLUSH \
+	-DSUPPORT_CPU_CACHED_BUFFERS \
+	-DDISABLE_PM \
+	-DSUPPORT_SGX_NEW_STATUS_VALS \
+	-DSUPPORT_PERCONTEXT_PB \
+	-DDRM_PVR_USE_INTEL_FB
+
+SUPPORT_EGL_EXTENSIONS ?=1
+ifeq ($(SUPPORT_EGL_EXTENSIONS),1)
+	PVRSRV_RESOURCE_PROFILING = y
+	PERPROC_LIST = y
+	RES_MAN_EXTEND = y
+	PVRSRV_OS_MEM_INFO = y
+else
+	PVRSRV_RESOURCE_PROFILING =
+        PERPROC_LIST =
+        RES_MAN_EXTEND =
+        PVRSRV_OS_MEM_INFO =
+endif
+ccflags-$(PVRSRV_RESOURCE_PROFILING) += -DPVRSRV_RESOURCE_PROFILING
+ccflags-$(PERPROC_LIST) += -DPERPROC_LIST
+ccflags-$(RES_MAN_EXTEND) += -DRES_MAN_EXTEND
+ccflags-$(PVRSRV_OS_MEM_INFO) += -DPVRSRV_OS_MEM_INFO
+
+ccflags-$(CONFIG_DRM_CDV_RELEASE) += -DBUILD="\"release\"" -DPVR_BUILD_TYPE="\"release\"" -DRELEASE
+ccflags-$(CONFIG_DRM_CDV_DEBUG) += -DBUILD="\"debug\"" -DPVR_BUILD_TYPE="\"debug\"" -DDEBUG -DDEBUG_LINUX_MEM_AREAS -DDEBUG_LINUX_MEMORY_ALLOCATIONS -DDEBUG_LINUX_MMAP_AREAS -DDEBUG_BRIDGE_KM -DPVRSRV_NEED_PVR_TRACE -DDEBUG_MESA_OGL_TRACE -DPVRSRV_USSE_EDM_STATUS_DEBUG -DPVRSRV_DUMP_MK_TRACE
+ccflags-$(CONFIG_PCI_MSI) += -DCONFIG_PCI_MSI
+
+ccflags-$(CONFIG_DRM_PVR_PDUMP) += -DPDUMP
+ccflags-$(CONFIG_DRM_PVR_TRACE) += -DDEBUG_TRACE_BRIDGE_KM
+	
+ENVDIR = pvr/services4/srvkm/env/linux
+COMMONDIR = pvr/services4/srvkm/common
+BRIDGEDDIR = pvr/services4/srvkm/bridged
+SGXDIR = pvr/services4/srvkm/devices/sgx
+FBDEVDIR = pvr/services4/3rdparty/linux_framebuffer_mrst
+DRMDRVDIR = drv
+SYSCONFIGDIR = pvr/services4/system/unified
+IMGVDIR = imgv
+BUFFER_CLASS_DIR = bc_video
+
+PDUMP_MAIN_DIR = pvr/tools/intern/debug/dbgdriv/linux
+PDUMP_COMMON_DIR = pvr/tools/intern/debug/dbgdriv/common
+
+cedarview_gfx-y += $(ENVDIR)/osfunc.o \
+	  $(ENVDIR)/mutils.o \
+	  $(ENVDIR)/mmap.o \
+	  $(ENVDIR)/module.o \
+	  $(ENVDIR)/pdump.o \
+	  $(ENVDIR)/proc.o \
+	  $(ENVDIR)/pvr_bridge_k.o \
+	  $(ENVDIR)/pvr_debug.o \
+	  $(ENVDIR)/mm.o \
+	  $(ENVDIR)/event.o \
+	  $(ENVDIR)/osperproc.o \
+	  $(ENVDIR)/pvr_drm.o
+
+cedarview_gfx-y += $(COMMONDIR)/buffer_manager.o \
+	  $(COMMONDIR)/devicemem.o \
+	  $(COMMONDIR)/deviceclass.o \
+	  $(COMMONDIR)/handle.o \
+	  $(COMMONDIR)/hash.o \
+	  $(COMMONDIR)/metrics.o \
+	  $(COMMONDIR)/pvrsrv.o \
+	  $(COMMONDIR)/queue.o \
+	  $(COMMONDIR)/ra.o \
+	  $(COMMONDIR)/resman.o \
+	  $(COMMONDIR)/power.o \
+	  $(COMMONDIR)/mem.o \
+	  $(COMMONDIR)/pdump_common.o \
+	  $(COMMONDIR)/perproc.o \
+	  $(COMMONDIR)/lists.o \
+	  $(COMMONDIR)/mem_debug.o \
+	  $(COMMONDIR)/osfunc_common.o
+
+cedarview_gfx-y += $(BRIDGEDDIR)/bridged_support.o \
+	  $(BRIDGEDDIR)/bridged_pvr_bridge.o \
+	  $(BRIDGEDDIR)/sgx/bridged_sgx_bridge.o
+
+cedarview_gfx-y += $(SYSCONFIGDIR)/sysconfig.o \
+	  $(SYSCONFIGDIR)/sysutils.o \
+	  $(SYSCONFIGDIR)/sys_pvr_drm_export.o 
+
+cedarview_gfx-y += $(SGXDIR)/sgxinit.o \
+	  $(SGXDIR)/sgxpower.o \
+	  $(SGXDIR)/sgxreset.o \
+	  $(SGXDIR)/sgxutils.o \
+	  $(SGXDIR)/sgxkick.o \
+	  $(SGXDIR)/sgxtransfer.o \
+	  $(SGXDIR)/mmu.o \
+	  $(SGXDIR)/pb.o
+
+cedarview_gfx-y += $(FBDEVDIR)/mrstlfb_displayclass.o \
+	  $(FBDEVDIR)/mrstlfb_linux.o
+
+cedarview_gfx-y += $(DRMDRVDIR)/psb_bl.o \
+	  $(DRMDRVDIR)/psb_dpst.o \
+	  $(DRMDRVDIR)/psb_drv.o \
+	  $(DRMDRVDIR)/psb_fb.o \
+	  $(DRMDRVDIR)/psb_gtt.o \
+	  $(DRMDRVDIR)/psb_hotplug.o \
+	  $(DRMDRVDIR)/psb_intel_bios.o \
+	  $(DRMDRVDIR)/psb_intel_opregion.o \
+	  $(DRMDRVDIR)/psb_intel_display.o \
+	  $(DRMDRVDIR)/psb_intel_i2c.o \
+	  $(DRMDRVDIR)/psb_intel_lvds.o \
+	  $(DRMDRVDIR)/psb_intel_modes.o \
+	  $(DRMDRVDIR)/psb_intel_hdmi.o \
+	  $(DRMDRVDIR)/psb_reset.o \
+	  $(DRMDRVDIR)/psb_schedule.o \
+	  $(DRMDRVDIR)/psb_sgx.o \
+	  $(DRMDRVDIR)/psb_socket.o \
+	  $(DRMDRVDIR)/psb_pvr_glue.o \
+	  $(DRMDRVDIR)/psb_umevents.o \
+	  $(DRMDRVDIR)/psb_intel_crt.o \
+	  $(DRMDRVDIR)/psb_intel_dpll_cdv.o \
+	  $(DRMDRVDIR)/psb_intel_dp.o	\
+	  $(DRMDRVDIR)/psb_intel_panel.o
+
+cedarview_gfx-y += $(IMGVDIR)/psb_buffer.o \
+	  $(IMGVDIR)/psb_fence.o \
+	  $(IMGVDIR)/psb_mmu.o \
+	  $(IMGVDIR)/psb_msvdx.o \
+	  $(IMGVDIR)/msvdx_power.o \
+	  $(IMGVDIR)/psb_msvdxinit.o \
+	  $(IMGVDIR)/psb_ttm_glue.o \
+	  $(IMGVDIR)/psb_ttm_fence.o \
+	  $(IMGVDIR)/psb_ttm_fence_user.o \
+	  $(IMGVDIR)/psb_ttm_placement_user.o 
+
+cedarview_gfx-y += $(DRMDRVDIR)/psb_powermgmt.o $(DRMDRVDIR)/psb_irq.o
+
+cedarview_gfx-y += $(BUFFER_CLASS_DIR)/bufferclass_video.o \
+                        $(BUFFER_CLASS_DIR)/bufferclass_video_linux.o
+
+cedarview_gfx-$(CONFIG_DRM_PVR_PDUMP) += $(PDUMP_MAIN_DIR)/main.o \
+					 $(PDUMP_MAIN_DIR)/hostfunc.o \
+					 $(PDUMP_COMMON_DIR)/dbgdriv.o \
+					 $(PDUMP_COMMON_DIR)/handle.o \
+					 $(PDUMP_COMMON_DIR)/hotkey.o \
+					 $(PDUMP_COMMON_DIR)/ioctl.o
+					
+
+obj-$(CONFIG_DRM_INTEL_CDV) += cedarview_gfx.o
+
diff --git a/drivers/staging/cdv/bc_video/bufferclass_video.c b/drivers/staging/cdv/bc_video/bufferclass_video.c
new file mode 100644
index 0000000..3464b46
--- /dev/null
+++ b/drivers/staging/cdv/bc_video/bufferclass_video.c
@@ -0,0 +1,327 @@
+/***************************************************************************
+ *
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************************/
+
+#if defined(__linux__)
+#include <linux/string.h>
+#else
+#include <string.h>
+#endif
+
+#include "bufferclass_video.h"
+#include "bufferclass_video_linux.h"
+
+#define VBUFFERCLASS_DEVICE_NAME "Video Bufferclass Device"
+#define CBUFFERCLASS_DEVICE_NAME "Camera Bufferclass Device"
+
+static void *gpvAnchorVideo[BC_VIDEO_DEVICE_MAX_ID];
+
+static void *gpcAnchor;
+static PFN_BC_GET_PVRJTABLE pfnGetPVRJTable = IMG_NULL;
+
+BC_VIDEO_DEVINFO *
+GetAnchorPtr (int id)
+{
+    BC_VIDEO_DEVINFO *AnchorPtr = NULL;
+    if (id < BC_VIDEO_DEVICE_MAX_ID)
+        AnchorPtr = gpvAnchorVideo[id];
+    else if (id == BC_CAMERA_DEVICEID)
+        AnchorPtr = gpcAnchor;
+    return AnchorPtr;
+}
+
+static void
+SetAnchorPtr (BC_VIDEO_DEVINFO * psDevInfo, int id)
+{
+    if (id < BC_VIDEO_DEVICE_MAX_ID)
+        gpvAnchorVideo[id] = (void *) psDevInfo;
+    else if (id == BC_CAMERA_DEVICEID)
+        gpcAnchor = (void *) psDevInfo;
+}
+
+static PVRSRV_ERROR
+OpenVBCDevice (IMG_UINT32 uDeviceID, IMG_HANDLE * phDevice)
+{
+    BC_VIDEO_DEVINFO *psDevInfo;
+    int id;
+    *phDevice = NULL;
+    for(id = 0; id < BC_VIDEO_DEVICE_MAX_ID; id++){
+        psDevInfo = GetAnchorPtr(id);
+        if(psDevInfo != NULL && psDevInfo->ulDeviceID == uDeviceID){
+            *phDevice = (IMG_HANDLE) psDevInfo;
+            break;
+        }
+    }
+
+    return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR OpenCBCDevice(IMG_UINT32 uDeviceID, IMG_HANDLE *phDevice)
+{
+    BC_VIDEO_DEVINFO *psDevInfo;
+
+    UNREFERENCED_PARAMETER(uDeviceID);
+    psDevInfo = GetAnchorPtr(BC_CAMERA_DEVICEID);
+
+    *phDevice = (IMG_HANDLE)psDevInfo;
+
+    return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR
+CloseBCDevice (IMG_UINT32 uDeviceID, IMG_HANDLE hDevice)
+{
+    UNREFERENCED_PARAMETER (uDeviceID);
+    UNREFERENCED_PARAMETER (hDevice);
+
+    return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR
+GetBCBuffer (IMG_HANDLE hDevice,
+        IMG_UINT32 ui32BufferNumber,
+        PVRSRV_SYNC_DATA * psSyncData, IMG_HANDLE * phBuffer)
+{
+    BC_VIDEO_DEVINFO *psDevInfo;
+
+    if (!hDevice || !phBuffer)
+    {
+        return (PVRSRV_ERROR_INVALID_PARAMS);
+    }
+
+    psDevInfo = (BC_VIDEO_DEVINFO *) hDevice;
+
+    if (ui32BufferNumber < psDevInfo->sBufferInfo.ui32BufferCount)
+    {
+        psDevInfo->psSystemBuffer[ui32BufferNumber].psSyncData = psSyncData;
+        *phBuffer = (IMG_HANDLE) & psDevInfo->psSystemBuffer[ui32BufferNumber];
+    }
+    else
+    {
+        return (PVRSRV_ERROR_INVALID_PARAMS);
+    }
+
+    return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR
+GetBCInfo (IMG_HANDLE hDevice, BUFFER_INFO * psBCInfo)
+{
+    BC_VIDEO_DEVINFO *psDevInfo;
+
+    if (!hDevice || !psBCInfo)
+    {
+        return (PVRSRV_ERROR_INVALID_PARAMS);
+    }
+
+    psDevInfo = (BC_VIDEO_DEVINFO *) hDevice;
+
+    *psBCInfo = psDevInfo->sBufferInfo;
+
+    return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR
+GetBCBufferAddr (IMG_HANDLE hDevice,
+        IMG_HANDLE hBuffer,
+        IMG_SYS_PHYADDR ** ppsSysAddr,
+        IMG_UINT32 * pui32ByteSize,
+        IMG_VOID ** ppvCpuVAddr,
+        IMG_HANDLE * phOSMapInfo,
+        IMG_BOOL * pbIsContiguous, IMG_UINT32 * pui32TilingStride)
+{
+    BC_VIDEO_BUFFER *psBuffer;
+
+    UNREFERENCED_PARAMETER (pui32TilingStride);
+    if (!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize)
+    {
+        return (PVRSRV_ERROR_INVALID_PARAMS);
+    }
+
+    psBuffer = (BC_VIDEO_BUFFER *) hBuffer;
+
+    *ppvCpuVAddr = psBuffer->sCPUVAddr;
+
+    *phOSMapInfo = IMG_NULL;
+    *pui32ByteSize = (IMG_UINT32) psBuffer->ulSize;
+
+    *ppsSysAddr = psBuffer->psSysAddr;
+    *pbIsContiguous = psBuffer->is_conti_addr;
+
+    return (PVRSRV_OK);
+}
+
+
+BCE_ERROR
+BC_Video_Register (int id)
+{
+    BC_VIDEO_DEVINFO *psDevInfo;
+
+    psDevInfo = GetAnchorPtr (id);
+
+    if (psDevInfo == NULL)
+    {
+        psDevInfo =
+            (BC_VIDEO_DEVINFO *) BCAllocKernelMem (sizeof (BC_VIDEO_DEVINFO));
+
+        if (!psDevInfo)
+        {
+            return (BCE_ERROR_OUT_OF_MEMORY);
+        }
+
+        SetAnchorPtr ((void *) psDevInfo, id);
+
+        psDevInfo->ulRefCount = 0;
+
+        if (BCOpenPVRServices (&psDevInfo->hPVRServices) != BCE_OK)
+        {
+            return (BCE_ERROR_INIT_FAILURE);
+        }
+        if (BCGetLibFuncAddr
+                (psDevInfo->hPVRServices, "PVRGetBufferClassJTable",
+                 &pfnGetPVRJTable) != BCE_OK)
+        {
+            return (BCE_ERROR_INIT_FAILURE);
+        }
+
+        if (!(*pfnGetPVRJTable) (&psDevInfo->sPVRJTable))
+        {
+            return (BCE_ERROR_INIT_FAILURE);
+        }
+
+        psDevInfo->ulNumBuffers = 0;
+
+        psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN;
+        psDevInfo->sBufferInfo.ui32Width = 0;
+        psDevInfo->sBufferInfo.ui32Height = 0;
+        psDevInfo->sBufferInfo.ui32ByteStride = 0;
+        psDevInfo->sBufferInfo.ui32BufferDeviceID = id;
+        psDevInfo->sBufferInfo.ui32Flags = 0;
+        psDevInfo->sBufferInfo.ui32BufferCount =
+            (IMG_UINT32) psDevInfo->ulNumBuffers;
+
+        if (id < BC_VIDEO_DEVICE_MAX_ID)
+        {
+            strncpy (psDevInfo->sBufferInfo.szDeviceName,
+                    VBUFFERCLASS_DEVICE_NAME, MAX_BUFFER_DEVICE_NAME_SIZE);
+            psDevInfo->sBCJTable.pfnOpenBCDevice = OpenVBCDevice;
+        }
+        else if (id == BC_CAMERA_DEVICEID)
+        {
+            strncpy (psDevInfo->sBufferInfo.szDeviceName,
+                    CBUFFERCLASS_DEVICE_NAME, MAX_BUFFER_DEVICE_NAME_SIZE);
+            psDevInfo->sBCJTable.pfnOpenBCDevice = OpenCBCDevice;
+        }
+
+        psDevInfo->sBCJTable.ui32TableSize =
+            sizeof (PVRSRV_BC_SRV2BUFFER_KMJTABLE);
+        psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice;
+        psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer;
+        psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo;
+        psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr;
+
+        if (psDevInfo->sPVRJTable.
+                pfnPVRSRVRegisterBCDevice (&psDevInfo->sBCJTable,
+                    &psDevInfo->ulDeviceID) != PVRSRV_OK)
+        {
+            return (BCE_ERROR_DEVICE_REGISTER_FAILED);
+        }
+    }
+
+    psDevInfo->ulRefCount++;
+
+    return (BCE_OK);
+}
+
+BCE_ERROR
+BC_Video_Unregister (int id)
+{
+    BC_VIDEO_DEVINFO *psDevInfo;
+
+    psDevInfo = GetAnchorPtr (id);
+
+    if (psDevInfo == NULL)
+    {
+        return (BCE_ERROR_GENERIC);
+    }
+
+    psDevInfo->ulRefCount--;
+
+    if (psDevInfo->ulRefCount == 0)
+    {
+        PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable = &psDevInfo->sPVRJTable;
+
+        if (psJTable->pfnPVRSRVRemoveBCDevice (psDevInfo->ulDeviceID) !=
+                PVRSRV_OK)
+        {
+            return (BCE_ERROR_GENERIC);
+        }
+
+        if (BCClosePVRServices (psDevInfo->hPVRServices) != BCE_OK)
+        {
+            psDevInfo->hPVRServices = NULL;
+            return (BCE_ERROR_GENERIC);
+        }
+
+        if (psDevInfo->psSystemBuffer)
+        {
+            BCFreeKernelMem (psDevInfo->psSystemBuffer);
+        }
+
+        BCFreeKernelMem (psDevInfo);
+
+        SetAnchorPtr (NULL, id);
+    }
+    return (BCE_OK);
+}
+
+BCE_ERROR
+BC_Video_Init (int id)
+{
+    BCE_ERROR eError;
+
+    eError = BC_Video_Register (id);
+    if (eError != BCE_OK)
+    {
+        return eError;
+    }
+
+    return (BCE_OK);
+}
+
+BCE_ERROR
+BC_Video_Deinit (int id)
+{
+    BCE_ERROR eError;
+
+    BC_DestroyBuffers (id);
+
+    eError = BC_Video_Unregister (id);
+    if (eError != BCE_OK)
+    {
+        return eError;
+    }
+
+    return (BCE_OK);
+}
diff --git a/drivers/staging/cdv/bc_video/bufferclass_video.h b/drivers/staging/cdv/bc_video/bufferclass_video.h
new file mode 100644
index 0000000..07dd33a
--- /dev/null
+++ b/drivers/staging/cdv/bc_video/bufferclass_video.h
@@ -0,0 +1,171 @@
+/**********************************************************************
+ *
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************************/
+
+#ifndef __BC_VIDEO_H__
+#define __BC_VIDEO_H__
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kernelbuffer.h"
+#include <kernel.h>
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+    enum BC_memory
+    {
+        BC_MEMORY_MMAP = 1,
+        BC_MEMORY_USERPTR = 2,
+    };
+
+    /*
+     * the following types are tested for fourcc in struct bc_buf_params_t
+     *   NV12
+     *   UYVY
+     *   RGB565 - not tested yet
+     *   YUYV
+     */
+    typedef struct bc_buf_params
+    {
+        int count;            /*number of buffers, [in/out] */
+        int width;            /*buffer width in pixel, multiple of 8 or 32 */
+        int height;            /*buffer height in pixel */
+        int stride;
+        unsigned int fourcc;    /*buffer pixel format */
+        enum BC_memory type;
+    } bc_buf_params_t;
+
+    extern IMG_IMPORT IMG_BOOL
+        PVRGetBufferClassJTable (PVRSRV_BC_BUFFER2SRV_KMJTABLE * psJTable);
+
+#define BC_VIDEO_DEVICE_MAX_ID          5
+#define BC_CAMERA_DEVICEID              8
+
+    typedef void *BCE_HANDLE;
+
+    typedef enum tag_bce_bool
+    {
+        BCE_FALSE = 0,
+        BCE_TRUE = 1,
+    } BCE_BOOL, *BCE_PBOOL;
+
+    typedef struct BC_VIDEO_BUFFER_TAG
+    {
+        unsigned long ulSize;
+        BCE_HANDLE hMemHandle;
+
+        IMG_SYS_PHYADDR *psSysAddr;
+
+        IMG_CPU_VIRTADDR sCPUVAddr;
+        PVRSRV_SYNC_DATA *psSyncData;
+
+        struct BC_VIDEO_BUFFER_TAG *psNext;
+        int sBufferHandle;
+        IMG_BOOL is_conti_addr;
+    } BC_VIDEO_BUFFER;
+
+    typedef struct BC_VIDEO_DEVINFO_TAG
+    {
+        IMG_UINT32 ulDeviceID;
+
+        BC_VIDEO_BUFFER *psSystemBuffer;
+
+        unsigned long ulNumBuffers;
+
+        PVRSRV_BC_BUFFER2SRV_KMJTABLE sPVRJTable;
+
+        PVRSRV_BC_SRV2BUFFER_KMJTABLE sBCJTable;
+
+        BCE_HANDLE hPVRServices;
+
+        unsigned long ulRefCount;
+
+        BUFFER_INFO sBufferInfo;
+        enum BC_memory buf_type;
+    } BC_VIDEO_DEVINFO;
+
+    typedef enum _BCE_ERROR_
+    {
+        BCE_OK = 0,
+        BCE_ERROR_GENERIC = 1,
+        BCE_ERROR_OUT_OF_MEMORY = 2,
+        BCE_ERROR_TOO_FEW_BUFFERS = 3,
+        BCE_ERROR_INVALID_PARAMS = 4,
+        BCE_ERROR_INIT_FAILURE = 5,
+        BCE_ERROR_CANT_REGISTER_CALLBACK = 6,
+        BCE_ERROR_INVALID_DEVICE = 7,
+        BCE_ERROR_DEVICE_REGISTER_FAILED = 8,
+        BCE_ERROR_NO_PRIMARY = 9
+    } BCE_ERROR;
+
+#ifndef UNREFERENCED_PARAMETER
+#define    UNREFERENCED_PARAMETER(param) (param) = (param)
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+    BCE_ERROR BC_Video_Register (int id);
+    BCE_ERROR BC_Video_Unregister (int id);
+    BCE_ERROR BC_Video_Buffers_Create (int id);
+    BCE_ERROR BC_Video_Buffers_Destroy (int id);
+    BCE_ERROR BC_Video_Init (int id);
+    BCE_ERROR BC_Video_Deinit (int id);
+
+    BCE_ERROR BCOpenPVRServices (BCE_HANDLE * phPVRServices);
+    BCE_ERROR BCClosePVRServices (BCE_HANDLE hPVRServices);
+
+    void *BCAllocKernelMem (unsigned long ulSize);
+    void BCFreeKernelMem (void *pvMem);
+
+    BCE_ERROR BCAllocDiscontigMemory (unsigned long ulSize,
+            BCE_HANDLE unref__ * phMemHandle,
+            IMG_CPU_VIRTADDR * pLinAddr,
+            IMG_SYS_PHYADDR ** ppPhysAddr);
+
+    void BCFreeDiscontigMemory (unsigned long ulSize,
+            BCE_HANDLE unref__ hMemHandle,
+            IMG_CPU_VIRTADDR LinAddr,
+            IMG_SYS_PHYADDR * pPhysAddr);
+
+    IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC (IMG_CPU_PHYADDR cpu_paddr);
+    IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC (IMG_SYS_PHYADDR sys_paddr);
+
+    void *MapPhysAddr (IMG_SYS_PHYADDR sSysAddr, unsigned long ulSize);
+    void UnMapPhysAddr (void *pvAddr, unsigned long ulSize);
+
+    BCE_ERROR BCGetLibFuncAddr (BCE_HANDLE hExtDrv, char *szFunctionName,
+            PFN_BC_GET_PVRJTABLE * ppfnFuncTable);
+    BC_VIDEO_DEVINFO *GetAnchorPtr (int id);
+    int GetBufferCount (unsigned int *puiBufferCount, int id);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/drivers/staging/cdv/bc_video/bufferclass_video_linux.c b/drivers/staging/cdv/bc_video/bufferclass_video_linux.c
new file mode 100644
index 0000000..f70418a
--- /dev/null
+++ b/drivers/staging/cdv/bc_video/bufferclass_video_linux.c
@@ -0,0 +1,838 @@
+/****************************************************************************
+ *
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#if defined(LMA)
+#include <linux/pci.h>
+#else
+#include <linux/dma-mapping.h>
+#endif
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drv.h"
+#include "ttm/ttm_bo_api.h"
+#include "ttm/ttm_placement.h"
+#include "ttm/ttm_object.h"
+
+#include "bufferclass_video.h"
+#include "bufferclass_video_linux.h"
+#include "pvrmodule.h"
+#include "sys_pvr_drm_export.h"
+
+#define DEVNAME    "bc_video"
+#define    DRVNAME    DEVNAME
+
+#if defined(BCE_USE_SET_MEMORY)
+#undef BCE_USE_SET_MEMORY
+#endif
+
+#if defined(__i386__) && defined(SUPPORT_LINUX_X86_PAT) && defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+#include <asm/cacheflush.h>
+#define    BCE_USE_SET_MEMORY
+#endif
+
+#define BC_CDV_COUNT	32
+#define BC_CDV_STRIDE	2048
+#define BC_CDV_HEIGHT	2048
+#define BC_CDV_WIDTH	2048
+
+static int width_align;
+unsigned int bc_video_id_usage[BC_VIDEO_DEVICE_MAX_ID];
+
+MODULE_SUPPORTED_DEVICE (DEVNAME);
+
+int FillBuffer (unsigned int uiBufferIndex);
+
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+static struct class *psPvrClass;
+#endif
+
+static int AssignedMajorNumber;
+
+#define unref__ __attribute__ ((unused))
+
+#if defined(LMA)
+#define PVR_BUFFERCLASS_MEMOFFSET (220 * 1024 * 1024)
+#define PVR_BUFFERCLASS_MEMSIZE      (4 * 1024 * 1024)
+
+unsigned long g_ulMemBase = 0;
+unsigned long g_ulMemCurrent = 0;
+
+#define VENDOR_ID_PVR               0x1010
+#define DEVICE_ID_PVR               0x1CF1
+
+#define PVR_MEM_PCI_BASENUM         2
+#endif
+
+#define file_to_id(file)  (iminor(file->f_path.dentry->d_inode))
+
+int
+BC_Video_ModInit (void)
+{
+    int i, j;
+    /*LDM_PCI is defined, while LDM_PLATFORM and LMA are not defined.*/
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+    struct device *psDev;
+#endif
+
+#if defined(LMA)
+    struct pci_dev *psPCIDev;
+    int error;
+#endif
+
+    /* video width is 4 byte aligned */
+    width_align = 4;
+
+#if defined(LMA)
+    psPCIDev = pci_get_device (VENDOR_ID_PVR, DEVICE_ID_PVR, NULL);
+    if (psPCIDev == NULL)
+    {
+        printk (KERN_ERR DRVNAME
+                ": BC_Video_ModInit:  pci_get_device failed\n");
+        goto ExitError;
+    }
+
+    if ((error = pci_enable_device (psPCIDev)) != 0)
+    {
+        printk (KERN_ERR DRVNAME
+                ": BC_Video_ModInit: pci_enable_device failed (%d)\n", error);
+        goto ExitError;
+    }
+#endif
+
+#if defined(DEBUG)
+    printk (KERN_ERR DRVNAME ": BC_Video_ModInit: major device %d\n",
+            AssignedMajorNumber);
+#endif
+
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+    psPvrClass = class_create (THIS_MODULE, "bc_video");
+    if (IS_ERR (psPvrClass))
+    {
+        printk (KERN_ERR DRVNAME
+                ": BC_Video_ModInit: unable to create class (%ld)",
+                PTR_ERR (psPvrClass));
+        goto ExitUnregister;
+    }
+
+    psDev = device_create (psPvrClass, NULL, MKDEV (AssignedMajorNumber, 0),
+		    	   NULL,
+			   DEVNAME);
+    if (IS_ERR (psDev))
+    {
+        printk (KERN_ERR DRVNAME
+                ": BC_Video_ModInit: unable to create device (%ld)",
+                PTR_ERR (psDev));
+        goto ExitDestroyClass;
+    }
+#endif
+
+#if defined(LMA)
+    g_ulMemBase =
+        pci_resource_start (psPCIDev,
+                PVR_MEM_PCI_BASENUM) + PVR_BUFFERCLASS_MEMOFFSET;
+#endif
+
+    for (i = 0; i < BC_VIDEO_DEVICE_MAX_ID; i++)
+    {
+        bc_video_id_usage[i] = 0;
+        if (BC_Video_Init (i) != BCE_OK)
+        {
+            printk (KERN_ERR DRVNAME
+                    ": BC_Video_ModInit: can't init video bc device %d.\n", i);
+            for (j = i; j >= 0; j--)
+            {
+                BC_Video_Deinit (j);
+            }
+            goto ExitUnregister;
+        }
+    }
+
+#if defined(LMA)
+    pci_disable_device (psPCIDev);
+#endif
+
+    return 0;
+
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ExitDestroyClass:
+    class_destroy (psPvrClass);
+#endif
+ExitUnregister:
+    unregister_chrdev (AssignedMajorNumber, DEVNAME);
+    //ExitDisable:
+#if defined(LMA)
+    pci_disable_device (psPCIDev);
+ExitError:
+#endif
+    return -EBUSY;
+}
+
+int
+BC_Video_ModCleanup (void)
+{
+    int i;
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+    device_destroy (psPvrClass, MKDEV (AssignedMajorNumber, 0));
+    class_destroy (psPvrClass);
+#endif
+
+    for (i = 0; i < BC_VIDEO_DEVICE_MAX_ID; i++)
+    {
+        if (BC_Video_Deinit (i) != BCE_OK)
+        {
+            printk (KERN_ERR DRVNAME
+                    ": BC_Video_ModCleanup: can't deinit video device %d.\n",
+                    i);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+    void *
+BCAllocKernelMem (unsigned long ulSize)
+{
+    return kmalloc (ulSize, GFP_KERNEL);
+}
+
+void
+BCFreeKernelMem (void *pvMem)
+{
+    kfree (pvMem);
+}
+
+#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
+#define    VMALLOC_TO_PAGE_PHYS(vAddr) page_to_phys(vmalloc_to_page(vAddr))
+
+BCE_ERROR
+BCAllocDiscontigMemory (unsigned long ulSize,
+        BCE_HANDLE unref__ * phMemHandle,
+        IMG_CPU_VIRTADDR * pLinAddr,
+        IMG_SYS_PHYADDR ** ppPhysAddr)
+{
+    unsigned long ulPages = RANGE_TO_PAGES (ulSize);
+    IMG_SYS_PHYADDR *pPhysAddr;
+    unsigned long ulPage;
+    IMG_CPU_VIRTADDR LinAddr;
+
+    LinAddr =
+        __vmalloc (ulSize, GFP_KERNEL | __GFP_HIGHMEM,
+                pgprot_noncached (PAGE_KERNEL));
+    if (!LinAddr)
+    {
+        return BCE_ERROR_OUT_OF_MEMORY;
+    }
+
+    pPhysAddr = kmalloc (ulPages * sizeof (IMG_SYS_PHYADDR), GFP_KERNEL);
+    if (!pPhysAddr)
+    {
+        vfree (LinAddr);
+        return BCE_ERROR_OUT_OF_MEMORY;
+    }
+
+    *pLinAddr = LinAddr;
+
+    for (ulPage = 0; ulPage < ulPages; ulPage++)
+    {
+        pPhysAddr[ulPage].uiAddr = VMALLOC_TO_PAGE_PHYS (LinAddr);
+
+        LinAddr += PAGE_SIZE;
+    }
+
+    *ppPhysAddr = pPhysAddr;
+
+    return BCE_OK;
+}
+
+void
+BCFreeDiscontigMemory (unsigned long ulSize,
+        BCE_HANDLE unref__ hMemHandle,
+        IMG_CPU_VIRTADDR LinAddr, IMG_SYS_PHYADDR * pPhysAddr)
+{
+    kfree (pPhysAddr);
+
+    vfree (LinAddr);
+}
+
+    BCE_ERROR
+BCAllocContigMemory (unsigned long ulSize,
+        BCE_HANDLE unref__ * phMemHandle,
+        IMG_CPU_VIRTADDR * pLinAddr, IMG_CPU_PHYADDR * pPhysAddr)
+{
+#if defined(LMA)
+    void *pvLinAddr;
+
+
+    if (g_ulMemCurrent + ulSize >= PVR_BUFFERCLASS_MEMSIZE)
+    {
+        return (BCE_ERROR_OUT_OF_MEMORY);
+    }
+
+    pvLinAddr = ioremap (g_ulMemBase + g_ulMemCurrent, ulSize);
+
+    if (pvLinAddr)
+    {
+        pPhysAddr->uiAddr = g_ulMemBase + g_ulMemCurrent;
+        *pLinAddr = pvLinAddr;
+
+        g_ulMemCurrent += ulSize;
+        return (BCE_OK);
+    }
+    return (BCE_ERROR_OUT_OF_MEMORY);
+#else
+#if defined(BCE_USE_SET_MEMORY)
+    void *pvLinAddr;
+    unsigned long ulAlignedSize = PAGE_ALIGN (ulSize);
+    int iPages = (int) (ulAlignedSize >> PAGE_SHIFT);
+    int iError;
+
+    pvLinAddr = kmalloc (ulAlignedSize, GFP_KERNEL);
+	if (pvLinAddr == NULL)
+		return BCE_ERROR_OUT_OF_MEMORY;
+
+    BUG_ON (((unsigned long) pvLinAddr) & ~PAGE_MASK);
+
+    iError = set_memory_wc ((unsigned long) pvLinAddr, iPages);
+    if (iError != 0)
+    {
+        printk (KERN_ERR DRVNAME
+                ": BCAllocContigMemory:  set_memory_wc failed (%d)\n", iError);
+	kfree(pvLinAddr);
+        return (BCE_ERROR_OUT_OF_MEMORY);
+    }
+
+    pPhysAddr->uiAddr = virt_to_phys (pvLinAddr);
+    *pLinAddr = pvLinAddr;
+
+    return (BCE_OK);
+#else
+    dma_addr_t dma;
+    void *pvLinAddr;
+
+    pvLinAddr = dma_alloc_coherent (NULL, ulSize, &dma, GFP_KERNEL);
+    if (pvLinAddr == NULL)
+    {
+        return (BCE_ERROR_OUT_OF_MEMORY);
+    }
+
+    pPhysAddr->uiAddr = dma;
+    *pLinAddr = pvLinAddr;
+
+    return (BCE_OK);
+#endif
+#endif
+}
+
+void
+BCFreeContigMemory (unsigned long ulSize,
+        BCE_HANDLE unref__ hMemHandle,
+        IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr)
+{
+#if defined(LMA)
+    g_ulMemCurrent -= ulSize;
+    iounmap (LinAddr);
+#else
+#if defined(BCE_USE_SET_MEMORY)
+    unsigned long ulAlignedSize = PAGE_ALIGN (ulSize);
+    int iError;
+    int iPages = (int) (ulAlignedSize >> PAGE_SHIFT);
+
+    iError = set_memory_wb ((unsigned long) LinAddr, iPages);
+    if (iError != 0)
+    {
+        printk (KERN_ERR DRVNAME
+                ": BCFreeContigMemory:  set_memory_wb failed (%d)\n", iError);
+    }
+    kfree (LinAddr);
+#else
+    dma_free_coherent (NULL, ulSize, LinAddr, (dma_addr_t) PhysAddr.uiAddr);
+#endif
+#endif
+}
+
+    IMG_SYS_PHYADDR
+CpuPAddrToSysPAddrBC (IMG_CPU_PHYADDR cpu_paddr)
+{
+    IMG_SYS_PHYADDR sys_paddr;
+    sys_paddr.uiAddr = cpu_paddr.uiAddr;
+    return sys_paddr;
+}
+
+    IMG_CPU_PHYADDR
+SysPAddrToCpuPAddrBC (IMG_SYS_PHYADDR sys_paddr)
+{
+    IMG_CPU_PHYADDR cpu_paddr;
+    cpu_paddr.uiAddr = sys_paddr.uiAddr;
+    return cpu_paddr;
+}
+
+BCE_ERROR
+BCOpenPVRServices (BCE_HANDLE * phPVRServices)
+{
+    *phPVRServices = 0;
+    return (BCE_OK);
+}
+
+
+BCE_ERROR
+BCClosePVRServices (BCE_HANDLE unref__ hPVRServices)
+{
+    return (BCE_OK);
+}
+
+BCE_ERROR
+BCGetLibFuncAddr (BCE_HANDLE unref__ hExtDrv, char *szFunctionName,
+        PFN_BC_GET_PVRJTABLE * ppfnFuncTable)
+{
+    if (strcmp ("PVRGetBufferClassJTable", szFunctionName) != 0)
+    {
+        return (BCE_ERROR_INVALID_PARAMS);
+    }
+
+    *ppfnFuncTable = PVRGetBufferClassJTable;
+
+    return (BCE_OK);
+}
+
+int
+BC_CreateBuffers (int id, bc_buf_params_t * p, IMG_BOOL is_conti_addr)
+{
+    BC_VIDEO_DEVINFO *psDevInfo;
+    IMG_UINT32 i, stride, size;
+    PVRSRV_PIXEL_FORMAT pixel_fmt;
+
+    if (p->count <= 0 || p->count > BC_CDV_COUNT)
+        return -EINVAL;
+
+    if (p->width <= 1 || p->width % width_align || p->height <= 1)
+        return -EINVAL;
+
+	if ((p->width > BC_CDV_WIDTH) || (p->height > BC_CDV_HEIGHT) ||
+		(p->stride > BC_CDV_STRIDE) || (p->stride < 32))
+		return -EINVAL; 
+
+    switch (p->fourcc)
+    {
+        case BC_PIX_FMT_NV12:
+            pixel_fmt = PVRSRV_PIXEL_FORMAT_NV12;
+            break;
+        case BC_PIX_FMT_UYVY:
+            pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY;
+            break;
+        case BC_PIX_FMT_RGB565:
+            pixel_fmt = PVRSRV_PIXEL_FORMAT_RGB565;
+            p->stride = p->stride << 1;    /* stride for RGB from user space is uncorrect */
+            break;
+        case BC_PIX_FMT_YUYV:
+            pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV;
+            break;
+        default:
+            return -EINVAL;
+            break;
+    }
+
+    stride = p->stride;
+
+    if (p->type != BC_MEMORY_MMAP && p->type != BC_MEMORY_USERPTR)
+        return -EINVAL;
+
+    if ((psDevInfo = GetAnchorPtr (id)) == IMG_NULL)
+        return -ENODEV;
+
+    if (psDevInfo->ulNumBuffers)
+        BC_DestroyBuffers (id);
+
+    psDevInfo->buf_type = p->type;
+    psDevInfo->psSystemBuffer =
+        BCAllocKernelMem (sizeof (BC_VIDEO_BUFFER) * p->count);
+
+    if (!psDevInfo->psSystemBuffer)
+        return -ENOMEM;
+
+    memset (psDevInfo->psSystemBuffer, 0, sizeof (BC_VIDEO_BUFFER) * p->count);
+    size = p->height * stride;
+    if (pixel_fmt == PVRSRV_PIXEL_FORMAT_NV12)
+        size += (stride >> 1) * (p->height >> 1) << 1;
+
+    for (i = 0; i < p->count; i++)
+    {
+        IMG_SYS_PHYADDR *pPhysAddr;
+        if (is_conti_addr)
+        {
+            pPhysAddr = BCAllocKernelMem (1 * sizeof (IMG_SYS_PHYADDR));
+            if (!pPhysAddr)
+            {
+                goto out_of_memory;
+            }
+            memset (pPhysAddr, 0, 1 * sizeof (IMG_SYS_PHYADDR));
+        }
+        else
+        {
+            unsigned long ulPages = RANGE_TO_PAGES (size);
+            pPhysAddr = BCAllocKernelMem (ulPages * sizeof (IMG_SYS_PHYADDR));
+            if (!pPhysAddr)
+            {
+                goto out_of_memory;
+            }
+            memset (pPhysAddr, 0, ulPages * sizeof (IMG_SYS_PHYADDR));
+        }
+        psDevInfo->psSystemBuffer[i].psSysAddr = pPhysAddr;
+	/*
+	 * Only after the memory is allocated successfully, try to modify
+	 * the psDevInfo->psSystemBuffer and update the number of
+	 * allocated buffers.
+	 */
+	psDevInfo->ulNumBuffers++;
+	psDevInfo->psSystemBuffer[i].ulSize = size;
+	psDevInfo->psSystemBuffer[i].psSyncData = IMG_NULL;
+
+	/*for discontig buffers, allocate memory for pPhysAddr */
+	psDevInfo->psSystemBuffer[i].is_conti_addr = is_conti_addr;
+    }
+    p->count = psDevInfo->ulNumBuffers;
+
+    psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ulNumBuffers;
+    psDevInfo->sBufferInfo.pixelformat = pixel_fmt;
+    psDevInfo->sBufferInfo.ui32Width = p->width;
+    psDevInfo->sBufferInfo.ui32Height = p->height;
+    psDevInfo->sBufferInfo.ui32ByteStride = stride;
+    psDevInfo->sBufferInfo.ui32BufferDeviceID = id;
+    psDevInfo->sBufferInfo.ui32Flags = PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE |
+        PVRSRV_BC_FLAGS_YUVCSC_BT601;
+    return 0;
+
+out_of_memory:
+        BC_DestroyBuffers (id);
+	return -ENOMEM;
+}
+
+int
+BC_DestroyBuffers (int id)
+{
+    BC_VIDEO_DEVINFO *psDevInfo;
+    IMG_UINT32 i;
+    if ((psDevInfo = GetAnchorPtr (id)) == IMG_NULL)
+        return -ENODEV;
+
+    if (!psDevInfo->ulNumBuffers)
+        return 0;
+
+    for (i = 0; i < psDevInfo->ulNumBuffers; i++) {
+	vfree(psDevInfo->psSystemBuffer[i].sCPUVAddr);
+        BCFreeKernelMem (psDevInfo->psSystemBuffer[i].psSysAddr);
+	psDevInfo->psSystemBuffer[i].psSysAddr = NULL;
+    }
+
+    BCFreeKernelMem (psDevInfo->psSystemBuffer);
+
+	psDevInfo->psSystemBuffer = NULL;
+    psDevInfo->ulNumBuffers = 0;
+    psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN;
+    psDevInfo->sBufferInfo.ui32Width = 0;
+    psDevInfo->sBufferInfo.ui32Height = 0;
+    psDevInfo->sBufferInfo.ui32ByteStride = 0;
+    psDevInfo->sBufferInfo.ui32BufferDeviceID = id;
+    psDevInfo->sBufferInfo.ui32Flags = 0;
+    psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ulNumBuffers;
+
+    return 0;
+}
+
+int
+GetBufferCount (unsigned int *puiBufferCount, int id)
+{
+    BC_VIDEO_DEVINFO *psDevInfo = GetAnchorPtr (id);
+
+    if (psDevInfo == IMG_NULL)
+    {
+        return -1;
+    }
+
+    *puiBufferCount = (unsigned int) psDevInfo->sBufferInfo.ui32BufferCount;
+
+    return 0;
+}
+
+int
+BC_Video_Bridge (struct drm_device *dev, IMG_VOID * arg,
+        struct drm_file *file_priv)
+{
+    int err = -EFAULT;
+
+    BC_VIDEO_DEVINFO *devinfo;
+    int i;
+    BC_Video_ioctl_package *psBridge = (BC_Video_ioctl_package *) arg;
+    int command = psBridge->ioctl_cmd;
+    int id = 0;
+	/*
+	 * It is noted that the command of "request_buffer" should be the
+	 * first request. Otherwise it will fail in the other BC_request.
+	 */ 
+    if (command == BC_Video_ioctl_request_buffers)
+    {
+        for (i = 0; i < BC_VIDEO_DEVICE_MAX_ID; i++)
+        {
+            if (bc_video_id_usage[i] == 0)
+            {
+                id = i;
+                break;
+            }
+        }
+        if (i == BC_VIDEO_DEVICE_MAX_ID)
+        {
+            printk (KERN_ERR DRVNAME
+                    " : Does you really need to run more than 5 video simulateously.\n");
+            return -1;
+        } else
+            psb_fpriv(file_priv)->bcd_index = id;
+    }
+    else {
+        id = psBridge->device_id;
+	if ((id >= BC_VIDEO_DEVICE_MAX_ID) || id < 0 ||
+		!bc_video_id_usage[id]) {
+		printk (KERN_ERR DRVNAME
+			" : Invalid device ID\n");
+		return -EINVAL;
+	}
+    }
+    if ((devinfo = GetAnchorPtr (id)) == IMG_NULL)
+        return -ENODEV;
+
+    switch (command)
+    {
+        case BC_Video_ioctl_get_buffer_count:
+            {
+                if (GetBufferCount (&psBridge->outputparam, id) == -1)
+                {
+                    printk (KERN_ERR DRVNAME
+                            " : GetBufferCount error in BC_Video_Bridge.\n");
+                    return err;
+                }
+                return 0;
+                break;
+            }
+        case BC_Video_ioctl_get_buffer_index:
+            {
+                int idx;
+                BC_VIDEO_BUFFER *buffer;
+
+                for (idx = 0; idx < devinfo->ulNumBuffers; idx++)
+                {
+                    buffer = &devinfo->psSystemBuffer[idx];
+
+                    if (psBridge->inputparam == buffer->sBufferHandle)
+                    {
+                        psBridge->outputparam = idx;
+                        return 0;
+                    }
+                }
+                printk (KERN_ERR DRVNAME ": BCIOGET_BUFFERIDX- buffer not found\n");
+                return -EINVAL;
+                break;
+            }
+        case BC_Video_ioctl_request_buffers:
+            {
+                bc_buf_params_t p;
+		int ret;
+                if (copy_from_user
+                        (&p, (void __user *) (psBridge->inputparam), sizeof (p)))
+                    return -EFAULT;
+
+                ret = BC_CreateBuffers (id, &p, IMG_FALSE);
+		if (ret) {
+			printk (KERN_ERR " : Failure in BC_buffer requests.\n");
+			return ret;
+		}
+                bc_video_id_usage[id] = 1;
+                psBridge->outputparam = id;
+                break;
+            }
+        case BC_Video_ioctl_set_buffer_phyaddr:
+            {
+                bc_buf_ptr_t p;
+                struct ttm_buffer_object *bo = NULL;
+                struct ttm_tt *ttm = NULL;
+                struct ttm_object_file *tfile = psb_fpriv (file_priv)->tfile;
+
+                if (copy_from_user
+                        (&p, (void __user *) (psBridge->inputparam), sizeof (p)))
+                    return -EFAULT;
+
+                if (p.index >= devinfo->ulNumBuffers || !p.handle)
+                {
+                    printk (KERN_ERR DRVNAME
+                            " : index big than NumBuffers or p.handle is NULL.\n");
+                    return -EINVAL;
+                }
+
+                bo = ttm_buffer_object_lookup (tfile, p.handle);
+                if (unlikely (bo == NULL))
+                {
+                    printk (KERN_ERR DRVNAME
+                            " : Could not find buffer object for setstatus.\n");
+                    return -EINVAL;
+                }
+                ttm = bo->ttm;
+
+                devinfo->psSystemBuffer[p.index].sCPUVAddr = NULL;
+                devinfo->psSystemBuffer[p.index].sBufferHandle = p.handle;
+                for (i = 0; i < ttm->num_pages; i++)
+                {
+                    if (ttm->pages[i] == NULL)
+                    {
+                        printk (KERN_ERR " : Debug: the page is NULL.\n");
+			ttm_bo_unref(&bo);
+                        return -EINVAL;
+                    }
+                    devinfo->psSystemBuffer[p.index].psSysAddr[i].uiAddr =
+                        page_to_pfn (ttm->pages[i]) << PAGE_SHIFT;
+                }
+                if (bo)
+                    ttm_bo_unref (&bo);
+                return 0;
+                break;
+            }
+        case BC_Video_ioctl_release_buffer_device:
+            {
+                bc_video_id_usage[id] = 0;
+
+                BC_DestroyBuffers (id);
+                return 0;
+                break;
+            }
+        case BC_Video_ioctl_alloc_buffer:
+            {
+                bc_buf_ptr_t p;
+                IMG_VOID *pvBuf;
+                IMG_UINT32 ui32Size;
+                IMG_UINT32 ulCounter;
+                BUFFER_INFO *bufferInfo;
+
+                if (copy_from_user
+                        (&p, (void __user *) (psBridge->inputparam), sizeof (p)))
+                    return -EFAULT;
+
+                if (p.index >= devinfo->ulNumBuffers)
+                {
+                    printk (KERN_ERR DRVNAME " : index big than NumBuffers.\n");
+                    return -EINVAL;
+                }
+
+                bufferInfo = &(devinfo->sBufferInfo);
+                if (bufferInfo->pixelformat != PVRSRV_PIXEL_FORMAT_NV12)
+                {
+                    printk (KERN_ERR DRVNAME
+                            " : BC_Video_ioctl_alloc_buffer only support NV12 format.\n");
+                    return -EINVAL;
+                }
+		if (devinfo->psSystemBuffer[p.index].sCPUVAddr) {
+			printk(KERN_ERR DRVNAME
+				" : Try to allow memory twice for one slot.\n");
+			return -EFAULT;
+		}
+		ui32Size = bufferInfo->ui32Height * bufferInfo->ui32ByteStride;
+                ui32Size +=
+                    (bufferInfo->ui32ByteStride >> 1) *
+                    (bufferInfo->ui32Height >> 1) << 1;
+
+                pvBuf =
+                    __vmalloc (ui32Size, GFP_KERNEL | __GFP_HIGHMEM,
+                            __pgprot ((pgprot_val (PAGE_KERNEL) & ~_PAGE_CACHE_MASK)
+                                | _PAGE_CACHE_WC));
+                if (pvBuf == NULL)
+                {
+                    printk (KERN_ERR DRVNAME
+                            " : Failed to allocate %d bytes buffer.\n", ui32Size);
+                    return -EINVAL;
+                }
+                devinfo->psSystemBuffer[p.index].sCPUVAddr = pvBuf;
+                devinfo->psSystemBuffer[p.index].sBufferHandle = 0;
+
+                i = 0;
+
+                for (ulCounter = 0; ulCounter < ui32Size; ulCounter += PAGE_SIZE)
+                {
+                    devinfo->psSystemBuffer[p.index].psSysAddr[i++].uiAddr =
+                        vmalloc_to_pfn (pvBuf + ulCounter) << PAGE_SHIFT;
+                }
+
+                if (p.handle)
+                {
+                    printk (KERN_ERR DRVNAME
+                            " : fill data %d bytes from user space 0x%x.\n", ui32Size,
+                            (int) p.handle);
+                    if (copy_from_user (pvBuf, (void __user *) p.handle, ui32Size)) {
+                	devinfo->psSystemBuffer[p.index].sCPUVAddr = NULL;
+			vfree(pvBuf);
+                        return -EFAULT;
+		      }
+                }
+                psBridge->outputparam = (int) pvBuf;
+
+                return 0;
+                break;
+            }
+        case BC_Video_ioctl_free_buffer:
+            {
+                bc_buf_ptr_t p;
+
+                if (copy_from_user
+                        (&p, (void __user *) (psBridge->inputparam), sizeof (p)))
+                {
+                    return -EFAULT;
+                }
+                if (p.index >= devinfo->ulNumBuffers)
+                {
+                    printk (KERN_ERR " : index big than NumBuffers.\n");
+                    return -EINVAL;
+                }
+
+		if (devinfo->psSystemBuffer[p.index].sCPUVAddr) {
+			vfree(devinfo->psSystemBuffer[p.index].sCPUVAddr);
+			devinfo->psSystemBuffer[p.index].sCPUVAddr = NULL;
+		} else {
+			printk(KERN_ERR DRVNAME
+				" : Try to free the invalid memory.\n");
+			return -EFAULT;
+		}
+                return 0;
+                break;
+            }
+        default:
+            return err;
+    }
+
+    return 0;
+}
+
diff --git a/drivers/staging/cdv/bc_video/bufferclass_video_linux.h b/drivers/staging/cdv/bc_video/bufferclass_video_linux.h
new file mode 100644
index 0000000..529257a
--- /dev/null
+++ b/drivers/staging/cdv/bc_video/bufferclass_video_linux.h
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ *
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************************/
+
+#ifndef __BC_VIDEO_LINUX_H__
+#define __BC_VIDEO_LINUX_H__
+
+#include <linux/ioctl.h>
+
+#define BC_FOURCC(a,b,c,d) \
+    ((unsigned long) ((a) | (b)<<8 | (c)<<16 | (d)<<24))
+
+#define BC_PIX_FMT_NV12     BC_FOURCC('N', 'V', '1', '2')    /*YUV 4:2:0 */
+#define BC_PIX_FMT_UYVY     BC_FOURCC('U', 'Y', 'V', 'Y')    /*YUV 4:2:2 */
+#define BC_PIX_FMT_YUYV     BC_FOURCC('Y', 'U', 'Y', 'V')    /*YUV 4:2:2 */
+#define BC_PIX_FMT_RGB565   BC_FOURCC('R', 'G', 'B', 'P')    /*RGB 5:6:5 */
+
+typedef struct BC_Video_ioctl_package_TAG
+{
+    int ioctl_cmd;
+    int device_id;
+    int inputparam;
+    int outputparam;
+} BC_Video_ioctl_package;
+
+typedef struct bc_buf_ptr
+{
+    unsigned int index;
+    int size;
+    unsigned long pa;
+    unsigned long handle;
+} bc_buf_ptr_t;
+
+#define BC_Video_ioctl_fill_buffer              0
+#define BC_Video_ioctl_get_buffer_count         1
+#define BC_Video_ioctl_get_buffer_phyaddr       2    /*get physical address by index */
+#define BC_Video_ioctl_get_buffer_index         3    /*get index by physical address */
+#define BC_Video_ioctl_request_buffers          4
+#define BC_Video_ioctl_set_buffer_phyaddr       5
+#define BC_Video_ioctl_release_buffer_device    6
+
+#define BC_Video_ioctl_alloc_buffer             7
+#define BC_Video_ioctl_free_buffer              8
+
+int BC_DestroyBuffers (int id);
+#endif
diff --git a/drivers/staging/cdv/drv/psb_bl.c b/drivers/staging/cdv/drv/psb_bl.c
new file mode 100644
index 0000000..e2f548f
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_bl.c
@@ -0,0 +1,135 @@
+/*
+ *  psb backlight using HAL
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ * Authors: Eric Knopp
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/version.h>
+#include "psb_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_bios.h"
+#include "psb_powermgmt.h"
+
+#define MRST_BLC_MAX_PWM_REG_FREQ	    0xFFFF
+#define BLC_PWM_PRECISION_FACTOR 100	/* 10000000 */
+#define BLC_PWM_FREQ_CALC_CONSTANT 32
+#define MHz 1000000
+#define BRIGHTNESS_MIN_LEVEL 1
+#define BRIGHTNESS_MAX_LEVEL 100
+#define BRIGHTNESS_MASK	0xFF
+#define BLC_POLARITY_NORMAL 0
+#define BLC_POLARITY_INVERSE 1
+#define BLC_ADJUSTMENT_MAX 100
+
+#define PSB_BLC_PWM_PRECISION_FACTOR    10
+#define PSB_BLC_MAX_PWM_REG_FREQ        0xFFFE
+#define PSB_BLC_MIN_PWM_REG_FREQ        0x2
+
+#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
+#define PSB_BACKLIGHT_PWM_CTL_SHIFT	(16)
+
+static struct backlight_device *psb_backlight_device;
+u8 blc_pol;
+u8 blc_type;
+
+
+int psb_set_brightness(struct backlight_device *bd)
+{
+	struct drm_device *dev = (struct drm_device *)bl_get_data(psb_backlight_device);
+	int level = bd->props.brightness;
+
+	DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
+
+	if (level > bd->props.max_brightness)
+		level = bd->props.max_brightness;
+
+	psb_intel_panel_set_backlight(dev, level);
+
+	return 0;
+}
+
+int psb_get_brightness(struct backlight_device *bd)
+{
+	struct drm_device *dev = (struct drm_device *)bl_get_data(psb_backlight_device);
+
+	/* return locally cached var instead of HW read (due to DPST etc.) */
+	return psb_intel_panel_get_backlight(dev);
+}
+
+struct backlight_ops psb_ops = {
+	.get_brightness = psb_get_brightness,
+	.update_status  = psb_set_brightness,
+};
+
+static int device_backlight_init(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private;
+
+	if (IS_CDV(dev)) {
+		dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
+		dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
+		return 0;
+	}
+
+	return 0;
+}
+
+int psb_backlight_init(struct drm_device *dev)
+{
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+	int ret = 0;
+	struct backlight_properties props;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = psb_intel_panel_get_max_backlight(dev);
+	props.type = BACKLIGHT_RAW;
+
+	psb_backlight_device = backlight_device_register("psb-bl", NULL, (void *)dev, &psb_ops, &props);
+	if (IS_ERR(psb_backlight_device))
+		return PTR_ERR(psb_backlight_device);
+
+	if ((ret = device_backlight_init(dev)) != 0)
+		return ret;
+
+	psb_backlight_device->props.brightness = psb_intel_panel_get_backlight(dev);
+	psb_backlight_device->props.max_brightness = props.max_brightness;
+	backlight_update_status(psb_backlight_device);
+#endif
+	return 0;
+}
+
+void psb_backlight_exit(void)
+{
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+	psb_backlight_device->props.brightness = 0;
+	backlight_update_status(psb_backlight_device);
+	backlight_device_unregister(psb_backlight_device);
+#endif
+	return;
+}
+
+struct backlight_device * psb_get_backlight_device(void)
+{
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+	return psb_backlight_device;
+#endif
+	return NULL;
+}
diff --git a/drivers/staging/cdv/drv/psb_dpst.c b/drivers/staging/cdv/drv/psb_dpst.c
new file mode 100644
index 0000000..eb940af
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_dpst.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *    James C. Gualario <james.c.gualario@intel.com>
+ *
+ */
+
+#include "psb_umevents.h"
+#include "psb_dpst.h"
+/**
+ * inform the kernel of the work to be performed and related function.
+ *
+ */
+DECLARE_WORK(dpst_dev_change_work, &psb_dpst_dev_change_wq);
+/**
+ * psb_dpst_notify_change_um - notify user mode of hotplug changes
+ *
+ * @name: name of event to notify user mode of change to
+ * @state: dpst state struct to get workqueue from
+ *
+ */
+int psb_dpst_notify_change_um(enum dpst_event_enum event,
+			      struct dpst_state *state)
+{
+	if (state == NULL)
+		return IRQ_HANDLED;
+
+	state->dpst_change_wq_data.dev_name_arry_rw_status
+		[state->dpst_change_wq_data.dev_name_write] =
+		DRM_DPST_READY_TO_READ;
+	state->dpst_change_wq_data.dpst_events
+		[state->dpst_change_wq_data.dev_name_write] =
+		event;
+	if (state->dpst_change_wq_data.dev_name_read_write_wrap_ack == 1)
+		state->dpst_change_wq_data.dev_name_read_write_wrap_ack = 0;
+	state->dpst_change_wq_data.dev_name_write++;
+	if (state->dpst_change_wq_data.dev_name_write ==
+	   state->dpst_change_wq_data.dev_name_read) {
+		state->dpst_change_wq_data.dev_name_write--;
+		return IRQ_NONE;
+	}
+	if (state->dpst_change_wq_data.dev_name_write >
+	   DRM_DPST_RING_DEPTH_MAX) {
+		state->dpst_change_wq_data.dev_name_write = 0;
+		state->dpst_change_wq_data.dev_name_write_wrap = 1;
+	}
+	state->dpst_change_wq_data.hotplug_dev_list = state->list;
+	queue_work(state->dpst_wq, &(state->dpst_change_wq_data.work));
+	return IRQ_HANDLED;
+}
+/*EXPORT_SYMBOL(psb_dpst_notify_change_um); */
+/**
+ *
+ * psb_dpst_create_and_notify_um - create and notify user mode of new dev
+ *
+ * @name: name to give for new event / device
+ * @state: dpst state instaces to associate event with
+ *
+ */
+struct umevent_obj *psb_dpst_create_and_notify_um(const char *name,
+						  struct dpst_state *state)
+{
+	return psb_create_umevent_obj(name, state->list);
+
+}
+/*EXPORT_SYMBOL(psb_dpst_create_and_notify_um); */
+/**
+ * psb_dpst_device_pool_create_and_init - make new hotplug device pool
+ *
+ * @parent_kobj - parent kobject to associate dpst kset with
+ * @state - dpst state instance to associate list with
+ *
+ */
+struct umevent_list *psb_dpst_device_pool_create_and_init(
+						  struct kobject *parent_kobj,
+						  struct dpst_state *state)
+{
+	struct umevent_list *new_hotplug_dev_list = NULL;
+	new_hotplug_dev_list = psb_umevent_create_list();
+	if (new_hotplug_dev_list)
+		psb_umevent_init(parent_kobj, new_hotplug_dev_list,
+				 "psb_dpst");
+
+	state->dpst_wq = create_singlethread_workqueue("dpst-wq");
+
+	if (!state->dpst_wq)
+		return NULL;
+
+	INIT_WORK(&state->dpst_change_wq_data.work, psb_dpst_dev_change_wq);
+
+	state->dpst_change_wq_data.dev_name_read = 0;
+	state->dpst_change_wq_data.dev_name_write = 0;
+	state->dpst_change_wq_data.dev_name_write_wrap = 0;
+	state->dpst_change_wq_data.dev_name_read_write_wrap_ack = 0;
+
+	memset(&(state->dpst_change_wq_data.dev_name_arry_rw_status[0]),
+	       0, sizeof(int)*DRM_DPST_RING_DEPTH);
+
+	return new_hotplug_dev_list;
+}
+/*EXPORT_SYMBOL(psb_dpst_device_pool_create_and_init);  */
+/**
+ * psb_dpst_init - init dpst subsystem
+ * @parent_kobj - parent kobject to associate dpst state with
+ *
+ */
+struct dpst_state *psb_dpst_init(struct kobject *parent_kobj)
+{
+	struct dpst_state *state;
+	struct umevent_obj *working_umevent;
+
+	state = kzalloc(sizeof(struct dpst_state), GFP_KERNEL);
+	if (state == NULL) {
+		DRM_ERROR("Failure in memory allocation\n");
+		return NULL;
+	}
+	state->list = NULL;
+	state->list = psb_dpst_device_pool_create_and_init(
+						  parent_kobj,
+						  state);
+	if (state->list == NULL) {
+		DRM_ERROR("Failure in memory allocation\n");
+		kfree(state);
+		return NULL;
+	}
+	working_umevent  =
+		psb_dpst_create_and_notify_um("init",
+					   state);
+	if (working_umevent == NULL) {
+		DRM_ERROR("Out of Memory\n");
+		goto failed_umevent;
+	}
+	state->dpst_change_wq_data.dev_umevent_arry
+		[DPST_EVENT_INIT_COMPLETE] = &(working_umevent->head);
+
+	working_umevent  =
+		psb_dpst_create_and_notify_um("hist_int",
+					   state);
+	if (working_umevent == NULL) {
+		DRM_ERROR("Out of Memory\n");
+		goto failed_umevent;
+	}
+	state->dpst_change_wq_data.dev_umevent_arry
+		[DPST_EVENT_HIST_INTERRUPT] = &(working_umevent->head);
+
+	working_umevent  =
+		psb_dpst_create_and_notify_um("term",
+					   state);
+	if (working_umevent == NULL) {
+		DRM_ERROR("Out of Memory\n");
+		goto failed_umevent;
+	}
+	state->dpst_change_wq_data.dev_umevent_arry
+		[DPST_EVENT_TERMINATE] = &(working_umevent->head);
+
+	working_umevent  =
+		psb_dpst_create_and_notify_um("phase_done",
+						   state);
+
+	if (working_umevent == NULL) {
+		DRM_ERROR("Out of Memory\n");
+		goto failed_umevent;
+	}
+	state->dpst_change_wq_data.dev_umevent_arry
+		[DPST_EVENT_PHASE_COMPLETE] = &(working_umevent->head);
+
+	return state;
+
+failed_umevent:
+	psb_dpst_device_pool_destroy(state);
+	return NULL;
+}
+/*EXPORT_SYMBOL(psb_dpst_init); */
+/**
+ * psb_dpst_device_pool_destroy - destroy all dpst related resources
+ *
+ * @state: dpst state instance to destroy
+ *
+ */
+void psb_dpst_device_pool_destroy(struct dpst_state *state)
+{
+	int i;
+	struct umevent_list *list;
+
+	list = state->list;
+	flush_workqueue(state->dpst_wq);
+	destroy_workqueue(state->dpst_wq);
+	for (i = 0; i < DRM_DPST_MAX_NUM_EVENTS;  i++) {
+		state->dpst_change_wq_data.dev_umevent_arry[i] = NULL;
+	}
+	psb_umevent_cleanup(list);
+	kfree(state);
+}
+/*EXPORT_SYMBOL(psb_dpst_device_pool_destroy); */
+/**
+ * psb_dpst_dev_change_wq - change workqueue implementation
+ *
+ * @work: work struct to use for kernel scheduling
+ *
+ */
+void psb_dpst_dev_change_wq(struct work_struct *work)
+{
+	struct dpst_disp_workqueue_data *wq_data;
+	int curr_event_index;
+	wq_data = to_dpst_disp_workqueue_data(work);
+	if (wq_data->dev_name_write_wrap == 1) {
+		wq_data->dev_name_read_write_wrap_ack = 1;
+		wq_data->dev_name_write_wrap = 0;
+		while (wq_data->dev_name_read != DRM_DPST_RING_DEPTH_MAX) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_DPST_READY_TO_READ) {
+				wq_data->dev_name_arry_rw_status
+				[wq_data->dev_name_read] =
+				DRM_DPST_READ_COMPLETE;
+				curr_event_index = wq_data->dpst_events
+					[wq_data->dev_name_read];
+				psb_umevent_notify_change_gfxsock
+					(list_entry(
+					   (wq_data->dev_umevent_arry
+					    [curr_event_index]),
+					   struct umevent_obj, head),
+					 DRM_DPST_SOCKET_GROUP_ID);
+			}
+			wq_data->dev_name_read++;
+		}
+		wq_data->dev_name_read = 0;
+		while (wq_data->dev_name_read < wq_data->dev_name_write-1) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_DPST_READY_TO_READ) {
+				wq_data->dev_name_arry_rw_status
+				[wq_data->dev_name_read] =
+				DRM_DPST_READ_COMPLETE;
+				curr_event_index = wq_data->dpst_events
+					[wq_data->dev_name_read];
+				psb_umevent_notify_change_gfxsock
+					(list_entry(
+					   (wq_data->dev_umevent_arry
+					    [curr_event_index]),
+					   struct umevent_obj, head),
+					 DRM_DPST_SOCKET_GROUP_ID);
+			}
+			wq_data->dev_name_read++;
+		}
+	} else {
+		while (wq_data->dev_name_read < wq_data->dev_name_write) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_DPST_READY_TO_READ) {
+				wq_data->dev_name_arry_rw_status
+				[wq_data->dev_name_read] =
+					DRM_DPST_READ_COMPLETE;
+				curr_event_index = wq_data->dpst_events
+					[wq_data->dev_name_read];
+				psb_umevent_notify_change_gfxsock
+					(list_entry(
+					   (wq_data->dev_umevent_arry
+					    [curr_event_index]),
+					   struct umevent_obj, head),
+					 DRM_DPST_SOCKET_GROUP_ID);
+			}
+			wq_data->dev_name_read++;
+		}
+	}
+	if (wq_data->dev_name_read > DRM_DPST_RING_DEPTH_MAX)
+		wq_data->dev_name_read = 0;
+}
+/*EXPORT_SYMBOL(psb_dpst_dev_change_wq); */
diff --git a/drivers/staging/cdv/drv/psb_dpst.h b/drivers/staging/cdv/drv/psb_dpst.h
new file mode 100644
index 0000000..97f82cd
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_dpst.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *    James C. Gualario <james.c.gualario@intel.com>
+ *
+ */
+
+#ifndef _PSB_DPST_H_
+#define _PSB_DPST_H_
+/**
+ * required includes
+ *
+ */
+#include "psb_umevents.h"
+/**
+ * dpst event enumeration
+ *
+ */
+enum dpst_event_enum {
+	DPST_EVENT_INIT_COMPLETE,
+	DPST_EVENT_HIST_INTERRUPT,
+	DPST_EVENT_TERMINATE,
+	DPST_EVENT_PHASE_COMPLETE,
+	DPST_MAX_EVENT
+};
+/**
+ * dpst specific defines
+ *
+ */
+#define DRM_DPST_RING_DEPTH 256
+#define DRM_DPST_RING_DEPTH_MAX (DRM_DPST_RING_DEPTH-1)
+#define DRM_DPST_READY_TO_READ 1
+#define DRM_DPST_READ_COMPLETE 2
+#define DRM_DPST_MAX_NUM_EVENTS (DPST_MAX_EVENT)
+/**
+ * dpst workqueue data struct.
+ */
+struct dpst_disp_workqueue_data {
+	struct work_struct work;
+	const char *dev_name;
+	int dev_name_write;
+	int dev_name_read;
+	int dev_name_write_wrap;
+	int dev_name_read_write_wrap_ack;
+	enum dpst_event_enum dpst_events[DRM_DPST_RING_DEPTH];
+	int dev_name_arry_rw_status[DRM_DPST_RING_DEPTH];
+	struct umevent_list *hotplug_dev_list;
+	struct list_head *dev_umevent_arry[DRM_DPST_MAX_NUM_EVENTS];
+};
+/**
+ * dpst state structure
+ *
+ */
+struct dpst_state {
+	struct workqueue_struct *dpst_wq;
+	struct dpst_disp_workqueue_data dpst_change_wq_data;
+	struct umevent_list *list;
+};
+/**
+ * main interface function prototytpes for dpst support.
+ *
+ */
+extern struct dpst_state *psb_dpst_init(struct kobject *parent_kobj);
+extern int psb_dpst_notify_change_um(enum dpst_event_enum event,
+				     struct dpst_state *state);
+extern struct umevent_obj *psb_dpst_create_and_notify_um(const char *name,
+						 struct dpst_state *state);
+extern struct umevent_list *psb_dpst_device_pool_create_and_init(
+						 struct kobject *parent_kobj,
+						 struct dpst_state *state);
+extern void psb_dpst_device_pool_destroy(struct dpst_state *state);
+/**
+ * to go back and forth between work struct and workqueue data
+ *
+ */
+#define to_dpst_disp_workqueue_data(x) \
+	container_of(x, struct dpst_disp_workqueue_data, work)
+
+/**
+ * function prototypes for workqueue implementation
+ *
+ */
+extern void psb_dpst_dev_change_wq(struct work_struct *work);
+#endif
diff --git a/drivers/staging/cdv/drv/psb_drm.h b/drivers/staging/cdv/drv/psb_drm.h
new file mode 100644
index 0000000..0f5c171
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_drm.h
@@ -0,0 +1,565 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * All Rights Reserved.
+ * Copyright (c) 2008, Tungsten Graphics Inc.  Cedar Park, TX., USA.
+ * 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 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.
+ *
+ **************************************************************************/
+
+#ifndef _PSB_DRM_H_
+#define _PSB_DRM_H_
+
+#if defined(__linux__) && !defined(__KERNEL__)
+#include<stdint.h>
+#include <linux/types.h>
+#include "drm_mode.h"
+#endif
+
+#include "psb_ttm_fence_user.h"
+#include "psb_ttm_placement_user.h"
+
+/*
+ * Menlow/MRST graphics driver package version
+ * a.b.c.xxxx
+ * a - Product Family: 5 - Linux
+ * b - Major Release Version: 0 - non-Gallium (Unbuntu);
+ *                            1 - Gallium (Moblin2)
+ * c - Hotfix Release
+ * xxxx - Graphics internal build #
+ */
+#define PSB_PACKAGE_VERSION "5.3.0.32L.0039"
+
+#define DRM_PSB_SAREA_MAJOR 0
+#define DRM_PSB_SAREA_MINOR 2
+#define PSB_FIXED_SHIFT 16
+
+#define PSB_NUM_PIPE 3
+
+/*
+ * Public memory types.
+ */
+
+#define DRM_PSB_MEM_MMU TTM_PL_PRIV1
+#define DRM_PSB_FLAG_MEM_MMU TTM_PL_FLAG_PRIV1
+
+#define TTM_PL_CI               TTM_PL_PRIV0
+#define TTM_PL_FLAG_CI          TTM_PL_FLAG_PRIV0       
+
+#define TTM_PL_RAR               TTM_PL_PRIV2
+#define TTM_PL_FLAG_RAR          TTM_PL_FLAG_PRIV2       
+
+typedef int32_t psb_fixed;
+typedef uint32_t psb_ufixed;
+
+static inline int32_t psb_int_to_fixed(int a)
+{
+	return a * (1 << PSB_FIXED_SHIFT);
+}
+
+static inline uint32_t psb_unsigned_to_ufixed(unsigned int a)
+{
+	return a << PSB_FIXED_SHIFT;
+}
+
+/*Status of the command sent to the gfx device.*/
+typedef enum {
+	DRM_CMD_SUCCESS,
+	DRM_CMD_FAILED,
+	DRM_CMD_HANG
+} drm_cmd_status_t;
+
+struct drm_psb_scanout {
+	uint32_t buffer_id;	/* DRM buffer object ID */
+	uint32_t rotation;	/* Rotation as in RR_rotation definitions */
+	uint32_t stride;	/* Buffer stride in bytes */
+	uint32_t depth;		/* Buffer depth in bits (NOT) bpp */
+	uint32_t width;		/* Buffer width in pixels */
+	uint32_t height;	/* Buffer height in lines */
+	int32_t transform[3][3];	/* Buffer composite transform */
+	/* (scaling, rot, reflect) */
+};
+
+#define DRM_PSB_SAREA_OWNERS 16
+#define DRM_PSB_SAREA_OWNER_2D 0
+#define DRM_PSB_SAREA_OWNER_3D 1
+
+#define DRM_PSB_SAREA_SCANOUTS 3
+
+struct drm_psb_sarea {
+	/* Track changes of this data structure */
+
+	uint32_t major;
+	uint32_t minor;
+
+	/* Last context to touch part of hw */
+	uint32_t ctx_owners[DRM_PSB_SAREA_OWNERS];
+
+	/* Definition of front- and rotated buffers */
+	uint32_t num_scanouts;
+	struct drm_psb_scanout scanouts[DRM_PSB_SAREA_SCANOUTS];
+
+	int planeA_x;
+	int planeA_y;
+	int planeA_w;
+	int planeA_h;
+	int planeB_x;
+	int planeB_y;
+	int planeB_w;
+	int planeB_h;
+	/* Number of active scanouts */
+	uint32_t num_active_scanouts;
+};
+
+#define PSB_RELOC_MAGIC         0x67676767
+#define PSB_RELOC_SHIFT_MASK    0x0000FFFF
+#define PSB_RELOC_SHIFT_SHIFT   0
+#define PSB_RELOC_ALSHIFT_MASK  0xFFFF0000
+#define PSB_RELOC_ALSHIFT_SHIFT 16
+
+#define PSB_RELOC_OP_OFFSET     0	/* Offset of the indicated
+					 * buffer
+					 */
+
+struct drm_psb_reloc {
+	uint32_t reloc_op;
+	uint32_t where;		/* offset in destination buffer */
+	uint32_t buffer;	/* Buffer reloc applies to */
+	uint32_t mask;		/* Destination format: */
+	uint32_t shift;		/* Destination format: */
+	uint32_t pre_add;	/* Destination format: */
+	uint32_t background;	/* Destination add */
+	uint32_t dst_buffer;	/* Destination buffer. Index into buffer_list */
+	uint32_t arg0;		/* Reloc-op dependant */
+	uint32_t arg1;
+};
+
+
+#define PSB_GPU_ACCESS_READ         (1ULL << 32)
+#define PSB_GPU_ACCESS_WRITE        (1ULL << 33)
+#define PSB_GPU_ACCESS_MASK         (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)
+
+#define PSB_BO_FLAG_COMMAND         (1ULL << 52)
+
+#define PSB_ENGINE_2D 0
+#define PSB_ENGINE_VIDEO 1
+
+/*
+ * For this fence class we have a couple of
+ * fence types.
+ */
+
+#define _PSB_FENCE_EXE_SHIFT           0
+#define _PSB_FENCE_FEEDBACK_SHIFT      4
+
+#define _PSB_FENCE_TYPE_EXE         (1 << _PSB_FENCE_EXE_SHIFT)
+#define _PSB_FENCE_TYPE_FEEDBACK    (1 << _PSB_FENCE_FEEDBACK_SHIFT)
+
+#define PSB_NUM_ENGINES 6
+
+
+#define PSB_FEEDBACK_OP_VISTEST (1 << 0)
+
+struct drm_psb_extension_rep {
+	int32_t exists;
+	uint32_t driver_ioctl_offset;
+	uint32_t sarea_offset;
+	uint32_t major;
+	uint32_t minor;
+	uint32_t pl;
+};
+
+#define DRM_PSB_EXT_NAME_LEN 128
+
+union drm_psb_extension_arg {
+	char extension[DRM_PSB_EXT_NAME_LEN];
+	struct drm_psb_extension_rep rep;
+};
+
+struct psb_validate_req {
+	uint64_t set_flags;
+	uint64_t clear_flags;
+	uint64_t next;
+	uint64_t presumed_gpu_offset;
+	uint32_t buffer_handle;
+	uint32_t presumed_flags;
+	uint32_t group;
+	uint32_t pad64;
+};
+
+struct psb_validate_rep {
+	uint64_t gpu_offset;
+	uint32_t placement;
+	uint32_t fence_type_mask;
+};
+
+#define PSB_USE_PRESUMED     (1 << 0)
+
+struct psb_validate_arg {
+	int handled;
+	int ret;
+	union {
+		struct psb_validate_req req;
+		struct psb_validate_rep rep;
+	} d;
+};
+
+
+#define DRM_PSB_FENCE_NO_USER        (1 << 0)
+
+struct psb_ttm_fence_rep {
+	uint32_t handle;
+	uint32_t fence_class;
+	uint32_t fence_type;
+	uint32_t signaled_types;
+	uint32_t error;
+};
+
+typedef struct drm_psb_cmdbuf_arg {
+	uint64_t buffer_list;	/* List of buffers to validate */
+	uint64_t clip_rects;	/* See i915 counterpart */
+	uint64_t scene_arg;
+	uint64_t fence_arg;
+
+	uint32_t ta_flags;
+
+	uint32_t ta_handle;	/* TA reg-value pairs */
+	uint32_t ta_offset;
+	uint32_t ta_size;
+
+	uint32_t oom_handle;
+	uint32_t oom_offset;
+	uint32_t oom_size;
+
+	uint32_t cmdbuf_handle;	/* 2D Command buffer object or, */
+	uint32_t cmdbuf_offset;	/* rasterizer reg-value pairs */
+	uint32_t cmdbuf_size;
+
+	uint32_t reloc_handle;	/* Reloc buffer object */
+	uint32_t reloc_offset;
+	uint32_t num_relocs;
+
+	int32_t damage;		/* Damage front buffer with cliprects */
+	/* Not implemented yet */
+	uint32_t fence_flags;
+	uint32_t engine;
+
+	/*
+	 * Feedback;
+	 */
+
+	uint32_t feedback_ops;
+	uint32_t feedback_handle;
+	uint32_t feedback_offset;
+	uint32_t feedback_breakpoints;
+	uint32_t feedback_size;
+} drm_psb_cmdbuf_arg_t;
+
+typedef struct drm_psb_pageflip_arg {
+	uint32_t flip_offset;
+	uint32_t stride;
+} drm_psb_pageflip_arg_t;
+
+typedef enum {
+	LNC_VIDEO_DEVICE_INFO,
+	LNC_VIDEO_GETPARAM_RAR_INFO,
+	LNC_VIDEO_GETPARAM_CI_INFO,
+	LNC_VIDEO_GETPARAM_RAR_HANDLER_OFFSET,
+	LNC_VIDEO_FRAME_SKIP,
+	IMG_VIDEO_DECODE_STATUS,
+	IMG_VIDEO_NEW_CONTEXT,
+	IMG_VIDEO_RM_CONTEXT,
+	IMG_VIDEO_MB_ERROR
+} lnc_getparam_key_t;
+
+struct drm_lnc_video_getparam_arg {
+	lnc_getparam_key_t key;
+	uint64_t arg;	/* argument pointer */
+	uint64_t value;	/* feed back pointer */
+};
+
+
+/*
+ * Feedback components:
+ */
+
+/*
+ * Vistest component. The number of these in the feedback buffer
+ * equals the number of vistest breakpoints + 1.
+ * This is currently the only feedback component.
+ */
+
+struct drm_psb_vistest {
+	uint32_t vt[8];
+};
+
+struct drm_psb_sizes_arg {
+	uint32_t ta_mem_size;
+	uint32_t mmu_size;
+	uint32_t pds_size;
+	uint32_t rastgeom_size;
+	uint32_t tt_size;
+	uint32_t vram_size;
+};
+
+struct drm_psb_hist_status_arg {
+	uint32_t buf[32];
+};
+
+struct drm_psb_dpst_lut_arg {
+	uint8_t lut[256];
+	int output_id;
+};
+
+struct mrst_timing_info {
+	uint16_t pixel_clock;
+	uint8_t hactive_lo;
+	uint8_t hblank_lo;
+	uint8_t hblank_hi:4;
+	uint8_t hactive_hi:4;
+	uint8_t vactive_lo;
+	uint8_t vblank_lo;
+	uint8_t vblank_hi:4;
+	uint8_t vactive_hi:4;
+	uint8_t hsync_offset_lo;
+	uint8_t hsync_pulse_width_lo;
+	uint8_t vsync_pulse_width_lo:4;
+	uint8_t vsync_offset_lo:4;
+	uint8_t vsync_pulse_width_hi:2;
+	uint8_t vsync_offset_hi:2;
+	uint8_t hsync_pulse_width_hi:2;
+	uint8_t hsync_offset_hi:2;
+	uint8_t width_mm_lo;
+	uint8_t height_mm_lo;
+	uint8_t height_mm_hi:4;
+	uint8_t width_mm_hi:4;
+	uint8_t hborder;
+	uint8_t vborder;
+	uint8_t unknown0:1;
+	uint8_t hsync_positive:1;
+	uint8_t vsync_positive:1;
+	uint8_t separate_sync:2;
+	uint8_t stereo:1;
+	uint8_t unknown6:1;
+	uint8_t interlaced:1;
+} __attribute__((packed));
+
+struct gct_ioctl_arg{
+	uint8_t bpi; /* boot panel index, number of panel used during boot */
+	uint8_t pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */
+	struct mrst_timing_info DTD; /* timing info for the selected panel */
+	uint32_t Panel_Port_Control;
+	uint32_t PP_On_Sequencing;/*1 dword,Register 0x61208,*/
+	uint32_t PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/
+	uint32_t PP_Cycle_Delay;
+	uint16_t Panel_Backlight_Inverter_Descriptor;
+	uint16_t Panel_MIPI_Display_Descriptor;
+} __attribute__ ((packed));
+
+#define PSB_DC_CRTC_SAVE 0x01
+#define PSB_DC_CRTC_RESTORE 0x02
+#define PSB_DC_OUTPUT_SAVE 0x04
+#define PSB_DC_OUTPUT_RESTORE 0x08
+#define PSB_DC_CRTC_MASK 0x03
+#define PSB_DC_OUTPUT_MASK 0x0C
+
+struct drm_psb_dc_state_arg {
+	uint32_t flags;
+	uint32_t obj_id;
+};
+
+struct drm_psb_mode_operation_arg {
+	uint32_t obj_id;
+	uint16_t operation;
+	struct drm_mode_modeinfo mode;
+	void *data;
+};
+
+struct drm_psb_stolen_memory_arg {
+	uint32_t base;
+	uint32_t size;
+};
+
+/*Display Register Bits*/
+#define REGRWBITS_PFIT_CONTROLS			(1 << 0)
+#define REGRWBITS_PFIT_AUTOSCALE_RATIOS		(1 << 1)
+#define REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS	(1 << 2)
+#define REGRWBITS_PIPEASRC			(1 << 3)
+#define REGRWBITS_PIPEBSRC			(1 << 4)
+#define REGRWBITS_VTOTAL_A			(1 << 5)
+#define REGRWBITS_VTOTAL_B			(1 << 6)
+#define REGRWBITS_DSPACNTR	(1 << 8)
+#define REGRWBITS_DSPBCNTR	(1 << 9)
+#define REGRWBITS_DSPCCNTR	(1 << 10)
+#define REGRBITS_PIPECONF	(1 << 11)
+
+
+/*Overlay Register Bits*/
+#define OV_REGRWBITS_OVADD			(1 << 0)
+#define OV_REGRWBITS_OGAM_ALL			(1 << 1)
+
+#define OVC_REGRWBITS_OVADD                  (1 << 2)
+#define OVC_REGRWBITS_OGAM_ALL			(1 << 3)
+
+struct drm_psb_register_rw_arg {
+	uint32_t b_force_hw_on;
+
+	uint32_t display_read_mask;
+	uint32_t display_write_mask;
+
+	struct {
+		uint32_t pfit_controls;
+		uint32_t pfit_autoscale_ratios;
+		uint32_t pfit_programmed_scale_ratios;
+		uint32_t pipeasrc;
+		uint32_t pipebsrc;
+		uint32_t vtotal_a;
+		uint32_t vtotal_b;
+		uint32_t pipe_enabled;
+	} display;
+
+	uint32_t overlay_read_mask;
+	uint32_t overlay_write_mask;
+
+	struct {
+		uint32_t OVADD;
+		uint32_t OGAMC0;
+		uint32_t OGAMC1;
+		uint32_t OGAMC2;
+		uint32_t OGAMC3;
+		uint32_t OGAMC4;
+		uint32_t OGAMC5;
+        	uint32_t IEP_ENABLED;
+        	uint32_t IEP_BLE_MINMAX;
+        	uint32_t IEP_BSSCC_CONTROL;
+                uint32_t b_wait_vblank;
+	} overlay;
+
+	uint32_t sprite_enable_mask;
+	uint32_t sprite_disable_mask;
+
+	struct {
+		uint32_t dspa_control;
+		uint32_t dspa_key_value;
+		uint32_t dspa_key_mask;
+		uint32_t dspc_control;
+		uint32_t dspc_stride;
+		uint32_t dspc_position;
+		uint32_t dspc_linear_offset;
+		uint32_t dspc_size;
+		uint32_t dspc_surface;
+	} sprite;
+
+	uint32_t subpicture_enable_mask;
+	uint32_t subpicture_disable_mask;
+};
+
+struct psb_gtt_mapping_arg {
+	void *hKernelMemInfo;
+	uint32_t offset_pages;
+};
+
+struct drm_psb_getpageaddrs_arg {
+	uint32_t handle;
+	unsigned long *page_addrs;
+	unsigned long gtt_offset;
+};
+
+
+#define MAX_SLICES_PER_PICTURE 72
+typedef struct drm_psb_msvdx_decode_status {
+	uint32_t fw_status;
+	uint32_t num_error_slice;
+	int32_t start_error_mb_list[MAX_SLICES_PER_PICTURE];
+	int32_t end_error_mb_list[MAX_SLICES_PER_PICTURE];
+	int32_t slice_missing_or_error[MAX_SLICES_PER_PICTURE];
+} drm_psb_msvdx_decode_status_t;
+
+/* Controlling the kernel modesetting buffers */
+
+#define DRM_PSB_KMS_OFF		0x00
+#define DRM_PSB_KMS_ON		0x01
+#define DRM_PSB_VT_LEAVE        0x02
+#define DRM_PSB_VT_ENTER        0x03
+#define DRM_PSB_EXTENSION       0x06
+#define DRM_PSB_SIZES           0x07
+#define DRM_PSB_FUSE_REG	0x08
+#define DRM_PSB_VBT		0x09
+#define DRM_PSB_DC_STATE	0x0A
+#define DRM_PSB_ADB		0x0B
+#define DRM_PSB_MODE_OPERATION	0x0C
+#define DRM_PSB_STOLEN_MEMORY	0x0D
+#define DRM_PSB_REGISTER_RW	0x0E
+#define DRM_PSB_GTT_MAP         0x0F
+#define DRM_PSB_GTT_UNMAP       0x10
+#define DRM_PSB_GETPAGEADDRS	0x11
+/**
+ * NOTE: Add new commands here, but increment
+ * the values below and increment their
+ * corresponding defines where they're
+ * defined elsewhere.
+ */
+#define DRM_PVR_RESERVED1	0x12
+#define DRM_PVR_RESERVED2	0x13
+#define DRM_PVR_RESERVED3	0x14
+#define DRM_PVR_RESERVED4	0x15
+#define DRM_PVR_RESERVED5	0x16
+
+#define DRM_PSB_HIST_ENABLE	0x17
+#define DRM_PSB_HIST_STATUS	0x18
+#define DRM_PSB_UPDATE_GUARD	0x19
+#define DRM_PSB_INIT_COMM	0x1A
+#define DRM_PSB_DPST		0x1B
+#define DRM_PSB_GAMMA		0x1C
+#define DRM_PSB_DPST_BL		0x1D
+
+#define DRM_PVR_RESERVED6	0x1E
+
+#define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F
+#define DRM_PSB_DPU_QUERY 0x20
+#define DRM_PSB_DPU_DSR_ON 0x21
+#define DRM_PSB_DPU_DSR_OFF 0x22
+
+#define DRM_PSB_DSR_ENABLE	0xfffffffe
+#define DRM_PSB_DSR_DISABLE	0xffffffff
+
+struct psb_drm_dpu_rect {  
+    int x, y;             
+    int width, height;    
+};  
+
+struct drm_psb_drv_dsr_off_arg {
+	int screen;
+	struct psb_drm_dpu_rect damage_rect;
+};
+
+
+struct drm_psb_dev_info_arg {
+	uint32_t num_use_attribute_registers;
+};
+#define DRM_PSB_DEVINFO         0x01
+
+#define PSB_MODE_OPERATION_MODE_VALID	0x01
+#define PSB_MODE_OPERATION_SET_DC_BASE  0x02
+
+struct drm_psb_get_pipe_from_crtc_id_arg {
+	/** ID of CRTC being requested **/
+	uint32_t crtc_id;
+
+	/** pipe of requested CRTC **/
+	uint32_t pipe;
+};
+
+#endif
diff --git a/drivers/staging/cdv/drv/psb_drv.c b/drivers/staging/cdv/drv/psb_drv.c
new file mode 100644
index 0000000..3159169
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_drv.c
@@ -0,0 +1,1896 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * All Rights Reserved.
+ * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA.
+ * 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 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.
+ *
+ **************************************************************************/
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drm.h"
+#include "psb_drv.h"
+#include "psb_fb.h"
+#include "psb_reg.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_bios.h"
+#include "psb_msvdx.h"
+#include <drm/drm_pciids.h>
+#include "pvr_drm_shared.h"
+#include "psb_powermgmt.h"
+#include "img_types.h"
+#include <linux/cpu.h>
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+#include <acpi/video.h>
+
+#include "psb_intel_hdmi.h"
+
+/*IMG headers*/
+#include "pvr_drm_shared.h"
+#include "img_types.h"
+#include "pvr_bridge.h"
+#include "linkage.h"
+
+#include "bufferclass_video_linux.h"
+
+int drm_psb_debug = 0;
+static int drm_psb_trap_pagefaults;
+int drm_msvdx_pmpolicy = PSB_PMPOLICY_POWERDOWN;
+int drm_msvdx_delay = 250;
+int drm_psb_ospm = 1;
+extern bool gbdispstatus;
+
+static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+
+MODULE_PARM_DESC(debug, "Enable debug output");
+MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
+MODULE_PARM_DESC(ospm, "switch for ospm support");
+MODULE_PARM_DESC(msvdx_pmpolicy, "msvdx power management policy btw frames");
+
+module_param_named(debug, drm_psb_debug, int, 0600);
+module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);
+module_param_named(msvdx_pmpolicy, drm_msvdx_pmpolicy, int, 0600);
+module_param_named(msvdx_command_delay, drm_msvdx_delay, int, 0600);
+module_param_named(ospm, drm_psb_ospm, int, 0600);
+#ifndef MODULE
+/* Make ospm configurable via cmdline firstly, and others can be enabled if needed. */
+static int __init config_ospm(char *arg)
+{
+	/* ospm turn on/off control can be passed in as a cmdline parameter */
+	/* to enable this feature add ospm=1 to cmdline */
+	/* to disable this feature add ospm=0 to cmdline */
+	if (!arg)
+		return -EINVAL;
+
+	if (!strcasecmp(arg, "0"))
+		drm_psb_ospm = 0;
+	else if (!strcasecmp (arg, "1"))
+		drm_psb_ospm = 1;
+
+	return 0;
+}
+early_param ("ospm", config_ospm);
+#endif
+
+static struct pci_device_id pciidlist[] = {
+    {0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0be1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0be2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0be3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0be4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0be5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0be6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0be7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0be8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0be9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0bea, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0beb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0bec, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0bed, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0bee, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0x8086, 0x0bef, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0, 0, 0}
+};
+
+MODULE_DEVICE_TABLE(pci, pciidlist);
+/*
+ * Standard IOCTLs.
+ */
+
+#define DRM_IOCTL_PSB_KMS_OFF	\
+		DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
+#define DRM_IOCTL_PSB_KMS_ON	\
+		DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
+#define DRM_IOCTL_PSB_VT_LEAVE	\
+		DRM_IO(DRM_PSB_VT_LEAVE + DRM_COMMAND_BASE)
+#define DRM_IOCTL_PSB_VT_ENTER	\
+		DRM_IO(DRM_PSB_VT_ENTER + DRM_COMMAND_BASE)
+#define DRM_IOCTL_PSB_EXTENSION	\
+		DRM_IOWR(DRM_PSB_EXTENSION + DRM_COMMAND_BASE, \
+			 union drm_psb_extension_arg)
+#define DRM_IOCTL_PSB_SIZES	\
+		DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
+			struct drm_psb_sizes_arg)
+#define DRM_IOCTL_PSB_FUSE_REG	\
+		DRM_IOWR(DRM_PSB_FUSE_REG + DRM_COMMAND_BASE, uint32_t)
+#define DRM_IOCTL_PSB_VBT	\
+		DRM_IOWR(DRM_PSB_VBT + DRM_COMMAND_BASE, \
+			struct gct_ioctl_arg)
+#define DRM_IOCTL_PSB_DC_STATE	\
+		DRM_IOW(DRM_PSB_DC_STATE + DRM_COMMAND_BASE, \
+			struct drm_psb_dc_state_arg)
+#define DRM_IOCTL_PSB_ADB	\
+		DRM_IOWR(DRM_PSB_ADB + DRM_COMMAND_BASE, uint32_t)
+#define DRM_IOCTL_PSB_MODE_OPERATION	\
+		DRM_IOWR(DRM_PSB_MODE_OPERATION + DRM_COMMAND_BASE, \
+			 struct drm_psb_mode_operation_arg)
+#define DRM_IOCTL_PSB_STOLEN_MEMORY	\
+		DRM_IOWR(DRM_PSB_STOLEN_MEMORY + DRM_COMMAND_BASE, \
+			 struct drm_psb_stolen_memory_arg)
+#define DRM_IOCTL_PSB_REGISTER_RW	\
+		DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \
+			 struct drm_psb_register_rw_arg)
+#define DRM_IOCTL_PSB_GTT_MAP	\
+		DRM_IOWR(DRM_PSB_GTT_MAP + DRM_COMMAND_BASE, \
+			 struct psb_gtt_mapping_arg)
+#define DRM_IOCTL_PSB_GTT_UNMAP	\
+		DRM_IOW(DRM_PSB_GTT_UNMAP + DRM_COMMAND_BASE, \
+			struct psb_gtt_mapping_arg)
+#define DRM_IOCTL_PSB_GETPAGEADDRS	\
+		DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_GETPAGEADDRS,\
+			 struct drm_psb_getpageaddrs_arg)
+#define DRM_IOCTL_PSB_HIST_ENABLE	\
+		DRM_IOWR(DRM_PSB_HIST_ENABLE + DRM_COMMAND_BASE, \
+			 uint32_t)
+#define DRM_IOCTL_PSB_HIST_STATUS	\
+		DRM_IOWR(DRM_PSB_HIST_STATUS + DRM_COMMAND_BASE, \
+			 struct drm_psb_hist_status_arg)
+#define DRM_IOCTL_PSB_UPDATE_GUARD	\
+		DRM_IOWR(DRM_PSB_UPDATE_GUARD + DRM_COMMAND_BASE, \
+			 uint32_t)
+#define DRM_IOCTL_PSB_INIT_COMM	\
+		DRM_IOWR(DRM_PSB_INIT_COMM + DRM_COMMAND_BASE, \
+			 uint32_t)
+#define DRM_IOCTL_PSB_DPST	\
+		DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \
+			 uint32_t)
+#define DRM_IOCTL_PSB_GAMMA	\
+		DRM_IOWR(DRM_PSB_GAMMA + DRM_COMMAND_BASE, \
+			 struct drm_psb_dpst_lut_arg)
+#define DRM_IOCTL_PSB_DPST_BL	\
+		DRM_IOWR(DRM_PSB_DPST_BL + DRM_COMMAND_BASE, \
+			 uint32_t)
+#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID	\
+		DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
+			 struct drm_psb_get_pipe_from_crtc_id_arg)
+
+/*pvr ioctls*/
+#define PVR_DRM_SRVKM_IOCTL \
+	DRM_IOW(DRM_COMMAND_BASE + PVR_DRM_SRVKM_CMD, \
+		PVRSRV_BRIDGE_PACKAGE)
+#define PVR_DRM_DISP_IOCTL \
+	DRM_IO(DRM_COMMAND_BASE + PVR_DRM_DISP_CMD)
+#define PVR_DRM_BC_IOCTL \
+	DRM_IO(DRM_COMMAND_BASE + PVR_DRM_BC_CMD)
+#define PVR_DRM_IS_MASTER_IOCTL \
+	DRM_IO(DRM_COMMAND_BASE + PVR_DRM_IS_MASTER_CMD)
+#define PVR_DRM_UNPRIV_IOCTL \
+	DRM_IOWR(DRM_COMMAND_BASE + PVR_DRM_UNPRIV_CMD, \
+		IMG_UINT32)
+#if defined(PDUMP)
+  #define PVR_DRM_DBGDRV_IOCTL \
+	DRM_IOW(DRM_COMMAND_BASE + PVR_DRM_DBGDRV_CMD, IOCTL_PACKAGE)
+#endif
+
+/*DPU/DSR stuff*/
+#define DRM_IOCRL_PSB_DPU_QUERY DRM_IOR(DRM_PSB_DPU_QUERY + DRM_COMMAND_BASE, IMG_UINT32)
+#define DRM_IOCRL_PSB_DPU_DSR_ON DRM_IOW(DRM_PSB_DPU_DSR_ON + DRM_COMMAND_BASE, IMG_UINT32)
+//#define DRM_IOCRL_PSB_DPU_DSR_OFF DRM_IOW(DRM_PSB_DPU_DSR_OFF + DRM_COMMAND_BASE, IMG_UINT32)
+#define DRM_IOCRL_PSB_DPU_DSR_OFF DRM_IOW(DRM_PSB_DPU_DSR_OFF + DRM_COMMAND_BASE, struct drm_psb_drv_dsr_off_arg)
+
+/*
+ * TTM execbuf extension.
+ */
+#if defined(PDUMP)
+#define DRM_PSB_CMDBUF		  (PVR_DRM_DBGDRV_CMD + 1)
+#else
+#define DRM_PSB_CMDBUF		  (DRM_PSB_DPU_DSR_OFF + 1)
+/* #define DRM_PSB_CMDBUF		  (DRM_PSB_DPST_BL + 1) */
+#endif
+
+#define DRM_PSB_SCENE_UNREF	  (DRM_PSB_CMDBUF + 1)
+#define DRM_IOCTL_PSB_CMDBUF	\
+		DRM_IOW(DRM_PSB_CMDBUF + DRM_COMMAND_BASE,	\
+			struct drm_psb_cmdbuf_arg)
+#define DRM_IOCTL_PSB_SCENE_UNREF	\
+		DRM_IOW(DRM_PSB_SCENE_UNREF + DRM_COMMAND_BASE, \
+			struct drm_psb_scene)
+#define DRM_IOCTL_PSB_KMS_OFF	  DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
+#define DRM_IOCTL_PSB_KMS_ON	  DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
+#define DRM_IOCTL_PSB_EXTENSION	\
+		DRM_IOWR(DRM_PSB_EXTENSION + DRM_COMMAND_BASE, \
+			 union drm_psb_extension_arg)
+/*
+ * TTM placement user extension.
+ */
+
+#define DRM_PSB_PLACEMENT_OFFSET   (DRM_PSB_SCENE_UNREF + 1)
+
+#define DRM_PSB_TTM_PL_CREATE	 (TTM_PL_CREATE + DRM_PSB_PLACEMENT_OFFSET)
+#define DRM_PSB_TTM_PL_REFERENCE (TTM_PL_REFERENCE + DRM_PSB_PLACEMENT_OFFSET)
+#define DRM_PSB_TTM_PL_UNREF	 (TTM_PL_UNREF + DRM_PSB_PLACEMENT_OFFSET)
+#define DRM_PSB_TTM_PL_SYNCCPU	 (TTM_PL_SYNCCPU + DRM_PSB_PLACEMENT_OFFSET)
+#define DRM_PSB_TTM_PL_WAITIDLE  (TTM_PL_WAITIDLE + DRM_PSB_PLACEMENT_OFFSET)
+#define DRM_PSB_TTM_PL_SETSTATUS (TTM_PL_SETSTATUS + DRM_PSB_PLACEMENT_OFFSET)
+#define DRM_PSB_TTM_PL_CREATE_UB (TTM_PL_CREATE_UB + DRM_PSB_PLACEMENT_OFFSET)
+
+/*
+ * TTM fence extension.
+ */
+
+#define DRM_PSB_FENCE_OFFSET	   (DRM_PSB_TTM_PL_CREATE_UB + 1)
+#define DRM_PSB_TTM_FENCE_SIGNALED (TTM_FENCE_SIGNALED + DRM_PSB_FENCE_OFFSET)
+#define DRM_PSB_TTM_FENCE_FINISH   (TTM_FENCE_FINISH + DRM_PSB_FENCE_OFFSET)
+#define DRM_PSB_TTM_FENCE_UNREF    (TTM_FENCE_UNREF + DRM_PSB_FENCE_OFFSET)
+
+#define DRM_PSB_FLIP	   (DRM_PSB_TTM_FENCE_UNREF + 1)	/*20*/
+/* PSB video extension */
+#define DRM_LNC_VIDEO_GETPARAM		(DRM_PSB_FLIP + 1)
+
+/*BC_VIDEO ioctl*/
+#define DRM_BUFFER_CLASS_VIDEO      (DRM_LNC_VIDEO_GETPARAM + 1)    /*0x32*/
+
+#define DRM_IOCTL_PSB_TTM_PL_CREATE    \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE,\
+		 union ttm_pl_create_arg)
+#define DRM_IOCTL_PSB_TTM_PL_REFERENCE \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_REFERENCE,\
+		 union ttm_pl_reference_arg)
+#define DRM_IOCTL_PSB_TTM_PL_UNREF    \
+	DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_UNREF,\
+		struct ttm_pl_reference_req)
+#define DRM_IOCTL_PSB_TTM_PL_SYNCCPU	\
+	DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SYNCCPU,\
+		struct ttm_pl_synccpu_arg)
+#define DRM_IOCTL_PSB_TTM_PL_WAITIDLE	 \
+	DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_WAITIDLE,\
+		struct ttm_pl_waitidle_arg)
+#define DRM_IOCTL_PSB_TTM_PL_SETSTATUS \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SETSTATUS,\
+		 union ttm_pl_setstatus_arg)
+#define DRM_IOCTL_PSB_TTM_PL_CREATE_UB    \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE_UB,\
+		 union ttm_pl_create_ub_arg)
+#define DRM_IOCTL_PSB_TTM_FENCE_SIGNALED \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_SIGNALED,	\
+		  union ttm_fence_signaled_arg)
+#define DRM_IOCTL_PSB_TTM_FENCE_FINISH \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_FINISH,	\
+		 union ttm_fence_finish_arg)
+#define DRM_IOCTL_PSB_TTM_FENCE_UNREF \
+	DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_UNREF,	\
+		 struct ttm_fence_unref_arg)
+#define DRM_IOCTL_PSB_FLIP \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_FLIP, \
+		 struct drm_psb_pageflip_arg)
+#define DRM_IOCTL_LNC_VIDEO_GETPARAM \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_LNC_VIDEO_GETPARAM, \
+		 struct drm_lnc_video_getparam_arg)
+
+/*bc_video ioctl*/
+#define DRM_IOCTL_BUFFER_CLASS_VIDEO \
+        DRM_IOWR(DRM_COMMAND_BASE + DRM_BUFFER_CLASS_VIDEO, \
+             BC_Video_ioctl_package)
+
+static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+static int psb_sizes_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv);
+static int psb_fuse_reg_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+static int psb_vbt_ioctl(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv);
+static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
+			      struct drm_file *file_priv);
+static int psb_adb_ioctl(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv);
+static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file_priv);
+static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
+				   struct drm_file *file_priv);
+static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
+				 struct drm_file *file_priv);
+static int psb_hist_enable_ioctl(struct drm_device *dev, void *data,
+				 struct drm_file *file_priv);
+static int psb_hist_status_ioctl(struct drm_device *dev, void *data,
+				 struct drm_file *file_priv);
+static int psb_update_guard_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv);
+static int psb_init_comm_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
+static int psb_dpst_ioctl(struct drm_device *dev, void *data,
+			  struct drm_file *file_priv);
+static int psb_gamma_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv);
+static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv);
+
+static int psb_ioctl_not_support(struct drm_device *dev, void *data,
+				 struct drm_file *file_priv)
+{
+	return -EOPNOTSUPP;
+}
+
+#define PSB_IOCTL_DEF(ioctl, func, flags) \
+	[DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
+
+static struct drm_ioctl_desc psb_ioctls[] = {
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_OFF, psbfb_kms_off_ioctl,
+		      DRM_ROOT_ONLY),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_ON,
+			psbfb_kms_on_ioctl,
+			DRM_ROOT_ONLY),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_LEAVE, psb_vt_leave_ioctl,
+		      DRM_ROOT_ONLY),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_ENTER,
+			psb_vt_enter_ioctl,
+			DRM_ROOT_ONLY),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_EXTENSION, psb_extension_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_FUSE_REG, psb_fuse_reg_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_VBT, psb_vbt_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_MAP,
+			psb_gtt_map_meminfo_ioctl,
+			DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_UNMAP,
+			psb_gtt_unmap_meminfo_ioctl,
+			DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GETPAGEADDRS,
+			psb_getpageaddrs_ioctl,
+			DRM_AUTH),
+	PSB_IOCTL_DEF(PVR_DRM_SRVKM_IOCTL, PVRSRV_BridgeDispatchKM, 0),
+	PSB_IOCTL_DEF(PVR_DRM_DISP_IOCTL, PVRDRM_Dummy_ioctl, 0),
+	PSB_IOCTL_DEF(PVR_DRM_BC_IOCTL, PVRDRM_Dummy_ioctl, 0),
+	PSB_IOCTL_DEF(PVR_DRM_IS_MASTER_IOCTL, PVRDRMIsMaster, DRM_MASTER),
+	PSB_IOCTL_DEF(PVR_DRM_UNPRIV_IOCTL, PVRDRMUnprivCmd, 0),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_HIST_ENABLE,
+			psb_hist_enable_ioctl,
+			DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_HIST_STATUS,
+			psb_hist_status_ioctl,
+			DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_UPDATE_GUARD, psb_update_guard_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_INIT_COMM, psb_init_comm_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID, psb_intel_get_pipe_from_crtc_id, 0),
+#if defined(PDUMP)
+	PSB_IOCTL_DEF(PVR_DRM_DBGDRV_IOCTL, SYSPVRDBGDrivIoctl, 0),
+#endif
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_CMDBUF, psb_cmdbuf_ioctl, DRM_AUTH),
+	/*to be removed later*/
+	/*PSB_IOCTL_DEF(DRM_IOCTL_PSB_SCENE_UNREF, drm_psb_scene_unref_ioctl,
+		      DRM_AUTH),*/
+
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE, psb_pl_create_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_REFERENCE, psb_pl_reference_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_UNREF, psb_pl_unref_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SYNCCPU, psb_pl_synccpu_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_WAITIDLE, psb_pl_waitidle_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SETSTATUS, psb_pl_setstatus_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE_UB, psb_pl_ub_create_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_SIGNALED,
+		      psb_fence_signaled_ioctl, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_FINISH, psb_fence_finish_ioctl,
+		      DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_UNREF, psb_fence_unref_ioctl,
+		      DRM_AUTH),
+	/*to be removed later */
+	/*PSB_IOCTL_DEF(DRM_IOCTL_PSB_FLIP, psb_page_flip, DRM_AUTH),*/
+	PSB_IOCTL_DEF(DRM_IOCTL_LNC_VIDEO_GETPARAM,
+			lnc_video_getparam, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_BUFFER_CLASS_VIDEO, BC_Video_Bridge, DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCRL_PSB_DPU_QUERY, psb_ioctl_not_support,
+	             DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCRL_PSB_DPU_DSR_ON, psb_ioctl_not_support,
+	             DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCRL_PSB_DPU_DSR_OFF, psb_ioctl_not_support,
+	              DRM_AUTH)
+};
+
+
+static void psb_lastclose(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+
+	return;
+
+	if (!dev->dev_private)
+		return;
+
+	mutex_lock(&dev_priv->cmdbuf_mutex);
+	if (dev_priv->context.buffers) {
+		vfree(dev_priv->context.buffers);
+		dev_priv->context.buffers = NULL;
+	}
+	mutex_unlock(&dev_priv->cmdbuf_mutex);
+}
+
+static void psb_do_takedown(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	struct ttm_bo_device *bdev = &dev_priv->bdev;
+
+
+	if (dev_priv->have_mem_mmu) {
+		ttm_bo_clean_mm(bdev, DRM_PSB_MEM_MMU);
+		dev_priv->have_mem_mmu = 0;
+	}
+
+	if (dev_priv->have_tt) {
+		ttm_bo_clean_mm(bdev, TTM_PL_TT);
+		dev_priv->have_tt = 0;
+	}
+
+	if (dev_priv->have_camera) {
+		ttm_bo_clean_mm(bdev, TTM_PL_CI);
+		dev_priv->have_camera = 0;
+	}
+	if (dev_priv->have_rar) {
+		ttm_bo_clean_mm(bdev, TTM_PL_RAR);
+		dev_priv->have_rar = 0;
+	}
+
+	psb_msvdx_uninit(dev);
+}
+
+static void psb_get_core_freq(struct drm_device *dev)
+{
+	uint32_t clock;
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private;
+
+	clock = PSB_RVDC32(INTEL_CDV_DISP_CLK_FREQ);
+
+	switch ((clock >> 4) & 0x0F) {
+	case 0:
+		dev_priv->core_freq = 160;
+		break;
+	case 1:
+		dev_priv->core_freq = 200;
+		break;
+	case 2:
+		dev_priv->core_freq = 267;
+		break;
+	case 3:
+		dev_priv->core_freq = 320;
+		break;
+	case 4:
+		dev_priv->core_freq = 356;
+		break;
+	case 5:
+		dev_priv->core_freq = 400;
+		break;
+	default:
+		dev_priv->core_freq = 0;
+	}
+}
+
+#define FB_REG06 0xD0810600
+#define FB_TOPAZ_DISABLE BIT0
+#define FB_MIPI_DISABLE  BIT11
+#define FB_REG09 0xD0810900
+#define FB_SKU_MASK  (BIT12|BIT13|BIT14)
+#define FB_SKU_SHIFT 12
+#define FB_SKU_100 0
+#define FB_SKU_100L 1
+#define FB_SKU_83 2
+#if 1 /* FIXME remove it after PO */
+#define FB_GFX_CLK_DIVIDE_MASK	(BIT20|BIT21|BIT22)
+#define FB_GFX_CLK_DIVIDE_SHIFT 20
+#define FB_VED_CLK_DIVIDE_MASK	(BIT23|BIT24)
+#define FB_VED_CLK_DIVIDE_SHIFT 23
+#define FB_VEC_CLK_DIVIDE_MASK	(BIT25|BIT26)
+#define FB_VEC_CLK_DIVIDE_SHIFT 25
+#endif	/* FIXME remove it after PO */
+
+static int psb_do_init(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	struct ttm_bo_device *bdev = &dev_priv->bdev;
+	struct psb_gtt *pg = dev_priv->pg;
+
+	uint32_t stolen_gtt;
+	uint32_t tt_start;
+	uint32_t tt_pages;
+
+	int ret = -ENOMEM;
+
+
+	/*
+	 * Initialize sequence numbers for the different command
+	 * submission mechanisms.
+	 */
+
+	dev_priv->sequence[PSB_ENGINE_2D] = 1;
+	dev_priv->sequence[PSB_ENGINE_VIDEO] = 1;
+
+	if (pg->mmu_gatt_start & 0x0FFFFFFF) {
+		DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n");
+		ret = -EINVAL;
+		goto out_err;
+	}
+
+	stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4;
+	stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	stolen_gtt = (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages;
+
+	dev_priv->gatt_free_offset = pg->mmu_gatt_start +
+				     (stolen_gtt << PAGE_SHIFT) * 1024;
+
+	if (1 || drm_debug) {
+		uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID);
+		uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION);
+
+		DRM_DEBUG_KMS("SGX core id = 0x%08x\n", core_id);
+		DRM_DEBUG_KMS("SGX core rev major = 0x%02x, minor = 0x%02x\n",
+			 (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >>
+			 _PSB_CC_REVISION_MAJOR_SHIFT,
+			 (core_rev & _PSB_CC_REVISION_MINOR_MASK) >>
+			 _PSB_CC_REVISION_MINOR_SHIFT);
+		DRM_DEBUG_KMS("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n",
+			  (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >>
+			  _PSB_CC_REVISION_MAINTENANCE_SHIFT,
+			  (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >>
+			  _PSB_CC_REVISION_DESIGNER_SHIFT);
+	}
+
+	spin_lock_init(&dev_priv->irqmask_lock);
+
+	tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
+	    pg->gatt_pages : PSB_TT_PRIV0_PLIMIT;
+	tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start;
+	tt_pages -= tt_start >> PAGE_SHIFT;
+	dev_priv->sizes.ta_mem_size = 0;
+
+
+	/* TT region managed by TTM. */
+	if (!ttm_bo_init_mm(bdev, TTM_PL_TT,
+			pg->gatt_pages -
+			(pg->ci_start >> PAGE_SHIFT) -
+			((dev_priv->ci_region_size + dev_priv->rar_region_size)
+			 >> PAGE_SHIFT))) {
+
+		dev_priv->have_tt = 1;
+		dev_priv->sizes.tt_size =
+			(tt_pages << PAGE_SHIFT) / (1024 * 1024) / 2;
+	}
+
+	DRM_DEBUG_KMS(" TT region size is %d\n",
+			pg->gatt_pages - (pg->ci_start >> PAGE_SHIFT) - ((dev_priv->ci_region_size +
+				dev_priv->rar_region_size) >> PAGE_SHIFT));
+	if (!ttm_bo_init_mm(bdev,
+			DRM_PSB_MEM_MMU,
+			PSB_MEM_TT_START >> PAGE_SHIFT)) {
+		dev_priv->have_mem_mmu = 1;
+		dev_priv->sizes.mmu_size =
+			PSB_MEM_TT_START / (1024*1024);
+	}
+
+
+	PSB_DEBUG_INIT("Init MSVDX\n");
+	if (psb_msvdx_init(dev)) {
+		ret = -EIO;
+		DRM_ERROR("Failure in MSVDX Initialization\n");
+		goto out_err;
+	}
+
+	return 0;
+out_err:
+	psb_do_takedown(dev);
+	return ret;
+}
+
+static int psb_driver_unload(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+
+	/*Fristly, unload pvr driver*/
+	PVRSRVDrmUnload(dev);
+
+	psb_intel_opregion_fini(dev);
+
+		psb_modeset_cleanup(dev);
+
+	if (dev_priv) {
+
+		/* psb_watchdog_takedown(dev_priv); */
+		psb_do_takedown(dev);
+
+		if (dev_priv->pf_pd) {
+			psb_mmu_free_pagedir(dev_priv->pf_pd);
+			dev_priv->pf_pd = NULL;
+		}
+		if (dev_priv->mmu) {
+			struct psb_gtt *pg = dev_priv->pg;
+
+			down_read(&pg->sem);
+			psb_mmu_remove_pfn_sequence(
+					psb_mmu_get_default_pd
+					(dev_priv->mmu),
+					pg->mmu_gatt_start,
+					pg->vram_stolen_size >> PAGE_SHIFT);
+			if (pg->ci_stolen_size != 0)
+				psb_mmu_remove_pfn_sequence(
+					psb_mmu_get_default_pd
+					(dev_priv->mmu),
+					pg->ci_start,
+					pg->ci_stolen_size >> PAGE_SHIFT);
+			if (pg->rar_stolen_size != 0)
+				psb_mmu_remove_pfn_sequence(
+					psb_mmu_get_default_pd
+					(dev_priv->mmu),
+					pg->rar_start,
+					pg->rar_stolen_size >> PAGE_SHIFT);
+			up_read(&pg->sem);
+			psb_mmu_driver_takedown(dev_priv->mmu);
+			dev_priv->mmu = NULL;
+		}
+		psb_gtt_takedown(dev_priv->pg, 1);
+		if (dev_priv->scratch_page) {
+			__free_page(dev_priv->scratch_page);
+			dev_priv->scratch_page = NULL;
+		}
+		if (dev_priv->has_bo_device) {
+			ttm_bo_device_release(&dev_priv->bdev);
+			dev_priv->has_bo_device = 0;
+		}
+		if (dev_priv->has_fence_device) {
+			ttm_fence_device_release(&dev_priv->fdev);
+			dev_priv->has_fence_device = 0;
+		}
+		if (dev_priv->vdc_reg) {
+			iounmap(dev_priv->vdc_reg);
+			dev_priv->vdc_reg = NULL;
+		}
+		if (dev_priv->sgx_reg) {
+			iounmap(dev_priv->sgx_reg);
+			dev_priv->sgx_reg = NULL;
+		}
+
+		if (dev_priv->msvdx_reg) {
+			iounmap(dev_priv->msvdx_reg);
+			dev_priv->msvdx_reg = NULL;
+		}
+
+		if (dev_priv->tdev)
+			ttm_object_device_release(&dev_priv->tdev);
+
+		if (dev_priv->has_global)
+			psb_ttm_global_release(dev_priv);
+
+		kfree(dev_priv);
+		dev->dev_private = NULL;
+
+		psb_intel_destory_bios(dev);
+	}
+
+	ospm_power_uninit();
+
+	return 0;
+}
+
+
+static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
+{
+	struct drm_psb_private *dev_priv;
+	struct ttm_bo_device *bdev;
+	unsigned long resource_start;
+	struct psb_gtt *pg;
+	unsigned long irqflags;
+	int ret = -ENOMEM;
+	uint32_t tt_pages;
+
+	DRM_DEBUG_KMS("psb - %s\n", PSB_PACKAGE_VERSION);
+
+#if defined(MODULE) && defined(CONFIG_NET)
+	psb_kobject_uevent_init();
+#endif
+
+	ret = SYSPVRInit();
+	if (ret)
+		return ret;
+
+	if (IS_CDV(dev))
+		DRM_DEBUG_KMS("Run drivers on Cedartrail platform!\n");
+
+	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
+	if (dev_priv == NULL)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&dev_priv->video_ctx);
+	dev_priv->num_pipe = 2;
+
+	/*init DPST umcomm to NULL*/
+	dev_priv->psb_dpst_state = NULL;
+	dev_priv->psb_hotplug_state = NULL;
+
+	dev_priv->dev = dev;
+	bdev = &dev_priv->bdev;
+
+	ret = psb_ttm_global_init(dev_priv);
+	if (unlikely(ret != 0))
+		goto out_err;
+	dev_priv->has_global = 1;
+
+	dev_priv->tdev = ttm_object_device_init(dev_priv->mem_global_ref.object,
+					   	PSB_OBJECT_HASH_ORDER);
+	if (unlikely(dev_priv->tdev == NULL))
+		goto out_err;
+
+	mutex_init(&dev_priv->temp_mem);
+	mutex_init(&dev_priv->cmdbuf_mutex);
+	mutex_init(&dev_priv->reset_mutex);
+	INIT_LIST_HEAD(&dev_priv->context.validate_list);
+	INIT_LIST_HEAD(&dev_priv->context.kern_validate_list);
+
+	spin_lock_init(&dev_priv->reloc_lock);
+
+	DRM_INIT_WAITQUEUE(&dev_priv->rel_mapped_queue);
+
+	dev->dev_private = (void *) dev_priv;
+	dev_priv->chipset = chipset;
+
+	PSB_DEBUG_GENERAL("Init watchdog and scheduler\n");
+	/* psb_watchdog_init(dev_priv); */
+	psb_scheduler_init(dev, &dev_priv->scheduler);
+
+
+	PSB_DEBUG_INIT("Mapping MMIO\n");
+	resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
+
+	if (IS_MSVDX(dev)) /* Work around for medfield by Li */
+		dev_priv->msvdx_reg = ioremap(resource_start + MRST_MSVDX_OFFSET,
+					      PSB_MSVDX_SIZE);
+	else
+		dev_priv->msvdx_reg = ioremap(resource_start + PSB_MSVDX_OFFSET,
+					      PSB_MSVDX_SIZE);
+
+	if (!dev_priv->msvdx_reg)
+		goto out_err;
+
+	dev_priv->vdc_reg = ioremap(resource_start + PSB_VDC_OFFSET,
+				    PSB_VDC_SIZE);
+	if (!dev_priv->vdc_reg)
+		goto out_err;
+
+	if (IS_MID(dev))
+		dev_priv->sgx_reg = ioremap(resource_start + MRST_SGX_OFFSET,
+					    PSB_SGX_SIZE);
+	else
+		dev_priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET,
+					    PSB_SGX_SIZE);
+
+	if (!dev_priv->sgx_reg)
+		goto out_err;
+
+	psb_get_core_freq(dev);
+
+	psb_intel_opregion_setup(dev);
+	psb_intel_init_bios(dev);
+
+	PSB_DEBUG_INIT("Init TTM fence and BO driver\n");
+
+	/* Init OSPM support */
+	ospm_power_init(dev);
+
+	ret = psb_ttm_fence_device_init(&dev_priv->fdev);
+	if (unlikely(ret != 0))
+		goto out_err;
+
+	/* For VXD385 DE2.x firmware support 16bit fence value */
+	if(IS_CDV(dev) && IS_FW_UPDATED) {
+		DRM_DEBUG_KMS("Setting up the video fences\n");
+		dev_priv->fdev.fence_class[PSB_ENGINE_VIDEO].wrap_diff = (1 << 14);
+		dev_priv->fdev.fence_class[PSB_ENGINE_VIDEO].flush_diff = ( 1 << 13);
+		dev_priv->fdev.fence_class[PSB_ENGINE_VIDEO].sequence_mask = 0x0000ffff;
+		dev_priv->sequence[PSB_ENGINE_VIDEO] = 1;
+	}
+	dev_priv->has_fence_device = 1;
+	ret = ttm_bo_device_init(bdev,
+				 dev_priv->bo_global_ref.ref.object,
+				 &psb_ttm_bo_driver,
+				 DRM_PSB_FILE_PAGE_OFFSET, false);
+	if (unlikely(ret != 0))
+		goto out_err;
+	dev_priv->has_bo_device = 1;
+	ttm_lock_init(&dev_priv->ttm_lock);
+
+	ret = -ENOMEM;
+
+	dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO);
+	if (!dev_priv->scratch_page)
+		goto out_err;
+
+	set_pages_uc(dev_priv->scratch_page, 1);
+
+	dev_priv->pg = psb_gtt_alloc(dev);
+	if (!dev_priv->pg)
+		goto out_err;
+
+	ret = psb_gtt_init(dev_priv->pg, 0);
+	if (ret)
+		goto out_err;
+
+	ret = psb_gtt_mm_init(dev_priv->pg);
+	if (ret)
+		goto out_err;
+
+	dev_priv->mmu = psb_mmu_driver_init((void *)0,
+					drm_psb_trap_pagefaults, 0,
+					dev_priv);
+	if (!dev_priv->mmu)
+		goto out_err;
+
+	pg = dev_priv->pg;
+
+	tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?  (pg->gatt_pages) :
+	       					             PSB_TT_PRIV0_PLIMIT;
+
+	/* CI/RAR use the lower half of TT. */
+	pg->ci_start = ((tt_pages *3)/ 4) << PAGE_SHIFT;
+	pg->rar_start = pg->ci_start + pg->ci_stolen_size;
+
+
+	/*
+	 * Make MSVDX/TOPAZ MMU aware of the CI stolen memory area.
+	 */
+	if (dev_priv->pg->ci_stolen_size != 0) {
+		down_read(&pg->sem);
+		ret = psb_mmu_insert_pfn_sequence(psb_mmu_get_default_pd
+				(dev_priv->mmu),
+				dev_priv->ci_region_start >> PAGE_SHIFT,
+				pg->mmu_gatt_start + pg->ci_start,
+				pg->ci_stolen_size >> PAGE_SHIFT, 0);
+		up_read(&pg->sem);
+		if (ret)
+			goto out_err;
+	}
+
+	/*
+	 * Make MSVDX/TOPAZ MMU aware of the rar stolen memory area.
+	 */
+	if (dev_priv->pg->rar_stolen_size != 0) {
+		down_read(&pg->sem);
+		ret = psb_mmu_insert_pfn_sequence(
+				psb_mmu_get_default_pd(dev_priv->mmu),
+				dev_priv->rar_region_start >> PAGE_SHIFT,
+				pg->mmu_gatt_start + pg->rar_start,
+				pg->rar_stolen_size >> PAGE_SHIFT, 0);
+		up_read(&pg->sem);
+		if (ret)
+			goto out_err;
+	}
+
+	dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0);
+	if (!dev_priv->pf_pd)
+		goto out_err;
+
+	psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
+	psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
+
+	spin_lock_init(&dev_priv->sequence_lock);
+
+	PSB_DEBUG_INIT("Begin to init MSVDX/Topaz\n");
+
+	ret = psb_do_init(dev);
+	if (ret)
+		return ret;
+
+	/*initialize the MSI*/
+	if (IS_MID(dev)) {
+		if (pci_enable_msi(dev->pdev)) {
+			DRM_ERROR("Enable MSI failed!\n");
+		} else {
+			PSB_DEBUG_INIT("Enabled MSI IRQ (%d)\n",
+				       dev->pdev->irq);
+			/* pci_write_config_word(pdev, 0x04, 0x07); */
+		}
+	}
+
+	ret = drm_vblank_init(dev, dev_priv->num_pipe);
+	if (ret)
+	    goto out_err;
+
+	/*
+	 * Install interrupt handlers prior to powering off SGX or else we will
+	 * crash.
+	 */
+	dev_priv->vdc_irq_mask = 0;
+	dev_priv->pipestat[0] = 0;
+	dev_priv->pipestat[1] = 0;
+	dev_priv->pipestat[2] = 0;
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
+	PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
+	PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		drm_irq_install(dev);
+
+	dev->vblank_disable_allowed = 1;
+
+	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+
+	dev->driver->get_vblank_counter = psb_get_vblank_counter;
+
+	psb_intel_opregion_init(dev);
+	acpi_video_register();
+
+	{
+		psb_modeset_init(dev);
+		psb_fbdev_init(dev);
+		drm_kms_helper_poll_init(dev);
+	}
+
+	/* initialize HDMI Hotplug interrupt forwarding
+	* notifications for user mode
+	*/
+
+	/*Intel drm driver load is done, continue doing pvr load*/
+	DRM_DEBUG_KMS("Pvr driver load\n");
+
+	ret = PVRSRVDrmLoad(dev, chipset);
+	if (ret)
+		return ret;
+
+	/*init for bc_video*/
+	return BC_Video_ModInit();
+
+out_err:
+	psb_driver_unload(dev);
+	return ret;
+}
+
+int psb_driver_device_is_agp(struct drm_device *dev)
+{
+	return 0;
+}
+
+int psb_extension_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	union drm_psb_extension_arg *arg = data;
+	struct drm_psb_extension_rep *rep = &arg->rep;
+
+	if (strcmp(arg->extension, "psb_ttm_placement_alphadrop") == 0) {
+		rep->exists = 1;
+		rep->driver_ioctl_offset = DRM_PSB_PLACEMENT_OFFSET;
+		rep->sarea_offset = 0;
+		rep->major = 1;
+		rep->minor = 0;
+		rep->pl = 0;
+		return 0;
+	}
+	if (strcmp(arg->extension, "psb_ttm_fence_alphadrop") == 0) {
+		rep->exists = 1;
+		rep->driver_ioctl_offset = DRM_PSB_FENCE_OFFSET;
+		rep->sarea_offset = 0;
+		rep->major = 1;
+		rep->minor = 0;
+		rep->pl = 0;
+		return 0;
+	}
+	if (strcmp(arg->extension, "psb_ttm_execbuf_alphadrop") == 0) {
+		rep->exists = 1;
+		rep->driver_ioctl_offset = DRM_PSB_CMDBUF;
+		rep->sarea_offset = 0;
+		rep->major = 1;
+		rep->minor = 0;
+		rep->pl = 0;
+		return 0;
+	}
+
+	/*return the page flipping ioctl offset*/
+	if (strcmp(arg->extension, "psb_page_flipping_alphadrop") == 0) {
+		rep->exists = 1;
+		rep->driver_ioctl_offset = DRM_PSB_FLIP;
+		rep->sarea_offset = 0;
+		rep->major = 1;
+		rep->minor = 0;
+		rep->pl = 0;
+		return 0;
+	}
+
+	/* return the video rar offset */
+	if (strcmp(arg->extension, "lnc_video_getparam") == 0) {
+		rep->exists = 1;
+		rep->driver_ioctl_offset = DRM_LNC_VIDEO_GETPARAM;
+		rep->sarea_offset = 0;
+		rep->major = 1;
+		rep->minor = 0;
+		rep->pl = 0;
+		return 0;
+	}
+
+	rep->exists = 0;
+	return 0;
+}
+
+static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct ttm_bo_device *bdev = &dev_priv->bdev;
+	int ret;
+
+	ret = ttm_vt_lock(&dev_priv->ttm_lock, 1,
+			     psb_fpriv(file_priv)->tfile);
+	if (unlikely(ret != 0))
+		return ret;
+
+	ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_TT);
+	if (unlikely(ret != 0))
+		goto out_unlock;
+
+	ret = ttm_bo_clean_mm(bdev, TTM_PL_TT);
+	if (unlikely(ret != 0))
+		DRM_INFO("Warning: GATT was not clean after VT switch.\n");
+
+	ttm_bo_swapout_all(&dev_priv->bdev);
+
+	return 0;
+out_unlock:
+	(void) ttm_vt_unlock(&dev_priv->ttm_lock);
+	return ret;
+}
+
+static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	return ttm_vt_unlock(&dev_priv->ttm_lock);
+}
+
+static int psb_sizes_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct drm_psb_sizes_arg *arg =
+		(struct drm_psb_sizes_arg *) data;
+
+	*arg = dev_priv->sizes;
+	return 0;
+}
+
+static int psb_fuse_reg_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	uint32_t *arg = data;
+
+	*arg = dev_priv->fuse_reg_value;
+	return 0;
+}
+static int psb_vbt_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct gct_ioctl_arg *pGCT = data;
+
+	memcpy(pGCT, &dev_priv->gct_data, sizeof(*pGCT));
+
+	return 0;
+}
+
+static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
+				struct drm_file *file_priv)
+{
+	uint32_t flags;
+	uint32_t obj_id;
+	struct drm_mode_object *obj;
+	struct drm_connector *connector;
+	struct drm_crtc *crtc;
+	struct drm_psb_dc_state_arg *arg =
+		(struct drm_psb_dc_state_arg *)data;
+
+	if (IS_MID(dev))
+		return 0;
+
+	flags = arg->flags;
+	obj_id = arg->obj_id;
+
+	if (flags & PSB_DC_CRTC_MASK) {
+		obj = drm_mode_object_find(dev, obj_id,
+				DRM_MODE_OBJECT_CRTC);
+		if (!obj) {
+			DRM_DEBUG_KMS("Invalid CRTC object.\n");
+			return -EINVAL;
+		}
+
+		crtc = obj_to_crtc(obj);
+
+		mutex_lock(&dev->mode_config.mutex);
+		if (drm_helper_crtc_in_use(crtc)) {
+			if (flags & PSB_DC_CRTC_SAVE)
+				crtc->funcs->save(crtc);
+			else
+				crtc->funcs->restore(crtc);
+		}
+		mutex_unlock(&dev->mode_config.mutex);
+
+		return 0;
+	} else if (flags & PSB_DC_OUTPUT_MASK) {
+		obj = drm_mode_object_find(dev, obj_id,
+				DRM_MODE_OBJECT_CONNECTOR);
+		if (!obj) {
+			DRM_DEBUG_KMS("Invalid connector id.\n");
+			return -EINVAL;
+		}
+
+		connector = obj_to_connector(obj);
+		if (flags & PSB_DC_OUTPUT_SAVE)
+			connector->funcs->save(connector);
+		else
+			connector->funcs->restore(connector);
+
+		return 0;
+	}
+
+	DRM_DEBUG_KMS("Bad flags 0x%x\n", flags);
+	return -EINVAL;
+}
+
+static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	uint32_t *arg = data;
+	struct backlight_device bd;
+	dev_priv->blc_adj2 = *arg;
+
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+	bd.props.brightness = psb_get_brightness(&bd);
+	psb_set_brightness(&bd);
+#endif
+	return 0;
+}
+
+static int psb_adb_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	uint32_t *arg = data;
+	struct backlight_device bd;
+	dev_priv->blc_adj1 = *arg;
+
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+	bd.props.brightness = psb_get_brightness(&bd);
+	psb_set_brightness(&bd);
+#endif
+	return 0;
+}
+
+static int psb_hist_enable_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	u32 irqCtrl = 0;
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct dpst_guardband guardband_reg;
+	struct dpst_ie_histogram_control ie_hist_cont_reg;
+	uint32_t *enable = data;
+
+	if (*enable == 1) {
+		ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
+		ie_hist_cont_reg.ie_pipe_assignment = 0;
+		ie_hist_cont_reg.histogram_mode_select = DPST_YUV_LUMA_MODE;
+		ie_hist_cont_reg.ie_histogram_enable = 1;
+		PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
+
+		guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+		guardband_reg.interrupt_enable = 1;
+		guardband_reg.interrupt_status = 1;
+		PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
+
+		irqCtrl = PSB_RVDC32(PIPEASTAT);
+		PSB_WVDC32(irqCtrl | PIPE_DPST_EVENT_ENABLE, PIPEASTAT);
+		/* Wait for two vblanks */
+	} else {
+		guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+		guardband_reg.interrupt_enable = 0;
+		guardband_reg.interrupt_status = 1;
+		PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
+
+		ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
+		ie_hist_cont_reg.ie_histogram_enable = 0;
+		PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
+
+		irqCtrl = PSB_RVDC32(PIPEASTAT);
+		irqCtrl &= ~PIPE_DPST_EVENT_ENABLE;
+		PSB_WVDC32(irqCtrl, PIPEASTAT);
+	}
+
+	return 0;
+}
+
+static int psb_hist_status_ioctl(struct drm_device *dev, void *data,
+				 struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv		= psb_priv(dev);
+	struct drm_psb_hist_status_arg *hist_status	= data;
+	uint32_t *arg					= hist_status->buf;
+	u32 iedbr_reg_data				= 0;
+	struct dpst_ie_histogram_control ie_hist_cont_reg;
+	u32 i;
+	int dpst3_bin_threshold_count	= 0;
+	uint32_t blm_hist_ctl		= HISTOGRAM_LOGIC_CONTROL;
+	uint32_t iebdr_reg		= HISTOGRAM_BIN_DATA;
+	uint32_t segvalue_max_22_bit	= 0x3fffff;
+	uint32_t iedbr_busy_bit		= 0x80000000;
+	int dpst3_bin_count		= 32;
+
+	ie_hist_cont_reg.data			= PSB_RVDC32(blm_hist_ctl);
+	ie_hist_cont_reg.bin_reg_func_select	= dpst3_bin_threshold_count;
+	ie_hist_cont_reg.bin_reg_index		= 0;
+
+	PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
+
+	for (i = 0; i < dpst3_bin_count; i++) {
+		iedbr_reg_data = PSB_RVDC32(iebdr_reg);
+
+		if (!(iedbr_reg_data & iedbr_busy_bit)) {
+			arg[i] = iedbr_reg_data & segvalue_max_22_bit;
+		} else {
+			i = 0;
+			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
+			ie_hist_cont_reg.bin_reg_index = 0;
+			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
+		}
+	}
+
+	return 0;
+}
+
+static int psb_init_comm_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct pci_dev *pdev = NULL;
+	struct device *ddev = NULL;
+	struct kobject *kobj = NULL;
+	uint32_t *arg = data;
+
+	if (*arg == 1) {
+		/*find handle to drm kboject*/
+		pdev = dev->pdev;
+		ddev = &pdev->dev;
+		kobj = &ddev->kobj;
+
+		if (dev_priv->psb_dpst_state == NULL) {
+			/*init dpst kmum comms*/
+			dev_priv->psb_dpst_state = psb_dpst_init(kobj);
+		} else {
+			DRM_INFO("DPST already initialized\n");
+		}
+		if (dev_priv->psb_dpst_state == NULL) {
+			DRM_ERROR("DPST is not initialized correctly\n");
+			return -EINVAL;
+		}
+		psb_irq_enable_dpst(dev);
+		psb_dpst_notify_change_um(DPST_EVENT_INIT_COMPLETE,
+					  dev_priv->psb_dpst_state);
+	} else {
+		if (dev_priv->psb_dpst_state == NULL) {
+			DRM_ERROR("DPST doesn't exit\n");
+			return -EINVAL;
+		}
+		/*hotplug and dpst destroy examples*/
+		psb_irq_disable_dpst(dev);
+		psb_dpst_notify_change_um(DPST_EVENT_TERMINATE,
+					  dev_priv->psb_dpst_state);
+		psb_dpst_device_pool_destroy(dev_priv->psb_dpst_state);
+		dev_priv->psb_dpst_state = NULL;
+	}
+	return 0;
+}
+
+/* return the current mode to the dpst module */
+static int psb_dpst_ioctl(struct drm_device *dev, void *data,
+			  struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	uint32_t *arg = data;
+	uint32_t x;
+	uint32_t y;
+	uint32_t reg;
+
+	reg = PSB_RVDC32(PIPEASRC);
+
+	/* horizontal is the left 16 bits */
+	x = reg >> 16;
+	/* vertical is the right 16 bits */
+	y = reg & 0x0000ffff;
+
+	/* the values are the image size minus one */
+	x+=1;
+	y+=1;
+
+	*arg = (x << 16) | y;
+
+	return 0;
+}
+
+static int psb_gamma_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct drm_psb_dpst_lut_arg *lut_arg = data;
+	struct drm_mode_object *obj;
+	struct drm_crtc *crtc;
+	struct drm_connector *connector;
+	struct psb_intel_crtc *psb_intel_crtc;
+	int i = 0;
+	int32_t obj_id;
+
+	obj_id = lut_arg->output_id;
+	obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
+	if (!obj) {
+		DRM_DEBUG_KMS("Invalid Connector object.\n");
+		return -EINVAL;
+	}
+
+	connector = obj_to_connector(obj);
+	crtc = connector->encoder->crtc;
+	psb_intel_crtc = to_psb_intel_crtc(crtc);
+
+	for (i = 0; i < 256; i++)
+		psb_intel_crtc->lut_adj[i] = lut_arg->lut[i];
+
+	psb_intel_crtc_load_lut(crtc);
+
+	return 0;
+}
+
+static int psb_update_guard_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct dpst_guardband* input = (struct dpst_guardband*) data;
+	struct dpst_guardband reg_data;
+
+	reg_data.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+	reg_data.guardband = input->guardband;
+	reg_data.guardband_interrupt_delay = input->guardband_interrupt_delay;
+	/* printk(KERN_ALERT "guardband = %u\ninterrupt delay = %u\n", 
+		reg_data.guardband, reg_data.guardband_interrupt_delay); */
+	PSB_WVDC32(reg_data.data, HISTOGRAM_INT_CONTROL);
+	
+	return 0;
+}
+
+static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	uint32_t obj_id;
+	uint16_t op;
+	struct drm_mode_modeinfo *umode;
+	struct drm_display_mode *mode = NULL;
+	struct drm_psb_mode_operation_arg *arg;
+	struct drm_mode_object *obj;
+	struct drm_connector *connector;
+	struct drm_framebuffer * drm_fb;
+	struct psb_framebuffer * psb_fb;
+	struct drm_connector_helper_funcs *connector_funcs;
+	int ret = 0;
+	int resp = MODE_OK;
+
+	arg = (struct drm_psb_mode_operation_arg *)data;
+        obj_id = arg->obj_id;
+	op = arg->operation;
+
+	switch(op) {
+	case PSB_MODE_OPERATION_SET_DC_BASE:
+		obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB);
+		if(!obj) {
+			DRM_ERROR("Invalid FB id %d\n", obj_id);
+			return -EINVAL;
+		}
+
+		drm_fb = obj_to_fb(obj);
+		psb_fb = to_psb_fb(drm_fb);
+			
+		REG_WRITE(DSPASURF, psb_fb->offset);
+		REG_READ(DSPASURF);
+		REG_WRITE(DSPBSURF, psb_fb->offset);
+		REG_READ(DSPBSURF);
+		
+		return 0;
+	case PSB_MODE_OPERATION_MODE_VALID:
+		umode = &arg->mode;
+
+		mutex_lock(&dev->mode_config.mutex);
+
+		obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
+		if (!obj) {
+			ret = -EINVAL;
+			goto mode_op_out;
+		}
+
+		connector = obj_to_connector(obj);
+
+		mode = drm_mode_create(dev);
+		if (!mode) {
+			ret = -ENOMEM;
+			goto mode_op_out;
+		}
+
+		/* drm_crtc_convert_umode(mode, umode); */
+		{
+			mode->clock = umode->clock;
+			mode->hdisplay = umode->hdisplay;
+			mode->hsync_start = umode->hsync_start;
+			mode->hsync_end = umode->hsync_end;
+			mode->htotal = umode->htotal;
+			mode->hskew = umode->hskew;
+			mode->vdisplay = umode->vdisplay;
+			mode->vsync_start = umode->vsync_start;
+			mode->vsync_end = umode->vsync_end;
+			mode->vtotal = umode->vtotal;
+			mode->vscan = umode->vscan;
+			mode->vrefresh = umode->vrefresh;
+			mode->flags = umode->flags;
+			mode->type = umode->type;
+			strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN);
+			mode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+		}
+
+		connector_funcs = (struct drm_connector_helper_funcs *)
+				   connector->helper_private;
+
+		if (connector_funcs->mode_valid) {
+			resp = connector_funcs->mode_valid(connector, mode);
+			arg->data = (void *)resp;
+		}
+
+		/*do some clean up work*/
+        	if(mode) {
+                	drm_mode_destroy(dev, mode);
+        	}
+mode_op_out:
+        	mutex_unlock(&dev->mode_config.mutex);
+        	return ret;
+
+	default:
+		DRM_DEBUG_KMS("Unsupported psb mode operation");
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
+				   struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct drm_psb_stolen_memory_arg *arg = data;
+
+	arg->base = dev_priv->pg->stolen_base;
+	arg->size = dev_priv->pg->vram_stolen_size;
+
+	return 0;
+}
+
+#define CRTC_PIPEA	(1 << 0)
+#define CRTC_PIPEB	(1 << 1)
+
+static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
+				 struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct drm_psb_register_rw_arg *arg = data;
+	unsigned int iep_ble_status;
+	unsigned long iep_timeout;
+
+	if (arg->display_write_mask != 0) {
+		if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
+			PSB_WVDC32(arg->display.pfit_controls,
+				   PFIT_CONTROL);
+		if (arg->display_write_mask & REGRWBITS_PFIT_AUTOSCALE_RATIOS)
+			PSB_WVDC32(arg->display.pfit_autoscale_ratios,
+				   PFIT_AUTO_RATIOS);
+		if (arg->display_write_mask & REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
+			PSB_WVDC32(arg->display.pfit_programmed_scale_ratios,
+				   PFIT_PGM_RATIOS);
+		if (arg->display_write_mask & REGRWBITS_PIPEASRC)
+			PSB_WVDC32(arg->display.pipeasrc, PIPEASRC);
+		if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
+			PSB_WVDC32(arg->display.pipebsrc, PIPEBSRC);
+		if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
+			PSB_WVDC32(arg->display.vtotal_a, VTOTAL_A);
+		if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
+			PSB_WVDC32(arg->display.vtotal_b, VTOTAL_B);
+	}
+
+	if (arg->display_read_mask != 0) {
+		if (arg->display_read_mask & REGRWBITS_PFIT_CONTROLS)
+			arg->display.pfit_controls = PSB_RVDC32(PFIT_CONTROL);
+		if (arg->display_read_mask & REGRWBITS_PFIT_AUTOSCALE_RATIOS)
+			arg->display.pfit_autoscale_ratios = PSB_RVDC32(PFIT_AUTO_RATIOS);
+		if (arg->display_read_mask & REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
+			arg->display.pfit_programmed_scale_ratios = PSB_RVDC32(PFIT_PGM_RATIOS);
+		if (arg->display_read_mask & REGRWBITS_PIPEASRC)
+			arg->display.pipeasrc = PSB_RVDC32(PIPEASRC);
+		if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
+			arg->display.pipebsrc = PSB_RVDC32(PIPEBSRC);
+		if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
+			arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A);
+		if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
+			arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B);
+		if (arg->display_read_mask & REGRBITS_PIPECONF) {
+				arg->display.pipe_enabled = 0;
+			if ((PSB_RVDC32(PIPEACONF) & PIPEACONF_ENABLE))
+				arg->display.pipe_enabled |= CRTC_PIPEA;
+			if ((PSB_RVDC32(PIPEBCONF) & PIPEACONF_ENABLE))
+				arg->display.pipe_enabled |= CRTC_PIPEB;
+		}
+	}
+
+	if (arg->overlay_write_mask != 0) {
+		if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
+			PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5);
+			PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4);
+			PSB_WVDC32(arg->overlay.OGAMC3, OV_OGAMC3);
+			PSB_WVDC32(arg->overlay.OGAMC2, OV_OGAMC2);
+			PSB_WVDC32(arg->overlay.OGAMC1, OV_OGAMC1);
+			PSB_WVDC32(arg->overlay.OGAMC0, OV_OGAMC0);
+		}
+		if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) {
+			PSB_WVDC32(arg->overlay.OGAMC5, OVC_OGAMC5);
+			PSB_WVDC32(arg->overlay.OGAMC4, OVC_OGAMC4);
+			PSB_WVDC32(arg->overlay.OGAMC3, OVC_OGAMC3);
+			PSB_WVDC32(arg->overlay.OGAMC2, OVC_OGAMC2);
+			PSB_WVDC32(arg->overlay.OGAMC1, OVC_OGAMC1);
+			PSB_WVDC32(arg->overlay.OGAMC0, OVC_OGAMC0);
+		}
+
+		if (arg->overlay_write_mask & OV_REGRWBITS_OVADD)
+		{
+			PSB_WVDC32(arg->overlay.OVADD, OV_OVADD);
+
+			if (arg->overlay.b_wait_vblank) {
+				/*Wait for 20ms.*/
+				unsigned long vblank_timeout = jiffies + HZ/50;
+				uint32_t temp;
+				while (time_before_eq(jiffies, vblank_timeout)) {
+					temp = PSB_RVDC32(OV_DOVASTA);
+					if ((temp & (0x1 << 31)) != 0) {
+						break;
+					}
+					cpu_relax();
+				}
+			}
+
+			if (IS_CDV(dev)) {
+
+				if (arg->overlay.IEP_ENABLED) {	
+					/* VBLANK period */
+					iep_timeout = jiffies + HZ / 10;
+					do{
+						iep_ble_status = PSB_RVDC32(0x31800);
+						if (time_after_eq(jiffies, iep_timeout)) {
+							DRM_ERROR("IEP Lite timeout\n");
+							break;
+						}
+						cpu_relax();
+					}while((iep_ble_status>>1) != 1);
+
+					arg->overlay.IEP_BLE_MINMAX    = PSB_RVDC32(0x31804);
+					arg->overlay.IEP_BSSCC_CONTROL = PSB_RVDC32(0x32000);
+				}
+			}
+		}
+		if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) {
+			PSB_WVDC32(arg->overlay.OVADD, OVC_OVADD);
+			if (arg->overlay.b_wait_vblank) {
+				/*Wait for 20ms.*/
+				unsigned long vblank_timeout = jiffies + HZ/50;
+				uint32_t temp;
+				while (time_before_eq(jiffies, vblank_timeout)) {
+					temp = PSB_RVDC32(OVC_DOVCSTA);
+					if ((temp & (0x1 << 31)) != 0) {
+						break;
+					}
+					cpu_relax();
+				}
+			}
+		}
+	}
+
+	if (arg->overlay_read_mask != 0) {
+		if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
+			arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5);
+			arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4);
+			arg->overlay.OGAMC3 = PSB_RVDC32(OV_OGAMC3);
+			arg->overlay.OGAMC2 = PSB_RVDC32(OV_OGAMC2);
+			arg->overlay.OGAMC1 = PSB_RVDC32(OV_OGAMC1);
+			arg->overlay.OGAMC0 = PSB_RVDC32(OV_OGAMC0);
+		}
+		if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) {
+			arg->overlay.OGAMC5 = PSB_RVDC32(OVC_OGAMC5);
+			arg->overlay.OGAMC4 = PSB_RVDC32(OVC_OGAMC4);
+			arg->overlay.OGAMC3 = PSB_RVDC32(OVC_OGAMC3);
+			arg->overlay.OGAMC2 = PSB_RVDC32(OVC_OGAMC2);
+			arg->overlay.OGAMC1 = PSB_RVDC32(OVC_OGAMC1);
+			arg->overlay.OGAMC0 = PSB_RVDC32(OVC_OGAMC0);
+		}
+		if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
+			arg->overlay.OVADD = PSB_RVDC32(OV_OVADD);
+		if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
+			arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD);
+	}
+
+	if (arg->sprite_enable_mask != 0) {
+		PSB_WVDC32(0x1F3E, DSPARB);
+		PSB_WVDC32(arg->sprite.dspa_control | PSB_RVDC32(DSPACNTR), DSPACNTR);
+		PSB_WVDC32(arg->sprite.dspa_key_value, DSPAKEYVAL);
+		PSB_WVDC32(arg->sprite.dspa_key_mask, DSPAKEYMASK);
+		PSB_WVDC32(PSB_RVDC32(DSPASURF), DSPASURF);
+		PSB_RVDC32(DSPASURF);
+		PSB_WVDC32(arg->sprite.dspc_control, DSPCCNTR);
+		PSB_WVDC32(arg->sprite.dspc_stride, DSPCSTRIDE);
+		PSB_WVDC32(arg->sprite.dspc_position, DSPCPOS);
+		PSB_WVDC32(arg->sprite.dspc_linear_offset, DSPCLINOFF);
+		PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE);
+		PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
+		PSB_RVDC32(DSPCSURF);
+	}
+
+	if (arg->sprite_disable_mask != 0) {
+		PSB_WVDC32(0x3F3E, DSPARB);
+		PSB_WVDC32(0x0, DSPCCNTR);
+		PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
+		PSB_RVDC32(DSPCSURF);
+	}
+
+	if (arg->subpicture_enable_mask != 0) {
+		uint32_t temp;
+		if ( arg->subpicture_enable_mask & REGRWBITS_DSPACNTR){
+			temp =  PSB_RVDC32(DSPACNTR);
+			temp &= ~DISPPLANE_PIXFORMAT_MASK;			
+			temp &= ~DISPPLANE_BOTTOM;
+			temp |= DISPPLANE_32BPP;
+			PSB_WVDC32(temp, DSPACNTR);
+
+			temp =  PSB_RVDC32(DSPABASE);
+			PSB_WVDC32(temp, DSPABASE);
+			PSB_RVDC32(DSPABASE);
+			temp =  PSB_RVDC32(DSPASURF);
+			PSB_WVDC32(temp, DSPASURF);
+			PSB_RVDC32(DSPASURF);
+		}
+		if ( arg->subpicture_enable_mask & REGRWBITS_DSPBCNTR){
+			temp =  PSB_RVDC32(DSPBCNTR);
+			temp &= ~DISPPLANE_PIXFORMAT_MASK;			
+			temp &= ~DISPPLANE_BOTTOM;
+			temp |= DISPPLANE_32BPP;
+			PSB_WVDC32(temp, DSPBCNTR);
+
+			temp =  PSB_RVDC32(DSPBBASE);
+			PSB_WVDC32(temp, DSPBBASE);
+			PSB_RVDC32(DSPBBASE);
+			temp =  PSB_RVDC32(DSPBSURF);
+			PSB_WVDC32(temp, DSPBSURF);
+			PSB_RVDC32(DSPBSURF);
+		}
+		if ( arg->subpicture_enable_mask & REGRWBITS_DSPCCNTR){
+			temp =  PSB_RVDC32(DSPCCNTR);
+			temp &= ~DISPPLANE_PIXFORMAT_MASK;			
+			temp &= ~DISPPLANE_BOTTOM;
+			temp |= DISPPLANE_32BPP;
+			PSB_WVDC32(temp, DSPCCNTR);
+
+			temp =  PSB_RVDC32(DSPCBASE);
+			PSB_WVDC32(temp, DSPCBASE);
+			PSB_RVDC32(DSPCBASE);
+			temp =  PSB_RVDC32(DSPCSURF);
+			PSB_WVDC32(temp, DSPCSURF);
+			PSB_RVDC32(DSPCSURF);
+		}
+	}
+	
+	if (arg->subpicture_disable_mask != 0) {
+		uint32_t temp;
+		if ( arg->subpicture_disable_mask & REGRWBITS_DSPACNTR){
+			temp =  PSB_RVDC32(DSPACNTR);
+			temp &= ~DISPPLANE_PIXFORMAT_MASK;			
+			temp |= DISPPLANE_32BPP_NO_ALPHA;
+			PSB_WVDC32(temp, DSPACNTR);
+
+			temp =  PSB_RVDC32(DSPABASE);
+			PSB_WVDC32(temp, DSPABASE);
+			PSB_RVDC32(DSPABASE);
+			temp =  PSB_RVDC32(DSPASURF);
+			PSB_WVDC32(temp, DSPASURF);
+			PSB_RVDC32(DSPASURF);
+		}
+		if ( arg->subpicture_disable_mask & REGRWBITS_DSPBCNTR){
+			temp =  PSB_RVDC32(DSPBCNTR);
+			temp &= ~DISPPLANE_PIXFORMAT_MASK;			
+			temp |= DISPPLANE_32BPP_NO_ALPHA;
+			PSB_WVDC32(temp, DSPBCNTR);
+
+			temp =  PSB_RVDC32(DSPBBASE);
+			PSB_WVDC32(temp, DSPBBASE);
+			PSB_RVDC32(DSPBBASE);
+			temp =  PSB_RVDC32(DSPBSURF);
+			PSB_WVDC32(temp, DSPBSURF);
+			PSB_RVDC32(DSPBSURF);
+		}
+		if ( arg->subpicture_disable_mask & REGRWBITS_DSPCCNTR){
+			temp =  PSB_RVDC32(DSPCCNTR);
+			temp &= ~DISPPLANE_PIXFORMAT_MASK;			
+			temp |= DISPPLANE_32BPP_NO_ALPHA;
+			PSB_WVDC32(temp, DSPCCNTR);
+
+			temp =  PSB_RVDC32(DSPCBASE);
+			PSB_WVDC32(temp, DSPCBASE);
+			PSB_RVDC32(DSPCBASE);
+			temp =  PSB_RVDC32(DSPCSURF);
+			PSB_WVDC32(temp, DSPCSURF);
+			PSB_RVDC32(DSPCSURF);
+		}
+	}
+
+	return 0;
+}
+
+/* always available as we are SIGIO'd */
+static unsigned int psb_poll(struct file *filp,
+			     struct poll_table_struct *wait)
+{
+	return POLLIN | POLLRDNORM;
+}
+
+static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
+{
+	DRM_DEBUG_KMS("\n");
+	return PVRSRVOpen(dev, priv);
+}
+
+/* When a client dies:
+ *    - Check for and clean up flipped page state
+ */
+void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv)
+{
+}
+
+static void psb_remove(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	drm_put_dev(dev);
+}
+
+static const struct dev_pm_ops psb_pm_ops = {
+        .runtime_suspend = psb_runtime_suspend,
+        .runtime_resume = psb_runtime_resume,
+        .runtime_idle = psb_runtime_idle,
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \
+			   DRIVER_IRQ_VBL | DRIVER_MODESET,
+	.load = psb_driver_load,
+	.unload = psb_driver_unload,
+
+	.ioctls = psb_ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(psb_ioctls),
+	.device_is_agp = psb_driver_device_is_agp,
+	.irq_preinstall = psb_irq_preinstall,
+	.irq_postinstall = psb_irq_postinstall,
+	.irq_uninstall = psb_irq_uninstall,
+	.irq_handler = psb_irq_handler,
+	.enable_vblank = psb_enable_vblank,
+	.disable_vblank = psb_disable_vblank,
+	.get_vblank_counter = psb_get_vblank_counter,
+	.firstopen = NULL,
+	.lastclose = psb_lastclose,
+	.open = psb_driver_open,
+	.postclose = PVRSRVDrmPostClose,
+	.suspend = PVRSRVDriverSuspend,
+	.resume = PVRSRVDriverResume,
+	.preclose = psb_driver_preclose,
+	.fops = {
+		 .owner = THIS_MODULE,
+		 .open = psb_open,
+		 .release = psb_release,
+		 .unlocked_ioctl = drm_ioctl,
+		 .mmap = psb_mmap,
+		 .poll = psb_poll,
+		 .fasync = drm_fasync,
+		 .read = drm_read,
+		 },
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = PSB_DRM_DRIVER_DATE,
+	.major = PSB_DRM_DRIVER_MAJOR,
+	.minor = PSB_DRM_DRIVER_MINOR,
+	.patchlevel = PSB_DRM_DRIVER_PATCHLEVEL
+};
+
+static struct pci_driver psb_pci_driver = {
+	.name = DRIVER_NAME,
+	.id_table = pciidlist,
+	.resume = ospm_power_resume,
+	.suspend = ospm_power_suspend,
+	.probe = psb_probe,
+	.remove = psb_remove,
+#if 0
+#ifdef CONFIG_PM
+	.driver.pm = &psb_pm_ops,
+#endif
+#endif
+};
+
+static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	return drm_get_pci_dev(pdev, ent, &driver);
+}
+
+static int __init psb_init(void)
+{
+	return drm_pci_init(&driver, &psb_pci_driver);
+}
+
+static void __exit psb_exit(void)
+{
+    int ret;
+
+    /*cleanup for bc_video*/
+    ret = BC_Video_ModCleanup();
+    if (ret != 0)
+    {
+        return;
+    }
+
+    drm_pci_exit(&driver, &psb_pci_driver);
+}
+
+late_initcall(psb_init);
+module_exit(psb_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/cdv/drv/psb_drv.h b/drivers/staging/cdv/drv/psb_drv.h
new file mode 100644
index 0000000..0d93bb0
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_drv.h
@@ -0,0 +1,1237 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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 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.
+ *
+ **************************************************************************/
+
+#ifndef _PSB_DRV_H_
+#define _PSB_DRV_H_
+
+#include <linux/version.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include "sys_pvr_drm_export.h"
+#include "psb_drm.h"
+#include "psb_reg.h"
+#include "psb_schedule.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_bios.h"
+#include "psb_hotplug.h"
+#include "psb_dpst.h"
+#include "psb_gtt.h"
+#include "psb_powermgmt.h"
+#include "ttm/ttm_object.h"
+#include "psb_ttm_fence_driver.h"
+#include "psb_ttm_userobj_api.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_lock.h"
+
+/*IMG headers*/
+#include "private_data.h"
+#include "pvr_drm.h"
+
+#include <linux/backlight.h>
+
+/*Append new drm mode definition here, align with libdrm definition*/
+#define DRM_MODE_SCALE_NO_SCALE   2
+
+extern struct ttm_bo_driver psb_ttm_bo_driver;
+
+enum panel_type {
+	TPO_CMD,
+	TPO_VID,
+	TMD_CMD,
+	TMD_VID,
+	PYR_CMD,
+	PYR_VID,
+	TPO,
+	TMD,
+	PYR,
+	HDMI,
+	GCT_DETECT
+};
+
+#define PCI_ID_TOPAZ_DISABLED 0x4101
+
+/*
+ *Hardware bugfixes
+ */
+
+#define OSPM_STAT
+
+#define DRIVER_NAME "pvrsrvkm"
+#define DRIVER_DESC "drm driver for the Intel GMA500"
+#define DRIVER_AUTHOR "Intel Corporation"
+#define OSPM_PROC_ENTRY "ospm"
+#define RTPM_PROC_ENTRY "rtpm"
+#define BLC_PROC_ENTRY "mrst_blc"
+#define DISPLAY_PROC_ENTRY "display_status"
+
+#define PSB_DRM_DRIVER_DATE "2009-03-10"
+#define PSB_DRM_DRIVER_MAJOR 8
+#define PSB_DRM_DRIVER_MINOR 1
+#define PSB_DRM_DRIVER_PATCHLEVEL 0
+
+/*
+ *TTM driver private offsets.
+ */
+
+#define DRM_PSB_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+
+#define PSB_OBJECT_HASH_ORDER 13
+#define PSB_FILE_OBJECT_HASH_ORDER 12
+#define PSB_BO_HASH_ORDER 12
+
+#define PSB_VDC_OFFSET		 0x00000000
+#define PSB_VDC_SIZE		 0x000080000
+#define MRST_MMIO_SIZE		 0x0000C0000
+#define MDFLD_MMIO_SIZE          0x000100000
+#define PSB_SGX_SIZE		 0x8000
+#define PSB_SGX_OFFSET		 0x00040000
+#define MRST_SGX_OFFSET		 0x00080000
+#define PSB_MMIO_RESOURCE	 0
+#define PSB_GATT_RESOURCE	 2
+#define PSB_GTT_RESOURCE	 3
+#define PSB_GMCH_CTRL		 0x52
+#define PSB_BSM			 0x5C
+#define _PSB_GMCH_ENABLED	 0x4
+#define PSB_PGETBL_CTL		 0x2020
+#define _PSB_PGETBL_ENABLED	 0x00000001
+#define PSB_SGX_2D_SLAVE_PORT	 0x4000
+#define PSB_TT_PRIV0_LIMIT	 (256*1024*1024)
+#define PSB_TT_PRIV0_PLIMIT	 (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
+#define PSB_NUM_VALIDATE_BUFFERS 2048
+
+#define PSB_MEM_MMU_START       0x00000000
+#define PSB_MEM_TT_START        0xE0000000
+
+#define PSB_GL3_CACHE_CTL	0x2100
+#define PSB_GL3_CACHE_STAT	0x2108
+
+/*
+ *Flags for external memory type field.
+ */
+
+#define MRST_MSVDX_OFFSET	0x90000	/*MSVDX Base offset */
+#define PSB_MSVDX_OFFSET	0x50000	/*MSVDX Base offset */
+/* MSVDX MMIO region is 0x50000 - 0x57fff ==> 32KB */
+#define PSB_MSVDX_SIZE		0x10000
+
+#define PSB_MMU_CACHED_MEMORY	  0x0001	/* Bind to MMU only */
+#define PSB_MMU_RO_MEMORY	  0x0002	/* MMU RO memory */
+#define PSB_MMU_WO_MEMORY	  0x0004	/* MMU WO memory */
+
+/*
+ *PTE's and PDE's
+ */
+
+#define PSB_PDE_MASK		  0x003FFFFF
+#define PSB_PDE_SHIFT		  22
+#define PSB_PTE_SHIFT		  12
+
+#define PSB_PTE_VALID		  0x0001	/* PTE / PDE valid */
+#define PSB_PTE_WO		  0x0002	/* Write only */
+#define PSB_PTE_RO		  0x0004	/* Read only */
+#define PSB_PTE_CACHED		  0x0008	/* CPU cache coherent */
+
+/*
+ *VDC registers and bits
+ */
+#define PSB_MSVDX_CLOCKGATING	  0x2064
+#define PSB_HWSTAM		  0x2098
+#define PSB_INSTPM		  0x20C0
+
+#define PSB_IRQ_ASLE			(1<<0)
+#define PSB_IRQ_PIPEB_DPBM		(1<<2)
+#define PSB_IRQ_PIPEA_DPBM		(1<<3)
+#define PSB_IRQ_PIPEB_EVENT		(1<<4)
+#define PSB_IRQ_PIPEB_VBLANK		(1<<5)
+#define PSB_IRQ_PIPEA_EVENT		(1<<6)
+#define PSB_IRQ_PIPEA_VBLANK		(1<<7)
+#define PSB_IRQ_SPRITEB_FLIP		(1<<8)
+#define PSB_IRQ_SPRITEA_FLIP		(1<<9)
+#define PSB_IRQ_PLANEB_FLIP		(1<<10)
+#define PSB_IRQ_PLANEA_FLIP		(1<<11)
+#define PSB_IRQ_MASTER_ERR		(1<<15)
+#define PSB_IRQ_DISP_HOTSYNC		(1<<17)
+#define _PSB_IRQ_SGX_FLAG		(1<<18)
+#define _PSB_IRQ_MSVDX_FLAG		(1<<19)
+
+/* This flag includes all the display IRQ bits excepts the vblank irqs. */
+#define _PSB_DISP_ALL_IRQ_FLAG (PSB_IRQ_ASLE | PSB_IRQ_PIPEB_DPBM | PSB_IRQ_PIPEA_DPBM | PSB_IRQ_PIPEA_EVENT |\
+	       			PSB_IRQ_PIPEB_EVENT | PSB_IRQ_PIPEA_VBLANK | PSB_IRQ_PIPEB_VBLANK)
+#define PSB_INT_IDENTITY_R	  0x20A4
+#define PSB_INT_MASK_R		  0x20A8
+#define PSB_INT_ENABLE_R	  0x20A0
+
+#define _PSB_MMU_ER_MASK      0x0001FF00
+#define _PSB_MMU_ER_HOST      (1 << 16)
+#define GPIOA			0x5010
+#define GPIOB			0x5014
+#define GPIOC			0x5018
+#define GPIOD			0x501c
+#define GPIOE			0x5020
+#define GPIOF			0x5024
+#define GPIOG			0x5028
+#define GPIOH			0x502c
+#define GPIO_CLOCK_DIR_MASK		(1 << 0)
+#define GPIO_CLOCK_DIR_IN		(0 << 1)
+#define GPIO_CLOCK_DIR_OUT		(1 << 1)
+#define GPIO_CLOCK_VAL_MASK		(1 << 2)
+#define GPIO_CLOCK_VAL_OUT		(1 << 3)
+#define GPIO_CLOCK_VAL_IN		(1 << 4)
+#define GPIO_CLOCK_PULLUP_DISABLE	(1 << 5)
+#define GPIO_DATA_DIR_MASK		(1 << 8)
+#define GPIO_DATA_DIR_IN		(0 << 9)
+#define GPIO_DATA_DIR_OUT		(1 << 9)
+#define GPIO_DATA_VAL_MASK		(1 << 10)
+#define GPIO_DATA_VAL_OUT		(1 << 11)
+#define GPIO_DATA_VAL_IN		(1 << 12)
+#define GPIO_DATA_PULLUP_DISABLE	(1 << 13)
+
+#define VCLK_DIVISOR_VGA0   0x6000
+#define VCLK_DIVISOR_VGA1   0x6004
+#define VCLK_POST_DIV	    0x6010
+
+#define PSB_COMM_2D (PSB_ENGINE_2D << 4)
+#define PSB_COMM_3D (PSB_ENGINE_3D << 4)
+#define PSB_COMM_TA (PSB_ENGINE_TA << 4)
+#define PSB_COMM_HP (PSB_ENGINE_HP << 4)
+#define PSB_COMM_USER_IRQ (1024 >> 2)
+#define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1)
+#define PSB_COMM_FW (2048 >> 2)
+
+#define PSB_UIRQ_VISTEST	       1
+#define PSB_UIRQ_OOM_REPLY	       2
+#define PSB_UIRQ_FIRE_TA_REPLY	       3
+#define PSB_UIRQ_FIRE_RASTER_REPLY     4
+
+#define PSB_2D_SIZE (256*1024*1024)
+#define PSB_MAX_RELOC_PAGES 1024
+
+#define PSB_LOW_REG_OFFS 0x0204
+#define PSB_HIGH_REG_OFFS 0x0600
+
+#define PSB_NUM_VBLANKS 2
+
+
+#define PSB_2D_SIZE (256*1024*1024)
+#define PSB_MAX_RELOC_PAGES 1024
+
+#define PSB_LOW_REG_OFFS 0x0204
+#define PSB_HIGH_REG_OFFS 0x0600
+
+#define PSB_NUM_VBLANKS 2
+#define PSB_WATCHDOG_DELAY (DRM_HZ * 2)
+#define PSB_LID_DELAY (DRM_HZ / 10)
+
+#define PSB_PWR_STATE_ON		1
+#define PSB_PWR_STATE_OFF		2
+
+#define PSB_PMPOLICY_NOPM		0
+#define PSB_PMPOLICY_CLOCKGATING	1
+#define PSB_PMPOLICY_POWERDOWN		2
+
+#define PSB_PMSTATE_POWERUP		0
+#define PSB_PMSTATE_CLOCKGATED		1
+#define PSB_PMSTATE_POWERDOWN		2
+#define PSB_PCIx_MSI_ADDR_LOC		0x94
+#define PSB_PCIx_MSI_DATA_LOC		0x98
+
+#define MDFLD_PLANE_MAX_WIDTH		2048
+#define MDFLD_PLANE_MAX_HEIGHT		2048
+
+struct opregion_header;
+struct opregion_acpi;
+struct opregion_swsci;
+struct opregion_asle;
+
+struct psb_intel_opregion {
+	struct opregion_header *header;
+	struct opregion_acpi *acpi;
+	struct opregion_swsci *swsci;
+	struct opregion_asle *asle;
+	void *vbt;
+	u32 __iomem *lid_state;
+};
+
+/**
+ *struct psb_context
+ *
+ *@buffers:	 array of pre-allocated validate buffers.
+ *@used_buffers: number of buffers in @buffers array currently in use.
+ *@validate_buffer: buffers validated from user-space.
+ *@kern_validate_buffers : buffers validated from kernel-space.
+ *@fence_flags : Fence flags to be used for fence creation.
+ *
+ *This structure is used during execbuf validation.
+ */
+
+struct psb_context {
+	struct psb_validate_buffer *buffers;
+	uint32_t used_buffers;
+	struct list_head validate_list;
+	struct list_head kern_validate_list;
+	uint32_t fence_types;
+	uint32_t val_seq;
+};
+
+struct psb_validate_buffer;
+
+struct psb_msvdx_cmd_queue {
+	struct list_head head;
+	void *cmd;
+	unsigned long cmd_size;
+	uint32_t sequence;
+};
+
+
+/* Currently defined profiles */
+enum VAProfile {
+	VAProfileMPEG2Simple		= 0,
+	VAProfileMPEG2Main		= 1,
+	VAProfileMPEG4Simple		= 2,
+	VAProfileMPEG4AdvancedSimple	= 3,
+	VAProfileMPEG4Main		= 4,
+	VAProfileH264Baseline		= 5,
+	VAProfileH264Main		= 6,
+	VAProfileH264High		= 7,
+	VAProfileVC1Simple		= 8,
+	VAProfileVC1Main		= 9,
+	VAProfileVC1Advanced		= 10,
+	VAProfileH263Baseline		= 11,
+	VAProfileJPEGBaseline           = 12,
+	VAProfileH264ConstrainedBaseline = 13
+};
+
+/* Currently defined entrypoints */
+enum VAEntrypoint {
+	VAEntrypointVLD		= 1,
+	VAEntrypointIZZ		= 2,
+	VAEntrypointIDCT	= 3,
+	VAEntrypointMoComp	= 4,
+	VAEntrypointDeblocking	= 5,
+	VAEntrypointEncSlice	= 6,	/* slice level encode */
+	VAEntrypointEncPicture 	= 7	/* pictuer encode, JPEG, etc */
+};
+
+
+struct psb_video_ctx {
+	struct list_head head;
+	struct file *filp; /* DRM device file pointer */
+	int ctx_type; /* profile<<8|entrypoint */
+	/* todo: more context specific data for multi-context support */
+};
+
+typedef int (*pfn_vsync_handler)(struct drm_device* dev, int pipe);
+
+
+#define MODE_SETTING_IN_CRTC 	0x1
+#define MODE_SETTING_IN_ENCODER 0x2
+#define MODE_SETTING_ON_GOING 	0x3
+#define MODE_SETTING_IN_DSR 	0x4
+#define MODE_SETTING_ENCODER_DONE 0x8
+
+struct drm_psb_private {
+	/*
+	 *TTM Glue.
+	 */
+
+	struct drm_global_reference mem_global_ref;
+	struct ttm_bo_global_ref bo_global_ref;
+	int has_global;
+
+	struct drm_device *dev;
+	struct ttm_object_device *tdev;
+	struct ttm_fence_device fdev;
+	struct ttm_bo_device bdev;
+	struct ttm_lock ttm_lock;
+	struct vm_operations_struct *ttm_vm_ops;
+	int has_fence_device;
+	int has_bo_device;
+
+	unsigned long chipset;
+
+	struct drm_psb_dev_info_arg dev_info;
+
+	struct psb_gtt *pg;
+
+	/*GTT Memory manager*/
+	struct psb_gtt_mm *gtt_mm;
+
+	struct page *scratch_page;
+	uint32_t sequence[PSB_NUM_ENGINES];
+	uint32_t last_sequence[PSB_NUM_ENGINES];
+	uint32_t last_submitted_seq[PSB_NUM_ENGINES];
+
+	struct psb_mmu_driver *mmu;
+	struct psb_mmu_pd *pf_pd;
+
+	uint8_t *sgx_reg;
+	uint8_t *vdc_reg;
+	uint32_t gatt_free_offset;
+
+	/* IMG video context */
+	struct list_head video_ctx;
+	/* Current video context */
+	struct psb_video_ctx *msvdx_ctx;
+	/* previous vieo context */
+	struct psb_video_ctx *last_msvdx_ctx;
+
+	/*
+	 *MSVDX
+	 */
+	uint8_t *msvdx_reg;
+	atomic_t msvdx_mmu_invaldc;
+	void *msvdx_private;
+
+	uint32_t video_device_fuse;
+
+	/*
+	 *Fencing / irq.
+	 */
+
+	uint32_t vdc_irq_mask;
+	uint32_t pipestat[PSB_NUM_PIPE];
+	bool vblanksEnabledForFlips;
+
+	spinlock_t irqmask_lock;
+	spinlock_t sequence_lock;
+
+	/*
+	 *Modesetting
+	 */
+	struct psb_intel_mode_device mode_dev;
+
+	struct drm_crtc *plane_to_crtc_mapping[PSB_NUM_PIPE];
+	struct drm_crtc *pipe_to_crtc_mapping[PSB_NUM_PIPE];
+	uint32_t num_pipe;
+
+	/*
+	 * CI share buffer
+	 */
+	unsigned int ci_region_start;
+	unsigned int ci_region_size;
+
+	/*
+	 * RAR share buffer;
+	 */
+	unsigned int rar_region_start;
+	unsigned int rar_region_size;
+
+	/*
+	 *Memory managers
+	 */
+
+	int have_camera;
+	int have_rar;
+	int have_tt;
+	int have_mem_mmu;
+	struct mutex temp_mem;
+
+	/*
+	 *Relocation buffer mapping.
+	 */
+
+	spinlock_t reloc_lock;
+	unsigned int rel_mapped_pages;
+	wait_queue_head_t rel_mapped_queue;
+
+	/*
+	 *SAREA
+	 */
+	struct drm_psb_sarea *sarea_priv;
+
+	/*
+	*OSPM info
+	*/
+	uint32_t ospm_base;
+
+	/*
+	 * Sizes info
+	 */
+
+	struct drm_psb_sizes_arg sizes;
+
+	uint32_t fuse_reg_value;
+
+	/* info that is stored from the gct */
+	struct gct_ioctl_arg gct_data;
+	enum panel_type panel_id;
+
+	/* pci revision id for B0:D2:F0 */
+	uint8_t platform_rev_id;
+
+	/*
+	 *LVDS info
+	 */
+	int backlight_duty_cycle;	/* restore backlight to this value */
+	bool panel_wants_dither;
+	struct drm_display_mode *panel_fixed_mode;
+	struct drm_display_mode *lfp_lvds_vbt_mode;
+
+	struct bdb_lvds_backlight *lvds_bl; /*LVDS backlight info from VBT*/
+	struct psb_intel_i2c_chan *lvds_i2c_bus;
+
+	/* Feature bits from the VBIOS*/
+	unsigned int int_tv_support:1;
+	unsigned int lvds_dither:1;
+	unsigned int lvds_vbt:1;
+	unsigned int int_crt_support:1;
+	unsigned int lvds_use_ssc:1;
+	int lvds_ssc_freq;
+	bool is_lvds_on;
+
+/* MRST private date start */
+/*FIXME JLIU7 need to revisit */
+	unsigned int core_freq;
+
+	/* pipe config register value */
+	uint32_t pipeconf;
+	uint32_t pipeconf1;
+	uint32_t pipeconf2;
+
+	/* plane control register value */
+	uint32_t dspcntr;
+	uint32_t dspcntr1;
+	uint32_t dspcntr2;
+
+	/*runtime PM state*/
+	int rpm_enabled;
+
+	/*
+	 *Register state
+	 */
+	uint32_t saveDSPACNTR;
+	uint32_t saveDSPBCNTR;
+	uint32_t savePIPEACONF;
+	uint32_t savePIPEBCONF;
+	uint32_t savePIPEASRC;
+	uint32_t savePIPEBSRC;
+	uint32_t saveFPA0;
+	uint32_t saveFPA1;
+	uint32_t saveDPLL_A;
+	uint32_t saveDPLL_A_MD;
+	uint32_t saveHTOTAL_A;
+	uint32_t saveHBLANK_A;
+	uint32_t saveHSYNC_A;
+	uint32_t saveVTOTAL_A;
+	uint32_t saveVBLANK_A;
+	uint32_t saveVSYNC_A;
+	uint32_t saveDSPASTRIDE;
+	uint32_t saveDSPASIZE;
+	uint32_t saveDSPAPOS;
+	uint32_t saveDSPABASE;
+	uint32_t saveDSPASURF;
+	uint32_t saveFPB0;
+	uint32_t saveFPB1;
+	uint32_t saveDPLL_B;
+	uint32_t saveDPLL_B_MD;
+	uint32_t saveHTOTAL_B;
+	uint32_t saveHBLANK_B;
+	uint32_t saveHSYNC_B;
+	uint32_t saveVTOTAL_B;
+	uint32_t saveVBLANK_B;
+	uint32_t saveVSYNC_B;
+	uint32_t saveDSPBSTRIDE;
+	uint32_t saveDSPBSIZE;
+	uint32_t saveDSPBPOS;
+	uint32_t saveDSPBBASE;
+	uint32_t saveDSPBSURF;
+	uint32_t saveVCLK_DIVISOR_VGA0;
+	uint32_t saveVCLK_DIVISOR_VGA1;
+	uint32_t saveVCLK_POST_DIV;
+	uint32_t saveVGACNTRL;
+	uint32_t saveADPA;
+	uint32_t saveLVDS;
+	uint32_t saveDVOA;
+	uint32_t saveDVOB;
+	uint32_t saveDVOC;
+	uint32_t savePP_ON;
+	uint32_t savePP_OFF;
+	uint32_t savePP_CONTROL;
+	uint32_t savePP_CYCLE;
+	uint32_t savePFIT_CONTROL;
+	uint32_t savePaletteA[256];
+	uint32_t savePaletteB[256];
+	uint32_t saveBLC_PWM_CTL2;
+	uint32_t saveBLC_PWM_CTL;
+	uint32_t saveCLOCKGATING;
+	uint32_t saveDSPARB;
+	uint32_t saveDSPATILEOFF;
+	uint32_t saveDSPBTILEOFF;
+	uint32_t saveDSPAADDR;
+	uint32_t saveDSPBADDR;
+	uint32_t savePFIT_AUTO_RATIOS;
+	uint32_t savePFIT_PGM_RATIOS;
+	uint32_t savePP_ON_DELAYS;
+	uint32_t savePP_OFF_DELAYS;
+	uint32_t savePP_DIVISOR;
+	uint32_t saveBSM;
+	uint32_t saveVBT;
+	uint32_t saveBCLRPAT_A;
+	uint32_t saveBCLRPAT_B;
+	uint32_t saveDSPALINOFF;
+	uint32_t saveDSPBLINOFF;
+	uint32_t savePERF_MODE;
+	uint32_t saveDSPFW1;
+	uint32_t saveDSPFW2;
+	uint32_t saveDSPFW3;
+	uint32_t saveDSPFW4;
+	uint32_t saveDSPFW5;
+	uint32_t saveDSPFW6;
+	uint32_t saveCHICKENBIT;
+	uint32_t saveDSPACURSOR_CTRL;
+	uint32_t saveDSPBCURSOR_CTRL;
+	uint32_t saveDSPACURSOR_BASE;
+	uint32_t saveDSPBCURSOR_BASE;
+	uint32_t saveDSPACURSOR_POS;
+	uint32_t saveDSPBCURSOR_POS;
+	uint32_t save_palette_a[256];
+	uint32_t save_palette_b[256];
+	uint32_t saveOV_OVADD;
+	uint32_t saveOV_OGAMC0;
+	uint32_t saveOV_OGAMC1;
+	uint32_t saveOV_OGAMC2;
+	uint32_t saveOV_OGAMC3;
+	uint32_t saveOV_OGAMC4;
+	uint32_t saveOV_OGAMC5;
+	uint32_t saveOVC_OVADD;
+	uint32_t saveOVC_OGAMC0;
+	uint32_t saveOVC_OGAMC1;
+	uint32_t saveOVC_OGAMC2;
+	uint32_t saveOVC_OGAMC3;
+	uint32_t saveOVC_OGAMC4;
+	uint32_t saveOVC_OGAMC5;
+
+	/*
+	 * extra MDFLD Register state
+	 */
+	uint32_t saveHDMIPHYMISCCTL;
+	uint32_t saveHDMIB_CONTROL;
+	uint32_t saveDSPCCNTR;
+	uint32_t savePIPECCONF;
+	uint32_t savePIPECSRC;
+	uint32_t saveHTOTAL_C;
+	uint32_t saveHBLANK_C;
+	uint32_t saveHSYNC_C;
+	uint32_t saveVTOTAL_C;
+	uint32_t saveVBLANK_C;
+	uint32_t saveVSYNC_C;
+	uint32_t saveDSPCSTRIDE;
+	uint32_t saveDSPCSIZE;
+	uint32_t saveDSPCPOS;
+	uint32_t saveDSPCSURF;
+	uint32_t saveDSPCLINOFF;
+	uint32_t saveDSPCTILEOFF;
+	uint32_t saveDSPCCURSOR_CTRL;
+	uint32_t saveDSPCCURSOR_BASE;
+	uint32_t saveDSPCCURSOR_POS;
+	uint32_t save_palette_c[256];
+	uint32_t saveOV_OVADD_C;
+	uint32_t saveOV_OGAMC0_C;
+	uint32_t saveOV_OGAMC1_C;
+	uint32_t saveOV_OGAMC2_C;
+	uint32_t saveOV_OGAMC3_C;
+	uint32_t saveOV_OGAMC4_C;
+	uint32_t saveOV_OGAMC5_C;
+
+	/* DSI reg save */
+	uint32_t saveDEVICE_READY_REG;
+	uint32_t saveINTR_EN_REG;
+	uint32_t saveDSI_FUNC_PRG_REG;
+	uint32_t saveHS_TX_TIMEOUT_REG;
+	uint32_t saveLP_RX_TIMEOUT_REG;
+	uint32_t saveTURN_AROUND_TIMEOUT_REG;
+	uint32_t saveDEVICE_RESET_REG;
+	uint32_t saveDPI_RESOLUTION_REG;
+	uint32_t saveHORIZ_SYNC_PAD_COUNT_REG;
+	uint32_t saveHORIZ_BACK_PORCH_COUNT_REG;
+	uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG;
+	uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG;
+	uint32_t saveVERT_SYNC_PAD_COUNT_REG;
+	uint32_t saveVERT_BACK_PORCH_COUNT_REG;
+	uint32_t saveVERT_FRONT_PORCH_COUNT_REG;
+	uint32_t saveHIGH_LOW_SWITCH_COUNT_REG;
+	uint32_t saveINIT_COUNT_REG;
+	uint32_t saveMAX_RET_PAK_REG;
+	uint32_t saveVIDEO_FMT_REG;
+	uint32_t saveEOT_DISABLE_REG;
+	uint32_t saveLP_BYTECLK_REG;
+	uint32_t saveHS_LS_DBI_ENABLE_REG;
+	uint32_t saveTXCLKESC_REG;
+	uint32_t saveDPHY_PARAM_REG;
+	uint32_t saveMIPI_CONTROL_REG;
+	uint32_t saveMIPI;
+	uint32_t saveMIPI_C;
+	void (*init_drvIC)(struct drm_device *dev);
+	void (*dsi_prePowerState)(struct drm_device *dev);
+	void (*dsi_postPowerState)(struct drm_device *dev);
+
+	/* DPST Register Save */
+	uint32_t saveHISTOGRAM_INT_CONTROL_REG;
+	uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG;
+	uint32_t savePWM_CONTROL_LOGIC;
+
+	uint32_t saveDSPCLK_GATE_D;
+	uint32_t saveRAMCLK_GATE_D;
+	uint32_t saveDSPFW[6];
+	u8 saveLBB;
+	uint32_t saveIER;
+	uint32_t saveIMR;
+
+	/* MSI reg save */
+
+	uint32_t msi_addr;
+	uint32_t msi_data;
+
+	/*
+	 *Scheduling.
+	 */
+
+	struct mutex reset_mutex;
+	struct psb_scheduler scheduler;
+	struct mutex cmdbuf_mutex;
+	atomic_t val_seq;
+
+	/*
+	 *TODO: change this to be per drm-context.
+	 */
+
+	struct psb_context context;
+
+	/*
+	 * LID-Switch
+	 */
+	struct psb_intel_opregion opregion;
+
+	/*
+	 *Watchdog
+	 */
+
+	spinlock_t watchdog_lock;
+	struct timer_list watchdog_timer;
+	struct work_struct watchdog_wq;
+	struct work_struct msvdx_watchdog_wq;
+	int timer_available;
+
+	uint32_t apm_reg;
+	uint16_t apm_base;
+#ifdef OSPM_STAT
+	unsigned char graphics_state;
+	unsigned long gfx_on_time;
+	unsigned long gfx_off_time;
+	unsigned long gfx_last_mode_change;
+	unsigned long gfx_on_cnt;
+	unsigned long gfx_off_cnt;
+#endif
+
+	/*
+	 * Used for modifying backlight from
+	 * xrandr -- consider removing and using HAL instead
+	 */
+	uint32_t blc_adj1;
+	uint32_t blc_adj2;
+
+	/*
+	 * DPST and Hotplug state
+	 */
+
+	struct dpst_state *psb_dpst_state;
+	struct hotplug_state *psb_hotplug_state;
+	pfn_vsync_handler psb_vsync_handler;
+
+	struct snd_intel_had_interface *had_interface;
+	void *had_pvt_data;
+
+	bool dplla_96mhz;
+
+	/*psb fb dev*/
+	void * fbdev;
+	uint32_t cur_pipe;
+	
+	/* Frame buffer relocation */
+	void * fb_reloc;
+	struct work_struct hotplug_work;
+
+	void * ovl_buf;
+	uint32_t ovl_offset;
+
+	uint32_t ui32MainPipe;
+	uint32_t pipeEnabled;
+	struct timer_list flip_timer;
+	int flip_counter;
+
+	struct backlight_device *backlight;
+	int child_dev_num;
+	struct child_device_config *child_dev;
+
+	struct drm_connector *int_lvds_connector;
+	struct drm_connector *int_edp_connector;
+	int backlight_level;	/* restore backlight to this value */
+	int backlight_enabled;
+
+	struct drm_property *broadcast_rgb_property;
+	struct drm_property *force_audio_property;
+	struct {
+		int rate;
+		int lanes;
+		int preemphasis;
+		int vswing;
+
+		bool initialized;
+		bool support;
+		int bpp;
+		struct edp_power_seq pps;
+	} edp;
+	uint8_t panel_type;
+};
+
+struct psb_fpriv {
+        int bcd_index;
+	struct ttm_object_file *tfile;
+};
+
+struct psb_mmu_driver;
+
+extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int);
+extern int drm_pick_crtcs(struct drm_device *dev);
+
+
+static inline struct psb_fpriv *psb_fpriv(struct drm_file *file_priv)
+{
+	PVRSRV_FILE_PRIVATE_DATA *pvr_file_priv
+			= (PVRSRV_FILE_PRIVATE_DATA *)file_priv->driver_priv;
+	return (struct psb_fpriv *) pvr_file_priv->pPriv;
+}
+
+static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
+{
+	return (struct drm_psb_private *) dev->dev_private;
+}
+
+/*
+ *TTM glue. psb_ttm_glue.c
+ */
+
+extern int psb_open(struct inode *inode, struct file *filp);
+extern int psb_release(struct inode *inode, struct file *filp);
+extern int psb_mmap(struct file *filp, struct vm_area_struct *vma);
+
+extern int psb_fence_signaled_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file_priv);
+extern int psb_verify_access(struct ttm_buffer_object *bo,
+			     struct file *filp);
+extern ssize_t psb_ttm_read(struct file *filp, char __user *buf,
+			    size_t count, loff_t *f_pos);
+extern ssize_t psb_ttm_write(struct file *filp, const char __user *buf,
+			    size_t count, loff_t *f_pos);
+extern int psb_fence_finish_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_priv);
+extern int psb_fence_unref_ioctl(struct drm_device *dev, void *data,
+				 struct drm_file *file_priv);
+extern int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data,
+				 struct drm_file *file_priv);
+extern int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_priv);
+extern int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
+extern int psb_pl_unref_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+extern int psb_pl_reference_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_priv);
+extern int psb_pl_create_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv);
+extern int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv);
+extern int psb_extension_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv);
+extern int psb_ttm_global_init(struct drm_psb_private *dev_priv);
+extern void psb_ttm_global_release(struct drm_psb_private *dev_priv);
+extern int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
+/*
+ *MMU stuff.
+ */
+
+extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
+					int trap_pagefaults,
+					int invalid_type,
+					struct drm_psb_private *dev_priv);
+extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver);
+extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver
+						 *driver);
+extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset,
+			       uint32_t gtt_start, uint32_t gtt_pages);
+extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
+					   int trap_pagefaults,
+					   int invalid_type);
+extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd);
+extern void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot);
+extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
+					unsigned long address,
+					uint32_t num_pages);
+extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd,
+				       uint32_t start_pfn,
+				       unsigned long address,
+				       uint32_t num_pages, int type);
+extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
+				  unsigned long *pfn);
+
+/*
+ *Enable / disable MMU for different requestors.
+ */
+
+
+extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context);
+extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
+				unsigned long address, uint32_t num_pages,
+				uint32_t desired_tile_stride,
+				uint32_t hw_tile_stride, int type);
+extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd,
+				 unsigned long address, uint32_t num_pages,
+				 uint32_t desired_tile_stride,
+				 uint32_t hw_tile_stride);
+/*
+ *psb_sgx.c
+ */
+
+
+
+extern int psb_cmdbuf_ioctl(struct drm_device *dev, void *data,
+			    struct drm_file *file_priv);
+extern int psb_reg_submit(struct drm_psb_private *dev_priv,
+			  uint32_t *regs, unsigned int cmds);
+
+
+extern void psb_fence_or_sync(struct drm_file *file_priv,
+			      uint32_t engine,
+			      uint32_t fence_types,
+			      uint32_t fence_flags,
+			      struct list_head *list,
+			      struct psb_ttm_fence_rep *fence_arg,
+			      struct ttm_fence_object **fence_p);
+extern int psb_validate_kernel_buffer(struct psb_context *context,
+				      struct ttm_buffer_object *bo,
+				      uint32_t fence_class,
+				      uint64_t set_flags,
+				      uint64_t clr_flags);
+
+/*
+ *psb_irq.c
+ */
+
+extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
+extern int psb_irq_enable_dpst(struct drm_device *dev);
+extern int psb_irq_disable_dpst(struct drm_device *dev);
+extern void psb_irq_preinstall(struct drm_device *dev);
+extern int psb_irq_postinstall(struct drm_device *dev);
+extern void psb_irq_uninstall(struct drm_device *dev);
+extern void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands);
+extern int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands);
+extern void psb_irq_turn_on_dpst(struct drm_device *dev);
+extern void psb_irq_turn_off_dpst(struct drm_device *dev);
+
+extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
+extern int psb_vblank_wait2(struct drm_device *dev,unsigned int *sequence);
+extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
+extern int psb_enable_vblank(struct drm_device *dev, int crtc);
+extern void psb_disable_vblank(struct drm_device *dev, int crtc);
+void
+psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);
+
+void
+psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);
+
+extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc);
+
+extern void psb_intel_enable_asle(struct drm_device *dev);
+
+/*
+ *psb_fence.c
+ */
+
+extern void psb_fence_handler(struct drm_device *dev, uint32_t class);
+
+extern int psb_fence_emit_sequence(struct ttm_fence_device *fdev,
+				   uint32_t fence_class,
+				   uint32_t flags, uint32_t *sequence,
+				   unsigned long *timeout_jiffies);
+extern void psb_fence_error(struct drm_device *dev,
+			    uint32_t class,
+			    uint32_t sequence, uint32_t type, int error);
+extern int psb_ttm_fence_device_init(struct ttm_fence_device *fdev);
+
+/* MSVDX/Topaz stuff */
+extern int psb_remove_videoctx(struct drm_psb_private *dev_priv, struct file *filp);
+
+extern int lnc_video_getparam(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv);
+
+extern int psb_try_power_down_msvdx(struct drm_device *dev);
+
+/*
+ * psb_opregion.c
+ */
+extern int psb_intel_opregion_setup(struct drm_device *dev);
+extern void psb_intel_opregion_init(struct drm_device *dev);
+extern void psb_intel_opregion_fini(struct drm_device *dev);
+extern void psb_intel_opregion_asle_intr(struct drm_device *dev);
+extern void psb_intel_opregion_enable_asle(struct drm_device *dev);
+
+/*
+ *psb_fb.c
+ */
+extern int psbfb_probed(struct drm_device *dev);
+extern int psbfb_remove(struct drm_device *dev,
+			struct drm_framebuffer *fb);
+extern int psbfb_kms_off_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv);
+extern int psbfb_kms_on_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+extern void *psbfb_vdc_reg(struct drm_device* dev);
+
+/*
+ *psb_reset.c
+ */
+
+extern void psb_schedule_watchdog(struct drm_psb_private *dev_priv);
+extern void psb_watchdog_init(struct drm_psb_private *dev_priv);
+extern void psb_watchdog_takedown(struct drm_psb_private *dev_priv);
+extern void psb_print_pagefault(struct drm_psb_private *dev_priv);
+
+/* modesetting */
+extern void psb_modeset_init(struct drm_device *dev);
+extern void psb_modeset_cleanup(struct drm_device *dev);
+extern void psb_intel_display_wa(struct drm_device *dev);
+
+/*fbdev*/
+extern int psb_fbdev_init(struct drm_device * dev);
+
+/* psb_bl.c */
+int psb_backlight_init(struct drm_device *dev);
+void psb_backlight_exit(void);
+int psb_set_brightness(struct backlight_device *bd);
+int psb_get_brightness(struct backlight_device *bd);
+struct backlight_device * psb_get_backlight_device(void);
+
+/*
+ *Debug print bits setting
+ */
+#define PSB_D_GENERAL (1 << 0)
+#define PSB_D_INIT    (1 << 1)
+#define PSB_D_IRQ     (1 << 2)
+#define PSB_D_ENTRY   (1 << 3)
+/* debug the get H/V BP/FP count */
+#define PSB_D_HV      (1 << 4)
+#define PSB_D_DBI_BF  (1 << 5)
+#define PSB_D_PM      (1 << 6)
+#define PSB_D_RENDER  (1 << 7)
+#define PSB_D_REG     (1 << 8)
+#define PSB_D_MSVDX   (1 << 9)
+#define PSB_D_TOPAZ   (1 << 10)
+
+#ifndef DRM_DEBUG_CODE
+/* To enable debug printout, set drm_psb_debug in psb_drv.c
+ * to any combination of above print flags.
+ */
+#define DRM_DEBUG_CODE 2
+#endif
+
+extern int drm_psb_debug;
+extern int drm_psb_disable_vsync;
+extern int drm_idle_check_interval;
+
+#define PSB_DEBUG_GENERAL(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_GENERAL, _fmt, ##_arg)
+#define PSB_DEBUG_INIT(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_INIT, _fmt, ##_arg)
+#define PSB_DEBUG_IRQ(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_IRQ, _fmt, ##_arg)
+#define PSB_DEBUG_ENTRY(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_ENTRY, _fmt, ##_arg)
+#define PSB_DEBUG_HV(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_HV, _fmt, ##_arg)
+#define PSB_DEBUG_DBI_BF(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_DBI_BF, _fmt, ##_arg)
+#define PSB_DEBUG_PM(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_PM, _fmt, ##_arg)
+#define PSB_DEBUG_RENDER(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_RENDER, _fmt, ##_arg)
+#define PSB_DEBUG_REG(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_REG, _fmt, ##_arg)
+#define PSB_DEBUG_MSVDX(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_MSVDX, _fmt, ##_arg)
+#define PSB_DEBUG_TOPAZ(_fmt, _arg...) \
+	PSB_DEBUG(PSB_D_TOPAZ, _fmt, ##_arg)
+
+#if DRM_DEBUG_CODE
+#define PSB_DEBUG(_flag, _fmt, _arg...)					\
+	do {								\
+		if (unlikely((_flag) & drm_psb_debug))			\
+			printk(KERN_DEBUG				\
+			       "[psb:0x%02x:%s] " _fmt , _flag,		\
+			       __func__ , ##_arg);			\
+	} while (0)
+#else
+#define PSB_DEBUG(_fmt, _arg...)     do { } while (0)
+#endif
+
+/*
+ *Utilities
+ */
+#define DRM_DRIVER_PRIVATE_T struct drm_psb_private
+
+static inline u32 CDV_MSG_READ32(uint port, uint offset)
+{
+	int mcr = (0x10<<24) | (port << 16) | (offset << 8);
+	uint32_t ret_val = 0;
+	struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0);
+	pci_write_config_dword (pci_root, 0xD0, mcr);
+	pci_read_config_dword (pci_root, 0xD4, &ret_val);
+	pci_dev_put(pci_root);
+	return ret_val;
+}
+static inline void CDV_MSG_WRITE32(uint port, uint offset, u32 value)
+{
+	int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
+	struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0);
+	pci_write_config_dword (pci_root, 0xD4, value);
+	pci_write_config_dword (pci_root, 0xD0, mcr);
+	pci_dev_put(pci_root);
+}
+
+static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	int reg_val = ioread32(dev_priv->vdc_reg + (reg));
+	PSB_DEBUG_REG("reg = 0x%x. reg_val = 0x%x. \n", reg, reg_val);
+	return reg_val;
+}
+
+#define REG_READ(reg)	       REGISTER_READ(dev, (reg))
+static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
+				      uint32_t val)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	if ((reg < 0x70084 || reg >0x70088) && (reg < 0xa000 || reg >0xa3ff))
+		PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val);
+
+	iowrite32((val), dev_priv->vdc_reg + (reg));
+}
+
+#define REG_WRITE(reg, val)	REGISTER_WRITE(dev, (reg), (val))
+
+static inline void REGISTER_WRITE16(struct drm_device *dev,
+					uint32_t reg, uint32_t val)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val);
+
+	iowrite16((val), dev_priv->vdc_reg + (reg));
+}
+
+#define REG_WRITE16(reg, val)	  REGISTER_WRITE16(dev, (reg), (val))
+
+static inline void REGISTER_WRITE8(struct drm_device *dev,
+				       uint32_t reg, uint32_t val)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val);
+
+	iowrite8((val), dev_priv->vdc_reg + (reg));
+}
+
+#define REG_WRITE8(reg, val)	 REGISTER_WRITE8(dev, (reg), (val))
+
+#define PSB_ALIGN_TO(_val, _align) \
+  (((_val) + ((_align) - 1)) & ~((_align) - 1))
+#define PSB_WVDC32(_val, _offs) \
+  iowrite32(_val, dev_priv->vdc_reg + (_offs))
+#define PSB_RVDC32(_offs) \
+  ioread32(dev_priv->vdc_reg + (_offs))
+
+/* #define TRAP_SGX_PM_FAULT 1 */
+#ifdef TRAP_SGX_PM_FAULT
+#define PSB_RSGX32(_offs)					\
+({								\
+    if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) {		\
+	DRM_ERROR("access sgx when it's off!! (READ) %s, %d\n", \
+	       __FILE__, __LINE__);				\
+	mdelay(1000);						\
+    }								\
+    ioread32(dev_priv->sgx_reg + (_offs));			\
+})
+#else
+#define PSB_RSGX32(_offs)					\
+  ioread32(dev_priv->sgx_reg + (_offs))
+#endif
+
+#define MSVDX_REG_DUMP 0
+
+#if MSVDX_REG_DUMP
+
+#define PSB_WMSVDX32(_val, _offs) \
+  DRM_DEBUG("MSVDX: write %08x to reg 0x%08x\n", (unsigned int)(_val), (unsigned int)(_offs));\
+  iowrite32(_val, dev_priv->msvdx_reg + (_offs))
+#define PSB_RMSVDX32(_offs) \
+  ioread32(dev_priv->msvdx_reg + (_offs))
+
+#else
+
+#define PSB_WMSVDX32(_val, _offs) \
+  iowrite32(_val, dev_priv->msvdx_reg + (_offs))
+#define PSB_RMSVDX32(_offs) \
+  ioread32(dev_priv->msvdx_reg + (_offs))
+
+#endif
+
+#define PSB_ALPL(_val, _base)			\
+  (((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT))
+#define PSB_ALPLM(_val, _base)			\
+  ((((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) & (_base ## _MASK))
+
+
+#define IS_PENWELL(dev) 0 /* FIXME */
+
+
+#define IS_CDV(dev) (((dev)->pci_device & 0xfff0) == 0x0BE0)
+#define IS_MID(dev) (IS_CDV(dev))
+
+#define IS_MSVDX(dev) (IS_CDV(dev))
+#define IS_TOPAZ(dev) (IS_CDV(dev))
+
+extern int drm_psb_ospm;
+
+#define _wait_for(COND, MS, W) ({ \
+        unsigned long timeout__ = jiffies + msecs_to_jiffies(MS);       \
+        int ret__ = 0;                                                  \
+        while (! (COND)) {                                              \
+                if (time_after(jiffies, timeout__)) {                   \
+                        ret__ = -ETIMEDOUT;                             \
+                        break;                                          \
+                }                                                       \
+                if (W && !in_dbg_master()) msleep(W);                   \
+        }                                                               \
+        ret__;                                                          \
+})      
+
+#define wait_for(COND, MS) _wait_for(COND, MS, 1)
+
+#endif
diff --git a/drivers/staging/cdv/drv/psb_fb.c b/drivers/staging/cdv/drv/psb_fb.c
new file mode 100644
index 0000000..6e6d348
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_fb.c
@@ -0,0 +1,848 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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 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.
+ *
+ **************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/console.h>
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+
+#include "psb_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_drv.h"
+#include "psb_ttm_userobj_api.h"
+#include "psb_fb.h"
+#include "psb_sgx.h"
+#include "psb_pvr_glue.h"
+
+
+extern int MRSTLFBHandleChangeFB(struct drm_device* dev, struct psb_framebuffer *psbfb);
+
+struct MRSTLFB_BUFFER_TAG;
+uint32_t MRSTLFBGetSize(struct MRSTLFB_BUFFER_TAG *pBuffer);
+void* MRSTLFBGetCPUVAddr(struct MRSTLFB_BUFFER_TAG *pBuffer);
+uint32_t MRSTLFBGetDevVAddr(struct MRSTLFB_BUFFER_TAG *pBuffer);
+extern int MRSTLFBAllocBuffer(struct drm_device *dev,
+			IMG_UINT32 ui32Size, struct MRSTLFB_BUFFER_TAG **ppBuffer);
+extern int MRSTLFBFreeBuffer(struct drm_device *dev,
+			struct MRSTLFB_BUFFER_TAG **ppBuffer);
+
+static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
+static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
+					      struct drm_file *file_priv,
+					      unsigned int *handle);
+
+static const struct drm_framebuffer_funcs psb_fb_funcs = {
+	.destroy = psb_user_framebuffer_destroy,
+	.create_handle = psb_user_framebuffer_create_handle,
+};
+
+#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
+
+void *psbfb_vdc_reg(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv;
+	dev_priv = (struct drm_psb_private *) dev->dev_private;
+	return dev_priv->vdc_reg;
+}
+/*EXPORT_SYMBOL(psbfb_vdc_reg); */
+
+static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	struct psb_fbdev * fbdev = info->par;
+	struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
+	uint32_t v;
+
+	if (!fb)
+		return -ENOMEM;
+
+	if (regno > 255)
+		return 1;
+
+	red = CMAP_TOHW(red, info->var.red.length);
+	blue = CMAP_TOHW(blue, info->var.blue.length);
+	green = CMAP_TOHW(green, info->var.green.length);
+	transp = CMAP_TOHW(transp, info->var.transp.length);
+
+	v = (red << info->var.red.offset) |
+	    (green << info->var.green.offset) |
+	    (blue << info->var.blue.offset) |
+	    (transp << info->var.transp.offset);
+
+	if (regno < 16) {
+		switch (fb->bits_per_pixel) {
+		case 16:
+			((uint32_t *) info->pseudo_palette)[regno] = v;
+			break;
+		case 24:
+		case 32:
+			((uint32_t *) info->pseudo_palette)[regno] = v;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int psbfb_kms_off(struct drm_device *dev, int suspend)
+{
+	struct drm_framebuffer *fb = 0;
+	struct psb_framebuffer * psbfb = to_psb_fb(fb);
+	DRM_DEBUG_KMS("psbfb_kms_off_ioctl\n");
+
+	mutex_lock(&dev->mode_config.mutex);
+	list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
+		struct fb_info *info = psbfb->fbdev;
+
+		if (suspend) {
+			fb_set_suspend(info, 1);
+			drm_fb_helper_blank(FB_BLANK_POWERDOWN, info);
+		}
+	}
+	mutex_unlock(&dev->mode_config.mutex);
+	return 0;
+}
+
+int psbfb_kms_off_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	int ret;
+
+	console_lock();
+	ret = psbfb_kms_off(dev, 0);
+	console_unlock();
+
+	return ret;
+}
+
+static int psbfb_kms_on(struct drm_device *dev, int resume)
+{
+	struct drm_framebuffer *fb = 0;
+	struct psb_framebuffer * psbfb = to_psb_fb(fb);
+
+	DRM_DEBUG_KMS("psbfb_kms_on_ioctl\n");
+
+	mutex_lock(&dev->mode_config.mutex);
+	list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
+		struct fb_info *info = psbfb->fbdev;
+
+		if (resume) {
+			fb_set_suspend(info, 0);
+			drm_fb_helper_blank(FB_BLANK_UNBLANK, info);
+		}
+	}
+	mutex_unlock(&dev->mode_config.mutex);
+
+	return 0;
+}
+
+int psbfb_kms_on_ioctl(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	int ret;
+
+	console_lock();
+	ret = psbfb_kms_on(dev, 0);
+	console_unlock();
+	drm_helper_disable_unused_functions(dev);
+	return ret;
+}
+
+void psbfb_suspend(struct drm_device *dev)
+{
+	console_lock();
+	psbfb_kms_off(dev, 1);
+	console_unlock();
+}
+
+void psbfb_resume(struct drm_device *dev)
+{
+	console_lock();
+	psbfb_kms_on(dev, 1);
+	console_unlock();
+	drm_helper_disable_unused_functions(dev);
+}
+
+static struct fb_ops psbfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_blank = drm_fb_helper_blank,
+	.fb_setcolreg = psbfb_setcolreg,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+};
+
+static struct drm_framebuffer *psb_framebuffer_create
+			(struct drm_device *dev, struct drm_mode_fb_cmd *r,
+			 void *mm_private)
+{
+	struct psb_framebuffer *fb;
+	int ret;
+
+	fb = kzalloc(sizeof(*fb), GFP_KERNEL);
+	if (!fb)
+		return NULL;
+
+	ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
+
+	if (ret)
+		goto err;
+
+	drm_helper_mode_fill_fb_struct(&fb->base, r);
+
+	fb->pvrBO = mm_private;
+
+	return &fb->base;
+
+err:
+	kfree(fb);
+	return NULL;
+}
+
+static struct drm_framebuffer *psb_user_framebuffer_create
+			(struct drm_device *dev, struct drm_file *filp,
+			 struct drm_mode_fb_cmd *r)
+{
+	struct psb_framebuffer *psbfb;
+	struct drm_framebuffer *fb;
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
+	IMG_HANDLE hKernelMemInfo = (IMG_HANDLE)r->handle;
+	struct drm_psb_private *dev_priv
+		= (struct drm_psb_private *) dev->dev_private;
+	struct psb_gtt *pg = dev_priv->pg;
+	struct MRSTLFB_BUFFER_TAG *buffer;
+	int ret;
+	uint32_t offset;
+	uint64_t size;
+
+	ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
+	if (ret) {
+		DRM_ERROR("Cannot get meminfo for handle 0x%x\n",
+			  (IMG_UINT32)hKernelMemInfo);
+
+		return NULL;
+	}
+
+	DRM_DEBUG_KMS("Got Kernel MemInfo for handle %x\n",
+		  (IMG_UINT32)hKernelMemInfo);
+
+	/* JB: TODO not drop, make smarter */
+	size = psKernelMemInfo->uAllocSize;
+	if (size < r->height * r->pitch)
+		return NULL;
+
+	/* JB: TODO not drop, refcount buffer */
+	/* return psb_framebuffer_create(dev, r, bo); */
+
+	fb = psb_framebuffer_create(dev, r, (void *)psKernelMemInfo);
+	if (!fb) {
+		DRM_ERROR("failed to allocate fb.\n");
+		return NULL;
+	}
+
+	psbfb = to_psb_fb(fb);
+	psbfb->size = size;
+	psbfb->hKernelMemInfo = hKernelMemInfo;
+
+	DRM_DEBUG_KMS("Mapping to gtt..., KernelMemInfo %p\n", psKernelMemInfo);
+
+	buffer = (struct MRSTLFB_BUFFER_TAG *)dev_priv->fb_reloc;
+	/*if not VRAM, map it into tt aperture*/
+	if (psKernelMemInfo->pvLinAddrKM != pg->vram_addr &&
+	    (!buffer || psKernelMemInfo->pvLinAddrKM != MRSTLFBGetCPUVAddr(buffer))) {
+		ret = psb_gtt_map_meminfo(dev, hKernelMemInfo, &offset);
+		if (ret) {
+			DRM_ERROR("map meminfo for 0x%x failed\n",
+				  (IMG_UINT32)hKernelMemInfo);
+			return NULL;
+		}
+		psbfb->offset = (offset << PAGE_SHIFT);
+	} else {
+		if (buffer)
+			psbfb->offset = MRSTLFBGetDevVAddr(buffer);
+		else
+			psbfb->offset = 0;
+	}
+
+	DRM_DEBUG_KMS("Mapping to gtt offset %x, KernelMemInfo %p for FB ID %d\n", psbfb->offset, psKernelMemInfo, fb->base.id);
+	MRSTLFBHandleChangeFB(dev, psbfb);
+
+	return fb;
+}
+
+static int psbfb_create(struct psb_fbdev * fbdev, struct drm_fb_helper_surface_size * sizes) 
+{
+	struct drm_device * dev = fbdev->psb_fb_helper.dev;
+	struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
+	struct psb_gtt *pg = dev_priv->pg;
+	struct fb_info * info;
+	struct drm_framebuffer *fb;
+	struct psb_framebuffer * psbfb;
+	struct drm_mode_fb_cmd mode_cmd;
+	struct device * device = &dev->pdev->dev;
+	struct MRSTLFB_BUFFER_TAG *buffer = NULL;
+	int size, aligned_size;
+	int ret, stride;
+
+	mode_cmd.width = sizes->surface_width;
+	mode_cmd.height = sizes->surface_height;
+
+	DRM_DEBUG_KMS("psbfb_create called with w = %d h = %d\n", sizes->surface_width, sizes->surface_height);
+
+	mode_cmd.bpp = 32;
+        //HW requires pitch to be 64 byte aligned
+        /*
+	 * The framebuffer is used by PVR driver. And it expects that the 
+         * stride is aligned to 32 in pixels. So we will first align the width to
+	 * 32. As currently it uses the 32bpp in framebuffer, it can assure that
+	 * it is aligned to 64 bytes.	
+	 */
+        stride = ALIGN(mode_cmd.width, 32);
+        mode_cmd.pitch =  ALIGN(stride * ((mode_cmd.bpp + 1) / 8), 64);
+        mode_cmd.depth = 24;
+
+	size = mode_cmd.pitch * mode_cmd.height;
+	aligned_size = ALIGN(size, PAGE_SIZE);
+
+	mutex_lock(&dev->struct_mutex);
+
+	if (aligned_size > pg->stolen_size) {
+		/* 
+		 * allocate new buffer if the request size is larger than
+		 * the stolen memory size
+		 */
+		ret = MRSTLFBAllocBuffer(dev, aligned_size, &buffer);
+		if (ret) {
+			ret = -ENOMEM;
+			goto out_err0;
+		}
+		dev_priv->fb_reloc = buffer;
+	}
+
+        fb = psb_framebuffer_create(dev, &mode_cmd, NULL);
+        if (!fb) {
+                ret = -ENOMEM;
+                goto out_err1;
+        }
+
+        psbfb = to_psb_fb(fb);
+        psbfb->size = size;
+	if (buffer)
+		psbfb->offset = MRSTLFBGetDevVAddr(buffer);
+
+	info = framebuffer_alloc(sizeof(struct psb_fbdev), device);
+	if(!info) {
+		ret = -ENOMEM;
+		goto out_err2;
+	}
+
+	info->par = fbdev;
+	psbfb->fbdev = info;
+
+	fbdev->psb_fb_helper.fb = fb;
+	fbdev->psb_fb_helper.fbdev = info;
+	fbdev->pfb = psbfb;
+
+	strcpy(info->fix.id, "psbfb");
+
+	info->flags = FBINFO_DEFAULT;
+	info->fbops = &psbfb_ops;
+	info->fix.smem_start = dev->mode_config.fb_base;
+	info->fix.smem_len = size;
+
+	if (buffer)
+		info->screen_base = MRSTLFBGetCPUVAddr(buffer);
+	else
+		info->screen_base = (char *)pg->vram_addr;
+
+	info->screen_size = size;
+
+	/* kick off vesafb */
+	if (pg->stolen_size) {       
+		info->apertures = alloc_apertures(1);
+		if (!info->apertures) {                
+			ret = -ENOMEM;                 
+			goto out_err2;        
+		}
+		info->apertures->ranges[0].base = dev->mode_config.fb_base;
+		info->apertures->ranges[0].size = pg->stolen_size;                                                                   
+	}
+	  
+	drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
+	drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper, sizes->fb_width, sizes->fb_height);
+
+	info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
+	info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
+
+	info->pixmap.size = 64 * 1024;
+	info->pixmap.buf_align = 8;
+	info->pixmap.access_align = 32;
+	info->pixmap.flags = FB_PIXMAP_SYSTEM;
+	info->pixmap.scan_align = 1;
+
+	DRM_DEBUG_KMS("fb depth is %d\n", fb->depth);
+	DRM_DEBUG_KMS("   pitch is %d\n", fb->pitch);
+	DRM_DEBUG_KMS("allocated %dx%d fb\n", psbfb->base.width, psbfb->base.height);	
+	DRM_DEBUG_KMS("The GTT offset %x for FB ID %d\n", psbfb->offset, fb->base.id);	
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+out_err2:
+	fb->funcs->destroy(fb);
+out_err1:
+	MRSTLFBFreeBuffer(dev, &buffer);
+out_err0:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno)
+{
+	DRM_DEBUG_KMS("%s\n", __FUNCTION__);
+}
+
+static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, int regno)
+{
+	DRM_DEBUG_KMS("%s\n", __FUNCTION__);
+}
+
+static int psbfb_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes)
+{
+	struct psb_fbdev * psb_fbdev = (struct psb_fbdev *)helper;
+	int new_fb = 0;
+	int ret;
+
+	DRM_DEBUG_KMS("%s\n", __FUNCTION__);
+
+	if(!helper->fb) {
+		ret = psbfb_create(psb_fbdev, sizes);
+		if(ret) {
+			return ret;
+		}
+
+		new_fb = 1;
+	}
+
+	return new_fb;
+}
+
+struct drm_fb_helper_funcs psb_fb_helper_funcs = {
+	.gamma_set = psbfb_gamma_set,
+	.gamma_get = psbfb_gamma_get,
+	.fb_probe = psbfb_probe,
+};
+
+int psb_fbdev_destroy(struct drm_device * dev, struct psb_fbdev * fbdev)
+{
+	struct fb_info * info;
+	struct psb_framebuffer * psbfb = fbdev->pfb;
+
+	if(fbdev->psb_fb_helper.fbdev) {
+		info = fbdev->psb_fb_helper.fbdev;
+		unregister_framebuffer(info);
+		iounmap(info->screen_base);
+		framebuffer_release(info);
+	}
+
+	drm_fb_helper_fini(&fbdev->psb_fb_helper);
+
+	drm_framebuffer_cleanup(&psbfb->base);
+	
+	return 0;
+}
+
+int psb_fbdev_init(struct drm_device * dev) 
+{
+	struct psb_fbdev * fbdev;
+	struct drm_psb_private * dev_priv = 
+		(struct drm_psb_private *)dev->dev_private;
+	int num_crtc;
+	
+	fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
+	if(!fbdev) {
+		DRM_ERROR("no memory\n");
+		return -ENOMEM;
+	}
+
+	dev_priv->fbdev = fbdev;
+	fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs;
+
+	if( IS_CDV(dev) ) {
+		num_crtc = 2;
+	}
+
+	drm_fb_helper_init(dev, &fbdev->psb_fb_helper, num_crtc, INTELFB_CONN_LIMIT);
+
+	drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
+	drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
+	return 0;
+}
+
+void psb_fbdev_fini(struct drm_device * dev)
+{
+	struct drm_psb_private * dev_priv = 
+		(struct drm_psb_private *)dev->dev_private;
+
+	if(!dev_priv->fbdev) {
+		return;
+	}
+
+	psb_fbdev_destroy(dev, dev_priv->fbdev);
+	MRSTLFBFreeBuffer(dev, (struct MRSTLFB_BUFFER_TAG **)(&dev_priv->fb_reloc));
+	kfree(dev_priv->fbdev);
+	dev_priv->fbdev = NULL;
+}
+
+static void psbfb_output_poll_changed(struct drm_device * dev)
+{
+	struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
+	struct psb_fbdev * fbdev = (struct psb_fbdev *)dev_priv->fbdev;
+	drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper);
+}
+
+int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
+{
+	struct fb_info *info;
+	struct psb_framebuffer * psbfb = to_psb_fb(fb);
+
+
+	info = psbfb->fbdev;
+	psbfb->pvrBO = NULL;
+
+	if (info) {
+		framebuffer_release(info);
+	}
+
+	return 0;
+}
+/*EXPORT_SYMBOL(psbfb_remove); */
+
+static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
+					      struct drm_file *file_priv,
+					      unsigned int *handle)
+{
+	/* JB: TODO currently we can't go from a bo to a handle with ttm */
+	(void) file_priv;
+	*handle = 0;
+	return 0;
+}
+
+static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
+{
+	struct drm_device *dev = fb->dev;
+	struct psb_framebuffer *psbfb = to_psb_fb(fb);
+
+	/*ummap gtt pages*/
+	if (psbfb->hKernelMemInfo)
+		psb_gtt_unmap_meminfo(dev, psbfb->hKernelMemInfo);
+	if (psbfb->fbdev)
+	{
+		psbfb_remove(dev, fb);
+	}
+	DRM_DEBUG_KMS("Remove FB ID %d\n", fb->base.id);
+	/* JB: TODO not drop, refcount buffer */
+	drm_framebuffer_cleanup(fb);
+
+	kfree(fb);
+	/* update DC info by using the console fb when only one FB is left */
+	if (dev->mode_config.num_fb == 1) {
+		struct drm_psb_private *dev_priv =
+	    		(struct drm_psb_private *) dev->dev_private;
+		struct psb_fbdev * psPsbFBDev = (struct psb_fbdev *)dev_priv->fbdev;
+
+        	fb = psPsbFBDev->psb_fb_helper.fb;
+		psbfb = to_psb_fb(fb);
+		MRSTLFBHandleChangeFB(dev, psbfb);
+		DRM_DEBUG_KMS("Update the DC info by using the original console fb ID %d\n",
+						fb->base.id);
+	}
+}
+
+static const struct drm_mode_config_funcs psb_mode_funcs = {
+	.fb_create = psb_user_framebuffer_create,
+	.output_poll_changed = psbfb_output_poll_changed,
+};
+
+static void cdv_disable_vga(struct drm_device *dev)
+{
+	u8 sr1;
+	u32 vga_reg;
+
+	vga_reg = VGACNTRL;
+
+	outb(1, VGA_SR_INDEX);
+	sr1 = inb(VGA_SR_DATA);
+	outb(sr1 | 1<<5, VGA_SR_DATA);
+	udelay(300);
+
+	REG_WRITE(vga_reg, VGA_DISP_DISABLE);
+	REG_READ(vga_reg);
+}
+
+static void psb_setup_outputs(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	struct drm_connector *connector;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	drm_mode_create_scaling_mode_property(dev);
+
+	/* disable the VGA plane explicitly on CDV*/
+	cdv_disable_vga(dev);
+
+	/* Setting CRT for CDV connector */
+	psb_intel_crt_init(dev, &dev_priv->mode_dev);
+
+	/* Set up integrated LVDS */
+	psb_intel_lvds_init(dev, &dev_priv->mode_dev);
+
+	if (REG_READ(SDVOB) & SDVO_DETECTED) {
+		//found = psb_intel_sdvo_init(dev, SDVOB);
+		//if (!found)
+		mdfld_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
+		if (REG_READ(DP_B) & DP_DETECTED) {
+			DRM_DEBUG_KMS("Probe DP on DP B port\n");
+			psb_intel_dp_init(dev, &dev_priv->mode_dev, DP_B);
+		}
+	}
+ 
+	if (REG_READ(SDVOC) & SDVO_DETECTED) {
+		//found = psb_intel_sdvo_init(dev, SDVOC);
+		//if (!found)
+		mdfld_hdmi_init(dev, &dev_priv->mode_dev, SDVOC);
+		if (REG_READ(DP_C) & DP_DETECTED) {
+			DRM_DEBUG_KMS("Probe DP on DP B port\n");
+			psb_intel_dp_init(dev, &dev_priv->mode_dev, DP_C);
+		}
+	}
+		
+	list_for_each_entry(connector, &dev->mode_config.connector_list,
+			    head) {
+		struct psb_intel_output *psb_intel_output =
+		    to_psb_intel_output(connector);
+		struct drm_encoder *encoder = &psb_intel_output->enc;
+		int crtc_mask = 0, clone_mask = 0;
+
+		/* valid crtcs */
+		switch (psb_intel_output->type) {
+		case INTEL_OUTPUT_ANALOG:
+			crtc_mask = (1 << 0) | (1 << 1);
+			clone_mask = (1 << INTEL_OUTPUT_ANALOG);
+			break;
+		case INTEL_OUTPUT_SDVO:
+			crtc_mask = ((1 << 0) | (1 << 1));
+			clone_mask = (1 << INTEL_OUTPUT_SDVO);
+			break;
+		case INTEL_OUTPUT_LVDS:
+			crtc_mask = (1 << 1);
+			clone_mask = (1 << INTEL_OUTPUT_LVDS);
+			break;
+		case INTEL_OUTPUT_HDMI:
+			crtc_mask = (1 << 0) | (1 << 1);
+			clone_mask = (1 << INTEL_OUTPUT_HDMI);
+			break;
+		case INTEL_OUTPUT_DISPLAYPORT:
+			crtc_mask = (1 << 0) | (1 << 1);
+			clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
+			break;
+		case INTEL_OUTPUT_EDP:
+			crtc_mask = (1 << 1);
+			clone_mask = (1 << INTEL_OUTPUT_EDP);
+		}
+
+		encoder->possible_crtcs = crtc_mask;
+		encoder->possible_clones =
+		    psb_intel_connector_clones(dev, clone_mask);
+
+	}
+	if (dev_priv->int_lvds_connector && dev_priv->int_edp_connector) {
+		DRM_ERROR("VBIOS initialize the LVDS/eDP. Buggy VBIOS\n");
+	}
+}
+
+static void *psb_bo_from_handle(struct drm_device *dev,
+				struct drm_file *file_priv,
+				unsigned int handle)
+{
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
+	IMG_HANDLE hKernelMemInfo = (IMG_HANDLE)handle;
+	int ret;
+
+	ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
+	if (ret) {
+		DRM_ERROR("Cannot get meminfo for handle 0x%x\n",
+			  (IMG_UINT32)hKernelMemInfo);
+		return NULL;
+	}
+
+	return (void *)psKernelMemInfo;
+}
+
+static size_t psb_bo_size(struct drm_device *dev, void *bof)
+{
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo	= (PVRSRV_KERNEL_MEM_INFO *)bof;
+	return (size_t)psKernelMemInfo->uAllocSize;
+}
+
+static size_t psb_bo_offset(struct drm_device *dev, void *bof)
+{
+	struct psb_framebuffer *psbfb
+		= (struct psb_framebuffer *)bof;
+
+	return (size_t)psbfb->offset;
+}
+
+static int psb_bo_pin_for_scanout(struct drm_device *dev, void *bo)
+{
+	 return 0;
+}
+
+static int psb_bo_unpin_for_scanout(struct drm_device *dev, void *bo) 
+{
+	return 0;
+}
+
+/* Cedarview display clock gating */
+void psb_intel_clock_gating (struct drm_device *dev)
+{
+	uint32_t reg_value;
+	reg_value = REG_READ(DSPCLK_GATE_D);
+
+	reg_value |= (DPUNIT_PIPEB_GATE_DISABLE |
+			DPUNIT_PIPEA_GATE_DISABLE |
+			DPCUNIT_CLOCK_GATE_DISABLE |
+			DPLSUNIT_CLOCK_GATE_DISABLE |
+			DPOUNIT_CLOCK_GATE_DISABLE |
+		 	DPIOUNIT_CLOCK_GATE_DISABLE);	
+
+	REG_WRITE(DSPCLK_GATE_D, reg_value);
+
+	udelay(500);		
+}
+/* Cedarview display workarounds */
+void psb_intel_display_wa (struct drm_device *dev)
+{
+	/* Disable bonus launch.
+	 *
+	 * Copy Ben's mail below.
+	 * 	On Win 7 we are experiencing possible flicker issue related to processor
+	 *	arbitration bug.
+	 *
+	 *	CPU and GPU competes for memory and display misses updates and flickers.
+	 *	Worst with dual core, dual displays.
+	 *
+	 *	Fixes were done to Win 7 gfx driver to disable a feature called Bonus
+	 *	Launch to work around the issue, by degrading performance.
+	 * */
+
+	CDV_MSG_WRITE32(3, 0x30, 0x08027108);
+}
+
+void psb_modeset_init(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
+	int i;
+
+	PSB_DEBUG_ENTRY("\n");
+	/* Init mm functions */
+	mode_dev->bo_from_handle = psb_bo_from_handle;
+	mode_dev->bo_size = psb_bo_size;
+	mode_dev->bo_offset = psb_bo_offset;
+	mode_dev->bo_pin_for_scanout = psb_bo_pin_for_scanout;
+	mode_dev->bo_unpin_for_scanout = psb_bo_unpin_for_scanout;
+
+	drm_mode_config_init(dev);
+
+	psb_intel_clock_gating(dev);
+
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+
+	dev->mode_config.funcs = (void *) &psb_mode_funcs;
+
+	/* set memory base */
+	/* MRST and PSB should use BAR 2*/
+	pci_read_config_dword(dev->pdev, PSB_BSM, (uint32_t *) &(dev->mode_config.fb_base));
+
+	for (i = 0; i < dev_priv->num_pipe; i++)
+		psb_intel_crtc_init(dev, i, mode_dev);
+
+	dev->mode_config.max_width = 8192;
+	dev->mode_config.max_height = 8192;
+
+	psb_setup_outputs(dev);
+
+	if (!dev_priv->ovl_buf) {
+		struct MRSTLFB_BUFFER_TAG *ovl_buffer = NULL;
+		if (MRSTLFBAllocBuffer(dev, 64 * 1024, &ovl_buffer)) {
+			printk(KERN_ERR "Can't allocate GTT memory for overlay\n");
+			dev_priv->ovl_offset = 0;
+		} else {
+			dev_priv->ovl_buf = ovl_buffer;
+			memset(MRSTLFBGetCPUVAddr(ovl_buffer), 0, 64 * 1024);
+			dev_priv->ovl_offset = MRSTLFBGetDevVAddr(ovl_buffer);
+			printk(KERN_INFO "Overlay GTT address is %x\n", dev_priv->ovl_offset);
+		}
+	}
+
+	psb_intel_display_wa(dev);
+
+	/* setup fbs */
+	/* drm_initial_config(dev); */
+}
+
+void psb_modeset_cleanup(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+
+	mutex_lock(&dev->struct_mutex);
+
+	drm_kms_helper_poll_fini(dev);
+	psb_fbdev_fini(dev);
+
+	if (dev_priv->ovl_buf) {
+		struct MRSTLFB_BUFFER_TAG *ovl_buffer = dev_priv->ovl_buf;
+		MRSTLFBFreeBuffer(dev, &ovl_buffer);
+		dev_priv->ovl_buf = NULL;
+	}
+
+	drm_mode_config_cleanup(dev);
+
+	mutex_unlock(&dev->struct_mutex);
+}
diff --git a/drivers/staging/cdv/drv/psb_fb.h b/drivers/staging/cdv/drv/psb_fb.h
new file mode 100644
index 0000000..8679353
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_fb.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011, Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *      Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifndef _PSB_FB_H_
+#define _PSB_FB_H_
+
+#include <linux/version.h>
+#include <drm/drmP.h>
+
+#include <drm/drm_fb_helper.h>
+
+#include "psb_drv.h"
+
+/*IMG Headers*/
+#include "servicesint.h"
+
+struct psb_framebuffer {
+	struct drm_framebuffer base;
+	struct address_space *addr_space;
+	struct ttm_buffer_object *bo;
+	struct fb_info * fbdev;
+	/* struct ttm_bo_kmap_obj kmap; */
+	PVRSRV_KERNEL_MEM_INFO *pvrBO;
+	IMG_HANDLE hKernelMemInfo;
+	uint32_t size;
+	uint32_t offset;
+};
+
+struct psb_fbdev {
+	struct drm_fb_helper psb_fb_helper;
+	struct psb_framebuffer * pfb;
+};
+
+#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)
+
+
+extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
+
+
+#endif
+
diff --git a/drivers/staging/cdv/drv/psb_gtt.c b/drivers/staging/cdv/drv/psb_gtt.c
new file mode 100644
index 0000000..20ed944
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_gtt.c
@@ -0,0 +1,1048 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ * 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 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.
+ *
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
+ */
+
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_pvr_glue.h"
+
+static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
+{
+	uint32_t mask = PSB_PTE_VALID;
+
+	if (type & PSB_MMU_CACHED_MEMORY)
+		mask |= PSB_PTE_CACHED;
+	if (type & PSB_MMU_RO_MEMORY)
+		mask |= PSB_PTE_RO;
+	if (type & PSB_MMU_WO_MEMORY)
+		mask |= PSB_PTE_WO;
+
+	return (pfn << PAGE_SHIFT) | mask;
+}
+
+struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
+{
+	struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
+
+	if (!tmp)
+		return NULL;
+
+	init_rwsem(&tmp->sem);
+	tmp->dev = dev;
+
+	return tmp;
+}
+
+void psb_gtt_takedown(struct psb_gtt *pg, int free)
+{
+	struct drm_psb_private *dev_priv = pg->dev->dev_private;
+
+	if (!pg)
+		return;
+
+	if (pg->gtt_map) {
+		iounmap(pg->gtt_map);
+		pg->gtt_map = NULL;
+	}
+	if (pg->initialized) {
+		pci_write_config_word(pg->dev->pdev, PSB_GMCH_CTRL,
+				      pg->gmch_ctrl);
+		PSB_WVDC32(pg->pge_ctl, PSB_PGETBL_CTL);
+		(void) PSB_RVDC32(PSB_PGETBL_CTL);
+	}
+	if (free)
+		kfree(pg);
+}
+
+int psb_gtt_init(struct psb_gtt *pg, int resume)
+{
+	struct drm_device *dev = pg->dev;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	unsigned gtt_pages;
+	unsigned long stolen_size, vram_stolen_size, ci_stolen_size;
+	unsigned long rar_stolen_size;
+	unsigned i, num_pages;
+	unsigned pfn_base;
+	uint32_t ci_pages;
+	uint32_t tt_pages;
+	uint32_t *ttm_gtt_map;
+	uint32_t dvmt_mode = 0;
+	int ret = 0;
+	uint32_t pte;
+
+	pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &pg->gmch_ctrl);
+	pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
+			      pg->gmch_ctrl | _PSB_GMCH_ENABLED);
+
+	pg->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
+	PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
+	(void) PSB_RVDC32(PSB_PGETBL_CTL);
+
+	pg->initialized = 1;
+
+	pg->gtt_phys_start = pg->pge_ctl; // & PAGE_MASK;
+	DRM_DEBUG("pg->gtt_phys_start = %x\n", pg->gtt_phys_start);
+
+	pg->gatt_start = 0x40000000; //pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
+	DRM_DEBUG("pg->gatt_start = %x\n", pg->gatt_start);
+	/* fix me: video mmu has hw bug to access 0x0D0000000,
+	 * then make gatt start at 0x0e000,0000 */
+	pg->mmu_gatt_start = PSB_MEM_TT_START;
+	pg->gtt_start = pg->pge_ctl;
+	DRM_DEBUG("pg->gtt_start %x\n", pg->gtt_start);
+//	gtt_pages =
+//	    pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
+//	pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
+//	    >> PAGE_SHIFT;
+
+	gtt_pages = (256) / 4;
+	pg->gatt_pages = 256 * 1024 * 1024 >> PAGE_SHIFT;
+
+	DRM_DEBUG("gtt_pages = %x\n", gtt_pages);
+
+	pci_read_config_dword(dev->pdev, PSB_BSM, &pg->stolen_base);
+	vram_stolen_size = pg->gtt_phys_start - pg->stolen_base - PAGE_SIZE;
+
+	/* CI is not included in the stolen size since the TOPAZ MMU bug */
+	ci_stolen_size = dev_priv->ci_region_size;
+	/* Don't add CI & RAR share buffer space
+	 * managed by TTM to stolen_size */
+	stolen_size = vram_stolen_size;
+
+	rar_stolen_size = dev_priv->rar_region_size;
+
+	dvmt_mode = (pg->gmch_ctrl >> 4) & 0x7;
+
+	DRM_DEBUG("GMMADR(region 0) start: 0x%08x (%dM).\n",
+		  pg->gatt_start, pg->gatt_pages/256);
+	DRM_DEBUG("GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n",
+		  pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start);
+	DRM_DEBUG("Stole memory information \n");
+	DRM_DEBUG("      base in RAM: 0x%x \n", pg->stolen_base);
+	DRM_DEBUG("      size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
+		  vram_stolen_size/1024);
+	DRM_DEBUG("      the correct size should be: %dM(dvmt mode=%d) \n",
+		  (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
+
+	if (ci_stolen_size > 0)
+		DRM_DEBUG("CI Stole memory: RAM base = 0x%08x, size = %lu M \n",
+				dev_priv->ci_region_start,
+				ci_stolen_size / 1024 / 1024);
+	if (rar_stolen_size > 0)
+		DRM_DEBUG("RAR Stole memory: RAM base = 0x%08x, size = %lu M \n",
+				dev_priv->rar_region_start,
+				rar_stolen_size / 1024 / 1024);
+
+	if (resume && (gtt_pages != pg->gtt_pages) &&
+	    (stolen_size != pg->stolen_size)) {
+		DRM_ERROR("GTT resume error.\n");
+		ret = -EINVAL;
+		goto out_err;
+	}
+
+	pg->gtt_pages = gtt_pages;
+	pg->stolen_size = stolen_size;
+	pg->vram_stolen_size = vram_stolen_size;
+	pg->ci_stolen_size = ci_stolen_size;
+	pg->rar_stolen_size = rar_stolen_size;
+	pg->gtt_map = ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
+	if (!pg->gtt_map) {
+		DRM_ERROR("Failure to map gtt.\n");
+		ret = -ENOMEM;
+		goto out_err;
+	}
+
+	pg->vram_addr = ioremap_wc(pg->stolen_base, stolen_size);
+	if (!pg->vram_addr) {
+		DRM_ERROR("Failure to map stolen base.\n");
+		ret = -ENOMEM;
+		goto out_err;
+	}
+
+	DRM_DEBUG("%s: vram kernel virtual address %p\n", __func__, pg->vram_addr);
+
+	tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
+		(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
+
+	ttm_gtt_map = pg->gtt_map + (tt_pages * 3)/4;
+
+	/*
+	 * insert vram stolen pages.
+	 */
+
+	pfn_base = pg->stolen_base >> PAGE_SHIFT;
+	num_pages = vram_stolen_size >> PAGE_SHIFT;
+	DRM_DEBUG_KMS("Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
+		  num_pages, pfn_base, 0);
+	for (i = 0; i < num_pages; ++i) {
+		pte = psb_gtt_mask_pte(pfn_base + i, 0);
+		iowrite32(pte, pg->gtt_map + i);
+	}
+
+	/*
+	 * Init rest of gtt managed by IMG.
+	 */
+	pfn_base = page_to_pfn(dev_priv->scratch_page);
+	pte = psb_gtt_mask_pte(pfn_base, 0);
+	for (; i < (tt_pages * 3)/4 - 1; ++i)
+		iowrite32(pte, pg->gtt_map + i);
+
+	/*
+	 * insert CI stolen pages
+	 */
+
+	pfn_base = dev_priv->ci_region_start >> PAGE_SHIFT;
+	ci_pages = num_pages = ci_stolen_size >> PAGE_SHIFT;
+	DRM_DEBUG("Set up %d CI stolen pages starting at 0x%08x, GTT offset %dK\n",
+		  num_pages, pfn_base, (ttm_gtt_map - pg->gtt_map) * 4);
+	for (i = 0; i < num_pages; ++i) {
+		pte = psb_gtt_mask_pte(pfn_base + i, 0);
+		iowrite32(pte, ttm_gtt_map + i);
+	}
+
+	/*
+	 * insert RAR stolen pages
+	 */
+	if (rar_stolen_size != 0) {
+		pfn_base = dev_priv->rar_region_start >> PAGE_SHIFT;
+		num_pages = rar_stolen_size >> PAGE_SHIFT;
+		DRM_DEBUG("Set up %d RAR stolen pages starting at 0x%08x, GTT offset %dK\n",
+			  num_pages, pfn_base,
+			  (ttm_gtt_map - pg->gtt_map + i) * 4);
+		for (; i < num_pages + ci_pages; ++i) {
+			pte = psb_gtt_mask_pte(pfn_base + i - ci_pages, 0);
+			iowrite32(pte, ttm_gtt_map + i);
+		}
+	}
+	/*
+	 * Init rest of gtt managed by TTM.
+	 */
+
+	pfn_base = page_to_pfn(dev_priv->scratch_page);
+	pte = psb_gtt_mask_pte(pfn_base, 0);
+	PSB_DEBUG_INIT("Initializing the rest of a total "
+		       "of %u gtt pages.\n", pg->gatt_pages);
+
+	for (; i < pg->gatt_pages - (tt_pages * 3) / 4; ++i)
+		iowrite32(pte, ttm_gtt_map + i);
+	(void) ioread32(pg->gtt_map + i - 1);
+
+	return 0;
+
+out_err:
+	psb_gtt_takedown(pg, 0);
+	return ret;
+}
+
+int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
+			 unsigned offset_pages, unsigned num_pages,
+			 unsigned desired_tile_stride,
+			 unsigned hw_tile_stride, int type)
+{
+	unsigned rows = 1;
+	unsigned add;
+	unsigned i;
+	unsigned j;
+	uint32_t *cur_page = NULL;
+	uint32_t pte;
+
+	if (hw_tile_stride)
+		rows = num_pages / desired_tile_stride;
+	else
+		desired_tile_stride = num_pages;
+
+	add = desired_tile_stride;
+
+	down_read(&pg->sem);
+	for (i = 0; i < rows; ++i) {
+		cur_page = pg->gtt_map + offset_pages;
+		for (j = 0; j < desired_tile_stride; ++j) {
+			pte =
+			    psb_gtt_mask_pte(page_to_pfn(*pages++), type);
+			iowrite32(pte, cur_page++);
+		}
+		offset_pages += add;
+	}
+	(void) ioread32(cur_page - 1);
+	up_read(&pg->sem);
+
+	return 0;
+}
+
+int psb_gtt_insert_phys_addresses(struct psb_gtt *pg, IMG_CPU_PHYADDR *pPhysFrames,
+                                                                  unsigned offset_pages, unsigned num_pages, int type)
+{
+        unsigned j;
+        uint32_t *cur_page = NULL;
+        uint32_t pte;
+
+        //printk("Allocatng IMG GTT mem at %x (pages %d)\n",offset_pages,num_pages);
+        down_read(&pg->sem);
+
+        cur_page = pg->gtt_map + offset_pages;
+        for (j = 0; j < num_pages; ++j)
+        {
+                pte =  psb_gtt_mask_pte( (pPhysFrames++)->uiAddr >> PAGE_SHIFT, type);
+                iowrite32(pte, cur_page++);
+                //printk("PTE %d: %x/%x\n",j,(pPhysFrames-1)->uiAddr,pte);
+        }
+        (void) ioread32(cur_page - 1);
+
+        up_read(&pg->sem);
+
+        return 0;
+}
+
+int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
+			 unsigned num_pages, unsigned desired_tile_stride,
+			 unsigned hw_tile_stride, int rc_prot)
+{
+	struct drm_psb_private *dev_priv = pg->dev->dev_private;
+	unsigned rows = 1;
+	unsigned add;
+	unsigned i;
+	unsigned j;
+	uint32_t *cur_page = NULL;
+	unsigned pfn_base = page_to_pfn(dev_priv->scratch_page);
+	uint32_t pte = psb_gtt_mask_pte(pfn_base, 0);
+
+	if (hw_tile_stride)
+		rows = num_pages / desired_tile_stride;
+	else
+		desired_tile_stride = num_pages;
+
+	add = desired_tile_stride;
+
+	if (rc_prot)
+		down_read(&pg->sem);
+	for (i = 0; i < rows; ++i) {
+		cur_page = pg->gtt_map + offset_pages;
+		for (j = 0; j < desired_tile_stride; ++j)
+			iowrite32(pte, cur_page++);
+
+		offset_pages += add;
+	}
+	(void) ioread32(cur_page - 1);
+	if (rc_prot)
+		up_read(&pg->sem);
+
+	return 0;
+}
+
+int psb_gtt_mm_init(struct psb_gtt *pg)
+{
+	struct psb_gtt_mm *gtt_mm;
+	struct drm_psb_private *dev_priv = pg->dev->dev_private;
+	struct drm_open_hash *ht;
+	struct drm_mm *mm;
+	int ret;
+	uint32_t tt_start;
+	uint32_t tt_size;
+
+	if (!pg || !pg->initialized) {
+		DRM_DEBUG("Invalid gtt struct\n");
+		return -EINVAL;
+	}
+
+	gtt_mm =  kzalloc(sizeof(struct psb_gtt_mm), GFP_KERNEL);
+	if (!gtt_mm)
+		return -ENOMEM;
+
+	spin_lock_init(&gtt_mm->lock);
+
+	ht = &gtt_mm->hash;
+	ret = drm_ht_create(ht, 20);
+	if (ret) {
+		DRM_DEBUG("Create hash table failed(%d)\n", ret);
+		goto err_free;
+	}
+
+	tt_start = (pg->stolen_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	/* align to 256K bytes. This is to pre-allocated overlay buffer,which is
+	 * aligned to 64K bytes  */
+	tt_start = ALIGN(tt_start, 64);
+	tt_start = (tt_start < pg->gatt_pages) ? tt_start : pg->gatt_pages;
+	tt_size = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
+			(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
+	mm = &gtt_mm->base;
+
+	/*will use tt_start ~ 128M for IMG TT buffers*/
+	ret = drm_mm_init(mm, tt_start, ((tt_size * 3)/4 - tt_start));
+	if (ret) {
+		DRM_DEBUG("drm_mm_int error(%d)\n", ret);
+		goto err_mm_init;
+	}
+
+	gtt_mm->count = 0;
+
+	dev_priv->gtt_mm = gtt_mm;
+
+	DRM_DEBUG("PSB GTT mem manager ready, tt_start %ld, tt_size %ld pages\n",
+		(unsigned long)tt_start,
+		(unsigned long)((tt_size / 2) - tt_start));
+	return 0;
+err_mm_init:
+	drm_ht_remove(ht);
+
+err_free:
+	kfree(gtt_mm);
+	return ret;
+}
+
+/**
+ * Delete all hash entries;
+ */
+void psb_gtt_mm_takedown(void)
+{
+	return;
+}
+
+static int psb_gtt_mm_get_ht_by_pid_locked(struct psb_gtt_mm *mm,
+				    u32 tgid,
+				    struct psb_gtt_hash_entry **hentry)
+{
+	struct drm_hash_item *entry;
+	struct psb_gtt_hash_entry *psb_entry;
+	int ret;
+
+	ret = drm_ht_find_item(&mm->hash, tgid, &entry);
+	if (ret) {
+		DRM_DEBUG("Cannot find entry pid=%u\n", tgid);
+		return ret;
+	}
+
+	psb_entry = container_of(entry, struct psb_gtt_hash_entry, item);
+	if (!psb_entry) {
+		DRM_DEBUG("Invalid entry");
+		return -EINVAL;
+	}
+
+	*hentry = psb_entry;
+	return 0;
+}
+
+
+static int psb_gtt_mm_insert_ht_locked(struct psb_gtt_mm *mm,
+				       u32 tgid,
+				       struct psb_gtt_hash_entry *hentry)
+{
+	struct drm_hash_item *item;
+	int ret;
+
+	if (!hentry) {
+		DRM_DEBUG("Invalid parameters\n");
+		return -EINVAL;
+	}
+
+	item = &hentry->item;
+	item->key = tgid;
+
+	/**
+	 * NOTE: drm_ht_insert_item will perform such a check
+	ret = psb_gtt_mm_get_ht_by_pid(mm, tgid, &tmp);
+	if (!ret) {
+		DRM_DEBUG("Entry already exists for pid %ld\n", tgid);
+		return -EAGAIN;
+	}
+	*/
+
+	/*Insert the given entry*/
+	ret = drm_ht_insert_item(&mm->hash, item);
+	if (ret) {
+		DRM_DEBUG("Insert failure\n");
+		return ret;
+	}
+
+	mm->count++;
+
+	return 0;
+}
+
+static int psb_gtt_mm_alloc_insert_ht(struct psb_gtt_mm *mm,
+				      u32 tgid,
+				      struct psb_gtt_hash_entry **entry)
+{
+	struct psb_gtt_hash_entry *hentry;
+	int ret;
+
+	/*if the hentry for this tgid exists, just get it and return*/
+	spin_lock(&mm->lock);
+	ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
+	if (!ret) {
+		DRM_DEBUG("Entry for tgid %u exist, hentry %p\n",
+			  tgid, hentry);
+		*entry = hentry;
+		spin_unlock(&mm->lock);
+		return 0;
+	}
+	spin_unlock(&mm->lock);
+
+	DRM_DEBUG("Entry for tgid %u doesn't exist, will create it\n", tgid);
+
+	hentry = kzalloc(sizeof(struct psb_gtt_hash_entry), GFP_KERNEL);
+	if (!hentry) {
+		DRM_DEBUG("Kmalloc failled\n");
+		return -ENOMEM;
+	}
+
+	ret = drm_ht_create(&hentry->ht, 20);
+	if (ret) {
+		DRM_DEBUG("Create hash table failed\n");
+		return ret;
+	}
+
+	spin_lock(&mm->lock);
+	ret = psb_gtt_mm_insert_ht_locked(mm, tgid, hentry);
+	spin_unlock(&mm->lock);
+
+	if (!ret)
+		*entry = hentry;
+
+	return ret;
+}
+
+static struct psb_gtt_hash_entry *
+psb_gtt_mm_remove_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
+{
+	struct psb_gtt_hash_entry *tmp;
+	int ret;
+
+	ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &tmp);
+	if (ret) {
+		DRM_DEBUG("Cannot find entry pid %u\n", tgid);
+		return NULL;
+	}
+
+	/*remove it from ht*/
+	drm_ht_remove_item(&mm->hash, &tmp->item);
+
+	mm->count--;
+
+	return tmp;
+}
+
+static int psb_gtt_mm_remove_free_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
+{
+	struct psb_gtt_hash_entry *entry;
+
+	entry = psb_gtt_mm_remove_ht_locked(mm, tgid);
+
+	if (!entry) {
+		DRM_DEBUG("Invalid entry");
+		return -EINVAL;
+	}
+
+	/*delete ht*/
+	drm_ht_remove(&entry->ht);
+
+	/*free this entry*/
+	kfree(entry);
+	return 0;
+}
+
+static int
+psb_gtt_mm_get_mem_mapping_locked(struct drm_open_hash *ht,
+			   u32 key,
+			   struct psb_gtt_mem_mapping **hentry)
+{
+	struct drm_hash_item *entry;
+	struct psb_gtt_mem_mapping *mapping;
+	int ret;
+
+	ret = drm_ht_find_item(ht, key, &entry);
+	if (ret) {
+		DRM_DEBUG("Cannot find key %u\n", key);
+		return ret;
+	}
+
+	mapping =  container_of(entry, struct psb_gtt_mem_mapping, item);
+	if (!mapping) {
+		DRM_DEBUG("Invalid entry\n");
+		return -EINVAL;
+	}
+
+	*hentry = mapping;
+	return 0;
+}
+
+static int
+psb_gtt_mm_insert_mem_mapping_locked(struct drm_open_hash *ht,
+			      u32 key,
+			      struct psb_gtt_mem_mapping *hentry)
+{
+	struct drm_hash_item *item;
+	struct psb_gtt_hash_entry *entry;
+	int ret;
+
+	if (!hentry) {
+		DRM_DEBUG("hentry is NULL\n");
+		return -EINVAL;
+	}
+
+	item = &hentry->item;
+	item->key = key;
+
+	ret = drm_ht_insert_item(ht, item);
+	if (ret) {
+		DRM_DEBUG("insert_item failed\n");
+		return ret;
+	}
+
+	entry = container_of(ht, struct psb_gtt_hash_entry, ht);
+	if (entry)
+		entry->count++;
+
+	return 0;
+}
+
+static int
+psb_gtt_mm_alloc_insert_mem_mapping(struct psb_gtt_mm *mm,
+				    struct drm_open_hash *ht,
+				    u32 key,
+				    struct drm_mm_node *node,
+				    struct psb_gtt_mem_mapping **entry)
+{
+	struct psb_gtt_mem_mapping *mapping;
+	int ret;
+
+	if (!node || !ht) {
+		DRM_DEBUG("parameter error\n");
+		return -EINVAL;
+	}
+
+	/*try to get this mem_map */
+	spin_lock(&mm->lock);
+	ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &mapping);
+	if (!ret) {
+		DRM_DEBUG("mapping entry for key %u exists, entry %p\n",
+			  key, mapping);
+		*entry = mapping;
+		spin_unlock(&mm->lock);
+		return 0;
+	}
+	spin_unlock(&mm->lock);
+
+	DRM_DEBUG("Mapping entry for key %u doesn't exist, will create it\n", key);
+
+	mapping = kzalloc(sizeof(struct psb_gtt_mem_mapping), GFP_KERNEL);
+	if (!mapping) {
+		DRM_DEBUG("kmalloc failed\n");
+		return -ENOMEM;
+	}
+
+	mapping->node = node;
+
+	spin_lock(&mm->lock);
+	ret = psb_gtt_mm_insert_mem_mapping_locked(ht, key, mapping);
+	spin_unlock(&mm->lock);
+
+	if (!ret)
+		*entry = mapping;
+
+	return ret;
+}
+
+static struct psb_gtt_mem_mapping *
+psb_gtt_mm_remove_mem_mapping_locked(struct drm_open_hash *ht, u32 key)
+{
+	struct psb_gtt_mem_mapping *tmp;
+	struct psb_gtt_hash_entry *entry;
+	int ret;
+
+	ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &tmp);
+	if (ret) {
+		DRM_DEBUG("Cannot find key %u\n", key);
+		return NULL;
+	}
+
+	drm_ht_remove_item(ht, &tmp->item);
+
+	entry = container_of(ht, struct psb_gtt_hash_entry, ht);
+	if (entry)
+		entry->count--;
+
+	return tmp;
+}
+
+static int psb_gtt_mm_remove_free_mem_mapping_locked(struct drm_open_hash *ht,
+					      u32 key,
+					      struct drm_mm_node **node)
+{
+	struct psb_gtt_mem_mapping *entry;
+
+	entry = psb_gtt_mm_remove_mem_mapping_locked(ht, key);
+	if (!entry) {
+		DRM_DEBUG("entry is NULL\n");
+		return -EINVAL;
+	}
+
+	*node = entry->node;
+
+	kfree(entry);
+	return 0;
+}
+
+static int psb_gtt_add_node(struct psb_gtt_mm *mm,
+			    u32 tgid,
+			    u32 key,
+			    struct drm_mm_node *node,
+			    struct psb_gtt_mem_mapping **entry)
+{
+	struct psb_gtt_hash_entry *hentry;
+	struct psb_gtt_mem_mapping *mapping;
+	int ret;
+
+	ret = psb_gtt_mm_alloc_insert_ht(mm, tgid, &hentry);
+	if (ret) {
+		DRM_DEBUG("alloc_insert failed\n");
+		return ret;
+	}
+
+	ret = psb_gtt_mm_alloc_insert_mem_mapping(mm,
+						  &hentry->ht,
+						  key,
+						  node,
+						  &mapping);
+	if (ret) {
+		DRM_DEBUG("mapping alloc_insert failed\n");
+		return ret;
+	}
+
+	*entry = mapping;
+
+	return 0;
+}
+
+static int psb_gtt_remove_node(struct psb_gtt_mm *mm,
+			       u32 tgid,
+			       u32 key,
+			       struct drm_mm_node **node)
+{
+	struct psb_gtt_hash_entry *hentry;
+	struct drm_mm_node *tmp;
+	int ret;
+
+	spin_lock(&mm->lock);
+	ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
+	if (ret) {
+		DRM_DEBUG("Cannot find entry for pid %u\n", tgid);
+		spin_unlock(&mm->lock);
+		return ret;
+	}
+	spin_unlock(&mm->lock);
+
+	/*remove mapping entry*/
+	spin_lock(&mm->lock);
+	ret = psb_gtt_mm_remove_free_mem_mapping_locked(&hentry->ht,
+							key,
+							&tmp);
+	if (ret) {
+		DRM_DEBUG("remove_free failed\n");
+		spin_unlock(&mm->lock);
+		return ret;
+	}
+
+	*node = tmp;
+
+	/*check the count of mapping entry*/
+	if (!hentry->count) {
+		DRM_DEBUG("count of mapping entry is zero, tgid=%u\n", tgid);
+		psb_gtt_mm_remove_free_ht_locked(mm, tgid);
+	}
+
+	spin_unlock(&mm->lock);
+
+	return 0;
+}
+
+static int psb_gtt_mm_alloc_mem(struct psb_gtt_mm *mm,
+				uint32_t pages,
+				uint32_t align,
+				struct drm_mm_node **node)
+{
+	struct drm_mm_node *tmp_node;
+	int ret;
+
+	do {
+		ret = drm_mm_pre_get(&mm->base);
+		if (unlikely(ret)) {
+			DRM_DEBUG("drm_mm_pre_get error\n");
+			return ret;
+		}
+
+		spin_lock(&mm->lock);
+		tmp_node = drm_mm_search_free(&mm->base, pages, align, 1);
+		if (unlikely(!tmp_node)) {
+			DRM_DEBUG("No free node found\n");
+			spin_unlock(&mm->lock);
+			break;
+		}
+
+		tmp_node = drm_mm_get_block_atomic(tmp_node, pages, align);
+		spin_unlock(&mm->lock);
+	} while (!tmp_node);
+
+	if (!tmp_node) {
+		DRM_DEBUG("Node allocation failed\n");
+		return -ENOMEM;
+	}
+
+	*node = tmp_node;
+	return 0;
+}
+
+static void psb_gtt_mm_free_mem(struct psb_gtt_mm *mm, struct drm_mm_node *node)
+{
+	spin_lock(&mm->lock);
+	drm_mm_put_block(node);
+	spin_unlock(&mm->lock);
+}
+
+int psb_gtt_map_meminfo(struct drm_device *dev,
+			IMG_HANDLE hKernelMemInfo,
+			uint32_t *offset)
+{
+	struct drm_psb_private *dev_priv
+	       = (struct drm_psb_private *)dev->dev_private;
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+	struct psb_gtt_mm *mm = dev_priv->gtt_mm;
+	struct psb_gtt *pg = dev_priv->pg;
+	uint32_t size, pages, offset_pages;
+	void *kmem;
+	struct drm_mm_node *node;
+	struct page **page_list;
+	struct psb_gtt_mem_mapping *mapping = NULL;
+	int ret;
+
+	ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
+	if (ret) {
+		DRM_DEBUG("Cannot find kernelMemInfo handle 0x%x\n",
+			  (unsigned int)hKernelMemInfo);
+		return -EINVAL;
+	}
+
+	DRM_DEBUG("Got psKernelMemInfo %p for handle 0x%x\n",
+		  psKernelMemInfo, (u32)hKernelMemInfo);
+
+	size = psKernelMemInfo->uAllocSize;
+	kmem = psKernelMemInfo->pvLinAddrKM;
+	pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+	DRM_DEBUG("KerMemInfo size %u, cpuVadr 0x%x, pages %u, osMemHdl 0x%x\n",
+		  size, (unsigned int)kmem, pages, (unsigned int)psKernelMemInfo->sMemBlk.hOSMemHandle);
+
+	if (!kmem)
+		DRM_DEBUG_KMS("kmem is NULL");
+
+	/*get pages*/
+	ret = psb_get_pages_by_mem_handle(psKernelMemInfo->sMemBlk.hOSMemHandle,
+					  &page_list);
+	if (ret) {
+		DRM_DEBUG("get pages error\n");
+		return ret;
+	}
+
+	DRM_DEBUG("get %u pages\n", pages);
+
+	/*alloc memory in TT apeture*/
+	ret = psb_gtt_mm_alloc_mem(mm, pages, 0, &node);
+	if (ret) {
+		DRM_DEBUG_KMS("alloc TT memory error\n");
+		goto failed_pages_alloc;
+	}
+
+	/*update psb_gtt_mm*/
+	ret = psb_gtt_add_node(mm,
+			       (u32)psb_get_tgid(),
+			       (u32)hKernelMemInfo,
+			       node,
+			       &mapping);
+	if (ret) {
+		DRM_DEBUG_KMS("add_node failed");
+		goto failed_add_node;
+	}
+
+	node = mapping->node;
+	offset_pages = node->start;
+
+	DRM_DEBUG_KMS("get free node for %u pages, offset %u pages",
+		  pages, offset_pages);
+
+	/*update gtt*/
+	psb_gtt_insert_pages(pg, page_list,
+			     (unsigned)offset_pages,
+			     (unsigned)pages,
+			     0,
+			     0,
+			     0);
+
+	*offset = offset_pages;
+	return 0;
+
+failed_add_node:
+	psb_gtt_mm_free_mem(mm, node);
+failed_pages_alloc:
+	kfree(page_list);
+	return ret;
+}
+
+int psb_gtt_unmap_meminfo(struct drm_device *dev, IMG_HANDLE hKernelMemInfo)
+{
+	struct drm_psb_private *dev_priv
+	       = (struct drm_psb_private *)dev->dev_private;
+	struct psb_gtt_mm *mm = dev_priv->gtt_mm;
+	struct psb_gtt *pg = dev_priv->pg;
+	uint32_t pages, offset_pages;
+	struct drm_mm_node *node;
+	int ret;
+
+	ret = psb_gtt_remove_node(mm,
+				  (u32)psb_get_tgid(),
+				  (u32)hKernelMemInfo,
+				  &node);
+	if (ret) {
+		DRM_DEBUG_KMS("remove node failed\n");
+		return ret;
+	}
+
+	/*remove gtt entries*/
+	offset_pages = node->start;
+	pages = node->size;
+
+	DRM_DEBUG_KMS("free node for %u pages, offset %u pages",
+		  pages, offset_pages);
+	psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1);
+
+
+	/*free tt node*/
+
+	psb_gtt_mm_free_mem(mm, node);
+	return 0;
+}
+
+int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv)
+{
+	struct psb_gtt_mapping_arg *arg
+	       = (struct psb_gtt_mapping_arg *)data;
+	uint32_t *offset_pages = &arg->offset_pages;
+
+	DRM_DEBUG("\n");
+
+	return psb_gtt_map_meminfo(dev, arg->hKernelMemInfo, offset_pages);
+}
+
+int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+
+	struct psb_gtt_mapping_arg *arg
+	       = (struct psb_gtt_mapping_arg *)data;
+
+	DRM_DEBUG("\n");
+
+	return psb_gtt_unmap_meminfo(dev, arg->hKernelMemInfo);
+}
+
+int psb_gtt_map_pvr_memory(struct drm_device *dev, 
+								 unsigned int hHandle,
+						  	     unsigned int ui32TaskId,
+								 IMG_CPU_PHYADDR *pPages,
+							   	 unsigned int ui32PagesNum,
+	 							 unsigned int *ui32Offset) 
+{
+	struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;	
+	struct psb_gtt_mm * mm = dev_priv->gtt_mm;
+	struct psb_gtt * pg = dev_priv->pg;
+	
+	uint32_t pages, offset_pages;
+	struct drm_mm_node * node = NULL;
+	struct psb_gtt_mem_mapping * mapping = NULL;
+	int ret;
+
+	pages = 0;   
+
+	/*alloc memory in TT apeture*/
+	ret = psb_gtt_mm_alloc_mem(mm, ui32PagesNum, 0, &node);
+	if(ret) 
+	{
+		DRM_DEBUG_KMS("alloc TT memory error\n");
+		goto failed_pages_alloc;
+	}
+
+   /*update psb_gtt_mm*/
+	ret = psb_gtt_add_node(mm,
+						   (u32)ui32TaskId,
+						   (u32)hHandle,
+						   node,
+						   &mapping);
+	if(ret) 
+	{
+		DRM_DEBUG_KMS("add_node failed");
+		goto failed_add_node;
+	}
+
+	node = mapping->node;
+	offset_pages = node->start;
+
+	DRM_DEBUG_KMS("get free node for size %u pages, offset at %x pages", ui32PagesNum, offset_pages);
+
+	/*update gtt*/
+	psb_gtt_insert_phys_addresses( pg, pPages, (unsigned)offset_pages, (unsigned)ui32PagesNum, 0 );
+
+	*ui32Offset = offset_pages;
+	return 0;
+
+failed_add_node:
+	psb_gtt_mm_free_mem(mm, node);
+failed_pages_alloc:
+	return ret;	
+}
+
+
+int psb_gtt_unmap_pvr_memory(struct drm_device *dev, unsigned int hHandle, unsigned int ui32TaskId) 
+{
+	struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
+	struct psb_gtt_mm * mm = dev_priv->gtt_mm;
+	struct psb_gtt * pg = dev_priv->pg;
+	uint32_t pages, offset_pages;
+	struct drm_mm_node * node;
+	int ret;
+
+	ret = psb_gtt_remove_node(mm,
+							  (u32)ui32TaskId,
+							  (u32)hHandle,
+                              &node);
+	if(ret)
+	{
+		DRM_ERROR("remove node failed\n");
+		return ret;
+	}
+
+	/*remove gtt entries*/
+	offset_pages = node->start;
+	pages = node->size;
+
+	psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1);
+
+	DRM_DEBUG_KMS("free node for size %u pages, offset at %x pages", pages, offset_pages);
+	/*free tt node*/
+	psb_gtt_mm_free_mem(mm, node);
+	return 0;
+}
diff --git a/drivers/staging/cdv/drv/psb_gtt.h b/drivers/staging/cdv/drv/psb_gtt.h
new file mode 100644
index 0000000..6966676
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_gtt.h
@@ -0,0 +1,112 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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 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.
+ *
+ **************************************************************************/
+
+#ifndef _PSB_GTT_H_
+#define _PSB_GTT_H_
+
+#include <drm/drmP.h>
+
+#include "img_types.h"
+
+struct psb_gtt {
+	struct drm_device *dev;
+	int initialized;
+	uint32_t gatt_start;
+	uint32_t mmu_gatt_start;
+	uint32_t ci_start;
+	uint32_t rar_start;
+	uint32_t gtt_start;
+	uint32_t gtt_phys_start;
+	unsigned gtt_pages;
+	unsigned gatt_pages;
+	uint32_t stolen_base;
+	void *vram_addr;
+	uint32_t pge_ctl;
+	u16 gmch_ctrl;
+	unsigned long stolen_size;
+	unsigned long vram_stolen_size;
+	unsigned long ci_stolen_size;
+	unsigned long rar_stolen_size;
+	uint32_t *gtt_map;
+	struct rw_semaphore sem;
+};
+
+struct psb_gtt_mm {
+	struct drm_mm base;
+	struct drm_open_hash hash;
+	uint32_t count;
+	spinlock_t lock;
+};
+
+struct psb_gtt_hash_entry {
+	struct drm_open_hash ht;
+	uint32_t count;
+	struct drm_hash_item item;
+};
+
+struct psb_gtt_mem_mapping {
+	struct drm_mm_node *node;
+	struct drm_hash_item item;
+};
+
+#if 0
+/*Ioctl args*/
+struct psb_gtt_mapping_arg {
+	IMG_HANDLE hKernelMemInfo;
+};
+#endif
+
+/*Exported functions*/
+extern int psb_gtt_init(struct psb_gtt *pg, int resume);
+extern int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
+				unsigned offset_pages, unsigned num_pages,
+				unsigned desired_tile_stride,
+				unsigned hw_tile_stride, int type);
+extern int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
+				unsigned num_pages,
+				unsigned desired_tile_stride,
+				unsigned hw_tile_stride,
+				int rc_prot);
+
+extern struct psb_gtt *psb_gtt_alloc(struct drm_device *dev);
+extern void psb_gtt_takedown(struct psb_gtt *pg, int free);
+extern int psb_gtt_map_meminfo(struct drm_device *dev,
+				IMG_HANDLE hKernelMemInfo,
+				uint32_t *offset);
+extern int psb_gtt_unmap_meminfo(struct drm_device *dev,
+				 IMG_HANDLE hKernelMemInfo);
+extern int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
+				     struct drm_file *file_priv);
+extern int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
+				       struct drm_file *file_priv);
+extern int psb_gtt_mm_init(struct psb_gtt *pg);
+extern void psb_gtt_mm_takedown(void);
+
+extern int psb_gtt_map_pvr_memory(struct drm_device *dev,
+                                                                  unsigned int hHandle,
+                                                                  unsigned int ui32TaskId,
+                                                                  IMG_CPU_PHYADDR *pPages,
+                                                                  unsigned int ui32PagesNum,
+                                                                  unsigned int *ui32Offset);
+
+extern int psb_gtt_unmap_pvr_memory(struct drm_device *dev,
+                                                                        unsigned int hHandle,
+                                                                        unsigned int ui32TaskId);
+
+#endif
diff --git a/drivers/staging/cdv/drv/psb_hotplug.c b/drivers/staging/cdv/drv/psb_hotplug.c
new file mode 100644
index 0000000..61219e1
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_hotplug.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *    James C. Gualario <james.c.gualario@intel.com>
+ *
+ */
+
+#include "psb_umevents.h"
+#include "psb_hotplug.h"
+/**
+ * inform the kernel of the work to be performed and related function.
+ *
+ */
+DECLARE_WORK(hotplug_dev_create_work, &psb_hotplug_dev_create_wq);
+DECLARE_WORK(hotplug_dev_remove_work, &psb_hotplug_dev_remove_wq);
+DECLARE_WORK(hotplug_dev_change_work, &psb_hotplug_dev_change_wq);
+/**
+ * psb_hotplug_notify_change_um - notify user mode of hotplug changes
+ *
+ * @name: name of event to notify user mode of change to
+ * @state: hotplug state to search for event object in
+ *
+ */
+int psb_hotplug_notify_change_um(const char *name,
+			     struct hotplug_state *state)
+{
+	strcpy(&(state->hotplug_change_wq_data.dev_name_arry
+		 [state->hotplug_change_wq_data.dev_name_write][0]), name);
+	state->hotplug_change_wq_data.dev_name_arry_rw_status
+		[state->hotplug_change_wq_data.dev_name_write] =
+		DRM_HOTPLUG_READY_TO_READ;
+	if (state->hotplug_change_wq_data.dev_name_read_write_wrap_ack == 1)
+		state->hotplug_change_wq_data.dev_name_read_write_wrap_ack = 0;
+	state->hotplug_change_wq_data.dev_name_write++;
+	if (state->hotplug_change_wq_data.dev_name_write ==
+	   state->hotplug_change_wq_data.dev_name_read) {
+		state->hotplug_change_wq_data.dev_name_write--;
+		return IRQ_NONE;
+	}
+	if (state->hotplug_change_wq_data.dev_name_write >
+	   DRM_HOTPLUG_RING_DEPTH_MAX) {
+		state->hotplug_change_wq_data.dev_name_write = 0;
+		state->hotplug_change_wq_data.dev_name_write_wrap = 1;
+	}
+	state->hotplug_change_wq_data.hotplug_dev_list = state->list;
+	queue_work(state->hotplug_wq, &(state->hotplug_change_wq_data.work));
+	return IRQ_HANDLED;
+}
+/**
+ *
+ * psb_hotplug_create_and_notify_um - create and notify user mode of new dev
+ *
+ * @name: name to give for new event / device
+ * @state: hotplug state to track new event /device in
+ *
+ */
+int psb_hotplug_create_and_notify_um(const char *name,
+				 struct hotplug_state *state)
+{
+	strcpy(&(state->hotplug_create_wq_data.dev_name_arry
+		 [state->hotplug_create_wq_data.dev_name_write][0]), name);
+	state->hotplug_create_wq_data.dev_name_arry_rw_status
+		[state->hotplug_create_wq_data.dev_name_write] =
+		DRM_HOTPLUG_READY_TO_READ;
+	if (state->hotplug_create_wq_data.dev_name_read_write_wrap_ack == 1)
+		state->hotplug_create_wq_data.dev_name_read_write_wrap_ack = 0;
+	state->hotplug_create_wq_data.dev_name_write++;
+	if (state->hotplug_create_wq_data.dev_name_write ==
+	   state->hotplug_create_wq_data.dev_name_read) {
+		state->hotplug_create_wq_data.dev_name_write--;
+		return IRQ_NONE;
+	}
+	if (state->hotplug_create_wq_data.dev_name_write >
+	   DRM_HOTPLUG_RING_DEPTH_MAX) {
+		state->hotplug_create_wq_data.dev_name_write = 0;
+		state->hotplug_create_wq_data.dev_name_write_wrap = 1;
+	}
+	state->hotplug_create_wq_data.hotplug_dev_list = state->list;
+	queue_work(state->hotplug_wq, &(state->hotplug_create_wq_data.work));
+	return IRQ_HANDLED;
+}
+/*EXPORT_SYMBOL(psb_hotplug_create_and_notify_um); */
+/**
+ * psb_hotplug_remove_and_notify_um - remove device and notify user mode
+ *
+ * @name: name of event / device to remove
+ * @state: hotplug state to remove event / device from
+ *
+ */
+int psb_hotplug_remove_and_notify_um(const char *name,
+				 struct hotplug_state *state)
+{
+	strcpy(&(state->hotplug_remove_wq_data.dev_name_arry
+		 [state->hotplug_remove_wq_data.dev_name_write][0]), name);
+	state->hotplug_remove_wq_data.dev_name_arry_rw_status
+		[state->hotplug_remove_wq_data.dev_name_write] =
+		DRM_HOTPLUG_READY_TO_READ;
+	if (state->hotplug_remove_wq_data.dev_name_read_write_wrap_ack == 1)
+		state->hotplug_remove_wq_data.dev_name_read_write_wrap_ack = 0;
+	state->hotplug_remove_wq_data.dev_name_write++;
+	if (state->hotplug_remove_wq_data.dev_name_write ==
+	   state->hotplug_remove_wq_data.dev_name_read) {
+		state->hotplug_remove_wq_data.dev_name_write--;
+		return IRQ_NONE;
+	}
+	if (state->hotplug_remove_wq_data.dev_name_write >
+	   DRM_HOTPLUG_RING_DEPTH_MAX) {
+		state->hotplug_remove_wq_data.dev_name_write = 0;
+		state->hotplug_remove_wq_data.dev_name_write_wrap = 1;
+	}
+	state->hotplug_remove_wq_data.hotplug_dev_list = state->list;
+	queue_work(state->hotplug_wq, &(state->hotplug_remove_wq_data.work));
+	return IRQ_HANDLED;
+}
+/*EXPORT_SYMBOL(psb_hotplug_remove_and_notify_um); */
+/**
+ * psb_hotplug_device_pool_create_and_init - make new hotplug device pool
+ *
+ * @parent_kobj: parent kobject to associate hotplug kset with
+ * @state: hotplug state to assocaite workqueues with
+ *
+ */
+struct umevent_list *psb_hotplug_device_pool_create_and_init(
+				     struct kobject *parent_kobj,
+				     struct hotplug_state *state)
+{
+	struct umevent_list *new_hotplug_dev_list = NULL;
+
+	new_hotplug_dev_list = psb_umevent_create_list();
+	if (new_hotplug_dev_list)
+		psb_umevent_init(parent_kobj, new_hotplug_dev_list,
+				 "psb_hotplug");
+
+	state->hotplug_wq = create_singlethread_workqueue("hotplug-wq");
+	if (!state->hotplug_wq)
+		return NULL;
+
+	INIT_WORK(&state->hotplug_create_wq_data.work,
+		  psb_hotplug_dev_create_wq);
+	INIT_WORK(&state->hotplug_remove_wq_data.work,
+		  psb_hotplug_dev_remove_wq);
+	INIT_WORK(&state->hotplug_change_wq_data.work,
+		  psb_hotplug_dev_change_wq);
+
+	state->hotplug_create_wq_data.dev_name_read = 0;
+	state->hotplug_create_wq_data.dev_name_write = 0;
+	state->hotplug_create_wq_data.dev_name_write_wrap = 0;
+	state->hotplug_create_wq_data.dev_name_read_write_wrap_ack = 0;
+	memset(&(state->hotplug_create_wq_data.dev_name_arry_rw_status[0]),
+	       0, sizeof(int)*DRM_HOTPLUG_RING_DEPTH);
+
+	state->hotplug_remove_wq_data.dev_name_read = 0;
+	state->hotplug_remove_wq_data.dev_name_write = 0;
+	state->hotplug_remove_wq_data.dev_name_write_wrap = 0;
+	state->hotplug_remove_wq_data.dev_name_read_write_wrap_ack = 0;
+	memset(&(state->hotplug_remove_wq_data.dev_name_arry_rw_status[0]),
+	       0, sizeof(int)*DRM_HOTPLUG_RING_DEPTH);
+
+	state->hotplug_change_wq_data.dev_name_read = 0;
+	state->hotplug_change_wq_data.dev_name_write = 0;
+	state->hotplug_change_wq_data.dev_name_write_wrap = 0;
+	state->hotplug_change_wq_data.dev_name_read_write_wrap_ack = 0;
+	memset(&(state->hotplug_change_wq_data.dev_name_arry_rw_status[0]),
+	       0, sizeof(int)*DRM_HOTPLUG_RING_DEPTH);
+
+	return new_hotplug_dev_list;
+}
+/*EXPORT_SYMBOL(psb_hotplug_device_pool_create_and_init); */
+/**
+ *
+ * psb_hotplug_init - init hotplug subsystem
+ *
+ * @parent_kobj: parent kobject to associate hotplug state with
+ *
+ */
+struct hotplug_state *psb_hotplug_init(struct kobject *parent_kobj)
+{
+	struct hotplug_state *state;
+	state = kzalloc(sizeof(struct hotplug_state), GFP_KERNEL);
+
+	if (!state)
+		return state;
+
+	state->list = NULL;
+	state->list = psb_hotplug_device_pool_create_and_init(
+						      parent_kobj,
+						      state);
+
+	psb_hotplug_create_and_notify_um("hpd_hdmi", state);
+
+	return state;
+}
+/**
+ * psb_hotplug_device_pool_destroy - destroy all hotplug related resources
+ *
+ * @state: hotplug state to destroy
+ *
+ */
+void psb_hotplug_device_pool_destroy(struct hotplug_state *state)
+{
+	flush_workqueue(state->hotplug_wq);
+	destroy_workqueue(state->hotplug_wq);
+	psb_umevent_cleanup(state->list);
+	kfree(state);
+}
+/*EXPORT_SYMBOL(psb_hotplug_device_pool_destroy); */
+/**
+ * psb_hotplug_dev_create_wq - create workqueue implementation
+ *
+ * @work: work struct to use for kernel scheduling
+ *
+ */
+void psb_hotplug_dev_create_wq(struct work_struct *work)
+{
+	struct hotplug_disp_workqueue_data *wq_data;
+	/* struct umevent_obj *wq_working_hotplug_disp_obj; */
+	wq_data = to_hotplug_disp_workqueue_data(work);
+	if (wq_data->dev_name_write_wrap == 1) {
+		wq_data->dev_name_read_write_wrap_ack = 1;
+		wq_data->dev_name_write_wrap = 0;
+		while (wq_data->dev_name_read != DRM_HOTPLUG_RING_DEPTH_MAX) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_HOTPLUG_READY_TO_READ) {
+				/*
+				wq_working_hotplug_disp_obj =
+				psb_create_umevent_obj(
+					&wq_data->dev_name_arry
+					[wq_data->dev_name_read][0],
+					wq_data->hotplug_dev_list);
+				*/
+				wq_data->dev_name_arry_rw_status
+					[wq_data->dev_name_read] =
+					DRM_HOTPLUG_READ_COMPLETE;
+				/* psb_umevent_notify
+					(wq_working_hotplug_disp_obj);*/
+			}
+			wq_data->dev_name_read++;
+		}
+		wq_data->dev_name_read = 0;
+		while (wq_data->dev_name_read < wq_data->dev_name_write-1) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_HOTPLUG_READY_TO_READ) {
+				/*
+				wq_working_hotplug_disp_obj =
+				psb_create_umevent_obj(
+					&wq_data->dev_name_arry
+					[wq_data->dev_name_read][0],
+					wq_data->hotplug_dev_list);
+				*/
+				wq_data->dev_name_arry_rw_status
+					[wq_data->dev_name_read] =
+					DRM_HOTPLUG_READ_COMPLETE;
+				/*psb_umevent_notify
+					(wq_working_hotplug_disp_obj);*/
+			}
+			wq_data->dev_name_read++;
+		}
+	} else {
+		while (wq_data->dev_name_read < wq_data->dev_name_write) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_HOTPLUG_READY_TO_READ) {
+				/*
+				wq_working_hotplug_disp_obj =
+				psb_create_umevent_obj(
+				&wq_data->dev_name_arry
+					[wq_data->dev_name_read][0],
+					wq_data->hotplug_dev_list);
+				*/
+				wq_data->dev_name_arry_rw_status
+					[wq_data->dev_name_read] =
+					DRM_HOTPLUG_READ_COMPLETE;
+				/*psb_umevent_notify
+					(wq_working_hotplug_disp_obj);*/
+			}
+			wq_data->dev_name_read++;
+		}
+	}
+	if (wq_data->dev_name_read > DRM_HOTPLUG_RING_DEPTH_MAX)
+		wq_data->dev_name_read = 0;
+}
+/*EXPORT_SYMBOL(psb_hotplug_dev_create_wq); */
+/**
+ * psb_hotplug_dev_remove_wq - remove workqueue implementation
+ *
+ * @work: work struct to use for kernel scheduling
+ *
+ */
+void psb_hotplug_dev_remove_wq(struct work_struct *work)
+{
+	struct hotplug_disp_workqueue_data *wq_data;
+	wq_data = to_hotplug_disp_workqueue_data(work);
+	if (wq_data->dev_name_write_wrap == 1) {
+		wq_data->dev_name_read_write_wrap_ack = 1;
+		wq_data->dev_name_write_wrap = 0;
+		while (wq_data->dev_name_read != DRM_HOTPLUG_RING_DEPTH_MAX) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_HOTPLUG_READY_TO_READ) {
+				psb_umevent_remove_from_list(
+				wq_data->hotplug_dev_list,
+				&wq_data->dev_name_arry
+				[wq_data->dev_name_read][0]);
+				wq_data->dev_name_arry_rw_status
+				[wq_data->dev_name_read] =
+				DRM_HOTPLUG_READ_COMPLETE;
+			}
+			wq_data->dev_name_read++;
+		}
+		wq_data->dev_name_read = 0;
+		while (wq_data->dev_name_read < wq_data->dev_name_write-1) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_HOTPLUG_READY_TO_READ) {
+				psb_umevent_remove_from_list(
+				wq_data->hotplug_dev_list,
+				&wq_data->dev_name_arry
+				[wq_data->dev_name_read][0]);
+				wq_data->dev_name_arry_rw_status
+				[wq_data->dev_name_read] =
+				DRM_HOTPLUG_READ_COMPLETE;
+			}
+			wq_data->dev_name_read++;
+		}
+	} else {
+		while (wq_data->dev_name_read < wq_data->dev_name_write) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_HOTPLUG_READY_TO_READ) {
+				psb_umevent_remove_from_list(
+				wq_data->hotplug_dev_list,
+				&wq_data->dev_name_arry
+				[wq_data->dev_name_read][0]);
+				wq_data->dev_name_arry_rw_status
+				[wq_data->dev_name_read] =
+				DRM_HOTPLUG_READ_COMPLETE;
+			}
+			wq_data->dev_name_read++;
+		}
+	}
+	if (wq_data->dev_name_read > DRM_HOTPLUG_RING_DEPTH_MAX)
+		wq_data->dev_name_read = 0;
+}
+/*EXPORT_SYMBOL(psb_hotplug_dev_remove_wq); */
+/**
+ * psb_hotplug_dev_change_wq - change workqueue implementation
+ *
+ * @work: work struct to use for kernel scheduling
+ *
+ */
+void psb_hotplug_dev_change_wq(struct work_struct *work)
+{
+	struct hotplug_disp_workqueue_data *wq_data;
+	struct umevent_obj *wq_working_hotplug_disp_obj;
+
+	wq_data = to_hotplug_disp_workqueue_data(work);
+	if (wq_data->dev_name_write_wrap == 1) {
+		wq_data->dev_name_read_write_wrap_ack = 1;
+		wq_data->dev_name_write_wrap = 0;
+		while (wq_data->dev_name_read != DRM_HOTPLUG_RING_DEPTH_MAX) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_HOTPLUG_READY_TO_READ) {
+				wq_data->dev_name_arry_rw_status
+				[wq_data->dev_name_read] =
+				DRM_HOTPLUG_READ_COMPLETE;
+
+				wq_working_hotplug_disp_obj =
+					psb_umevent_find_obj(
+					     &wq_data->dev_name_arry
+					     [wq_data->dev_name_read][0],
+					      wq_data->hotplug_dev_list);
+				psb_umevent_notify_change_gfxsock
+					(wq_working_hotplug_disp_obj,
+					 DRM_HOTPLUG_SOCKET_GROUP_ID);
+			}
+			wq_data->dev_name_read++;
+		}
+		wq_data->dev_name_read = 0;
+		while (wq_data->dev_name_read < wq_data->dev_name_write-1) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_HOTPLUG_READY_TO_READ) {
+				wq_data->dev_name_arry_rw_status
+				[wq_data->dev_name_read] =
+				DRM_HOTPLUG_READ_COMPLETE;
+
+				wq_working_hotplug_disp_obj =
+					psb_umevent_find_obj(
+					     &wq_data->dev_name_arry
+					     [wq_data->dev_name_read][0],
+					      wq_data->hotplug_dev_list);
+				psb_umevent_notify_change_gfxsock
+					(wq_working_hotplug_disp_obj,
+					 DRM_HOTPLUG_SOCKET_GROUP_ID);
+			}
+			wq_data->dev_name_read++;
+		}
+	} else {
+		while (wq_data->dev_name_read < wq_data->dev_name_write) {
+			if (wq_data->dev_name_arry_rw_status
+			   [wq_data->dev_name_read] ==
+			   DRM_HOTPLUG_READY_TO_READ) {
+				wq_data->dev_name_arry_rw_status
+				[wq_data->dev_name_read] =
+					DRM_HOTPLUG_READ_COMPLETE;
+
+				wq_working_hotplug_disp_obj =
+					psb_umevent_find_obj(
+					     &wq_data->dev_name_arry
+					     [wq_data->dev_name_read][0],
+					      wq_data->hotplug_dev_list);
+				psb_umevent_notify_change_gfxsock
+					(wq_working_hotplug_disp_obj,
+					 DRM_HOTPLUG_SOCKET_GROUP_ID);
+			}
+			wq_data->dev_name_read++;
+		}
+	}
+	if (wq_data->dev_name_read > DRM_HOTPLUG_RING_DEPTH_MAX)
+		wq_data->dev_name_read = 0;
+}
+/*EXPORT_SYMBOL(psb_hotplug_dev_change_wq); */
diff --git a/drivers/staging/cdv/drv/psb_hotplug.h b/drivers/staging/cdv/drv/psb_hotplug.h
new file mode 100644
index 0000000..cffede5
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_hotplug.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *    James C. Gualario <james.c.gualario@intel.com>
+ *
+ */
+#ifndef _PSB_HOTPLUG_H_
+#define _PSB_HOTPLUG_H_
+/**
+ * required includes
+ *
+ */
+#include "psb_umevents.h"
+/**
+ * hotplug specific defines
+ *
+ */
+#define DRM_HOTPLUG_RING_DEPTH 256
+#define DRM_HOTPLUG_RING_DEPTH_MAX (DRM_HOTPLUG_RING_DEPTH-1)
+#define DRM_HOTPLUG_READY_TO_READ 1
+#define DRM_HOTPLUG_READ_COMPLETE 2
+/**
+ * hotplug workqueue data struct.
+ */
+struct hotplug_disp_workqueue_data {
+	struct work_struct work;
+	const char *dev_name;
+	int dev_name_write;
+	int dev_name_read;
+	int dev_name_write_wrap;
+	int dev_name_read_write_wrap_ack;
+	char dev_name_arry[DRM_HOTPLUG_RING_DEPTH][24];
+	int dev_name_arry_rw_status[DRM_HOTPLUG_RING_DEPTH];
+	struct umevent_list *hotplug_dev_list;
+};
+/**
+ * hotplug state structure
+ *
+ */
+struct hotplug_state {
+	struct workqueue_struct *hotplug_wq;
+	struct hotplug_disp_workqueue_data hotplug_remove_wq_data;
+	struct hotplug_disp_workqueue_data hotplug_create_wq_data;
+	struct hotplug_disp_workqueue_data hotplug_change_wq_data;
+	struct umevent_list *list;
+};
+/**
+ * main interface function prototytpes for hotplug support.
+ *
+ */
+struct hotplug_state *psb_hotplug_init(struct kobject *parent_kobj);
+extern int psb_hotplug_notify_change_um(const char *name,
+				    struct hotplug_state *state);
+extern int psb_hotplug_create_and_notify_um(const char *name,
+					struct hotplug_state *state);
+extern int psb_hotplug_remove_and_notify_um(const char *name,
+					struct hotplug_state *state);
+extern struct umevent_list *psb_hotplug_device_pool_create_and_init(
+					    struct kobject *parent_kobj,
+					    struct hotplug_state *state);
+extern void psb_hotplug_device_pool_destroy(struct hotplug_state *state);
+/**
+ * to go back and forth between work strauct and workqueue data
+ *
+ */
+#define to_hotplug_disp_workqueue_data(x) \
+	container_of(x, struct hotplug_disp_workqueue_data, work)
+
+/**
+ * function prototypes for workqueue implementation
+ *
+ */
+extern void psb_hotplug_dev_create_wq(struct work_struct *work);
+extern void psb_hotplug_dev_remove_wq(struct work_struct *work);
+extern void psb_hotplug_dev_change_wq(struct work_struct *work);
+#endif
diff --git a/drivers/staging/cdv/drv/psb_intel_bios.c b/drivers/staging/cdv/drv/psb_intel_bios.c
new file mode 100644
index 0000000..8868f7e
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_bios.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drm.h"
+#include "psb_drv.h"
+#include "drm_dp_helper.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_bios.h"
+
+
+static void *find_section(struct bdb_header *bdb, int section_id)
+{
+	u8 *base = (u8 *)bdb;
+	int index = 0;
+	u16 total, current_size;
+	u8 current_id;
+
+	/* skip to first section */
+	index += bdb->header_size;
+	total = bdb->bdb_size;
+
+	/* walk the sections looking for section_id */
+	while (index < total) {
+		current_id = *(base + index);
+		index++;
+		current_size = *((u16 *)(base + index));
+		index += 2;
+		if (current_id == section_id)
+			return base + index;
+		index += current_size;
+	}
+
+	return NULL;
+}
+
+static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
+			struct lvds_dvo_timing *dvo_timing)
+{
+	panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
+		dvo_timing->hactive_lo;
+	panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
+		((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
+	panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
+		dvo_timing->hsync_pulse_width;
+	panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
+		((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
+
+	panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
+		dvo_timing->vactive_lo;
+	panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
+		dvo_timing->vsync_off;
+	panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
+		dvo_timing->vsync_pulse_width;
+	panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
+		((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
+	panel_fixed_mode->clock = dvo_timing->clock * 10;
+	panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
+
+	/* Some VBTs have bogus h/vtotal values */
+	if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
+		panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
+	if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
+		panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
+
+	drm_mode_set_name(panel_fixed_mode);
+}
+
+static void parse_backlight_data(struct drm_psb_private *dev_priv,
+				struct bdb_header *bdb)
+{
+	struct bdb_lvds_backlight *vbt_lvds_bl = NULL;
+	struct bdb_lvds_backlight *lvds_bl;
+	u8 p_type = 0;
+	void *bl_start = NULL;
+	struct bdb_lvds_options *lvds_opts
+				= find_section(bdb, BDB_LVDS_OPTIONS);
+
+	dev_priv->lvds_bl = NULL;
+
+	if (lvds_opts) {
+		DRM_DEBUG("lvds_options found at %p\n", lvds_opts);
+		p_type = lvds_opts->panel_type;
+	} else {
+		DRM_DEBUG("no lvds_options\n");
+		return;
+	}
+
+	bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
+	vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;
+
+	lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL);
+	if (!lvds_bl) {
+		DRM_DEBUG("No memory\n");
+		return;
+	}
+
+	memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl));
+
+	dev_priv->lvds_bl = lvds_bl;
+}
+
+/* Try to find integrated panel data */
+static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
+			    struct bdb_header *bdb)
+{
+	struct bdb_lvds_options *lvds_options;
+	struct bdb_lvds_lfp_data *lvds_lfp_data;
+	struct bdb_lvds_lfp_data_entry *entry;
+	struct lvds_dvo_timing *dvo_timing;
+	struct drm_display_mode *panel_fixed_mode;
+
+	/* Defaults if we can't find VBT info */
+	dev_priv->lvds_dither = 0;
+	dev_priv->lvds_vbt = 0;
+
+	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
+	if (!lvds_options)
+		return;
+
+	dev_priv->lvds_dither = lvds_options->pixel_dither;
+	if (lvds_options->panel_type == 0xff)
+		return;
+
+	dev_priv->panel_type = lvds_options->panel_type;
+	lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
+	if (!lvds_lfp_data)
+		return;
+
+	dev_priv->lvds_vbt = 1;
+
+	entry = &lvds_lfp_data->data[lvds_options->panel_type];
+	dvo_timing = &entry->dvo_timing;
+
+	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode),
+				      GFP_KERNEL);
+
+	if (!panel_fixed_mode) {
+		DRM_DEBUG("Out of memory\n");
+		return;
+	}
+	fill_detail_timing_data(panel_fixed_mode, dvo_timing);
+
+	dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
+
+	DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
+	drm_mode_debug_printmodeline(panel_fixed_mode);
+
+	return;
+}
+
+static void parse_general_features(struct drm_psb_private *dev_priv,
+		       struct bdb_header *bdb)
+{
+	struct bdb_general_features *general;
+
+	/* Set sensible defaults in case we can't find the general block */
+	dev_priv->int_tv_support = 1;
+	dev_priv->int_crt_support = 1;
+
+	general = find_section(bdb, BDB_GENERAL_FEATURES);
+	if (general) {
+		dev_priv->int_tv_support = general->int_tv_support;
+		dev_priv->int_crt_support = general->int_crt_support;
+		dev_priv->lvds_use_ssc = general->enable_ssc;
+
+		if (dev_priv->lvds_use_ssc)
+			dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96;
+	}
+}
+
+static void
+parse_driver_features(struct drm_psb_private *dev_priv,
+		      struct bdb_header *bdb)
+{
+	struct bdb_driver_features *driver;
+
+	driver = find_section(bdb, BDB_DRIVER_FEATURES);
+	if (!driver)
+		return;
+
+	if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
+		dev_priv->edp.support = 1;
+
+	/* This bit means to use 96Mhz for DPLL_A or not */
+	if (driver->primary_lfp_id)
+		dev_priv->dplla_96mhz = true;
+	else
+		dev_priv->dplla_96mhz = false;
+}
+
+
+static void
+parse_edp(struct drm_psb_private *dev_priv, struct bdb_header *bdb)
+{
+	struct bdb_edp *edp;
+	struct edp_power_seq *edp_pps;
+	struct edp_link_params *edp_link_params;
+	uint8_t	panel_type;
+
+	edp = find_section(bdb, BDB_EDP);
+	
+	dev_priv->edp.bpp = 18;
+	if (!edp) {
+		if (dev_priv->edp.support) {
+			DRM_DEBUG_KMS("No eDP BDB found but eDP panel "
+				      "supported, assume %dbpp panel color "
+				      "depth.\n",
+				      dev_priv->edp.bpp);
+		}
+		return;
+	}
+
+	panel_type = dev_priv->panel_type;
+	switch ((edp->color_depth >> (panel_type * 2)) & 3) {
+	case EDP_18BPP:
+		dev_priv->edp.bpp = 18;
+		break;
+	case EDP_24BPP:
+		dev_priv->edp.bpp = 24;
+		break;
+	case EDP_30BPP:
+		dev_priv->edp.bpp = 30;
+		break;
+	}
+
+	/* Get the eDP sequencing and link info */
+	edp_pps = &edp->power_seqs[panel_type];
+	edp_link_params = &edp->link_params[panel_type];
+
+	dev_priv->edp.pps = *edp_pps;
+
+	DRM_DEBUG_KMS("EDP timing in vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
+				dev_priv->edp.pps.t1_t3, dev_priv->edp.pps.t8, 
+				dev_priv->edp.pps.t9, dev_priv->edp.pps.t10,
+				dev_priv->edp.pps.t11_t12);
+
+	dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
+		DP_LINK_BW_1_62;
+	switch (edp_link_params->lanes) {
+	case 0:
+		dev_priv->edp.lanes = 1;
+		break;
+	case 1:
+		dev_priv->edp.lanes = 2;
+		break;
+	case 3:
+	default:
+		dev_priv->edp.lanes = 4;
+		break;
+	}
+	DRM_DEBUG_KMS("VBT reports EDP: Lane_count %d, Lane_rate %d, Bpp %d\n",
+			dev_priv->edp.lanes, dev_priv->edp.rate, dev_priv->edp.bpp);
+
+	switch (edp_link_params->preemphasis) {
+	case 0:
+		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
+		break;
+	case 1:
+		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
+		break;
+	case 2:
+		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
+		break;
+	case 3:
+		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
+		break;
+	}
+	switch (edp_link_params->vswing) {
+	case 0:
+		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_400;
+		break;
+	case 1:
+		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_600;
+		break;
+	case 2:
+		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_800;
+		break;
+	case 3:
+		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_1200;
+		break;
+	}
+	DRM_DEBUG_KMS("VBT reports EDP: VSwing  %d, Preemph %d\n",
+			dev_priv->edp.vswing, dev_priv->edp.preemphasis);
+}
+
+static u16
+get_blocksize(void *p)
+{
+	u16 *block_ptr, block_size;
+
+	block_ptr = (u16 *)((char *)p - 2);
+	block_size = *block_ptr;
+	return block_size;
+}
+
+static void
+parse_device_mapping(struct drm_psb_private *dev_priv,
+		     struct bdb_header *bdb)
+{
+	struct bdb_general_definitions *p_defs;
+	struct child_device_config *p_child, *child_dev_ptr;
+	int i, child_device_num, count;
+	u16     block_size;
+
+	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+	if (!p_defs) {
+		DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
+		return;
+	}
+	/* judge whether the size of child device meets the requirements.
+	 * If the child device size obtained from general definition block
+	 * is different with sizeof(struct child_device_config), skip the
+	 * parsing of sdvo device info
+	 */
+	if (p_defs->child_dev_size != sizeof(*p_child)) {
+		/* different child dev size . Ignore it */
+		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
+		return;
+	}
+	/* get the block size of general definitions */
+	block_size = get_blocksize(p_defs);
+	/* get the number of child device */
+	child_device_num = (block_size - sizeof(*p_defs)) /
+			    sizeof(*p_child);
+	count = 0;
+	/* get the number of child device that is present */
+	for (i = 0; i < child_device_num; i++) {
+		p_child = &(p_defs->devices[i]);
+		if (!p_child->device_type) {
+			/* skip the device block if device type is invalid */
+			continue;
+		}
+		count++;
+	}
+	if (!count) {
+		DRM_DEBUG_KMS("no child dev is parsed from VBT\n");
+		return;
+	}
+	dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL);
+	if (!dev_priv->child_dev) {
+		DRM_DEBUG_KMS("No memory space for child device\n");
+		return;
+	}
+
+	dev_priv->child_dev_num = count;
+	count = 0;
+	for (i = 0; i < child_device_num; i++) {
+		p_child = &(p_defs->devices[i]);
+		if (!p_child->device_type) {
+			/* skip the device block if device type is invalid */
+			continue;
+		}
+		child_dev_ptr = dev_priv->child_dev + count;
+		count++;
+		memcpy((void *)child_dev_ptr, (void *)p_child,
+				sizeof(*p_child));
+	}
+	return;
+}
+
+
+
+
+/**
+ * psb_intel_init_bios - initialize VBIOS settings & find VBT
+ * @dev: DRM device
+ *
+ * Loads the Video BIOS and checks that the VBT exists.  Sets scratch registers
+ * to appropriate values.
+ *
+ * VBT existence is a sanity check that is relied on by other i830_bios.c code.
+ * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
+ * feed an updated VBT back through that, compared to what we'll fetch using
+ * this method of groping around in the BIOS data.
+ *
+ * Returns 0 on success, nonzero on failure.
+ */
+bool psb_intel_init_bios(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct pci_dev *pdev = dev->pdev;
+	struct vbt_header *vbt = NULL;
+	struct bdb_header *bdb;
+	u8 __iomem *bios;
+	size_t size;
+	int i;
+
+	dev_priv->panel_type = 0xff;
+
+	bios = pci_map_rom(pdev, &size);
+	if (!bios)
+		return -1;
+
+	/* Scour memory looking for the VBT signature */
+	for (i = 0; i + 4 < size; i++) {
+		if (!memcmp(bios + i, "$VBT", 4)) {
+			vbt = (struct vbt_header *)(bios + i);
+			break;
+		}
+	}
+
+	if (!vbt) {
+		DRM_ERROR("VBT signature missing\n");
+		pci_unmap_rom(pdev, bios);
+		return -1;
+	}
+
+	bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
+
+	/* Grab useful general definitions */
+	parse_general_features(dev_priv, bdb);
+	parse_driver_features(dev_priv, bdb);
+	parse_lfp_panel_data(dev_priv, bdb);
+	parse_backlight_data(dev_priv, bdb);
+	parse_device_mapping(dev_priv, bdb);
+	parse_edp(dev_priv, bdb);
+
+	pci_unmap_rom(pdev, bios);
+
+	return 0;
+}
+
+/**
+ * Destory and free VBT data
+ */
+void psb_intel_destory_bios(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *lfp_lvds_vbt_mode =
+				dev_priv->lfp_lvds_vbt_mode;
+	struct bdb_lvds_backlight *lvds_bl =
+				dev_priv->lvds_bl;
+
+
+	if (lfp_lvds_vbt_mode) {
+		dev_priv->lfp_lvds_vbt_mode = NULL;
+		kfree(lfp_lvds_vbt_mode);
+	}
+
+	if (lvds_bl) {
+		dev_priv->lvds_bl = NULL;
+		kfree(lvds_bl);
+	}
+
+	kfree(dev_priv->child_dev);
+}
diff --git a/drivers/staging/cdv/drv/psb_intel_bios.h b/drivers/staging/cdv/drv/psb_intel_bios.h
new file mode 100644
index 0000000..adf39c1
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_bios.h
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifndef _I830_BIOS_H_
+#define _I830_BIOS_H_
+
+#include <drm/drmP.h>
+
+struct vbt_header {
+	u8 signature[20];		/**< Always starts with 'VBT$' */
+	u16 version;			/**< decimal */
+	u16 header_size;		/**< in bytes */
+	u16 vbt_size;			/**< in bytes */
+	u8 vbt_checksum;
+	u8 reserved0;
+	u32 bdb_offset;			/**< from beginning of VBT */
+	u32 aim_offset[4];		/**< from beginning of VBT */
+} __attribute__((packed));
+
+
+struct bdb_header {
+	u8 signature[16];		/**< Always 'BIOS_DATA_BLOCK' */
+	u16 version;			/**< decimal */
+	u16 header_size;		/**< in bytes */
+	u16 bdb_size;			/**< in bytes */
+};
+
+/* strictly speaking, this is a "skip" block, but it has interesting info */
+struct vbios_data {
+	u8 type; /* 0 == desktop, 1 == mobile */
+	u8 relstage;
+	u8 chipset;
+	u8 lvds_present:1;
+	u8 tv_present:1;
+	u8 rsvd2:6; /* finish byte */
+	u8 rsvd3[4];
+	u8 signon[155];
+	u8 copyright[61];
+	u16 code_segment;
+	u8 dos_boot_mode;
+	u8 bandwidth_percent;
+	u8 rsvd4; /* popup memory size */
+	u8 resize_pci_bios;
+	u8 rsvd5; /* is crt already on ddc2 */
+} __attribute__((packed));
+
+/*
+ * There are several types of BIOS data blocks (BDBs), each block has
+ * an ID and size in the first 3 bytes (ID in first, size in next 2).
+ * Known types are listed below.
+ */
+#define BDB_GENERAL_FEATURES	  1
+#define BDB_GENERAL_DEFINITIONS	  2
+#define BDB_OLD_TOGGLE_LIST	  3
+#define BDB_MODE_SUPPORT_LIST	  4
+#define BDB_GENERIC_MODE_TABLE	  5
+#define BDB_EXT_MMIO_REGS	  6
+#define BDB_SWF_IO		  7
+#define BDB_SWF_MMIO		  8
+#define BDB_DOT_CLOCK_TABLE	  9
+#define BDB_MODE_REMOVAL_TABLE	 10
+#define BDB_CHILD_DEVICE_TABLE	 11
+#define BDB_DRIVER_FEATURES	 12
+#define BDB_DRIVER_PERSISTENCE	 13
+#define BDB_EXT_TABLE_PTRS	 14
+#define BDB_DOT_CLOCK_OVERRIDE	 15
+#define BDB_DISPLAY_SELECT	 16
+/* 17 rsvd */
+#define BDB_DRIVER_ROTATION	 18
+#define BDB_DISPLAY_REMOVE	 19
+#define BDB_OEM_CUSTOM		 20
+#define BDB_EFP_LIST		 21 /* workarounds for VGA hsync/vsync */
+#define BDB_SDVO_LVDS_OPTIONS	 22
+#define BDB_SDVO_PANEL_DTDS	 23
+#define BDB_SDVO_LVDS_PNP_IDS	 24
+#define BDB_SDVO_LVDS_POWER_SEQ	 25
+#define BDB_TV_OPTIONS		 26
+#define BDB_LVDS_OPTIONS	 40
+#define BDB_LVDS_LFP_DATA_PTRS	 41
+#define BDB_LVDS_LFP_DATA	 42
+#define BDB_LVDS_BACKLIGHT	 43
+#define BDB_LVDS_POWER		 44
+#define BDB_SKIP		254 /* VBIOS private block, ignore */
+
+#define BDB_EDP			 27
+
+struct bdb_general_features {
+	/* bits 1 */
+	u8 panel_fitting:2;
+	u8 flexaim:1;
+	u8 msg_enable:1;
+	u8 clear_screen:3;
+	u8 color_flip:1;
+
+	/* bits 2 */
+	u8 download_ext_vbt:1;
+	u8 enable_ssc:1;
+	u8 ssc_freq:1;
+	u8 enable_lfp_on_override:1;
+	u8 disable_ssc_ddt:1;
+	u8 rsvd8:3; /* finish byte */
+
+	/* bits 3 */
+	u8 disable_smooth_vision:1;
+	u8 single_dvi:1;
+	u8 rsvd9:6; /* finish byte */
+
+	/* bits 4 */
+	u8 legacy_monitor_detect;
+
+	/* bits 5 */
+	u8 int_crt_support:1;
+	u8 int_tv_support:1;
+	u8 rsvd11:6; /* finish byte */
+} __attribute__((packed));
+
+#define DEVICE_TYPE_INT_LFP    0x1022
+#define DEVICE_TYPE_LFP         0x22
+
+struct child_device_config {
+	u16 handle;
+	u16 device_type;
+	u8  device_id[10]; /* ascii string */
+	u16 addin_offset;
+	u8  dvo_port; /* See Device_PORT_* above */
+	u8  i2c_pin;
+	u8  slave_addr;
+	u8  ddc_pin;
+	u16 edid_ptr;
+	u8  dvo_cfg; /* See DEVICE_CFG_* above */
+	u8  dvo2_port;
+	u8  i2c2_pin;
+	u8  slave2_addr;
+	u8  ddc2_pin;
+	u8  capabilities;
+	u8  dvo_wiring;/* See DEVICE_WIRE_* above */
+	u8  dvo2_wiring;
+	u16 extended_type;
+	u8  dvo_function;
+} __attribute__((packed));
+
+struct bdb_general_definitions {
+	/* DDC GPIO */
+	u8 crt_ddc_gmbus_pin;
+
+	/* DPMS bits */
+	u8 dpms_acpi:1;
+	u8 skip_boot_crt_detect:1;
+	u8 dpms_aim:1;
+	u8 rsvd1:5; /* finish byte */
+
+	/* boot device bits */
+	u8 boot_display[2];
+	u8 child_dev_size;
+
+	/* device info */
+	struct child_device_config devices[0];
+} __attribute__((packed));
+
+struct bdb_lvds_options {
+	u8 panel_type;
+	u8 rsvd1;
+	/* LVDS capabilities, stored in a dword */
+	u8 pfit_mode:2;
+	u8 pfit_text_mode_enhanced:1;
+	u8 pfit_gfx_mode_enhanced:1;
+	u8 pfit_ratio_auto:1;
+	u8 pixel_dither:1;
+	u8 lvds_edid:1;
+	u8 rsvd2:1;
+	u8 rsvd4;
+} __attribute__((packed));
+
+struct bdb_lvds_backlight {
+	u8 type:2;
+	u8 pol:1;
+	u8 gpio:3;
+	u8 gmbus:2;
+	u16 freq;
+	u8 minbrightness;
+	u8 i2caddr;
+	u8 brightnesscmd;
+	/*FIXME: more...*/
+} __attribute__((packed));
+
+/* LFP pointer table contains entries to the struct below */
+struct bdb_lvds_lfp_data_ptr {
+	u16 fp_timing_offset; /* offsets are from start of bdb */
+	u8 fp_table_size;
+	u16 dvo_timing_offset;
+	u8 dvo_table_size;
+	u16 panel_pnp_id_offset;
+	u8 pnp_table_size;
+} __attribute__((packed));
+
+struct bdb_lvds_lfp_data_ptrs {
+	u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
+	struct bdb_lvds_lfp_data_ptr ptr[16];
+} __attribute__((packed));
+
+/* LFP data has 3 blocks per entry */
+struct lvds_fp_timing {
+	u16 x_res;
+	u16 y_res;
+	u32 lvds_reg;
+	u32 lvds_reg_val;
+	u32 pp_on_reg;
+	u32 pp_on_reg_val;
+	u32 pp_off_reg;
+	u32 pp_off_reg_val;
+	u32 pp_cycle_reg;
+	u32 pp_cycle_reg_val;
+	u32 pfit_reg;
+	u32 pfit_reg_val;
+	u16 terminator;
+} __attribute__((packed));
+
+struct lvds_dvo_timing {
+	u16 clock;		/**< In 10khz */
+	u8 hactive_lo;
+	u8 hblank_lo;
+	u8 hblank_hi:4;
+	u8 hactive_hi:4;
+	u8 vactive_lo;
+	u8 vblank_lo;
+	u8 vblank_hi:4;
+	u8 vactive_hi:4;
+	u8 hsync_off_lo;
+	u8 hsync_pulse_width;
+	u8 vsync_pulse_width:4;
+	u8 vsync_off:4;
+	u8 rsvd0:6;
+	u8 hsync_off_hi:2;
+	u8 h_image;
+	u8 v_image;
+	u8 max_hv;
+	u8 h_border;
+	u8 v_border;
+	u8 rsvd1:3;
+	u8 digital:2;
+	u8 vsync_positive:1;
+	u8 hsync_positive:1;
+	u8 rsvd2:1;
+} __attribute__((packed));
+
+struct lvds_pnp_id {
+	u16 mfg_name;
+	u16 product_code;
+	u32 serial;
+	u8 mfg_week;
+	u8 mfg_year;
+} __attribute__((packed));
+
+struct bdb_lvds_lfp_data_entry {
+	struct lvds_fp_timing fp_timing;
+	struct lvds_dvo_timing dvo_timing;
+	struct lvds_pnp_id pnp_id;
+} __attribute__((packed));
+
+struct bdb_lvds_lfp_data {
+	struct bdb_lvds_lfp_data_entry data[16];
+} __attribute__((packed));
+
+struct aimdb_header {
+	char signature[16];
+	char oem_device[20];
+	u16 aimdb_version;
+	u16 aimdb_header_size;
+	u16 aimdb_size;
+} __attribute__((packed));
+
+struct aimdb_block {
+	u8 aimdb_id;
+	u16 aimdb_size;
+} __attribute__((packed));
+
+struct vch_panel_data {
+	u16 fp_timing_offset;
+	u8 fp_timing_size;
+	u16 dvo_timing_offset;
+	u8 dvo_timing_size;
+	u16 text_fitting_offset;
+	u8 text_fitting_size;
+	u16 graphics_fitting_offset;
+	u8 graphics_fitting_size;
+} __attribute__((packed));
+
+struct vch_bdb_22 {
+	struct aimdb_block aimdb_block;
+	struct vch_panel_data panels[16];
+} __attribute__((packed));
+
+struct bdb_sdvo_lvds_options {
+	u8 panel_backlight;
+	u8 h40_set_panel_type;
+	u8 panel_type;
+	u8 ssc_clk_freq;
+	u16 als_low_trip;
+	u16 als_high_trip;
+	u8 sclalarcoeff_tab_row_num;
+	u8 sclalarcoeff_tab_row_size;
+	u8 coefficient[8];
+	u8 panel_misc_bits_1;
+	u8 panel_misc_bits_2;
+	u8 panel_misc_bits_3;
+	u8 panel_misc_bits_4;
+} __attribute__((packed));
+
+#define BDB_DRIVER_FEATURE_NO_LVDS		0
+#define BDB_DRIVER_FEATURE_INT_LVDS		1
+#define BDB_DRIVER_FEATURE_SDVO_LVDS		2
+#define BDB_DRIVER_FEATURE_EDP			3
+
+struct bdb_driver_features {
+	u8 boot_dev_algorithm:1;
+	u8 block_display_switch:1;
+	u8 allow_display_switch:1;
+	u8 hotplug_dvo:1;
+	u8 dual_view_zoom:1;
+	u8 int15h_hook:1;
+	u8 sprite_in_clone:1;
+	u8 primary_lfp_id:1;
+
+	u16 boot_mode_x;
+	u16 boot_mode_y;
+	u8 boot_mode_bpp;
+	u8 boot_mode_refresh;
+
+	u16 enable_lfp_primary:1;
+	u16 selective_mode_pruning:1;
+	u16 dual_frequency:1;
+	u16 render_clock_freq:1; /* 0: high freq; 1: low freq */
+	u16 nt_clone_support:1;
+	u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */
+	u16 sprite_display_assign:1; /* 0: secondary; 1: primary */
+	u16 cui_aspect_scaling:1;
+	u16 preserve_aspect_ratio:1;
+	u16 sdvo_device_power_down:1;
+	u16 crt_hotplug:1;
+	u16 lvds_config:2;
+	u16 tv_hotplug:1;
+	u16 hdmi_config:2;
+
+	u8 static_display:1;
+	u8 reserved2:7;
+	u16 legacy_crt_max_x;
+	u16 legacy_crt_max_y;
+	u8 legacy_crt_max_refresh;
+
+	u8 hdmi_termination;
+	u8 custom_vbt_version;
+} __attribute__((packed));
+
+#define EDP_18BPP	0
+#define EDP_24BPP	1
+#define EDP_30BPP	2
+#define EDP_RATE_1_62	0
+#define EDP_RATE_2_7	1
+#define EDP_LANE_1	0
+#define EDP_LANE_2	1
+#define EDP_LANE_4	3
+#define EDP_PREEMPHASIS_NONE	0
+#define EDP_PREEMPHASIS_3_5dB	1
+#define EDP_PREEMPHASIS_6dB	2
+#define EDP_PREEMPHASIS_9_5dB	3
+#define EDP_VSWING_0_4V		0
+#define EDP_VSWING_0_6V		1
+#define EDP_VSWING_0_8V		2
+#define EDP_VSWING_1_2V		3
+
+struct edp_power_seq {
+	u16 t1_t3;
+	u16 t8;
+	u16 t9;
+	u16 t10;
+	u16 t11_t12;
+} __attribute__ ((packed));
+
+struct edp_link_params {
+	u8 rate:4;
+	u8 lanes:4;
+	u8 preemphasis:4;
+	u8 vswing:4;
+} __attribute__ ((packed));
+
+struct bdb_edp {
+	struct edp_power_seq power_seqs[16];
+	u32 color_depth;
+	u32 sdrrs_msa_timing_delay;
+	struct edp_link_params link_params[16];
+} __attribute__ ((packed));
+
+extern bool psb_intel_init_bios(struct drm_device *dev);
+extern void psb_intel_destory_bios(struct drm_device *dev);
+
+/*
+ * Driver<->VBIOS interaction occurs through scratch bits in
+ * GR18 & SWF*.
+ */
+
+/* GR18 bits are set on display switch and hotkey events */
+#define GR18_DRIVER_SWITCH_EN	(1<<7) /* 0: VBIOS control, 1: driver control */
+#define GR18_HOTKEY_MASK	0x78 /* See also SWF4 15:0 */
+#define   GR18_HK_NONE		(0x0<<3)
+#define   GR18_HK_LFP_STRETCH	(0x1<<3)
+#define   GR18_HK_TOGGLE_DISP	(0x2<<3)
+#define   GR18_HK_DISP_SWITCH	(0x4<<3) /* see SWF14 15:0 for what to enable */
+#define   GR18_HK_POPUP_DISABLED (0x6<<3)
+#define   GR18_HK_POPUP_ENABLED	(0x7<<3)
+#define   GR18_HK_PFIT		(0x8<<3)
+#define   GR18_HK_APM_CHANGE	(0xa<<3)
+#define   GR18_HK_MULTIPLE	(0xc<<3)
+#define GR18_USER_INT_EN	(1<<2)
+#define GR18_A0000_FLUSH_EN	(1<<1)
+#define GR18_SMM_EN		(1<<0)
+
+/* Set by driver, cleared by VBIOS */
+#define SWF00_YRES_SHIFT	16
+#define SWF00_XRES_SHIFT	0
+#define SWF00_RES_MASK		0xffff
+
+/* Set by VBIOS at boot time and driver at runtime */
+#define SWF01_TV2_FORMAT_SHIFT	8
+#define SWF01_TV1_FORMAT_SHIFT	0
+#define SWF01_TV_FORMAT_MASK	0xffff
+
+#define SWF10_VBIOS_BLC_I2C_EN	(1<<29)
+#define SWF10_GTT_OVERRIDE_EN	(1<<28)
+#define SWF10_LFP_DPMS_OVR	(1<<27) /* override DPMS on display switch */
+#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24)
+#define   SWF10_OLD_TOGGLE	0x0
+#define   SWF10_TOGGLE_LIST_1	0x1
+#define   SWF10_TOGGLE_LIST_2	0x2
+#define   SWF10_TOGGLE_LIST_3	0x3
+#define   SWF10_TOGGLE_LIST_4	0x4
+#define SWF10_PANNING_EN	(1<<23)
+#define SWF10_DRIVER_LOADED	(1<<22)
+#define SWF10_EXTENDED_DESKTOP	(1<<21)
+#define SWF10_EXCLUSIVE_MODE	(1<<20)
+#define SWF10_OVERLAY_EN	(1<<19)
+#define SWF10_PLANEB_HOLDOFF	(1<<18)
+#define SWF10_PLANEA_HOLDOFF	(1<<17)
+#define SWF10_VGA_HOLDOFF	(1<<16)
+#define SWF10_ACTIVE_DISP_MASK	0xffff
+#define   SWF10_PIPEB_LFP2	(1<<15)
+#define   SWF10_PIPEB_EFP2	(1<<14)
+#define   SWF10_PIPEB_TV2	(1<<13)
+#define   SWF10_PIPEB_CRT2	(1<<12)
+#define   SWF10_PIPEB_LFP	(1<<11)
+#define   SWF10_PIPEB_EFP	(1<<10)
+#define   SWF10_PIPEB_TV	(1<<9)
+#define   SWF10_PIPEB_CRT	(1<<8)
+#define   SWF10_PIPEA_LFP2	(1<<7)
+#define   SWF10_PIPEA_EFP2	(1<<6)
+#define   SWF10_PIPEA_TV2	(1<<5)
+#define   SWF10_PIPEA_CRT2	(1<<4)
+#define   SWF10_PIPEA_LFP	(1<<3)
+#define   SWF10_PIPEA_EFP	(1<<2)
+#define   SWF10_PIPEA_TV	(1<<1)
+#define   SWF10_PIPEA_CRT	(1<<0)
+
+#define SWF11_MEMORY_SIZE_SHIFT	16
+#define SWF11_SV_TEST_EN	(1<<15)
+#define SWF11_IS_AGP		(1<<14)
+#define SWF11_DISPLAY_HOLDOFF	(1<<13)
+#define SWF11_DPMS_REDUCED	(1<<12)
+#define SWF11_IS_VBE_MODE	(1<<11)
+#define SWF11_PIPEB_ACCESS	(1<<10) /* 0 here means pipe a */
+#define SWF11_DPMS_MASK		0x07
+#define   SWF11_DPMS_OFF	(1<<2)
+#define   SWF11_DPMS_SUSPEND	(1<<1)
+#define   SWF11_DPMS_STANDBY	(1<<0)
+#define   SWF11_DPMS_ON		0
+
+#define SWF14_GFX_PFIT_EN	(1<<31)
+#define SWF14_TEXT_PFIT_EN	(1<<30)
+#define SWF14_LID_STATUS_CLOSED	(1<<29) /* 0 here means open */
+#define SWF14_POPUP_EN		(1<<28)
+#define SWF14_DISPLAY_HOLDOFF	(1<<27)
+#define SWF14_DISP_DETECT_EN	(1<<26)
+#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */
+#define SWF14_DRIVER_STATUS	(1<<24)
+#define SWF14_OS_TYPE_WIN9X	(1<<23)
+#define SWF14_OS_TYPE_WINNT	(1<<22)
+/* 21:19 rsvd */
+#define SWF14_PM_TYPE_MASK	0x00070000
+#define   SWF14_PM_ACPI_VIDEO	(0x4 << 16)
+#define   SWF14_PM_ACPI		(0x3 << 16)
+#define   SWF14_PM_APM_12	(0x2 << 16)
+#define   SWF14_PM_APM_11	(0x1 << 16)
+#define SWF14_HK_REQUEST_MASK	0x0000ffff /* see GR18 6:3 for event type */
+	  /* if GR18 indicates a display switch */
+#define   SWF14_DS_PIPEB_LFP2_EN (1<<15)
+#define   SWF14_DS_PIPEB_EFP2_EN (1<<14)
+#define   SWF14_DS_PIPEB_TV2_EN  (1<<13)
+#define   SWF14_DS_PIPEB_CRT2_EN (1<<12)
+#define   SWF14_DS_PIPEB_LFP_EN  (1<<11)
+#define   SWF14_DS_PIPEB_EFP_EN  (1<<10)
+#define   SWF14_DS_PIPEB_TV_EN	 (1<<9)
+#define   SWF14_DS_PIPEB_CRT_EN  (1<<8)
+#define   SWF14_DS_PIPEA_LFP2_EN (1<<7)
+#define   SWF14_DS_PIPEA_EFP2_EN (1<<6)
+#define   SWF14_DS_PIPEA_TV2_EN  (1<<5)
+#define   SWF14_DS_PIPEA_CRT2_EN (1<<4)
+#define   SWF14_DS_PIPEA_LFP_EN  (1<<3)
+#define   SWF14_DS_PIPEA_EFP_EN  (1<<2)
+#define   SWF14_DS_PIPEA_TV_EN	 (1<<1)
+#define   SWF14_DS_PIPEA_CRT_EN  (1<<0)
+	  /* if GR18 indicates a panel fitting request */
+#define   SWF14_PFIT_EN		(1<<0) /* 0 means disable */
+	  /* if GR18 indicates an APM change request */
+#define   SWF14_APM_HIBERNATE	0x4
+#define   SWF14_APM_SUSPEND	0x3
+#define   SWF14_APM_STANDBY	0x1
+#define   SWF14_APM_RESTORE	0x0
+
+/* Add the device class for LFP, TV, HDMI */
+#define	 DEVICE_TYPE_INT_LFP	0x1022
+#define	 DEVICE_TYPE_INT_TV	0x1009
+#define	 DEVICE_TYPE_HDMI	0x60D2
+#define	 DEVICE_TYPE_DP		0x68C6
+#define	 DEVICE_TYPE_eDP	0x78C6
+
+/* define the DVO port for HDMI output type */
+#define		DVO_B		1
+#define		DVO_C		2
+#define		DVO_D		3
+
+/* define the PORT for DP output type */
+#define		PORT_IDPB	7
+#define		PORT_IDPC	8
+
+#endif /* _I830_BIOS_H_ */
diff --git a/drivers/staging/cdv/drv/psb_intel_crt.c b/drivers/staging/cdv/drv/psb_intel_crt.c
new file mode 100644
index 0000000..221bcdd
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_crt.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ */
+
+#include <linux/i2c.h>
+#include <drm/drmP.h>
+
+#include "psb_intel_bios.h"
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_powermgmt.h"
+#include <linux/pm_runtime.h>
+
+
+static void psb_intel_crt_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	u32 temp, reg;
+	reg = ADPA;
+
+	temp = REG_READ(reg);
+	temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
+	temp &= ~ADPA_DAC_ENABLE;
+
+	switch(mode) {
+	case DRM_MODE_DPMS_ON:
+		temp |= ADPA_DAC_ENABLE;
+		break;
+	case DRM_MODE_DPMS_STANDBY:
+		temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
+		break;
+	case DRM_MODE_DPMS_SUSPEND:
+		temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
+		break;
+	case DRM_MODE_DPMS_OFF:
+		temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
+		break;
+	}
+
+	REG_WRITE(reg, temp);
+}
+
+static int psb_intel_crt_mode_valid(struct drm_connector *connector,
+				struct drm_display_mode *mode)
+{
+	int max_clock = 0;
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+		return MODE_NO_DBLESCAN;
+
+	/* The lowest clock for CDV is 20000KHz */
+	if (mode->clock < 20000)
+		return MODE_CLOCK_LOW;
+
+	/* The max clock for CDV is 355 instead of 400 */
+	max_clock = 355000;
+	if (mode->clock > max_clock)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static bool psb_intel_crt_mode_fixup(struct drm_encoder *encoder,
+				 struct drm_display_mode *mode,
+				 struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void psb_intel_crt_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+
+	struct drm_device *dev = encoder->dev;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct psb_intel_crtc *psb_intel_crtc =
+					to_psb_intel_crtc(crtc);
+	int dpll_md_reg;
+	u32 adpa, dpll_md;
+	u32 adpa_reg;
+
+	if (psb_intel_crtc->pipe == 0)
+		dpll_md_reg = DPLL_A_MD;
+	else
+		dpll_md_reg = DPLL_B_MD;
+
+	adpa_reg = ADPA;
+
+	/*
+	 * Disable separate mode multiplier used when cloning SDVO to CRT
+	 * XXX this needs to be adjusted when we really are cloning
+	 */
+	{
+		dpll_md = REG_READ(dpll_md_reg);
+		REG_WRITE(dpll_md_reg,
+			   dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
+	}
+
+	adpa = 0;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		adpa |= ADPA_HSYNC_ACTIVE_HIGH;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		adpa |= ADPA_VSYNC_ACTIVE_HIGH;
+
+	if (psb_intel_crtc->pipe == 0) {
+		adpa |= ADPA_PIPE_A_SELECT;
+	} else {
+		adpa |= ADPA_PIPE_B_SELECT;
+	}
+
+	REG_WRITE(adpa_reg, adpa);
+}
+
+
+/**
+ * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
+ *
+ * \return true if CRT is connected.
+ * \return false if CRT is disconnected.
+ */
+static bool psb_intel_crt_detect_hotplug(struct drm_connector *connector, bool force)
+{
+	struct drm_device *dev = connector->dev;
+	u32 hotplug_en, orig;
+	int i, tries = 0, ret = false;
+
+	/*
+	 * On 4 series desktop, CRT detect sequence need to be done twice
+	 * to get a reliable result.
+	 * This is also applied for CDV.
+	 */
+
+	if (IS_CDV(dev))
+		tries = 2;
+	else
+		tries = 1;
+	hotplug_en = orig = REG_READ(PORT_HOTPLUG_EN);
+	hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK);
+	hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
+
+	if (IS_CDV(dev))
+		hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
+
+	hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
+
+	for (i = 0; i < tries ; i++) {
+		unsigned long timeout;
+		/* turn on the FORCE_DETECT */
+		REG_WRITE(PORT_HOTPLUG_EN, hotplug_en);
+		timeout = jiffies + msecs_to_jiffies(1000);
+		/* wait for FORCE_DETECT to go off */
+		do {
+			if (!(REG_READ(PORT_HOTPLUG_EN) &
+					CRT_HOTPLUG_FORCE_DETECT))
+				break;
+			msleep(1);
+		} while (time_after(timeout, jiffies));
+	}
+
+	if ((REG_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
+	    CRT_HOTPLUG_MONITOR_NONE)
+		ret = true;
+
+	 /* clear the interrupt we just generated, if any */
+	REG_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
+
+	/* and put the bits back */
+	REG_WRITE(PORT_HOTPLUG_EN, orig);
+
+	return ret;
+}
+
+static bool psb_intel_crt_detect_ddc(struct drm_connector *connector)
+{
+	struct psb_intel_output *psb_intel_output =
+				to_psb_intel_output(connector);
+
+	/* CRT should always be at 0, but check anyway */
+	if (psb_intel_output->type != INTEL_OUTPUT_ANALOG)
+		return false;
+
+	return psb_intel_ddc_probe(psb_intel_output);
+}
+
+
+static enum drm_connector_status psb_intel_crt_detect(struct drm_connector *connector, bool force)
+{
+	struct drm_device *dev = connector->dev;
+
+	if (IS_CDV(dev)) {
+		if (psb_intel_crt_detect_hotplug(connector, force))
+			return connector_status_connected;
+		else
+			return connector_status_disconnected;
+	}
+
+	if (psb_intel_crt_detect_ddc(connector))
+		return connector_status_connected;
+
+	/* If it fails in hotplug/DDC detection, return disconnected */
+	return connector_status_disconnected;
+}
+
+static void psb_intel_crt_destroy(struct drm_connector *connector)
+{
+	struct psb_intel_output *intel_output = to_psb_intel_output(connector);
+
+	psb_intel_i2c_destroy(intel_output->ddc_bus);
+	drm_sysfs_connector_remove(connector);
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+static int psb_intel_crt_get_modes(struct drm_connector *connector)
+{
+	int ret;
+	struct psb_intel_output *intel_output =
+				to_psb_intel_output(connector);
+
+
+	ret = psb_intel_ddc_get_modes(intel_output);
+
+	return ret;
+
+}
+
+static int psb_intel_crt_set_property(struct drm_connector *connector,
+				  struct drm_property *property,
+				  uint64_t value)
+{
+	return 0;
+}
+
+/*
+ * Routines for controlling stuff on the analog port
+ */
+
+static const struct drm_encoder_helper_funcs psb_intel_crt_helper_funcs = {
+	.dpms = psb_intel_crt_dpms,
+	.mode_fixup = psb_intel_crt_mode_fixup,
+	.prepare = psb_intel_encoder_prepare,
+	.commit = psb_intel_encoder_commit,
+	.mode_set = psb_intel_crt_mode_set,
+};
+
+static const struct drm_connector_funcs psb_intel_crt_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.detect = psb_intel_crt_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = psb_intel_crt_destroy,
+	.set_property = psb_intel_crt_set_property,
+};
+
+static const struct drm_connector_helper_funcs psb_intel_crt_connector_helper_funcs = {
+	.mode_valid = psb_intel_crt_mode_valid,
+	.get_modes = psb_intel_crt_get_modes,
+	.best_encoder = psb_intel_best_encoder,
+};
+
+static void psb_intel_crt_enc_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs psb_intel_crt_enc_funcs = {
+	.destroy = psb_intel_crt_enc_destroy,
+};
+
+void psb_intel_crt_init(struct drm_device *dev,
+			struct psb_intel_mode_device *mode_dev)
+{
+
+	struct psb_intel_output *psb_intel_output;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+
+	u32 i2c_reg;
+
+	psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
+	if (!psb_intel_output)
+		return;
+
+	psb_intel_output->mode_dev = mode_dev;
+	connector = &psb_intel_output->base;
+	drm_connector_init(dev, connector,
+			   &psb_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
+
+	encoder = &psb_intel_output->enc;
+	drm_encoder_init(dev, encoder,
+				&psb_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC);
+
+	drm_mode_connector_attach_encoder(&psb_intel_output->base,
+					  &psb_intel_output->enc);
+
+	/* Set up the DDC bus. */
+	i2c_reg = GPIOA;
+	/* Remove the following code for CDV */
+	/*
+	if (dev_priv->crt_ddc_bus != 0)
+		i2c_reg = dev_priv->crt_ddc_bus;
+	}*/
+	psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
+						i2c_reg, "CRTDDC_A");
+	if (!psb_intel_output->ddc_bus) {
+		DRM_ERROR("DDC bus registration failed.\n");
+		goto failed_ddc;
+	}
+
+	psb_intel_output->type = INTEL_OUTPUT_ANALOG;
+	/*
+	psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT);
+	psb_intel_output->crtc_mask = (1 << 0) | (1 << 1);
+	*/
+	connector->interlace_allowed = 0;
+	connector->doublescan_allowed = 0;
+
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	drm_encoder_helper_add(encoder, &psb_intel_crt_helper_funcs);
+	drm_connector_helper_add(connector, &psb_intel_crt_connector_helper_funcs);
+
+	drm_sysfs_connector_add(connector);
+
+	return;
+failed_ddc:
+	drm_encoder_cleanup(&psb_intel_output->enc);
+	drm_connector_cleanup(&psb_intel_output->base);
+	kfree(psb_intel_output);
+	return;
+}
diff --git a/drivers/staging/cdv/drv/psb_intel_display.c b/drivers/staging/cdv/drv/psb_intel_display.c
new file mode 100644
index 0000000..cfc8de9
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_display.c
@@ -0,0 +1,1855 @@
+/*
+ * Copyright Â© 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ */
+
+#include <linux/i2c.h>
+#include <linux/pm_runtime.h>
+
+#include <drm/drmP.h>
+#include "psb_fb.h"
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_display.h"
+#include "psb_powermgmt.h"
+
+
+struct psb_intel_range_t {
+	int min, max;
+};
+
+struct psb_intel_p2_t {
+	int dot_limit;
+	int p2_slow, p2_fast;
+};
+
+#define INTEL_P2_NUM		      2
+
+struct psb_intel_limit_t {
+	struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1;
+	struct psb_intel_p2_t p2;
+	bool (* find_pll)(const struct psb_intel_limit_t *, struct drm_crtc *,
+				int, int, struct psb_intel_clock_t *);
+};
+
+static bool cdv_intel_find_best_PLL(const struct psb_intel_limit_t *limit,
+					struct drm_crtc *crtc, int target,
+					int refclk,
+					struct psb_intel_clock_t *best_clock);
+static bool cdv_intel_find_dp_pll(const struct psb_intel_limit_t *limit, struct drm_crtc *crtc, int target,
+				int refclk,
+				struct psb_intel_clock_t *best_clock);
+
+#define I8XX_DOT_MIN		  25000
+#define I8XX_DOT_MAX		 350000
+#define I8XX_VCO_MIN		 930000
+#define I8XX_VCO_MAX		1400000
+#define I8XX_N_MIN		      3
+#define I8XX_N_MAX		     16
+#define I8XX_M_MIN		     96
+#define I8XX_M_MAX		    140
+#define I8XX_M1_MIN		     18
+#define I8XX_M1_MAX		     26
+#define I8XX_M2_MIN		      6
+#define I8XX_M2_MAX		     16
+#define I8XX_P_MIN		      4
+#define I8XX_P_MAX		    128
+#define I8XX_P1_MIN		      2
+#define I8XX_P1_MAX		     33
+#define I8XX_P1_LVDS_MIN	      1
+#define I8XX_P1_LVDS_MAX	      6
+#define I8XX_P2_SLOW		      4
+#define I8XX_P2_FAST		      2
+#define I8XX_P2_LVDS_SLOW	      14
+#define I8XX_P2_LVDS_FAST	      14	/* No fast option */
+#define I8XX_P2_SLOW_LIMIT	 165000
+
+#define I9XX_DOT_MIN		  20000
+#define I9XX_DOT_MAX		 400000
+#define I9XX_VCO_MIN		1400000
+#define I9XX_VCO_MAX		2800000
+#define I9XX_N_MIN		      3
+#define I9XX_N_MAX		      8
+#define I9XX_M_MIN		     70
+#define I9XX_M_MAX		    120
+#define I9XX_M1_MIN		     10
+#define I9XX_M1_MAX		     20
+#define I9XX_M2_MIN		      5
+#define I9XX_M2_MAX		      9
+#define I9XX_P_SDVO_DAC_MIN	      5
+#define I9XX_P_SDVO_DAC_MAX	     80
+#define I9XX_P_LVDS_MIN		      7
+#define I9XX_P_LVDS_MAX		     98
+#define I9XX_P1_MIN		      1
+#define I9XX_P1_MAX		      8
+#define I9XX_P2_SDVO_DAC_SLOW		     10
+#define I9XX_P2_SDVO_DAC_FAST		      5
+#define I9XX_P2_SDVO_DAC_SLOW_LIMIT	 200000
+#define I9XX_P2_LVDS_SLOW		     14
+#define I9XX_P2_LVDS_FAST		      7
+#define I9XX_P2_LVDS_SLOW_LIMIT		 112000
+
+#define INTEL_LIMIT_I8XX_DVO_DAC    0
+#define INTEL_LIMIT_I8XX_LVDS	    1
+#define INTEL_LIMIT_I9XX_SDVO_DAC   2
+#define INTEL_LIMIT_I9XX_LVDS	    3
+
+#define CDV_LIMIT_SINGLE_LVDS_96	0
+#define CDV_LIMIT_SINGLE_LVDS_100	1
+#define CDV_LIMIT_DAC_HDMI_27		2
+#define CDV_LIMIT_DAC_HDMI_96		3
+#define CDV_LIMIT_DP_27			4
+#define CDV_LIMIT_DP_100		5
+
+static const struct psb_intel_limit_t cdv_intel_limits[] = {
+	{			/* CDV_SIGNLE_LVDS_96MHz */
+	 .dot = {.min = 20000, .max = 115500},
+	 .vco = {.min = 1800000, .max = 3600000},
+	 .n = {.min = 2, .max = 6},
+	 .m = {.min = 60, .max = 160},
+	 .m1 = {.min = 0, .max = 0},
+	 .m2 = {.min = 58, .max = 158},
+	 .p = {.min = 28, .max = 140},
+	 .p1 = {.min = 2, .max = 10},
+	 .p2 = {.dot_limit = 200000,
+		.p2_slow = 14, .p2_fast = 14},
+	 .find_pll = cdv_intel_find_best_PLL,
+	 },
+	{			/* CDV_SINGLE_LVDS_100MHz */
+	 .dot = {.min = 20000, .max = 115500},
+	 .vco = {.min = 1800000, .max = 3600000},
+	 .n = {.min = 2, .max = 6},
+	 .m = {.min = 60, .max = 160},
+	 .m1 = {.min = 0, .max = 0},
+	 .m2 = {.min = 58, .max = 158},
+	 .p = {.min = 28, .max = 140},
+	 .p1 = {.min = 2, .max = 10},
+	 /* The single-channel range is 25-112Mhz, and dual-channel
+	  * is 80-224Mhz.  Prefer single channel as much as possible.
+	  */
+	 .p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14},
+	 .find_pll = cdv_intel_find_best_PLL,
+	 },
+	{			/* CDV_DAC_HDMI_27MHz */
+	 .dot = {.min = 20000, .max = 400000},
+	 .vco = {.min = 1809000, .max = 3564000},
+	 .n = {.min = 1, .max = 1},
+	 .m = {.min = 67, .max = 132},
+	 .m1 = {.min = 0, .max = 0},
+	 .m2 = {.min = 65, .max = 130},
+	 .p = {.min = 5, .max = 90},
+	 .p1 = {.min = 1, .max = 9},
+	 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
+	 .find_pll = cdv_intel_find_best_PLL,
+	 },
+	{			/* CDV_DAC_HDMI_96MHz */
+	 .dot = {.min = 20000, .max = 400000},
+	 .vco = {.min = 1800000, .max = 3600000},
+	 .n = {.min = 2, .max = 6},
+	 .m = {.min = 60, .max = 160},
+	 .m1 = {.min = 0, .max = 0},
+	 .m2 = {.min = 58, .max = 158},
+	 .p = {.min = 5, .max = 100},
+	 .p1 = {.min = 1, .max = 10},
+	 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
+	 .find_pll = cdv_intel_find_best_PLL,
+	 },
+	{			/* CDV_DP_27MHz */
+	 .dot = {.min = 160000, .max = 272000},
+	 .vco = {.min = 1809000, .max = 3564000},
+	 .n = {.min = 1, .max = 1},
+	 .m = {.min = 67, .max = 132},
+	 .m1 = {.min = 0, .max = 0},
+	 .m2 = {.min = 65, .max = 130},
+	 .p = {.min = 5, .max = 90},
+	 .p1 = {.min = 1, .max = 9},
+	 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10},
+	 .find_pll = cdv_intel_find_dp_pll,
+	 },
+	{			/* CDV_DP_100MHz */
+	 .dot = {.min = 160000, .max = 272000},
+	 .vco = {.min = 1800000, .max = 3600000},
+	 .n = {.min = 2, .max = 6},
+	 .m = {.min = 60, .max = 164},
+	 .m1 = {.min = 0, .max = 0},
+	 .m2 = {.min = 58, .max = 162},
+	 .p = {.min = 5, .max = 100},
+	 .p1 = {.min = 1, .max = 10},
+	 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10},
+	 .find_pll = cdv_intel_find_dp_pll,
+	 }	
+};
+
+static const struct psb_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc, int refclk)
+{
+	const struct psb_intel_limit_t *limit;
+
+	DRM_DEBUG_KMS("ref clk is %d\n", refclk);
+
+	if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+		/*
+ 		 * Now only single-channel LVDS is supported on CDV. If it is
+ 		 * incorrect, please add the dual-channel LVDS.
+ 		 */
+		if (refclk == 96000)
+			limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
+		else 
+			limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
+	} else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
+			psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
+		if (refclk == 27000)
+			limit = &cdv_intel_limits[CDV_LIMIT_DP_27];
+		else
+			limit = &cdv_intel_limits[CDV_LIMIT_DP_100];
+	} else {
+		if (refclk == 27000)
+			limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27];
+		else
+			limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_96];
+	}
+	return limit;
+}
+/* On the CDV the M is written, which is similar to that on Pineview */
+/*static bool single_m_multiplier(struct drm_device *dev)
+{
+	return IS_CDV(dev);
+}
+*/
+
+/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
+static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
+{
+	clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
+	clock->p = clock->p1 * clock->p2;
+	clock->vco = refclk * clock->m / (clock->n + 2);
+	clock->dot = clock->vco / clock->p;
+}
+
+
+/* m1 is reserved as 0 in CDV, n is a ring counter */
+static void cdv_intel_clock(struct drm_device *dev, 
+			int refclk, struct psb_intel_clock_t *clock)
+{
+	clock->m = clock->m2 + 2;
+	clock->p = clock->p1 * clock->p2;
+	clock->vco = (refclk * clock->m) / clock->n;
+	clock->dot = clock->vco / clock->p;
+}
+
+/**
+ * Returns whether any output on the specified pipe is of the specified type
+ */
+bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct drm_connector *l_entry;
+
+	list_for_each_entry(l_entry, &mode_config->connector_list, head) {
+		if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
+			struct psb_intel_output *psb_intel_output =
+			    to_psb_intel_output(l_entry);
+			if (psb_intel_output->type == type)
+				return true;
+		}
+	}
+	return false;
+}
+
+#define INTELPllInvalid(s)   { /* ErrorF (s) */; return false; }
+/**
+ * Returns whether the given set of divisors are valid for a given refclk with
+ * the given connectors.
+ */
+
+static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc,
+				const struct psb_intel_limit_t *limit,
+			       struct psb_intel_clock_t *clock)
+{
+	if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
+		INTELPllInvalid("p1 out of range\n");
+	if (clock->p < limit->p.min || limit->p.max < clock->p)
+		INTELPllInvalid("p out of range\n");
+	/* unnecessary to check the range of m(m1/M2)/n again */
+	/*
+	if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
+		INTELPllInvalid("m2 out of range\n");
+	if (clock->m < limit->m.min || limit->m.max < clock->m)
+		INTELPllInvalid("m out of range\n");
+	if (clock->n < limit->n.min || limit->n.max < clock->n)
+		INTELPllInvalid("n out of range\n");
+	*/
+	if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
+		INTELPllInvalid("vco out of range\n");
+	/* XXX: We may need to be checking "Dot clock"
+	 * depending on the multiplier, connector, etc.,
+	 * rather than just a single range.
+	 */
+	if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
+		INTELPllInvalid("dot out of range\n");
+
+	return true;
+}
+
+static bool cdv_intel_find_best_PLL(const struct psb_intel_limit_t *limit, struct drm_crtc *crtc, int target,
+				int refclk,
+				struct psb_intel_clock_t *best_clock)
+{
+	struct drm_device *dev = crtc->dev;
+	struct psb_intel_clock_t clock;
+	int err = target;
+
+
+	if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
+	    (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
+		/*
+		 * For LVDS, if the panel is on, just rely on its current
+		 * settings for dual-channel.  We haven't figured out how to
+		 * reliably set up different single/dual channel state, if we
+		 * even can.
+		 */
+		if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
+		    LVDS_CLKB_POWER_UP)
+			clock.p2 = limit->p2.p2_fast;
+		else
+			clock.p2 = limit->p2.p2_slow;
+	} else {
+		if (target < limit->p2.dot_limit)
+			clock.p2 = limit->p2.p2_slow;
+		else
+			clock.p2 = limit->p2.p2_fast;
+	}
+
+	memset(best_clock, 0, sizeof(*best_clock));
+	clock.m1 = 0;
+	/* m1 is reserved as 0 in CDV, n is a ring counter. So skip the m1 loop */
+	for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
+		for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max;
+					     clock.m2++) {
+			for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
+				     clock.p1++) {
+				int this_err;
+
+				cdv_intel_clock(dev, refclk, &clock);
+
+				if (!cdv_intel_PLL_is_valid(crtc, limit, &clock))
+						continue;
+				
+				this_err = abs(clock.dot - target);
+				if (this_err < err) {
+					*best_clock = clock;
+					err = this_err;
+				}
+			}
+		}
+	}
+
+	return err != target;
+}
+
+static bool cdv_intel_find_dp_pll(const struct psb_intel_limit_t *limit, struct drm_crtc *crtc, int target,
+				int refclk,
+				struct psb_intel_clock_t *best_clock)
+{
+	struct psb_intel_clock_t clock;
+	if (refclk == 27000) {
+		if (target < 200000) {
+			clock.p1 = 2;
+			clock.p2 = 10;
+			clock.n = 1;
+			clock.m1 = 0;
+			clock.m2 = 118;
+		} else {
+			clock.p1 = 1;
+			clock.p2 = 10;
+			clock.n = 1;
+			clock.m1 = 0;
+			clock.m2 = 98;
+		}
+	} else if (refclk == 100000) {
+		if (target < 200000) {
+			clock.p1 = 2;
+			clock.p2 = 10;
+			clock.n = 5;
+			clock.m1 = 0;
+			clock.m2 = 160;
+		} else {
+			clock.p1 = 1;
+			clock.p2 = 10;
+			clock.n = 5;
+			clock.m1 = 0;
+			clock.m2 = 133;
+		}
+	} else
+		return false;
+	clock.m = clock.m2 + 2;
+	clock.p = clock.p1 * clock.p2;
+	clock.vco = (refclk * clock.m) / clock.n;
+	clock.dot = clock.vco / clock.p;
+	memcpy(best_clock, &clock, sizeof(struct psb_intel_clock_t));
+	return true;
+		
+}
+
+void psb_intel_wait_for_vblank(struct drm_device *dev)
+{
+	/* Wait for 20ms, i.e. one cycle at 50hz. */
+	mdelay(20);
+}
+
+static bool psb_intel_pipe_enabled(struct drm_device *dev, int pipe)
+{
+	struct drm_crtc *crtc;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct psb_intel_crtc *psb_intel_crtc = NULL;
+
+	crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+	psb_intel_crtc = to_psb_intel_crtc(crtc);
+
+	if (crtc->fb == NULL || !psb_intel_crtc->active) {
+		return false;
+	}
+	return true;
+}
+
+#define		FIFO_PIPEA		(1 << 0)
+#define		FIFO_PIPEB		(1 << 1)
+
+static bool psb_intel_single_pipe_active (struct drm_device *dev)
+{
+	uint32_t pipe_enabled = 0;
+
+	if (psb_intel_pipe_enabled(dev, 0)) {
+		pipe_enabled |= FIFO_PIPEA;
+	}
+	if (psb_intel_pipe_enabled(dev, 1)) {
+		pipe_enabled |= FIFO_PIPEB;
+	}
+
+	DRM_DEBUG_KMS("pipe enabled %x\n", pipe_enabled);
+
+	if ((pipe_enabled == FIFO_PIPEA) || (pipe_enabled == FIFO_PIPEB))
+		return true;
+	else
+		return false;
+}
+
+static bool is_pipeb_lvds(struct drm_device *dev, struct drm_crtc *crtc)
+{
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct drm_connector *connector;
+
+	if (psb_intel_crtc->pipe != 1)
+		return false;
+
+	list_for_each_entry(connector, &mode_config->connector_list, head) {
+		struct psb_intel_output *psb_intel_output =
+		    to_psb_intel_output(connector);
+
+		if (!connector->encoder
+		    || connector->encoder->crtc != crtc)
+			continue;
+
+		if (psb_intel_output->type == INTEL_OUTPUT_LVDS)
+			return true;
+	}
+
+	return false;
+}
+
+static void psb_intel_disable_self_refresh (struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	if (REG_READ(FW_BLC_SELF) & FW_BLC_SELF_EN) {
+
+		/* Disable self-refresh before adjust WM */
+		REG_WRITE(FW_BLC_SELF, (REG_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN));
+		REG_READ(FW_BLC_SELF);
+
+		psb_intel_wait_for_vblank(dev);
+
+		/* Cedarview workaround to write ovelay plane, which force to leave
+		 * MAX_FIFO state.
+		 */
+		REG_WRITE(OV_OVADD, dev_priv->ovl_offset);
+		REG_READ(OV_OVADD);
+
+		psb_intel_wait_for_vblank(dev);
+	}
+
+}
+
+static void psb_intel_update_watermark (struct drm_device *dev, struct drm_crtc *crtc)
+{
+
+	if (psb_intel_single_pipe_active(dev)) {
+		u32 fw;
+
+		fw = REG_READ(DSPFW1);
+		fw &= ~DSP_FIFO_SR_WM_MASK;
+		fw |= (0x7e << DSP_FIFO_SR_WM_SHIFT);
+		fw &= ~CURSOR_B_FIFO_WM_MASK;
+		fw |= (0x4 << CURSOR_B_FIFO_WM_SHIFT);
+		REG_WRITE(DSPFW1, fw);
+
+		fw = REG_READ(DSPFW2);
+		fw &= ~CURSOR_A_FIFO_WM_MASK;
+		fw |= (0x6 << CURSOR_A_FIFO_WM_SHIFT);
+		fw &= ~DSP_PLANE_C_FIFO_WM_MASK;
+		fw |= (0x8 << DSP_PLANE_C_FIFO_WM_SHIFT);
+		REG_WRITE(DSPFW2, fw);
+
+		REG_WRITE(DSPFW3, 0x36000000);
+
+		/* ignore FW4 */
+
+		if (is_pipeb_lvds(dev, crtc)) {
+			REG_WRITE(DSPFW5, 0x00040330);
+		} else {
+			fw = (3 << DSP_PLANE_B_FIFO_WM1_SHIFT) |
+			     (4 << DSP_PLANE_A_FIFO_WM1_SHIFT) |
+			     (3 << CURSOR_B_FIFO_WM1_SHIFT) |
+			     (4 << CURSOR_FIFO_SR_WM1_SHIFT);
+			REG_WRITE(DSPFW5, fw);
+		}
+
+		REG_WRITE(DSPFW6, 0x10);
+
+		psb_intel_wait_for_vblank(dev);
+
+		/* enable self-refresh for single pipe active */
+		REG_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+		REG_READ(FW_BLC_SELF);
+		psb_intel_wait_for_vblank(dev);
+
+	} else {
+
+		/* HW team suggested values... */
+		REG_WRITE(DSPFW1, 0x3f880808);
+		REG_WRITE(DSPFW2, 0x0b020202);
+		REG_WRITE(DSPFW3, 0x24000000);
+		REG_WRITE(DSPFW4, 0x08030202);
+		REG_WRITE(DSPFW5, 0x01010101);
+		REG_WRITE(DSPFW6, 0x1d0);
+
+		psb_intel_wait_for_vblank(dev);
+
+		psb_intel_disable_self_refresh(dev);
+	
+	}
+}
+
+int psb_intel_pipe_set_base(struct drm_crtc *crtc,
+			    int x, int y, struct drm_framebuffer *old_fb)
+{
+	struct drm_device *dev = crtc->dev;
+	/* struct drm_i915_master_private *master_priv; */
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
+	struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
+	int pipe = psb_intel_crtc->pipe;
+	unsigned long Start, Offset;
+	int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
+	int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
+	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
+	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+	u32 dspcntr;
+	int ret = 0;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	/* no fb bound */
+	if (!crtc->fb) {
+		DRM_DEBUG_KMS("No FB bound\n");
+		return 0;
+	}
+
+	Start = mode_dev->bo_offset(dev, psbfb);
+	Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+
+	REG_WRITE(dspstride, crtc->fb->pitch);
+
+	dspcntr = REG_READ(dspcntr_reg);
+	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+
+	switch (crtc->fb->bits_per_pixel) {
+	case 8:
+		dspcntr |= DISPPLANE_8BPP;
+		break;
+	case 16:
+		if (crtc->fb->depth == 15)
+			dspcntr |= DISPPLANE_15_16BPP;
+		else
+			dspcntr |= DISPPLANE_16BPP;
+		break;
+	case 24:
+	case 32:
+		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+		break;
+	default:
+		DRM_ERROR("Unknown color depth\n");
+		ret = -EINVAL;
+		goto psb_intel_pipe_set_base_exit;
+	}
+	REG_WRITE(dspcntr_reg, dspcntr);
+
+	DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d for FB ID %d\n", Start, Offset, x, y, psbfb->base.base.id);
+	if (IS_CDV(dev)) {
+		REG_WRITE(dspbase, Offset);
+		REG_READ(dspbase);
+		REG_WRITE(dspsurf, Start);
+		REG_READ(dspsurf);
+	} else {
+		REG_WRITE(dspbase, Start + Offset);
+		REG_READ(dspbase);
+	}
+
+psb_intel_pipe_set_base_exit:
+
+	return ret;
+}
+
+#define CRTC_FLIP_TIMEOUT	100	/* ms */
+#define MAX_FLIP_COUNTER	100
+
+#define CRTC_PIPEA		0
+#define CRTC_PIPEB		1
+#define PIPEA_ENABLED		(1 << 0)
+#define PIPEB_ENABLED		(1 << 1)
+
+static void psb_flip_timer(unsigned long arg)
+{
+	struct drm_device *dev = (struct drm_device *) arg;
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *)(dev->dev_private);
+
+	if (dev_priv->psb_vsync_handler)
+		(dev_priv->psb_vsync_handler)(dev, dev_priv->ui32MainPipe);
+
+	dev_priv->flip_counter--;
+	if (dev_priv->vblanksEnabledForFlips && !dev_priv->pipeEnabled &&
+			dev_priv->flip_counter) {
+		mod_timer(&dev_priv->flip_timer, jiffies +
+			 msecs_to_jiffies(CRTC_FLIP_TIMEOUT));
+	}
+}
+
+
+/**
+ * Sets the power management mode of the pipe and plane.
+ *
+ * This code should probably grow support for turning the cursor off and back
+ * on appropriately at the same time as we're turning the pipe off/on.
+ */
+static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+	struct drm_device *dev = crtc->dev;
+	/* struct drm_i915_master_private *master_priv; */
+	struct drm_psb_private *dev_priv = dev->dev_private; 
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	int pipe = psb_intel_crtc->pipe;
+	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+	int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
+	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+	int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT;
+	u32 temp;
+	u32 target_pipe;
+
+	/* XXX: When our outputs are all unaware of DPMS modes other than off
+	 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
+	 */
+
+	psb_intel_disable_self_refresh(dev);
+	
+	switch (mode) {
+	case DRM_MODE_DPMS_ON:
+	case DRM_MODE_DPMS_STANDBY:
+	case DRM_MODE_DPMS_SUSPEND:
+		DRM_DEBUG_KMS("Turning on display in dpms on pipe: %d\n", pipe);
+
+		if (psb_intel_crtc->active)
+			break;
+
+		psb_intel_crtc->active = true;
+
+		/* Enable the DPLL */
+		temp = REG_READ(dpll_reg);
+		if ((temp & DPLL_VCO_ENABLE) == 0) {
+			REG_WRITE(dpll_reg, temp);
+			REG_READ(dpll_reg);
+			/* Wait for the clocks to stabilize. */
+			udelay(150);
+			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
+			REG_READ(dpll_reg);
+			/* Wait for the clocks to stabilize. */
+			udelay(150);
+			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
+			REG_READ(dpll_reg);
+			/* Wait for the clocks to stabilize. */
+			udelay(150);
+		}
+
+		/* Jim Bish - switch plan and pipe per scott */
+		/* Enable the plane */
+		temp = REG_READ(dspcntr_reg);
+		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
+			REG_WRITE(dspcntr_reg,
+				  temp | DISPLAY_PLANE_ENABLE);
+			/* Flush the plane changes */
+			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+		}
+
+		udelay(150);
+
+		/* Enable the pipe */
+		temp = REG_READ(pipeconf_reg);
+		if ((temp & PIPEACONF_ENABLE) == 0)
+			REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
+
+		temp = REG_READ(pipestat_reg);
+		temp &= ~(0xFFFF);
+		temp |= PIPE_FIFO_UNDERRUN;
+		REG_WRITE(pipestat_reg, temp);
+		REG_READ(pipestat_reg);
+		
+		psb_intel_crtc_load_lut(crtc);
+
+		dev_priv->pipeEnabled |= (1 << pipe);
+		/* Give the overlay scaler a chance to enable
+		 * if it's on this pipe */
+		/* psb_intel_crtc_dpms_video(crtc, true); TODO */
+		break;
+	case DRM_MODE_DPMS_OFF:
+		DRM_DEBUG_KMS("Turning off display in dpms on pipe: %d\n", pipe);
+		if (!psb_intel_crtc->active)
+			break;
+
+		psb_intel_crtc->active = false;
+
+		/* Give the overlay scaler a chance to disable
+		 * if it's on this pipe */
+		/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
+
+		/* Disable the VGA plane that we never use */
+		REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+
+		drm_vblank_off(dev, pipe);
+
+		if (!IS_I9XX(dev)) {
+			/* Wait for vblank for the disable to take effect */
+			psb_intel_wait_for_vblank(dev);
+		}
+
+		/* Next, disable display pipes */
+		temp = REG_READ(pipeconf_reg);
+		if ((temp & PIPEACONF_ENABLE) != 0) {
+			REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
+			REG_READ(pipeconf_reg);
+		}
+
+		/* Wait for vblank for the disable to take effect. */
+		psb_intel_wait_for_vblank(dev);
+
+		/* Disable display plane */
+		temp = REG_READ(dspcntr_reg);
+		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
+			REG_WRITE(dspcntr_reg,
+				  temp & ~DISPLAY_PLANE_ENABLE);
+			/* Flush the plane changes */
+			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+			REG_READ(dspbase_reg);
+		}
+
+		temp = REG_READ(dpll_reg);
+		if ((temp & DPLL_VCO_ENABLE) != 0) {
+			REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
+			REG_READ(dpll_reg);
+		}
+
+		/* Wait for the clocks to turn off. */
+		udelay(150);
+
+		dev_priv->pipeEnabled &= ~(1 << pipe);
+		break;
+	}
+	
+	psb_intel_update_watermark(dev, crtc);
+
+	if ((dev_priv->pipeEnabled == PIPEA_ENABLED) || 
+			(dev_priv->pipeEnabled == PIPEB_ENABLED)) {
+		target_pipe = CRTC_PIPEA;
+		if (dev_priv->pipeEnabled == PIPEB_ENABLED)
+			target_pipe = CRTC_PIPEB;
+	} else {
+		target_pipe = CRTC_PIPEB;
+	}
+	if (target_pipe != dev_priv->ui32MainPipe) {
+		DRM_DEBUG_KMS("Main flip pipe is switched from %d to %d\n",
+			dev_priv->ui32MainPipe, target_pipe);
+		if (dev_priv->vblanksEnabledForFlips) {
+			if (!dev->vblank_enabled[dev_priv->ui32MainPipe])
+				psb_disable_vblank(dev, dev_priv->ui32MainPipe);
+			psb_enable_vblank(dev, target_pipe);
+		}
+		dev_priv->ui32MainPipe = target_pipe;
+	}
+	if (mode == DRM_MODE_DPMS_OFF) {
+		if (dev_priv->vblanksEnabledForFlips && !dev_priv->pipeEnabled) {
+			dev_priv->flip_counter =  MAX_FLIP_COUNTER;
+			mod_timer(&dev_priv->flip_timer, jiffies +
+				 msecs_to_jiffies(CRTC_FLIP_TIMEOUT));
+		}
+	} else {
+		dev_priv->flip_counter = 0;
+		del_timer(&dev_priv->flip_timer);
+		
+	}
+}
+
+static void psb_intel_crtc_prepare(struct drm_crtc *crtc)
+{
+	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void psb_intel_crtc_commit(struct drm_crtc *crtc)
+{
+	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+void psb_intel_encoder_prepare(struct drm_encoder *encoder)
+{
+	struct drm_encoder_helper_funcs *encoder_funcs =
+	    encoder->helper_private;
+	/* lvds has its own version of prepare see psb_intel_lvds_prepare */
+	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
+}
+
+void psb_intel_encoder_commit(struct drm_encoder *encoder)
+{
+	struct drm_encoder_helper_funcs *encoder_funcs =
+	    encoder->helper_private;
+	/* lvds has its own version of commit see psb_intel_lvds_commit */
+	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
+}
+
+static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc,
+				  struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+
+/**
+ * Return the pipe currently connected to the panel fitter,
+ * or -1 if the panel fitter is not present or not in use
+ */
+static int psb_intel_panel_fitter_pipe(struct drm_device *dev)
+{
+	u32 pfit_control;
+
+	/* i830 doesn't have a panel fitter */
+	if (IS_I830(dev))
+		return -1;
+
+	pfit_control = REG_READ(PFIT_CONTROL);
+
+	/* See if the panel fitter is in use */
+	if ((pfit_control & PFIT_ENABLE) == 0)
+		return -1;
+
+	/* 965 can place panel fitter on either pipe */
+	if (IS_I965G(dev) || IS_MID(dev))
+		return (pfit_control >> 29) & 0x3;
+
+	/* older chips can only use pipe 1 */
+	return 1;
+}
+
+static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode,
+			       int x, int y,
+			       struct drm_framebuffer *old_fb)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_psb_private *dev_priv = dev->dev_private; 
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	int pipe = psb_intel_crtc->pipe;
+	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+	int dpll_md_reg = (psb_intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
+	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+	int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
+	int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
+	int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
+	int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
+	int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
+	int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
+	int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
+	int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
+	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
+	int refclk;
+	struct psb_intel_clock_t clock;
+	u32 dpll = 0, dspcntr, pipeconf;
+	bool ok;
+	bool is_crt = false, is_lvds = false, is_tv = false;
+	bool is_hdmi = false, is_dp = false;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct drm_connector *connector;
+	const struct psb_intel_limit_t *limit;
+	u32	ddi_select = 0;
+	bool is_edp = false;
+
+	DRM_DEBUG_KMS("cdv_intel_crtc_mode_set called for pipe %d\n", pipe);
+
+	list_for_each_entry(connector, &mode_config->connector_list, head) {
+		struct psb_intel_output *psb_intel_output =
+		    to_psb_intel_output(connector);
+
+		if (!connector->encoder
+		    || connector->encoder->crtc != crtc)
+			continue;
+
+		switch (psb_intel_output->type) {
+		case INTEL_OUTPUT_LVDS:
+			is_lvds = true;
+			break;
+		case INTEL_OUTPUT_TVOUT:
+			is_tv = true;
+			break;
+		case INTEL_OUTPUT_ANALOG:
+			is_crt = true;
+			break;
+		case INTEL_OUTPUT_HDMI:
+			is_hdmi = true;
+			ddi_select = psb_intel_output->ddi_select;
+			break;
+		case INTEL_OUTPUT_DISPLAYPORT:
+			is_dp = true;
+			ddi_select = psb_intel_output->ddi_select;
+			break;
+		case INTEL_OUTPUT_EDP:
+			is_edp = true;
+			ddi_select = psb_intel_output->ddi_select;
+			break;
+		default:
+			DRM_ERROR("Unsupported output type!\n");
+			return 0;
+		}
+	}
+
+	if (dev_priv->dplla_96mhz)
+		/* low-end sku, 96/100 mhz */
+		refclk = 96000;
+	else
+		/* high-end sku, 27/100 mhz */
+		refclk = 27000;
+	if (is_dp || is_edp) {
+		/*
+		 * Based on the spec the low-end SKU has only CRT/LVDS. So it is
+		 * unnecessary to consider it for DP/eDP.
+		 * On the high-end SKU, it will use the 27/100M reference clk
+		 * for DP/eDP. When using SSC clock, the ref clk is 100MHz.Otherwise
+		 * it will be 27MHz. From the VBIOS code it seems that the pipe A choose
+		 * 27MHz for DP/eDP while the Pipe B chooses the 100MHz.
+		 */ 
+		if (pipe == 0)
+			refclk = 27000;
+		else
+			refclk = 100000;
+	}
+
+	if (is_lvds && dev_priv->lvds_use_ssc) {
+		refclk = dev_priv->lvds_ssc_freq * 1000;
+		DRM_DEBUG_KMS("Use SSC reference clock %d Mhz\n", dev_priv->lvds_ssc_freq);
+	}
+
+	DRM_DEBUG_KMS("Use reference clock %d Khz\n", refclk);
+
+	drm_mode_debug_printmodeline(adjusted_mode);
+
+	limit = cdv_intel_limit(crtc, refclk);
+	ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk,
+				 &clock);
+	if (!ok) {
+		DRM_ERROR("Couldn't find PLL settings for mode!\n");
+		return 0;
+	}
+
+	dpll = DPLL_VGA_MODE_DIS;
+	if (is_tv) {
+		/* XXX: just matching BIOS for now */
+/*	dpll |= PLL_REF_INPUT_TVCLKINBC; */
+		dpll |= 3;
+	}
+#if 0
+	else if (is_lvds)
+		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
+
+#endif
+
+	if (is_dp || is_edp) {
+		psb_intel_dp_set_m_n(crtc, mode, adjusted_mode);
+	} else {
+		REG_WRITE(PIPE_GMCH_DATA_M(pipe), 0);
+		REG_WRITE(PIPE_GMCH_DATA_N(pipe), 0);
+		REG_WRITE(PIPE_DP_LINK_M(pipe), 0);
+		REG_WRITE(PIPE_DP_LINK_N(pipe), 0);
+	}
+		
+	dpll |= DPLL_SYNCLOCK_ENABLE;
+
+	/* setup pipeconf */
+	pipeconf = REG_READ(pipeconf_reg);
+	pipeconf &= ~(PIPE_BPC_MASK);
+	if (is_edp) {
+		switch (dev_priv->edp.bpp) {
+		case 24:
+			pipeconf |= PIPE_8BPC;
+			break;
+		case 18:
+			pipeconf |= PIPE_6BPC;
+			break;
+		case 30:
+			pipeconf |= PIPE_10BPC;
+			break;
+		default:
+			pipeconf |= PIPE_8BPC;
+			break;
+		}
+	} else if (is_lvds) {
+		/* the BPC will be 6 if it is 18-bit LVDS panel */
+		if ((REG_READ(LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
+			pipeconf |= PIPE_8BPC;
+		else
+			pipeconf |= PIPE_6BPC;
+	} else
+		pipeconf |= PIPE_8BPC;
+			
+		
+	/* Set up the display plane register */
+	dspcntr = DISPPLANE_GAMMA_ENABLE;
+
+	if (pipe == 0)
+		dspcntr |= DISPPLANE_SEL_PIPE_A;
+	else
+		dspcntr |= DISPPLANE_SEL_PIPE_B;
+
+	dspcntr |= DISPLAY_PLANE_ENABLE;
+	pipeconf |= PIPEACONF_ENABLE;
+
+	REG_WRITE(dpll_reg, dpll);
+        REG_READ(dpll_reg);
+
+	psb_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds, ddi_select);
+
+        udelay(150);
+
+	/* The LVDS pin pair needs to be on before the DPLLs are enabled.
+	 * This is an exception to the general rule that mode_set doesn't turn
+	 * things on.
+	 */
+	if (is_lvds) {
+		u32 lvds = REG_READ(LVDS);
+
+		lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP |
+			LVDS_PIPEB_SELECT;
+		/* Set the B0-B3 data pairs corresponding to
+		 * whether we're going to
+		 * set the DPLLs for dual-channel mode or not.
+		 */
+		if (clock.p2 == 7)
+			lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
+		else
+			lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
+
+		/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
+		 * appropriately here, but we need to look more
+		 * thoroughly into how panels behave in the two modes.
+		 */
+
+		REG_WRITE(LVDS, lvds);
+		REG_READ(LVDS);
+	}
+
+	dpll |= DPLL_VCO_ENABLE;
+
+		
+	/* Disable the panel fitter if it was on our pipe */
+	if (psb_intel_panel_fitter_pipe(dev) == pipe)
+		REG_WRITE(PFIT_CONTROL, 0);
+
+	DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
+	drm_mode_debug_printmodeline(mode);
+
+	REG_WRITE(dpll_reg,
+                   (REG_READ(dpll_reg) & ~DPLL_LOCK) |
+                   DPLL_VCO_ENABLE);
+        REG_READ(dpll_reg);
+	/* Wait for the clocks to stabilize. */
+        udelay(150); /* 42 usec w/o calibration, 110 with.  rounded up. */
+
+        if (!(REG_READ(dpll_reg) & DPLL_LOCK)) {
+                DRM_ERROR("Failed to get DPLL lock\n");
+                return -EBUSY;
+        }
+
+	if (IS_CDV(dev)) {
+		int sdvo_pixel_multiply =
+		    adjusted_mode->clock / mode->clock;
+		REG_WRITE(dpll_md_reg,
+			  (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
+			  ((sdvo_pixel_multiply -
+			    1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
+	}
+
+	REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
+		  ((adjusted_mode->crtc_htotal - 1) << 16));
+	REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
+		  ((adjusted_mode->crtc_hblank_end - 1) << 16));
+	REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
+		  ((adjusted_mode->crtc_hsync_end - 1) << 16));
+	REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
+		  ((adjusted_mode->crtc_vtotal - 1) << 16));
+	REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
+		  ((adjusted_mode->crtc_vblank_end - 1) << 16));
+	REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
+		  ((adjusted_mode->crtc_vsync_end - 1) << 16));
+	/* pipesrc and dspsize control the size that is scaled from,
+	 * which should always be the user's requested size.
+	 */
+	REG_WRITE(dspsize_reg,
+		  ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
+	REG_WRITE(dsppos_reg, 0);
+	REG_WRITE(pipesrc_reg,
+		  ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
+	REG_WRITE(pipeconf_reg, pipeconf);
+	REG_READ(pipeconf_reg);
+
+	psb_intel_wait_for_vblank(dev);
+
+	REG_WRITE(dspcntr_reg, dspcntr);
+
+	/* Flush the plane changes */
+	{
+		struct drm_crtc_helper_funcs *crtc_funcs =
+		    crtc->helper_private;
+		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
+	}
+
+	psb_intel_wait_for_vblank(dev);
+
+	return 0;
+}
+
+/** Loads the palette/gamma unit for the CRTC with the prepared values */
+void psb_intel_crtc_load_lut(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	int palreg = PALETTE_A;
+	int i;
+
+	/* The clocks have to be on to load the palette. */
+	if (!crtc->enabled)
+		return;
+
+	switch (psb_intel_crtc->pipe) {
+	case 0:
+		palreg = PALETTE_A;
+		break;
+	case 1:
+		palreg = PALETTE_B;
+		break;
+	default:
+		DRM_ERROR("Illegal Pipe Number. \n");
+		return;
+	}
+	
+	for (i = 0; i < 256; i++) {
+		REG_WRITE(palreg + 4 * i,
+			  ((psb_intel_crtc->lut_r[i] +
+			    psb_intel_crtc->lut_adj[i]) << 16) |
+			  ((psb_intel_crtc->lut_g[i] +
+			    psb_intel_crtc->lut_adj[i]) << 8) |
+			  (psb_intel_crtc->lut_b[i] +
+			   psb_intel_crtc->lut_adj[i]));
+	}
+}
+
+/**
+ * Save HW states of giving crtc
+ */
+static void psb_intel_crtc_save(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	/* struct drm_psb_private *dev_priv =
+			(struct drm_psb_private *)dev->dev_private; */
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
+	int pipeA = (psb_intel_crtc->pipe == 0);
+	uint32_t paletteReg;
+	int i;
+
+	DRM_DEBUG("\n");
+
+	if (!crtc_state) {
+		DRM_DEBUG("No CRTC state found\n");
+		return;
+	}
+
+	crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
+	crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
+	crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
+	crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
+	crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
+	crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
+	crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
+	crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
+	crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
+	crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
+	crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
+	crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
+	crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
+
+	/*NOTE: DSPSIZE DSPPOS only for psb*/
+	crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
+	crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
+
+	crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
+
+	DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
+			crtc_state->saveDSPCNTR,
+			crtc_state->savePIPECONF,
+			crtc_state->savePIPESRC,
+			crtc_state->saveFP0,
+			crtc_state->saveFP1,
+			crtc_state->saveDPLL,
+			crtc_state->saveHTOTAL,
+			crtc_state->saveHBLANK,
+			crtc_state->saveHSYNC,
+			crtc_state->saveVTOTAL,
+			crtc_state->saveVBLANK,
+			crtc_state->saveVSYNC,
+			crtc_state->saveDSPSTRIDE,
+			crtc_state->saveDSPSIZE,
+			crtc_state->saveDSPPOS,
+			crtc_state->saveDSPBASE
+		);
+
+	paletteReg = pipeA ? PALETTE_A : PALETTE_B;
+	for (i = 0; i < 256; ++i)
+		crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
+}
+
+/**
+ * Restore HW states of giving crtc
+ */
+static void psb_intel_crtc_restore(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	/* struct drm_psb_private * dev_priv =
+				(struct drm_psb_private *)dev->dev_private; */
+	struct psb_intel_crtc *psb_intel_crtc =  to_psb_intel_crtc(crtc);
+	struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
+	/* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
+	int pipeA = (psb_intel_crtc->pipe == 0);
+	uint32_t paletteReg;
+	int i;
+
+	DRM_DEBUG("\n");
+
+	if (!crtc_state) {
+		DRM_DEBUG("No crtc state\n");
+		return;
+	}
+
+	DRM_DEBUG(
+		"current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
+		REG_READ(pipeA ? DSPACNTR : DSPBCNTR),
+		REG_READ(pipeA ? PIPEACONF : PIPEBCONF),
+		REG_READ(pipeA ? PIPEASRC : PIPEBSRC),
+		REG_READ(pipeA ? FPA0 : FPB0),
+		REG_READ(pipeA ? FPA1 : FPB1),
+		REG_READ(pipeA ? DPLL_A : DPLL_B),
+		REG_READ(pipeA ? HTOTAL_A : HTOTAL_B),
+		REG_READ(pipeA ? HBLANK_A : HBLANK_B),
+		REG_READ(pipeA ? HSYNC_A : HSYNC_B),
+		REG_READ(pipeA ? VTOTAL_A : VTOTAL_B),
+		REG_READ(pipeA ? VBLANK_A : VBLANK_B),
+		REG_READ(pipeA ? VSYNC_A : VSYNC_B),
+		REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE),
+		REG_READ(pipeA ? DSPASIZE : DSPBSIZE),
+		REG_READ(pipeA ? DSPAPOS : DSPBPOS),
+		REG_READ(pipeA ? DSPABASE : DSPBBASE)
+		);
+
+	DRM_DEBUG(
+		"saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
+		crtc_state->saveDSPCNTR,
+		crtc_state->savePIPECONF,
+		crtc_state->savePIPESRC,
+		crtc_state->saveFP0,
+		crtc_state->saveFP1,
+		crtc_state->saveDPLL,
+		crtc_state->saveHTOTAL,
+		crtc_state->saveHBLANK,
+		crtc_state->saveHSYNC,
+		crtc_state->saveVTOTAL,
+		crtc_state->saveVBLANK,
+		crtc_state->saveVSYNC,
+		crtc_state->saveDSPSTRIDE,
+		crtc_state->saveDSPSIZE,
+		crtc_state->saveDSPPOS,
+		crtc_state->saveDSPBASE
+		);
+
+
+#if 0
+	if (drm_helper_crtc_in_use(crtc))
+		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+
+
+	if (psb_intel_panel_fitter_pipe(dev) == psb_intel_crtc->pipe) {
+		REG_WRITE(PFIT_CONTROL, crtc_state->savePFITCTRL);
+		DRM_DEBUG("write pfit_controle: %x\n", REG_READ(PFIT_CONTROL));
+	}
+#endif
+
+	if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
+		REG_WRITE(pipeA ? DPLL_A : DPLL_B,
+			crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
+		REG_READ(pipeA ? DPLL_A : DPLL_B);
+		DRM_DEBUG("write dpll: %x\n",
+				REG_READ(pipeA ? DPLL_A : DPLL_B));
+		udelay(150);
+	}
+
+	REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
+	REG_READ(pipeA ? FPA0 : FPB0);
+
+	REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
+	REG_READ(pipeA ? FPA1 : FPB1);
+
+	REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
+	REG_READ(pipeA ? DPLL_A : DPLL_B);
+	udelay(150);
+
+	REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
+	REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
+	REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
+	REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
+	REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
+	REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
+	REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
+
+	REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
+	REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
+
+	REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
+	REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
+	REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
+
+	psb_intel_wait_for_vblank(dev);
+
+	REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
+	REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
+
+	psb_intel_wait_for_vblank(dev);
+
+	paletteReg = pipeA ? PALETTE_A : PALETTE_B;
+	for (i = 0; i < 256; ++i)
+		REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
+}
+
+static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
+				 struct drm_file *file_priv,
+				 uint32_t handle,
+				 uint32_t width, uint32_t height)
+{
+	struct drm_device *dev = crtc->dev;
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
+	int pipe = psb_intel_crtc->pipe;
+	uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
+	uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
+	uint32_t temp;
+	size_t addr = 0;
+	uint32_t page_offset;
+	size_t size;
+	void *bo;
+	int ret;
+
+	DRM_DEBUG("\n");
+
+	/* if we want to turn of the cursor ignore width and height */
+	if (!handle) {
+		DRM_DEBUG("cursor off\n");
+		/* turn off the cursor */
+		temp = 0;
+		temp |= CURSOR_MODE_DISABLE;
+
+		REG_WRITE(control, temp);
+		REG_WRITE(base, 0);
+
+		/* unpin the old bo */
+		if (psb_intel_crtc->cursor_bo) {
+			mode_dev->bo_unpin_for_scanout(dev,
+						       psb_intel_crtc->cursor_bo);
+			psb_intel_crtc->cursor_bo = NULL;
+		}
+
+		if (psb_intel_crtc->cursor_handle) {
+			psb_gtt_unmap_meminfo(dev, psb_intel_crtc->cursor_handle);
+			psb_intel_crtc->cursor_handle = NULL;
+		}
+
+		return 0;
+	}
+
+	/* Currently we only support 64x64 cursors */
+	if (width != 64 || height != 64) {
+		DRM_ERROR("we currently only support 64x64 cursors\n");
+		return -EINVAL;
+	}
+
+	bo = mode_dev->bo_from_handle(dev, file_priv, handle);
+	if (!bo)
+		return -ENOENT;
+
+	ret = mode_dev->bo_pin_for_scanout(dev, bo);
+	if (ret)
+		return ret;
+	size = mode_dev->bo_size(dev, bo);
+	if (size < width * height * 4) {
+		DRM_ERROR("buffer is to small\n");
+		return -ENOMEM;
+	}
+
+	/*insert this bo into gtt*/
+	DRM_DEBUG("%s: map meminfo for hw cursor. handle %x\n",
+						__func__, handle);
+
+	ret = psb_gtt_map_meminfo(dev, (IMG_HANDLE)handle, &page_offset);
+	if (ret) {
+		DRM_ERROR("Can not map meminfo to GTT. handle 0x%x\n", handle);
+		return ret;
+	}
+
+	addr = page_offset << PAGE_SHIFT;
+
+
+	psb_intel_crtc->cursor_addr = addr;
+
+	temp = 0;
+	/* set the pipe for the cursor */
+	temp |= (pipe << 28);
+	temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+
+	REG_WRITE(control, temp);
+	REG_WRITE(base, addr);
+
+	/* unpin the old bo */
+	if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo)
+		mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo);
+
+	psb_intel_crtc->cursor_bo = bo;
+
+	if (psb_intel_crtc->cursor_handle && psb_intel_crtc->cursor_handle != (void *)handle)
+		psb_gtt_unmap_meminfo(dev, psb_intel_crtc->cursor_handle);
+
+	psb_intel_crtc->cursor_handle = (IMG_HANDLE)handle;
+
+	return 0;
+}
+
+static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct drm_device *dev = crtc->dev;
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	int pipe = psb_intel_crtc->pipe;
+	uint32_t temp = 0;
+	uint32_t adder;
+
+
+	if (x < 0) {
+		temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
+		x = -x;
+	}
+	if (y < 0) {
+		temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
+		y = -y;
+	}
+
+	temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
+	temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
+
+	adder = psb_intel_crtc->cursor_addr;
+
+	REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
+	REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
+
+	return 0;
+}
+
+static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
+				 u16 *green, u16 *blue, uint32_t start, uint32_t size)
+{
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	int i;
+	int end = (start + size > 256) ? 256 : start + size;
+
+	for (i = start; i < end; i++) {
+		psb_intel_crtc->lut_r[i] = red[i] >> 8;
+		psb_intel_crtc->lut_g[i] = green[i] >> 8;
+		psb_intel_crtc->lut_b[i] = blue[i] >> 8;
+	}
+
+	psb_intel_crtc_load_lut(crtc);
+}
+
+static int psb_crtc_set_config(struct drm_mode_set *set)
+{
+	int ret = 0;
+	struct drm_device * dev = set->crtc->dev;
+	struct drm_psb_private * dev_priv = dev->dev_private;
+
+	if(!dev_priv->rpm_enabled)
+		return drm_crtc_helper_set_config(set);
+
+	pm_runtime_forbid(&dev->pdev->dev);
+
+	ret = drm_crtc_helper_set_config(set);
+
+	pm_runtime_allow(&dev->pdev->dev);
+
+	return ret;
+}
+
+/* Returns the clock of the currently programmed mode of the given pipe. */
+static int psb_intel_crtc_clock_get(struct drm_device *dev,
+				struct drm_crtc *crtc)
+{
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	int pipe = psb_intel_crtc->pipe;
+	u32 dpll;
+	u32 fp;
+	struct psb_intel_clock_t clock;
+	bool is_lvds;
+
+	dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
+	if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
+		fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
+	else
+		fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
+	is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
+
+	clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
+	clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
+	clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
+
+	if (is_lvds) {
+		clock.p1 =
+		    ffs((dpll &
+			 DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
+			DPLL_FPA01_P1_POST_DIV_SHIFT);
+		clock.p2 = 14;
+
+		if ((dpll & PLL_REF_INPUT_MASK) ==
+		    PLLB_REF_INPUT_SPREADSPECTRUMIN) {
+			/* XXX: might not be 66MHz */
+			i8xx_clock(66000, &clock);
+		} else
+			i8xx_clock(48000, &clock);
+	} else {
+		if (dpll & PLL_P1_DIVIDE_BY_TWO)
+			clock.p1 = 2;
+		else {
+			clock.p1 =
+			    ((dpll &
+			      DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
+			     DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
+		}
+		if (dpll & PLL_P2_DIVIDE_BY_4)
+			clock.p2 = 4;
+		else
+			clock.p2 = 2;
+
+		i8xx_clock(48000, &clock);
+	}
+
+	/* XXX: It would be nice to validate the clocks, but we can't reuse
+	 * i830PllIsValid() because it relies on the xf86_config connector
+	 * configuration being accurate, which it isn't necessarily.
+	 */
+
+	return clock.dot;
+}
+
+/** Returns the currently programmed mode of the given pipe. */
+struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
+					     struct drm_crtc *crtc)
+{
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	int pipe = psb_intel_crtc->pipe;
+	struct drm_display_mode *mode;
+	int htot;
+	int hsync;
+	int vtot;
+	int vsync;
+
+	htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
+	hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
+	vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
+	vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
+
+	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+	if (!mode)
+		return NULL;
+
+	mode->clock = psb_intel_crtc_clock_get(dev, crtc);
+	mode->hdisplay = (htot & 0xffff) + 1;
+	mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
+	mode->hsync_start = (hsync & 0xffff) + 1;
+	mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
+	mode->vdisplay = (vtot & 0xffff) + 1;
+	mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
+	mode->vsync_start = (vsync & 0xffff) + 1;
+	mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
+
+	drm_mode_set_name(mode);
+	drm_mode_set_crtcinfo(mode, 0);
+
+	return mode;
+}
+
+static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
+{
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+
+	kfree(psb_intel_crtc->crtc_state);
+	drm_crtc_cleanup(crtc);
+	kfree(psb_intel_crtc);
+}
+
+static const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
+	.dpms = psb_intel_crtc_dpms,
+	.mode_fixup = psb_intel_crtc_mode_fixup,
+	.mode_set = cdv_intel_crtc_mode_set,
+	.mode_set_base = psb_intel_pipe_set_base,
+	.prepare = psb_intel_crtc_prepare,
+	.commit = psb_intel_crtc_commit,
+};
+
+const struct drm_crtc_funcs psb_intel_crtc_funcs = {
+	.save = psb_intel_crtc_save,
+	.restore = psb_intel_crtc_restore,
+	.cursor_set = psb_intel_crtc_cursor_set,
+	.cursor_move = psb_intel_crtc_cursor_move,
+	.gamma_set = psb_intel_crtc_gamma_set,
+	.set_config = psb_crtc_set_config,
+	.destroy = psb_intel_crtc_destroy,
+};
+
+/*
+ * Set the default value of cursor control and base register
+ * to zero. This is a workaround for h/w defect on oaktrail
+ */
+void psb_intel_cursor_init(struct drm_device *dev, int pipe)
+{
+	uint32_t control;
+	uint32_t base;
+      
+	switch (pipe) {
+	case 0:
+		control = CURACNTR;
+		base = CURABASE;
+		break;
+	case 1:
+		control = CURBCNTR;
+		base = CURBBASE;
+		break;
+	case 2:
+		control = CURCCNTR;
+		base = CURCBASE;
+		break;
+	default:
+		return;
+	}
+
+	REG_WRITE(control, 0);
+	REG_WRITE(base, 0);
+}
+
+void psb_intel_crtc_init(struct drm_device *dev, int pipe,
+			 struct psb_intel_mode_device *mode_dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct psb_intel_crtc *psb_intel_crtc;
+	int i;
+	uint16_t *r_base, *g_base, *b_base;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	/* We allocate a extra array of drm_connector pointers
+	 * for fbdev after the crtc */
+	psb_intel_crtc = kzalloc(sizeof(struct psb_intel_crtc) +
+				 (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)),
+				 GFP_KERNEL);
+	if (psb_intel_crtc == NULL)
+		return;
+
+	psb_intel_crtc->crtc_state = kzalloc(sizeof(struct psb_intel_crtc_state),
+					     GFP_KERNEL);
+	if (!psb_intel_crtc->crtc_state) {
+		DRM_ERROR("Crtc state error: No memory\n");
+		kfree(psb_intel_crtc);
+		return;
+	}
+
+	drm_crtc_init(dev, &psb_intel_crtc->base, &psb_intel_crtc_funcs);
+
+	drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256);
+	psb_intel_crtc->pipe = pipe;
+	psb_intel_crtc->plane = pipe;
+	psb_intel_crtc->active = true;
+
+	r_base = psb_intel_crtc->base.gamma_store;
+	g_base = r_base + 256;
+	b_base = g_base + 256;
+	for (i = 0; i < 256; i++) {
+		psb_intel_crtc->lut_r[i] = i;
+		psb_intel_crtc->lut_g[i] = i;
+		psb_intel_crtc->lut_b[i] = i;
+		r_base[i] = i << 8;
+		g_base[i] = i << 8;
+		b_base[i] = i << 8;
+
+		psb_intel_crtc->lut_adj[i] = 0;
+	}
+
+	psb_intel_crtc->mode_dev = mode_dev;
+	psb_intel_crtc->cursor_addr = 0;
+
+	drm_crtc_helper_add(&psb_intel_crtc->base,
+			    &cdv_intel_helper_funcs);
+
+	/* Setup the array of drm_connector pointer array */
+	psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base;
+	BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
+	       dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] != NULL);
+	dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] = &psb_intel_crtc->base;
+	dev_priv->pipe_to_crtc_mapping[psb_intel_crtc->pipe] = &psb_intel_crtc->base;
+	psb_intel_crtc->mode_set.connectors =
+	    (struct drm_connector **) (psb_intel_crtc + 1);
+	psb_intel_crtc->mode_set.num_connectors = 0;
+
+	psb_intel_cursor_init(dev, pipe);
+
+	if (pipe == 0) {
+		init_timer(&dev_priv->flip_timer);
+		dev_priv->flip_timer.function = psb_flip_timer;
+		dev_priv->flip_timer.data = (unsigned long)dev;
+		dev_priv->pipeEnabled = 0;
+	}
+}
+
+int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct drm_psb_get_pipe_from_crtc_id_arg *pipe_from_crtc_id = data;
+	struct drm_mode_object *drmmode_obj;
+	struct psb_intel_crtc *crtc;
+
+	if (!dev_priv) {
+		DRM_ERROR("called with no initialization\n");
+		return -EINVAL;
+	}
+
+	drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
+			DRM_MODE_OBJECT_CRTC);
+
+	if (!drmmode_obj) {
+		DRM_ERROR("no such CRTC id\n");
+		return -EINVAL;
+	}
+
+	crtc = to_psb_intel_crtc(obj_to_crtc(drmmode_obj));
+	pipe_from_crtc_id->pipe = crtc->pipe;
+
+	return 0;
+}
+
+struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
+{
+	struct drm_crtc *crtc = NULL;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+		if (psb_intel_crtc->pipe == pipe)
+			break;
+	}
+	return crtc;
+}
+
+int psb_intel_connector_clones(struct drm_device *dev, int type_mask)
+{
+	int index_mask = 0;
+	struct drm_connector *connector;
+	int entry = 0;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list,
+			    head) {
+		struct psb_intel_output *psb_intel_output =
+		    to_psb_intel_output(connector);
+		if (type_mask & (1 << psb_intel_output->type))
+			index_mask |= (1 << entry);
+		entry++;
+	}
+	return index_mask;
+}
+
+void psb_intel_modeset_cleanup(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	del_timer_sync(&dev_priv->flip_timer);
+
+	drm_mode_config_cleanup(dev);
+}
+
+
+/* current intel driver doesn't take advantage of encoders
+   always give back the encoder for the connector
+*/
+struct drm_encoder *psb_intel_best_encoder(struct drm_connector *connector)
+{
+	struct psb_intel_output *psb_intel_output =
+					to_psb_intel_output(connector);
+
+	return &psb_intel_output->enc;
+}
+
+
diff --git a/drivers/staging/cdv/drv/psb_intel_display.h b/drivers/staging/cdv/drv/psb_intel_display.h
new file mode 100644
index 0000000..8e90e05
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_display.h
@@ -0,0 +1,25 @@
+/* copyright (c) 2011, Intel Corporation
+ * 
+ * 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 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.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ */
+
+#ifndef _INTEL_DISPLAY_H_
+#define _INTEL_DISPLAY_H_
+
+bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type);
+
+#endif
diff --git a/drivers/staging/cdv/drv/psb_intel_dp.c b/drivers/staging/cdv/drv/psb_intel_dp.c
new file mode 100644
index 0000000..daf1ac1
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_dp.c
@@ -0,0 +1,1905 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_drm.h"
+#include "psb_intel_reg.h"
+#include "drm_dp_helper.h"
+#include "psb_intel_bios.h"
+
+
+#define DP_LINK_STATUS_SIZE	6
+#define DP_LINK_CHECK_TIMEOUT	(10 * 1000)
+
+#define DP_LINK_CONFIGURATION_SIZE	9
+
+#define CDV_FAST_LINK_TRAIN	1
+
+struct psb_intel_dp {
+	uint32_t output_reg;
+	uint32_t DP;
+	uint8_t  link_configuration[DP_LINK_CONFIGURATION_SIZE];
+	bool has_audio;
+	int force_audio;
+	uint32_t color_range;
+	uint8_t link_bw;
+	uint8_t lane_count;
+	uint8_t dpcd[4];
+	struct psb_intel_output *output;
+	struct i2c_adapter adapter;
+	struct i2c_algo_dp_aux_data algo;
+	uint8_t	train_set[4];
+	uint8_t link_status[DP_LINK_STATUS_SIZE];
+	int panel_power_up_delay;
+	int panel_power_down_delay;
+	int panel_power_cycle_delay;
+	int backlight_on_delay;
+	int backlight_off_delay;
+	struct drm_display_mode *panel_fixed_mode;  /* for eDP */
+	bool panel_on;
+};
+
+struct ddi_regoff {
+	uint32_t	PreEmph1;
+	uint32_t	PreEmph2;
+	uint32_t	VSwing1;
+	uint32_t	VSwing2;
+	uint32_t	VSwing3;
+	uint32_t	VSwing4;
+	uint32_t	VSwing5;
+};
+
+static struct ddi_regoff ddi_DP_train_table[] = {
+	{.PreEmph1 = 0x812c, .PreEmph2 = 0x8124, .VSwing1 = 0x8154,
+	.VSwing2 = 0x8148, .VSwing3 = 0x814C, .VSwing4 = 0x8150,
+	.VSwing5 = 0x8158,},
+	{.PreEmph1 = 0x822c, .PreEmph2 = 0x8224, .VSwing1 = 0x8254,
+	.VSwing2 = 0x8248, .VSwing3 = 0x824C, .VSwing4 = 0x8250,
+	.VSwing5 = 0x8258,},
+};
+
+static uint32_t dp_vswing_premph_table[] = {
+        0x55338954,	0x4000,
+        0x554d8954,	0x2000,
+        0x55668954,	0,
+        0x559ac0d4,	0x6000,
+};
+/**
+ * is_edp - is the given port attached to an eDP panel (either CPU or PCH)
+ * @intel_dp: DP struct
+ *
+ * If a CPU or PCH DP output is attached to an eDP panel, this function
+ * will return true, and false otherwise.
+ */
+static bool is_edp(struct psb_intel_output *output)
+{
+	return output->type == INTEL_OUTPUT_EDP;
+}
+
+
+static void psb_intel_dp_start_link_train(struct psb_intel_output *output);
+static void psb_intel_dp_complete_link_train(struct psb_intel_output *output);
+static void psb_intel_dp_link_down(struct psb_intel_output *output);
+
+static int
+psb_intel_dp_max_lane_count(struct psb_intel_output *output)
+{
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	int max_lane_count = 4;
+
+	if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
+		max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
+		switch (max_lane_count) {
+		case 1: case 2: case 4:
+			break;
+		default:
+			max_lane_count = 4;
+		}
+	}
+	return max_lane_count;
+}
+
+static int
+psb_intel_dp_max_link_bw(struct psb_intel_output *output)
+{
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE];
+
+	switch (max_link_bw) {
+	case DP_LINK_BW_1_62:
+	case DP_LINK_BW_2_7:
+		break;
+	default:
+		max_link_bw = DP_LINK_BW_1_62;
+		break;
+	}
+	return max_link_bw;
+}
+
+static int
+psb_intel_dp_link_clock(uint8_t link_bw)
+{
+	if (link_bw == DP_LINK_BW_2_7)
+		return 270000;
+	else
+		return 162000;
+}
+
+static int
+psb_intel_dp_link_required(int pixel_clock, int bpp)
+{
+	return (pixel_clock * bpp + 7) / 8;
+}
+
+static int
+psb_intel_dp_max_data_rate(int max_link_clock, int max_lanes)
+{
+	return (max_link_clock * max_lanes * 19) / 20;
+}
+
+static void psb_intel_edp_panel_vdd_on(struct psb_intel_output *intel_output)
+{
+	struct drm_device *dev = intel_output->base.dev;
+	struct psb_intel_dp *intel_dp = intel_output->dev_priv;
+	u32 pp;
+
+	if (intel_dp->panel_on) {
+		DRM_DEBUG_KMS("Skip VDD on because of panel on\n");
+		return;
+	}	
+	DRM_DEBUG_KMS("\n");
+
+	pp = REG_READ(PP_CONTROL);
+
+	pp |= EDP_FORCE_VDD;
+	REG_WRITE(PP_CONTROL, pp);
+	REG_READ(PP_CONTROL);
+	msleep(intel_dp->panel_power_up_delay);
+}
+
+static void psb_intel_edp_panel_vdd_off(struct psb_intel_output *intel_output)
+{
+	struct drm_device *dev = intel_output->base.dev;
+	u32 pp;
+
+
+	DRM_DEBUG_KMS("\n");
+	pp = REG_READ(PP_CONTROL);
+
+	pp &= ~EDP_FORCE_VDD;
+	REG_WRITE(PP_CONTROL, pp);
+	REG_READ(PP_CONTROL);
+
+}
+
+/* Returns true if the panel was already on when called */
+static bool psb_intel_edp_panel_on (struct psb_intel_output *intel_output)
+{
+	struct drm_device *dev = intel_output->base.dev;
+	struct psb_intel_dp *intel_dp = intel_output->dev_priv;
+	u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_NONE;
+
+
+	if (intel_dp->panel_on)
+		return true;
+
+	DRM_DEBUG_KMS("\n");
+	pp = REG_READ(PP_CONTROL);
+	pp &= ~PANEL_UNLOCK_MASK;
+
+	pp |= (PANEL_UNLOCK_REGS | POWER_TARGET_ON);
+	REG_WRITE(PP_CONTROL, pp);
+	REG_READ(PP_CONTROL);
+
+	if (wait_for(((REG_READ(PP_STATUS) & idle_on_mask) == idle_on_mask), 1000)) {
+		DRM_DEBUG_KMS("Error in Powering up eDP panel, status %x\n", REG_READ(PP_STATUS));
+		intel_dp->panel_on = false;
+	} else
+		intel_dp->panel_on = true;	
+	msleep(intel_dp->panel_power_up_delay);
+
+	return false;
+}
+
+static void psb_intel_edp_panel_off (struct psb_intel_output *intel_output)
+{
+	struct drm_device *dev = intel_output->base.dev;
+	u32 pp, idle_off_mask = PP_ON ;
+	struct psb_intel_dp *intel_dp = intel_output->dev_priv;
+
+	DRM_DEBUG_KMS("\n");
+
+	pp = REG_READ(PP_CONTROL);
+
+	if ((pp & POWER_TARGET_ON) == 0) 
+		return;
+
+	intel_dp->panel_on = false;
+	pp &= ~PANEL_UNLOCK_MASK;
+	/* ILK workaround: disable reset around power sequence */
+
+	pp &= ~POWER_TARGET_ON;
+	pp &= ~EDP_FORCE_VDD;
+	pp &= ~EDP_BLC_ENABLE;
+	REG_WRITE(PP_CONTROL, pp);
+	REG_READ(PP_CONTROL);
+	DRM_DEBUG_KMS("PP_STATUS %x\n", REG_READ(PP_STATUS));
+
+	if (wait_for((REG_READ(PP_STATUS) & idle_off_mask) == 0, 1000)) {
+		DRM_DEBUG_KMS("Error in turning off Panel\n");	
+	}
+
+	msleep(intel_dp->panel_power_cycle_delay);
+	DRM_DEBUG_KMS("Over\n");
+}
+
+static void psb_intel_edp_backlight_on (struct psb_intel_output *intel_output)
+{
+	struct drm_device *dev = intel_output->base.dev;
+	u32 pp;
+
+	DRM_DEBUG_KMS("\n");
+	/*
+	 * If we enable the backlight right away following a panel power
+	 * on, we may see slight flicker as the panel syncs with the eDP
+	 * link.  So delay a bit to make sure the image is solid before
+	 * allowing it to appear.
+	 */
+	msleep(300);
+	pp = REG_READ(PP_CONTROL);
+
+	pp |= EDP_BLC_ENABLE;
+	REG_WRITE(PP_CONTROL, pp);
+	psb_intel_panel_enable_backlight(dev);
+}
+
+static void psb_intel_edp_backlight_off (struct psb_intel_output *intel_output)
+{
+	struct drm_device *dev = intel_output->base.dev;
+	struct psb_intel_dp *intel_dp = intel_output->dev_priv;
+	u32 pp;
+
+	DRM_DEBUG_KMS("\n");
+	psb_intel_panel_disable_backlight(dev);
+	msleep(10);
+	pp = REG_READ(PP_CONTROL);
+
+	pp &= ~EDP_BLC_ENABLE;
+	REG_WRITE(PP_CONTROL, pp);
+	msleep(intel_dp->backlight_off_delay);
+}
+
+static int
+psb_intel_dp_mode_valid(struct drm_connector *connector,
+		    struct drm_display_mode *mode)
+{
+	struct psb_intel_output *output = to_psb_intel_output(connector);
+	int max_link_clock = psb_intel_dp_link_clock(psb_intel_dp_max_link_bw(output));
+	int max_lanes = psb_intel_dp_max_lane_count(output);
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	struct drm_psb_private *dev_priv = connector->dev->dev_private;
+
+	if (is_edp(output) && intel_dp->panel_fixed_mode) {
+		if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
+			return MODE_PANEL;
+
+		if (mode->vdisplay > intel_dp->panel_fixed_mode->vdisplay)
+			return MODE_PANEL;
+	}
+
+	/* only refuse the mode on non eDP since we have seen some weird eDP panels
+	   which are outside spec tolerances but somehow work by magic */
+	if (!is_edp(output) &&
+	    (psb_intel_dp_link_required(mode->clock, 24)
+	     > psb_intel_dp_max_data_rate(max_link_clock, max_lanes)))
+		return MODE_CLOCK_HIGH;
+
+	if (is_edp(output)) {
+	    if (psb_intel_dp_link_required(mode->clock, dev_priv->edp.bpp)
+	     	> psb_intel_dp_max_data_rate(max_link_clock, max_lanes))
+		return MODE_CLOCK_HIGH;
+		
+	}
+	if (mode->clock < 10000)
+		return MODE_CLOCK_LOW;
+
+	return MODE_OK;
+}
+
+static uint32_t
+pack_aux(uint8_t *src, int src_bytes)
+{
+	int	i;
+	uint32_t v = 0;
+
+	if (src_bytes > 4)
+		src_bytes = 4;
+	for (i = 0; i < src_bytes; i++)
+		v |= ((uint32_t) src[i]) << ((3-i) * 8);
+	return v;
+}
+
+static void
+unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes)
+{
+	int i;
+	if (dst_bytes > 4)
+		dst_bytes = 4;
+	for (i = 0; i < dst_bytes; i++)
+		dst[i] = src >> ((3-i) * 8);
+}
+
+static int
+psb_intel_dp_aux_ch(struct psb_intel_output *output,
+		uint8_t *send, int send_bytes,
+		uint8_t *recv, int recv_size)
+{
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	uint32_t output_reg = intel_dp->output_reg;
+	struct drm_device *dev = output->base.dev;
+	uint32_t ch_ctl = output_reg + 0x10;
+	uint32_t ch_data = ch_ctl + 4;
+	int i;
+	int recv_bytes;
+	uint32_t status;
+	uint32_t aux_clock_divider;
+	int try, precharge;
+
+	/* The clock divider is based off the hrawclk,
+	 * and would like to run at 2MHz. So, take the
+	 * hrawclk value and divide by 2 and use that
+	 * On CDV platform it uses 200MHz as hrawclk.
+	 *
+	 */
+	aux_clock_divider = 200 / 2;
+
+	precharge = 4;
+
+	if (is_edp(output))
+		precharge = 10;
+
+	if (REG_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) {
+		DRM_ERROR("dp_aux_ch not started status 0x%08x\n",
+			  REG_READ(ch_ctl));
+		return -EBUSY;
+	}
+
+	/* Must try at least 3 times according to DP spec */
+	for (try = 0; try < 5; try++) {
+		/* Load the send data into the aux channel data registers */
+		for (i = 0; i < send_bytes; i += 4)
+			REG_WRITE(ch_data + i,
+				   pack_aux(send + i, send_bytes - i));
+	
+		/* Send the command and wait for it to complete */
+		REG_WRITE(ch_ctl,
+			   DP_AUX_CH_CTL_SEND_BUSY |
+			   DP_AUX_CH_CTL_TIME_OUT_400us |
+			   (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
+			   (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
+			   (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
+			   DP_AUX_CH_CTL_DONE |
+			   DP_AUX_CH_CTL_TIME_OUT_ERROR |
+			   DP_AUX_CH_CTL_RECEIVE_ERROR);
+		for (;;) {
+			status = REG_READ(ch_ctl);
+			if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
+				break;
+			udelay(100);
+		}
+	
+		/* Clear done status and any errors */
+		REG_WRITE(ch_ctl,
+			   status |
+			   DP_AUX_CH_CTL_DONE |
+			   DP_AUX_CH_CTL_TIME_OUT_ERROR |
+			   DP_AUX_CH_CTL_RECEIVE_ERROR);
+		if (status & DP_AUX_CH_CTL_DONE)
+			break;
+	}
+
+	if ((status & DP_AUX_CH_CTL_DONE) == 0) {
+		DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status);
+		return -EBUSY;
+	}
+
+	/* Check for timeout or receive error.
+	 * Timeouts occur when the sink is not connected
+	 */
+	if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) {
+		DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status);
+		return -EIO;
+	}
+
+	/* Timeouts occur when the device isn't connected, so they're
+	 * "normal" -- don't fill the kernel log with these */
+	if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
+		DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status);
+		return -ETIMEDOUT;
+	}
+
+	/* Unload any bytes sent back from the other side */
+	recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >>
+		      DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
+	if (recv_bytes > recv_size)
+		recv_bytes = recv_size;
+	
+	for (i = 0; i < recv_bytes; i += 4)
+		unpack_aux(REG_READ(ch_data + i),
+			   recv + i, recv_bytes - i);
+
+	return recv_bytes;
+}
+
+/* Write data to the aux channel in native mode */
+static int
+psb_intel_dp_aux_native_write(struct psb_intel_output *output,
+			  uint16_t address, uint8_t *send, int send_bytes)
+{
+	int ret;
+	uint8_t	msg[20];
+	int msg_bytes;
+	uint8_t	ack;
+
+	if (send_bytes > 16)
+		return -1;
+	msg[0] = AUX_NATIVE_WRITE << 4;
+	msg[1] = address >> 8;
+	msg[2] = address & 0xff;
+	msg[3] = send_bytes - 1;
+	memcpy(&msg[4], send, send_bytes);
+	msg_bytes = send_bytes + 4;
+	for (;;) {
+		ret = psb_intel_dp_aux_ch(output, msg, msg_bytes, &ack, 1);
+		if (ret < 0)
+			return ret;
+		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
+			break;
+		else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
+			udelay(100);
+		else
+			return -EIO;
+	}
+	return send_bytes;
+}
+
+/* Write a single byte to the aux channel in native mode */
+static int
+psb_intel_dp_aux_native_write_1(struct psb_intel_output *output,
+			    uint16_t address, uint8_t byte)
+{
+	return psb_intel_dp_aux_native_write(output, address, &byte, 1);
+}
+
+/* read bytes from a native aux channel */
+static int
+psb_intel_dp_aux_native_read(struct psb_intel_output *output,
+			 uint16_t address, uint8_t *recv, int recv_bytes)
+{
+	uint8_t msg[4];
+	int msg_bytes;
+	uint8_t reply[20];
+	int reply_bytes;
+	uint8_t ack;
+	int ret;
+
+	msg[0] = AUX_NATIVE_READ << 4;
+	msg[1] = address >> 8;
+	msg[2] = address & 0xff;
+	msg[3] = recv_bytes - 1;
+
+	msg_bytes = 4;
+	reply_bytes = recv_bytes + 1;
+
+	for (;;) {
+		ret = psb_intel_dp_aux_ch(output, msg, msg_bytes,
+				      reply, reply_bytes);
+		if (ret == 0)
+			return -EPROTO;
+		if (ret < 0)
+			return ret;
+		ack = reply[0];
+		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) {
+			memcpy(recv, reply + 1, ret - 1);
+			return ret - 1;
+		}
+		else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
+			udelay(100);
+		else
+			return -EIO;
+	}
+}
+
+static int
+psb_intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+		    uint8_t write_byte, uint8_t *read_byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	struct psb_intel_dp *intel_dp = container_of(adapter,
+						struct psb_intel_dp,
+						adapter);
+	struct psb_intel_output *output = intel_dp->output;
+	uint16_t address = algo_data->address;
+	uint8_t msg[5];
+	uint8_t reply[2];
+	unsigned retry;
+	int msg_bytes;
+	int reply_bytes;
+	int ret;
+
+	/* Set up the command byte */
+	if (mode & MODE_I2C_READ)
+		msg[0] = AUX_I2C_READ << 4;
+	else
+		msg[0] = AUX_I2C_WRITE << 4;
+
+	if (!(mode & MODE_I2C_STOP))
+		msg[0] |= AUX_I2C_MOT << 4;
+
+	msg[1] = address >> 8;
+	msg[2] = address;
+
+	switch (mode) {
+	case MODE_I2C_WRITE:
+		msg[3] = 0;
+		msg[4] = write_byte;
+		msg_bytes = 5;
+		reply_bytes = 1;
+		break;
+	case MODE_I2C_READ:
+		msg[3] = 0;
+		msg_bytes = 4;
+		reply_bytes = 2;
+		break;
+	default:
+		msg_bytes = 3;
+		reply_bytes = 1;
+		break;
+	}
+
+	for (retry = 0; retry < 5; retry++) {
+		ret = psb_intel_dp_aux_ch(output,
+				      msg, msg_bytes,
+				      reply, reply_bytes);
+		if (ret < 0) {
+			DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
+			return ret;
+		}
+
+		switch (reply[0] & AUX_NATIVE_REPLY_MASK) {
+		case AUX_NATIVE_REPLY_ACK:
+			/* I2C-over-AUX Reply field is only valid
+			 * when paired with AUX ACK.
+			 */
+			break;
+		case AUX_NATIVE_REPLY_NACK:
+			DRM_DEBUG_KMS("aux_ch native nack\n");
+			return -EREMOTEIO;
+		case AUX_NATIVE_REPLY_DEFER:
+			udelay(100);
+			continue;
+		default:
+			DRM_ERROR("aux_ch invalid native reply 0x%02x\n",
+				  reply[0]);
+			return -EREMOTEIO;
+		}
+
+		switch (reply[0] & AUX_I2C_REPLY_MASK) {
+		case AUX_I2C_REPLY_ACK:
+			if (mode == MODE_I2C_READ) {
+				*read_byte = reply[1];
+			}
+			return reply_bytes - 1;
+		case AUX_I2C_REPLY_NACK:
+			DRM_DEBUG_KMS("aux_i2c nack\n");
+			return -EREMOTEIO;
+		case AUX_I2C_REPLY_DEFER:
+			DRM_DEBUG_KMS("aux_i2c defer\n");
+			udelay(100);
+			break;
+		default:
+			DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]);
+			return -EREMOTEIO;
+		}
+	}
+
+	DRM_ERROR("too many retries, giving up\n");
+	return -EREMOTEIO;
+}
+
+static int
+psb_intel_dp_i2c_init(struct psb_intel_output *output, const char *name)
+{
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	int ret;
+	DRM_DEBUG_KMS("i2c_init %s\n", name);
+	intel_dp->algo.running = false;
+	intel_dp->algo.address = 0;
+	intel_dp->algo.aux_ch = psb_intel_dp_i2c_aux_ch;
+
+	memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter));
+	intel_dp->adapter.owner = THIS_MODULE;
+	intel_dp->adapter.class = I2C_CLASS_DDC;
+	strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
+	intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
+	intel_dp->adapter.algo_data = &intel_dp->algo;
+	intel_dp->adapter.dev.parent = &output->base.kdev;
+	
+	if (is_edp(output))
+		psb_intel_edp_panel_vdd_on(output);
+	ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
+	if (is_edp(output))
+		psb_intel_edp_panel_vdd_off(output);
+	
+	return ret;
+}
+
+static bool
+psb_intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		    struct drm_display_mode *adjusted_mode)
+{
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	int lane_count, clock;
+	int max_lane_count = psb_intel_dp_max_lane_count(output);
+	int max_clock = psb_intel_dp_max_link_bw(output) == DP_LINK_BW_2_7 ? 1 : 0;
+	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
+	int bpp = 24;
+	struct drm_psb_private *dev_priv = encoder->dev->dev_private;
+
+	if (is_edp(output) && intel_dp->panel_fixed_mode) {
+		psb_intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode);
+		mode->clock = intel_dp->panel_fixed_mode->clock;
+		bpp = dev_priv->edp.bpp;
+	}
+
+	for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
+		for (clock = max_clock; clock >= 0; clock--) {
+			int link_avail = psb_intel_dp_max_data_rate(psb_intel_dp_link_clock(bws[clock]), lane_count);
+
+			if (psb_intel_dp_link_required(mode->clock, bpp)
+					<= link_avail) {
+				intel_dp->link_bw = bws[clock];
+				intel_dp->lane_count = lane_count;
+				adjusted_mode->clock = psb_intel_dp_link_clock(intel_dp->link_bw);
+				DRM_DEBUG_KMS("Display port link bw %02x lane "
+						"count %d clock %d\n",
+				       intel_dp->link_bw, intel_dp->lane_count,
+				       adjusted_mode->clock);
+				return true;
+			}
+		}
+	}
+	if (is_edp(output)) {
+		/* okay we failed just pick the highest */
+		intel_dp->lane_count = max_lane_count;
+		intel_dp->link_bw = bws[max_clock];
+		adjusted_mode->clock = psb_intel_dp_link_clock(intel_dp->link_bw);
+		DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
+			      "count %d clock %d\n",
+			      intel_dp->link_bw, intel_dp->lane_count,
+			      adjusted_mode->clock);
+
+		return true;
+	}
+	return false;
+}
+
+struct psb_intel_dp_m_n {
+	uint32_t	tu;
+	uint32_t	gmch_m;
+	uint32_t	gmch_n;
+	uint32_t	link_m;
+	uint32_t	link_n;
+};
+
+static void
+psb_intel_reduce_ratio(uint32_t *num, uint32_t *den)
+{
+	/*
+	while (*num > 0xffffff || *den > 0xffffff) {
+		*num >>= 1;
+		*den >>= 1;
+	}*/
+	uint64_t value, m;
+	m = *num;
+	value = m * (0x800000);
+	m = do_div(value, *den);
+	*num = value;
+	*den = 0x800000;
+}
+
+static void
+psb_intel_dp_compute_m_n(int bpp,
+		     int nlanes,
+		     int pixel_clock,
+		     int link_clock,
+		     struct psb_intel_dp_m_n *m_n)
+{
+	m_n->tu = 64;
+	m_n->gmch_m = (pixel_clock * bpp + 7) >> 3;
+	m_n->gmch_n = link_clock * nlanes;
+	psb_intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
+	m_n->link_m = pixel_clock;
+	m_n->link_n = link_clock;
+	psb_intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
+}
+
+void
+psb_intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
+		 struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct drm_encoder *encoder;
+	struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
+	int lane_count = 4, bpp = 24;
+	struct psb_intel_dp_m_n m_n;
+	int pipe = intel_crtc->pipe;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	/*
+	 * Find the lane count in the intel_encoder private
+	 */
+	list_for_each_entry(encoder, &mode_config->encoder_list, head) {
+		struct psb_intel_output *intel_output;
+		struct psb_intel_dp *intel_dp;
+
+		if (encoder->crtc != crtc)
+			continue;
+
+		intel_output = enc_to_psb_intel_output(encoder);
+		intel_dp = intel_output->dev_priv;
+		if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) {
+			lane_count = intel_dp->lane_count;
+			break;
+		} else if (is_edp(intel_output)) {
+			lane_count = intel_dp->lane_count;
+			bpp = dev_priv->edp.bpp;
+			break;
+		}
+	}
+
+	/*
+	 * Compute the GMCH and Link ratios. The '3' here is
+	 * the number of bytes_per_pixel post-LUT, which we always
+	 * set up for 8-bits of R/G/B, or 3 bytes total.
+	 */
+	psb_intel_dp_compute_m_n(bpp, lane_count,
+			     mode->clock, adjusted_mode->clock, &m_n);
+
+	{
+		REG_WRITE(PIPE_GMCH_DATA_M(pipe),
+			   ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
+			   m_n.gmch_m);
+		REG_WRITE(PIPE_GMCH_DATA_N(pipe), m_n.gmch_n);
+		REG_WRITE(PIPE_DP_LINK_M(pipe), m_n.link_m);
+		REG_WRITE(PIPE_DP_LINK_N(pipe), m_n.link_n);
+	}
+}
+
+static void
+psb_intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		  struct drm_display_mode *adjusted_mode)
+{
+	struct psb_intel_output *intel_output = enc_to_psb_intel_output(encoder);
+	struct drm_crtc *crtc = encoder->crtc;
+	struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
+	struct psb_intel_dp *intel_dp = intel_output->dev_priv;
+	struct drm_device *dev = encoder->dev;
+
+	intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
+	intel_dp->DP |= intel_dp->color_range;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		intel_dp->DP |= DP_SYNC_HS_HIGH;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		intel_dp->DP |= DP_SYNC_VS_HIGH;
+
+	intel_dp->DP |= DP_LINK_TRAIN_OFF;
+
+	switch (intel_dp->lane_count) {
+	case 1:
+		intel_dp->DP |= DP_PORT_WIDTH_1;
+		break;
+	case 2:
+		intel_dp->DP |= DP_PORT_WIDTH_2;
+		break;
+	case 4:
+		intel_dp->DP |= DP_PORT_WIDTH_4;
+		break;
+	}
+	if (intel_dp->has_audio)
+		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
+
+	memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
+	intel_dp->link_configuration[0] = intel_dp->link_bw;
+	intel_dp->link_configuration[1] = intel_dp->lane_count;
+
+	/*
+	 * Check for DPCD version > 1.1 and enhanced framing support
+	 */
+	if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+	    (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
+		intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+		intel_dp->DP |= DP_ENHANCED_FRAMING;
+	}
+
+	/* CPT DP's pipe select is decided in TRANS_DP_CTL */
+	if (intel_crtc->pipe == 1)
+		intel_dp->DP |= DP_PIPEB_SELECT;
+
+	REG_WRITE(intel_dp->output_reg, (intel_dp->DP | DP_PORT_EN));
+	DRM_DEBUG_KMS("DP expected reg is %x\n", intel_dp->DP);
+	if (is_edp(intel_output)) {
+		uint32_t pfit_control;
+		psb_intel_edp_panel_on(intel_output);
+
+		if (mode->hdisplay != adjusted_mode->hdisplay ||
+			    mode->vdisplay != adjusted_mode->vdisplay)
+			pfit_control = PFIT_ENABLE;
+		else
+			pfit_control = 0;
+
+		pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
+
+		REG_WRITE(PFIT_CONTROL, pfit_control);
+	}
+}
+
+
+/* If the sink supports it, try to set the power state appropriately */
+static void psb_intel_dp_sink_dpms(struct psb_intel_output *output, int mode)
+{
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	int ret, i;
+
+	/* Should have a valid DPCD by this point */
+	if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
+		return;
+
+	if (mode != DRM_MODE_DPMS_ON) {
+		ret = psb_intel_dp_aux_native_write_1(output, DP_SET_POWER,
+						  DP_SET_POWER_D3);
+		if (ret != 1)
+			DRM_DEBUG_DRIVER("failed to write sink power state\n");
+	} else {
+		/*
+		 * When turning on, we need to retry for 1ms to give the sink
+		 * time to wake up.
+		 */
+		for (i = 0; i < 3; i++) {
+			ret = psb_intel_dp_aux_native_write_1(output,
+							  DP_SET_POWER,
+							  DP_SET_POWER_D0);
+			if (ret == 1)
+				break;
+			udelay(1000);
+		}
+	}
+}
+
+static void psb_intel_dp_prepare(struct drm_encoder *encoder)
+{
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+
+	if (is_edp(output)) {
+		psb_intel_edp_backlight_off(output);
+		psb_intel_edp_panel_off(output);
+	}
+	if (is_edp(output))
+		psb_intel_edp_panel_vdd_on(output);
+	/* Wake up the sink first */
+	psb_intel_dp_sink_dpms(output, DRM_MODE_DPMS_ON);
+	psb_intel_dp_link_down(output);
+
+	if (is_edp(output))
+		psb_intel_edp_panel_vdd_off(output);
+}
+
+static void psb_intel_dp_commit(struct drm_encoder *encoder)
+{
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+
+	if (is_edp(output)) {
+		psb_intel_edp_panel_on(output);
+	}
+
+	psb_intel_dp_start_link_train(output);
+	psb_intel_dp_complete_link_train(output);
+
+	if (is_edp(output)) {
+		psb_intel_edp_backlight_on(output);
+	}
+}
+
+static void
+psb_intel_dp_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct psb_intel_output *intel_output = enc_to_psb_intel_output(encoder);
+	struct psb_intel_dp *intel_dp = intel_output->dev_priv;
+	struct drm_device *dev = encoder->dev;
+	uint32_t dp_reg = REG_READ(intel_dp->output_reg);
+
+	if (mode != DRM_MODE_DPMS_ON) {
+		if (is_edp(intel_output)) {
+			psb_intel_edp_backlight_off(intel_output);
+			psb_intel_edp_panel_vdd_on(intel_output);
+		}
+		psb_intel_dp_sink_dpms(intel_output, mode);
+		psb_intel_dp_link_down(intel_output);
+
+		if (is_edp(intel_output)) {
+			psb_intel_edp_panel_vdd_off(intel_output);
+			psb_intel_edp_panel_off(intel_output);
+		}
+	} else {
+		if (is_edp(intel_output)) {
+			psb_intel_edp_panel_on(intel_output);
+		}
+
+		psb_intel_dp_sink_dpms(intel_output, mode);
+		if (!(dp_reg & DP_PORT_EN)) {
+			psb_intel_dp_start_link_train(intel_output);
+			psb_intel_dp_complete_link_train(intel_output);
+		}
+		if (is_edp(intel_output)) {
+			psb_intel_edp_backlight_on(intel_output);
+		}
+	}
+}
+
+/*
+ * Native read with retry for link status and receiver capability reads for
+ * cases where the sink may still be asleep.
+ */
+static bool
+psb_intel_dp_aux_native_read_retry(struct psb_intel_output *output, uint16_t address,
+			       uint8_t *recv, int recv_bytes)
+{
+	int ret, i;
+
+	/*
+	 * Sinks are *supposed* to come up within 1ms from an off state,
+	 * but we're also supposed to retry 3 times per the spec.
+	 */
+	for (i = 0; i < 3; i++) {
+		ret = psb_intel_dp_aux_native_read(output, address, recv,
+					       recv_bytes);
+		if (ret == recv_bytes)
+			return true;
+		udelay(1000);
+	}
+
+	return false;
+}
+
+/*
+ * Fetch AUX CH registers 0x202 - 0x207 which contain
+ * link status information
+ */
+static bool
+psb_intel_dp_get_link_status(struct psb_intel_output *output)
+{
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	return psb_intel_dp_aux_native_read_retry(output,
+					      DP_LANE0_1_STATUS,
+					      intel_dp->link_status,
+					      DP_LINK_STATUS_SIZE);
+}
+
+static uint8_t
+psb_intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
+		     int r)
+{
+	return link_status[r - DP_LANE0_1_STATUS];
+}
+
+static uint8_t
+psb_intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
+				 int lane)
+{
+	int	    i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
+	int	    s = ((lane & 1) ?
+			 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
+			 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
+	uint8_t l = psb_intel_dp_link_status(link_status, i);
+
+	return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
+}
+
+static uint8_t
+psb_intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
+				      int lane)
+{
+	int	    i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
+	int	    s = ((lane & 1) ?
+			 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
+			 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
+	uint8_t l = psb_intel_dp_link_status(link_status, i);
+
+	return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
+}
+
+
+#if 0
+static char	*voltage_names[] = {
+	"0.4V", "0.6V", "0.8V", "1.2V"
+};
+static char	*pre_emph_names[] = {
+	"0dB", "3.5dB", "6dB", "9.5dB"
+};
+static char	*link_train_names[] = {
+	"pattern 1", "pattern 2", "idle", "off"
+};
+#endif
+
+#define CDV_DP_VOLTAGE_MAX	    DP_TRAIN_VOLTAGE_SWING_1200
+/*
+static uint8_t
+psb_intel_dp_pre_emphasis_max(uint8_t voltage_swing)
+{
+	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+	case DP_TRAIN_VOLTAGE_SWING_400:
+		return DP_TRAIN_PRE_EMPHASIS_6;
+	case DP_TRAIN_VOLTAGE_SWING_600:
+		return DP_TRAIN_PRE_EMPHASIS_6;
+	case DP_TRAIN_VOLTAGE_SWING_800:
+		return DP_TRAIN_PRE_EMPHASIS_3_5;
+	case DP_TRAIN_VOLTAGE_SWING_1200:
+	default:
+		return DP_TRAIN_PRE_EMPHASIS_0;
+	}
+}
+*/
+static void
+psb_intel_get_adjust_train(struct psb_intel_output *output)
+{
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	uint8_t v = 0;
+	uint8_t p = 0;
+	int lane;
+
+	for (lane = 0; lane < intel_dp->lane_count; lane++) {
+		uint8_t this_v = psb_intel_get_adjust_request_voltage(intel_dp->link_status, lane);
+		uint8_t this_p = psb_intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane);
+
+		if (this_v > v)
+			v = this_v;
+		if (this_p > p)
+			p = this_p;
+	}
+	
+	if (v >= CDV_DP_VOLTAGE_MAX)
+		v = CDV_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
+
+	if (p == DP_TRAIN_PRE_EMPHASIS_MASK)
+		p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+		
+	for (lane = 0; lane < 4; lane++)
+		intel_dp->train_set[lane] = v | p;
+}
+
+
+static uint8_t
+psb_intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
+		      int lane)
+{
+	int i = DP_LANE0_1_STATUS + (lane >> 1);
+	int s = (lane & 1) * 4;
+	uint8_t l = psb_intel_dp_link_status(link_status, i);
+
+	return (l >> s) & 0xf;
+}
+
+/* Check for clock recovery is done on all channels */
+static bool
+psb_intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
+{
+	int lane;
+	uint8_t lane_status;
+
+	for (lane = 0; lane < lane_count; lane++) {
+		lane_status = psb_intel_get_lane_status(link_status, lane);
+		if ((lane_status & DP_LANE_CR_DONE) == 0)
+			return false;
+	}
+	return true;
+}
+
+/* Check to see if channel eq is done on all channels */
+#define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\
+			 DP_LANE_CHANNEL_EQ_DONE|\
+			 DP_LANE_SYMBOL_LOCKED)
+static bool
+psb_intel_channel_eq_ok(struct psb_intel_output *output)
+{
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	uint8_t lane_align;
+	uint8_t lane_status;
+	int lane;
+
+	lane_align = psb_intel_dp_link_status(intel_dp->link_status,
+					  DP_LANE_ALIGN_STATUS_UPDATED);
+	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
+		return false;
+	for (lane = 0; lane < intel_dp->lane_count; lane++) {
+		lane_status = psb_intel_get_lane_status(intel_dp->link_status, lane);
+		if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS)
+			return false;
+	}
+	return true;
+}
+
+static bool
+psb_intel_dp_set_link_train(struct psb_intel_output *output,
+			uint32_t dp_reg_value,
+			uint8_t dp_train_pat)
+{
+	
+	struct drm_device *dev = output->base.dev;
+	int ret;
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+
+	REG_WRITE(intel_dp->output_reg, dp_reg_value);
+	REG_READ(intel_dp->output_reg);
+
+	ret = psb_intel_dp_aux_native_write_1(output,
+				    DP_TRAINING_PATTERN_SET,
+				    dp_train_pat);
+
+	if (ret != 1) {
+		DRM_DEBUG_KMS("Failure in setting link pattern %x\n",
+				dp_train_pat);
+		return false;
+	}
+
+	return true;
+}
+
+
+static bool
+psb_intel_dplink_set_level(struct psb_intel_output *output,
+			uint8_t dp_train_pat)
+{
+	
+	int ret;
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+
+	ret = psb_intel_dp_aux_native_write(output,
+					DP_TRAINING_LANE0_SET,
+					intel_dp->train_set,
+					intel_dp->lane_count);
+
+	if (ret != intel_dp->lane_count) {
+		DRM_DEBUG_KMS("Failure in setting level %d, lane_cnt= %d\n",
+				intel_dp->train_set[0], intel_dp->lane_count);
+		return false;
+	}
+	return true;
+}
+
+static void
+psb_intel_dp_set_vswing_premph(struct psb_intel_output *output, uint8_t signal_level)
+{
+	struct drm_device *dev = output->base.dev;
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	struct ddi_regoff *ddi_reg;
+	int vswing, premph, index;
+
+	if (intel_dp->output_reg == DP_B)
+		ddi_reg = &ddi_DP_train_table[0];
+	else
+		ddi_reg = &ddi_DP_train_table[1];
+
+	vswing = (signal_level & DP_TRAIN_VOLTAGE_SWING_MASK);
+	premph = ((signal_level & DP_TRAIN_PRE_EMPHASIS_MASK)) >>
+				DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+	if (vswing + premph > 3)
+		return;
+#ifdef CDV_FAST_LINK_TRAIN
+	return;
+#endif
+	DRM_DEBUG_KMS("Test2\n");
+	//return ;
+	psb_sb_reset(dev);
+	/* ;Swing voltage programming
+        ;gfx_dpio_set_reg(0xc058, 0x0505313A) */
+	psb_sb_write(dev, ddi_reg->VSwing5, 0x0505313A);
+
+	/* ;gfx_dpio_set_reg(0x8154, 0x43406055) */
+	psb_sb_write(dev, ddi_reg->VSwing1, 0x43406055);
+
+	/* ;gfx_dpio_set_reg(0x8148, 0x55338954)
+	 * The VSwing_PreEmph table is also considered based on the vswing/premp
+	 */
+	index = (vswing + premph) * 2;
+	if (premph == 1 && vswing == 1) {
+		psb_sb_write(dev, ddi_reg->VSwing2, 0x055738954);
+	} else
+		psb_sb_write(dev, ddi_reg->VSwing2, dp_vswing_premph_table[index]);
+
+	/* ;gfx_dpio_set_reg(0x814c, 0x40802040) */
+	if ((vswing + premph) == DP_TRAIN_VOLTAGE_SWING_1200)
+		psb_sb_write(dev, ddi_reg->VSwing3, 0x70802040);
+	else
+		psb_sb_write(dev, ddi_reg->VSwing3, 0x40802040);
+
+	/* ;gfx_dpio_set_reg(0x8150, 0x2b405555) */
+	//psb_sb_write(dev, ddi_reg->VSwing4, 0x2b405555);
+
+	/* ;gfx_dpio_set_reg(0x8154, 0xc3406055) */
+	psb_sb_write(dev, ddi_reg->VSwing1, 0xc3406055);
+
+	/* ;Pre emphasis programming
+	 * ;gfx_dpio_set_reg(0xc02c, 0x1f030040)
+	 */
+	psb_sb_write(dev, ddi_reg->PreEmph1, 0x1f030040);
+
+	/* ;gfx_dpio_set_reg(0x8124, 0x00004000) */
+	index = 2 * premph + 1;
+	psb_sb_write(dev, ddi_reg->PreEmph2, dp_vswing_premph_table[index]);
+	return;	
+}
+
+
+/* Enable corresponding port and start training pattern 1 */
+static void
+psb_intel_dp_start_link_train(struct psb_intel_output *output)
+{
+	struct drm_device *dev = output->base.dev;
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	int i;
+	uint8_t voltage;
+	bool clock_recovery = false;
+	int tries;
+	u32 reg;
+	uint32_t DP = intel_dp->DP;
+
+	DP |= DP_PORT_EN;
+		DP &= ~DP_LINK_TRAIN_MASK;
+		
+		reg = DP;	
+		reg |= DP_LINK_TRAIN_PAT_1;
+	/* Enable output, wait for it to become active */
+	REG_WRITE(intel_dp->output_reg, reg);
+	REG_READ(intel_dp->output_reg);
+	psb_intel_wait_for_vblank(dev);
+
+	DRM_DEBUG_KMS("Link config\n");
+	/* Write the link configuration data */
+	psb_intel_dp_aux_native_write(output, DP_LINK_BW_SET,
+				  intel_dp->link_configuration,
+				  2);
+
+	memset(intel_dp->train_set, 0, 4);
+	voltage = 0;
+	tries = 0;
+	clock_recovery = false;
+
+	DRM_DEBUG_KMS("Start train\n");
+		reg = DP | DP_LINK_TRAIN_PAT_1;
+
+
+	for (;;) {
+		/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
+		DRM_DEBUG_KMS("DP Link Train Set %x, Link_config %x, %x\n",
+				intel_dp->train_set[0],
+				intel_dp->link_configuration[0],
+				intel_dp->link_configuration[1]);
+
+		if (!psb_intel_dp_set_link_train(output, reg, DP_TRAINING_PATTERN_1)) {
+			DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 1\n");
+		}
+		psb_intel_dp_set_vswing_premph(output, intel_dp->train_set[0]);
+		/* Set training pattern 1 */
+
+		psb_intel_dplink_set_level(output, DP_TRAINING_PATTERN_1);
+
+		udelay(200);
+		if (!psb_intel_dp_get_link_status(output))
+			break;
+
+		DRM_DEBUG_KMS("DP Link status %x, %x, %x, %x, %x, %x\n",
+				intel_dp->link_status[0], intel_dp->link_status[1], intel_dp->link_status[2],
+				intel_dp->link_status[3], intel_dp->link_status[4], intel_dp->link_status[5]);
+
+		if (psb_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+			DRM_DEBUG_KMS("PT1 train is done\n");
+			clock_recovery = true;
+			break;
+		}
+
+		/* Check to see if we've tried the max voltage */
+		for (i = 0; i < intel_dp->lane_count; i++)
+			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+				break;
+		if (i == intel_dp->lane_count)
+			break;
+
+		/* Check to see if we've tried the same voltage 5 times */
+		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+			++tries;
+			if (tries == 5)
+				break;
+		} else
+			tries = 0;
+		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+
+		/* Compute new intel_dp->train_set as requested by target */
+		psb_intel_get_adjust_train(output);
+
+	}
+
+	if (!clock_recovery) {
+		DRM_DEBUG_KMS("failure in DP patter 1 training, train set %x\n", intel_dp->train_set[0]);
+	}
+	
+	intel_dp->DP = DP;
+}
+
+static void
+psb_intel_dp_complete_link_train(struct psb_intel_output *output)
+{
+	struct drm_device *dev = output->base.dev;
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	bool channel_eq = false;
+	int tries, cr_tries;
+	u32 reg;
+	uint32_t DP = intel_dp->DP;
+
+	/* channel equalization */
+	tries = 0;
+	cr_tries = 0;
+	channel_eq = false;
+
+	DRM_DEBUG_KMS("\n");
+		reg = DP | DP_LINK_TRAIN_PAT_2;
+
+	for (;;) {
+
+		DRM_DEBUG_KMS("DP Link Train Set %x, Link_config %x, %x\n",
+				intel_dp->train_set[0],
+				intel_dp->link_configuration[0],
+				intel_dp->link_configuration[1]);
+		/* channel eq pattern */
+		if (!psb_intel_dp_set_link_train(output, reg,
+					     DP_TRAINING_PATTERN_2)) {
+			DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 2\n");
+		}
+		/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
+
+		if (cr_tries > 5) {
+			DRM_ERROR("failed to train DP, aborting\n");
+			psb_intel_dp_link_down(output);
+			break;
+		}
+
+		psb_intel_dp_set_vswing_premph(output, intel_dp->train_set[0]);
+
+		psb_intel_dplink_set_level(output, DP_TRAINING_PATTERN_2);
+
+		udelay(1000);
+		if (!psb_intel_dp_get_link_status(output))
+			break;
+
+		DRM_DEBUG_KMS("DP Link status %x, %x, %x, %x, %x, %x\n",
+				intel_dp->link_status[0], intel_dp->link_status[1], intel_dp->link_status[2],
+				intel_dp->link_status[3], intel_dp->link_status[4], intel_dp->link_status[5]);
+		/* Make sure clock is still ok */
+		if (!psb_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+			psb_intel_dp_start_link_train(output);
+			cr_tries++;
+			continue;
+		}
+
+		if (psb_intel_channel_eq_ok(output)) {
+			DRM_DEBUG_KMS("PT2 train is done\n");
+			channel_eq = true;
+			break;
+		}
+
+		/* Try 5 times, then try clock recovery if that fails */
+		if (tries > 5) {
+			psb_intel_dp_link_down(output);
+			psb_intel_dp_start_link_train(output);
+			tries = 0;
+			cr_tries++;
+			continue;
+		}
+
+		/* Compute new intel_dp->train_set as requested by target */
+		psb_intel_get_adjust_train(output);
+		++tries;
+
+	}
+
+	reg = DP | DP_LINK_TRAIN_OFF;
+
+	REG_WRITE(intel_dp->output_reg, reg);
+	REG_READ(intel_dp->output_reg);
+	psb_intel_dp_aux_native_write_1(output,
+				    DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
+}
+
+static void
+psb_intel_dp_link_down(struct psb_intel_output *output)
+{
+	struct drm_device *dev = output->base.dev;
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	uint32_t DP = intel_dp->DP;
+
+	if ((REG_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)
+		return;
+
+	DRM_DEBUG_KMS("\n");
+
+
+	{
+		DP &= ~DP_LINK_TRAIN_MASK;
+		REG_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
+	}
+	REG_READ(intel_dp->output_reg);
+
+	msleep(17);
+
+	REG_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
+	REG_READ(intel_dp->output_reg);
+}
+
+static enum drm_connector_status
+cdv_dp_detect(struct psb_intel_output *output)
+{
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	enum drm_connector_status status;
+
+	status = connector_status_disconnected;
+	if (psb_intel_dp_aux_native_read(output, 0x000, intel_dp->dpcd,
+				     sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd))
+	{
+		if (intel_dp->dpcd[DP_DPCD_REV] != 0)
+			status = connector_status_connected;
+	}
+	if (status == connector_status_connected)
+		DRM_DEBUG_KMS("DPCD: Rev=%x LN_Rate=%x LN_CNT=%x LN_DOWNSP=%x\n",
+			intel_dp->dpcd[0], intel_dp->dpcd[1],
+			intel_dp->dpcd[2], intel_dp->dpcd[3]);
+	return status;
+}
+
+/**
+ * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection.
+ *
+ * \return true if DP port is connected.
+ * \return false if DP port is disconnected.
+ */
+static enum drm_connector_status
+psb_intel_dp_detect(struct drm_connector *connector, bool force)
+{
+	struct psb_intel_output *output = to_psb_intel_output(connector);
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	enum drm_connector_status status;
+	struct edid *edid = NULL;
+
+	intel_dp->has_audio = false;
+	
+	if (is_edp(output))
+		psb_intel_edp_panel_vdd_on(output);
+	status = cdv_dp_detect(output);
+	if (status != connector_status_connected) {
+		if (is_edp(output))
+			psb_intel_edp_panel_vdd_off(output);
+		return status;
+	}
+
+	if (intel_dp->force_audio) {
+		intel_dp->has_audio = intel_dp->force_audio > 0;
+	} else {
+		edid = drm_get_edid(connector, &intel_dp->adapter);
+		if (edid) {
+			intel_dp->has_audio = drm_detect_monitor_audio(edid);
+			connector->display_info.raw_edid = NULL;
+			kfree(edid);
+		}
+	}
+
+	if (is_edp(output))
+		psb_intel_edp_panel_vdd_off(output);
+	return connector_status_connected;
+}
+
+static int psb_intel_dp_get_modes(struct drm_connector *connector)
+{
+	struct psb_intel_output *intel_output = to_psb_intel_output(connector);
+	struct psb_intel_dp *intel_dp = intel_output->dev_priv;
+	struct edid *edid = NULL;
+	int ret = 0;
+
+
+	if (is_edp(intel_output))
+		psb_intel_edp_panel_vdd_on(intel_output);
+
+	edid = drm_get_edid(&intel_output->base,
+			 	&intel_dp->adapter);
+	if (edid) {
+		drm_mode_connector_update_edid_property(&intel_output->
+							base, edid);
+		ret = drm_add_edid_modes(&intel_output->base, edid);
+		kfree(edid);
+	}
+
+	if (is_edp(intel_output)) {
+		struct drm_device *dev = connector->dev;
+		struct drm_psb_private *dev_priv = dev->dev_private;
+		
+		psb_intel_edp_panel_vdd_off(intel_output);
+		if (ret) {
+			if (is_edp(intel_output) && !intel_dp->panel_fixed_mode) {
+				struct drm_display_mode *newmode;
+				list_for_each_entry(newmode, &connector->probed_modes,
+					    head) {
+					if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
+						intel_dp->panel_fixed_mode =
+							drm_mode_duplicate(dev, newmode);
+						break;
+					}
+				}
+			}
+
+			return ret;
+		}
+		if (!intel_dp->panel_fixed_mode && dev_priv->lfp_lvds_vbt_mode) {
+			intel_dp->panel_fixed_mode =
+				drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
+			if (intel_dp->panel_fixed_mode) {
+				intel_dp->panel_fixed_mode->type |=
+					DRM_MODE_TYPE_PREFERRED;
+			}
+		}
+		if (intel_dp->panel_fixed_mode != NULL) {
+			struct drm_display_mode *mode;
+			mode = drm_mode_duplicate(dev, intel_dp->panel_fixed_mode);
+			drm_mode_probed_add(connector, mode);
+			return 1;
+		}
+	}
+
+	return ret;
+}
+
+static bool
+psb_intel_dp_detect_audio(struct drm_connector *connector)
+{
+	struct psb_intel_output *output = to_psb_intel_output(connector);
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	struct edid *edid;
+	bool has_audio = false;
+
+	if (is_edp(output))
+		psb_intel_edp_panel_vdd_on(output);
+
+	edid = drm_get_edid(connector, &intel_dp->adapter);
+	if (edid) {
+		has_audio = drm_detect_monitor_audio(edid);
+
+		connector->display_info.raw_edid = NULL;
+		kfree(edid);
+	}
+
+	if (is_edp(output))
+		psb_intel_edp_panel_vdd_off(output);
+
+	return has_audio;
+}
+
+static int
+psb_intel_dp_set_property(struct drm_connector *connector,
+		      struct drm_property *property,
+		      uint64_t val)
+{
+	struct drm_psb_private *dev_priv = connector->dev->dev_private;
+	struct psb_intel_output *output = to_psb_intel_output(connector);
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+	int ret;
+
+	ret = drm_connector_property_set_value(connector, property, val);
+	if (ret)
+		return ret;
+
+	if (property == dev_priv->force_audio_property) {
+		int i = val;
+		bool has_audio;
+
+		if (i == intel_dp->force_audio)
+			return 0;
+
+		intel_dp->force_audio = i;
+
+		if (i == 0)
+			has_audio = psb_intel_dp_detect_audio(connector);
+		else
+			has_audio = i > 0;
+
+		if (has_audio == intel_dp->has_audio)
+			return 0;
+
+		intel_dp->has_audio = has_audio;
+		goto done;
+	}
+
+	if (property == dev_priv->broadcast_rgb_property) {
+		if (val == !!intel_dp->color_range)
+			return 0;
+
+		intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0;
+		goto done;
+	}
+
+	return -EINVAL;
+
+done:
+	if (output->enc.crtc) {
+		struct drm_crtc *crtc = output->enc.crtc;
+		drm_crtc_helper_set_mode(crtc, &crtc->mode,
+					 crtc->x, crtc->y,
+					 crtc->fb);
+	}
+
+	return 0;
+}
+
+static void
+psb_intel_dp_destroy (struct drm_connector *connector)
+{
+	struct psb_intel_output *output = to_psb_intel_output(connector);
+	struct psb_intel_dp *intel_dp = output->dev_priv;
+
+	if (is_edp(output)) {
+		psb_intel_panel_destroy_backlight(connector->dev);
+		if (intel_dp->panel_fixed_mode) {
+			kfree(intel_dp->panel_fixed_mode);
+			intel_dp->panel_fixed_mode = NULL;
+		}
+	}
+
+	i2c_del_adapter(&intel_dp->adapter);
+	drm_sysfs_connector_remove(connector);
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+static void psb_intel_dp_encoder_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_helper_funcs psb_intel_dp_helper_funcs = {
+	.dpms = psb_intel_dp_dpms,
+	.mode_fixup = psb_intel_dp_mode_fixup,
+	.prepare = psb_intel_dp_prepare,
+	.mode_set = psb_intel_dp_mode_set,
+	.commit = psb_intel_dp_commit,
+};
+
+static const struct drm_connector_funcs psb_intel_dp_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.detect = psb_intel_dp_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = psb_intel_dp_set_property,
+	.destroy = psb_intel_dp_destroy,
+};
+
+static const struct drm_connector_helper_funcs psb_intel_dp_connector_helper_funcs = {
+	.get_modes = psb_intel_dp_get_modes,
+	.mode_valid = psb_intel_dp_mode_valid,
+	.best_encoder = psb_intel_best_encoder,
+};
+
+static const struct drm_encoder_funcs psb_intel_dp_enc_funcs = {
+	.destroy = psb_intel_dp_encoder_destroy,
+};
+
+
+static void
+psb_intel_dp_add_properties(struct psb_intel_output *output, struct drm_connector *connector)
+{
+	psb_intel_attach_force_audio_property(connector);
+	psb_intel_attach_broadcast_rgb_property(connector);
+}
+
+/* check the VBT to see whether the eDP is on DP-D port */
+static bool psb_intel_dpc_is_edp(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct child_device_config *p_child;
+	int i;
+
+	if (!dev_priv->child_dev_num)
+		return false;
+
+	for (i = 0; i < dev_priv->child_dev_num; i++) {
+		p_child = dev_priv->child_dev + i;
+
+		if (p_child->dvo_port == PORT_IDPC &&
+		    p_child->device_type == DEVICE_TYPE_eDP)
+			return true;
+	}
+	return false;
+}
+
+void
+psb_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int output_reg)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	struct psb_intel_output *psb_intel_output;
+	struct psb_intel_dp *intel_dp;
+	const char *name = NULL;
+	int type;
+
+	psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
+			       sizeof(struct psb_intel_dp), GFP_KERNEL);
+	if (!psb_intel_output)
+		return;
+
+	intel_dp = (struct psb_intel_dp *)(psb_intel_output + 1);
+	psb_intel_output->mode_dev = mode_dev;
+	connector = &psb_intel_output->base;
+	encoder = &psb_intel_output->enc;
+	psb_intel_output->dev_priv=intel_dp;
+	intel_dp->output = psb_intel_output;
+
+	intel_dp->output_reg = output_reg;
+	
+	type = DRM_MODE_CONNECTOR_DisplayPort;
+	psb_intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
+
+	if ((output_reg == DP_C) && psb_intel_dpc_is_edp(dev)) {
+		type = DRM_MODE_CONNECTOR_eDP;
+		psb_intel_output->type = INTEL_OUTPUT_EDP;
+	}
+	drm_connector_init(dev, connector, &psb_intel_dp_connector_funcs, type);
+	drm_connector_helper_add(connector, &psb_intel_dp_connector_helper_funcs);
+
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	connector->interlace_allowed = 0;
+	connector->doublescan_allowed = 0;
+
+	drm_encoder_init(dev, encoder, &psb_intel_dp_enc_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+	drm_encoder_helper_add(encoder, &psb_intel_dp_helper_funcs);
+
+	drm_mode_connector_attach_encoder(&psb_intel_output->base,
+					  &psb_intel_output->enc);
+
+	drm_sysfs_connector_add(connector);
+
+	/* Set up the DDC bus. */
+	switch (output_reg) {
+		case DP_B:
+			name = "DPDDC-B";
+			psb_intel_output->ddi_select = (DP_MASK | DDI0_SELECT);
+			break;
+		case DP_C:
+			name = "DPDDC-C";
+			psb_intel_output->ddi_select = (DP_MASK | DDI1_SELECT);
+			break;
+	}
+
+	psb_intel_dp_i2c_init(psb_intel_output, name);
+	psb_intel_dp_add_properties(psb_intel_output, connector);
+	
+	if (is_edp(psb_intel_output)) {
+		u32 pwm_ctrl, pp_on;
+		pp_on = REG_READ(PP_CONTROL);
+		pp_on &= ~PANEL_UNLOCK_MASK;
+	        pp_on |= PANEL_UNLOCK_REGS;
+		
+		REG_WRITE(PP_CONTROL, pp_on);
+
+		pwm_ctrl = REG_READ(BLC_PWM_CTL2);
+		pwm_ctrl |= PWM_PIPE_B;
+		REG_WRITE(BLC_PWM_CTL2, pwm_ctrl);
+	}
+	if (is_edp(psb_intel_output)) {
+		int ret;
+		struct edp_power_seq    cur;
+                u32 pp_on, pp_off, pp_div;
+
+                pp_on = REG_READ(PP_ON_DELAYS);
+                pp_off = REG_READ(PP_OFF_DELAYS);
+                pp_div = REG_READ(PP_DIVISOR);
+	
+		/* Pull timing values out of registers */
+                cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >>
+                        PANEL_POWER_UP_DELAY_SHIFT;
+
+                cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >>
+                        PANEL_LIGHT_ON_DELAY_SHIFT;
+
+                cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >>
+                        PANEL_LIGHT_OFF_DELAY_SHIFT;
+
+                cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >>
+                        PANEL_POWER_DOWN_DELAY_SHIFT;
+
+                cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
+                               PANEL_POWER_CYCLE_DELAY_SHIFT);
+
+                DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
+                              cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12);
+
+
+		intel_dp->panel_power_up_delay = cur.t1_t3 / 10;
+                intel_dp->backlight_on_delay = cur.t8 / 10;
+                intel_dp->backlight_off_delay = cur.t9 / 10;
+                intel_dp->panel_power_down_delay = cur.t10 / 10;
+                intel_dp->panel_power_cycle_delay = (cur.t11_t12 - 1) * 100;
+
+                DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n",
+                              intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay,
+                              intel_dp->panel_power_cycle_delay);
+
+                DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
+                              intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
+
+
+		psb_intel_edp_panel_vdd_on(psb_intel_output);
+		ret = psb_intel_dp_aux_native_read(psb_intel_output, DP_DPCD_REV,
+					       intel_dp->dpcd,
+					       sizeof(intel_dp->dpcd));
+		psb_intel_edp_panel_vdd_off(psb_intel_output);
+		if (ret == 0) {
+			/* if this fails, presume the device is a ghost */
+			DRM_INFO("failed to retrieve link info, disabling eDP\n");
+			psb_intel_dp_encoder_destroy(&psb_intel_output->enc);
+			psb_intel_dp_destroy(&psb_intel_output->base);
+			kfree(psb_intel_output);
+			return;
+		} else {
+			DRM_DEBUG_KMS("DPCD: Rev=%x LN_Rate=%x LN_CNT=%x LN_DOWNSP=%x\n",
+				intel_dp->dpcd[0], intel_dp->dpcd[1], 
+				intel_dp->dpcd[2], intel_dp->dpcd[3]);
+			
+		}
+	}
+
+	if (is_edp(psb_intel_output)) {
+		dev_priv->int_edp_connector = connector;
+                psb_intel_panel_setup_backlight(dev);
+	}
+}
diff --git a/drivers/staging/cdv/drv/psb_intel_dpll_cdv.c b/drivers/staging/cdv/drv/psb_intel_dpll_cdv.c
new file mode 100644
index 0000000..257003a
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_dpll_cdv.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2011 Intel Corporation
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <drm/drmP.h>
+
+#include "psb_intel_bios.h"
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+
+
+int
+psb_sb_read(struct drm_device *dev, u32 reg, u32 *val)
+{
+	int ret;
+
+	ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
+	if (ret) {
+		DRM_ERROR("timeout waiting for SB to idle before read\n");
+		return ret;
+	}
+
+	REG_WRITE(SB_ADDR, reg);
+	REG_WRITE(SB_PCKT,
+		   SET_FIELD(SB_OPCODE_READ, SB_OPCODE) |
+		   SET_FIELD(SB_DEST_DPLL, SB_DEST) |
+		   SET_FIELD(0xf, SB_BYTE_ENABLE));
+
+	ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
+	if (ret) {
+		DRM_ERROR("timeout waiting for SB to idle after read\n");
+		return ret;
+	}
+
+	*val = REG_READ(SB_DATA);
+
+	return 0;
+}
+
+int
+psb_sb_write(struct drm_device *dev, u32 reg, u32 val)
+{
+	int ret;
+	static bool dpio_debug = false;
+	u32 temp;
+
+	if (dpio_debug) {
+		if (psb_sb_read(dev, reg, &temp) == 0)
+			DRM_DEBUG_KMS("0x%08x: 0x%08x (before)\n", reg, temp);
+		DRM_DEBUG_KMS("0x%08x: 0x%08x\n", reg, val);
+	}
+
+	ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
+	if (ret) {
+		DRM_ERROR("timeout waiting for SB to idle before write\n");
+		return ret;
+	}
+
+	REG_WRITE(SB_ADDR, reg);
+	REG_WRITE(SB_DATA, val);
+	REG_WRITE(SB_PCKT,
+		   SET_FIELD(SB_OPCODE_WRITE, SB_OPCODE) |
+		   SET_FIELD(SB_DEST_DPLL, SB_DEST) |
+		   SET_FIELD(0xf, SB_BYTE_ENABLE));
+
+	ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
+	if (ret) {
+		DRM_ERROR("timeout waiting for SB to idle after write\n");
+		return ret;
+	}
+
+	if (dpio_debug) {
+		if (psb_sb_read(dev, reg, &temp) == 0)
+			DRM_DEBUG_KMS("0x%08x: 0x%08x (after)\n", reg, temp);
+	}
+
+	return 0;
+}
+
+/* Reset the DPIO configuration register.  The BIOS does this at every
+ * mode set.
+ */
+void
+psb_sb_reset(struct drm_device *dev)
+{
+
+	REG_WRITE(DPIO_CFG, 0);
+	REG_READ(DPIO_CFG);
+	REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N);
+}
+
+static void
+psb_print_clock(struct psb_intel_clock_t *clock)
+{
+	DRM_DEBUG_KMS("CDV clock: n %d m1 %d m2 %d p1 %d p2 %d dot %d vco %d m %d p %d\n",
+		      clock->n, clock->m1, clock->m2, clock->p1, clock->p2, clock->dot,
+		      clock->vco, clock->m, clock->p);
+}
+
+/* Unlike most Intel display engines, on Cedarview the DPLL registers
+ * are behind this sideband bus.  They must be programmed while the
+ * DPLL reference clock is on in the DPLL control register, but before
+ * the DPLL is enabled in the DPLL control register.
+ */
+int
+psb_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
+		       struct psb_intel_clock_t *clock, bool is_lvds, u32 ddi_select)
+{
+	struct psb_intel_crtc *psb_crtc =
+				to_psb_intel_crtc(crtc);
+	int pipe = psb_crtc->pipe;
+	u32 m, n_vco, p;
+	int ret = 0;
+	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+	int ref_sfr = (pipe == 0) ? SB_REF_DPLLA : SB_REF_DPLLB;
+	u32 ref_value;
+	u32 lane_reg, lane_value;
+
+	psb_print_clock(clock);
+
+	psb_sb_reset(dev);
+
+	REG_WRITE(dpll_reg, DPLL_SYNCLOCK_ENABLE | DPLL_VGA_MODE_DIS);
+
+	udelay(100);
+
+	/* Follow the BIOS and write the REF/SFR Register. Hardcoded value */
+	psb_sb_read(dev, SB_REF_SFR(pipe), &ref_value);
+	ref_value = 0x68A701;
+	psb_sb_write(dev, SB_REF_SFR(pipe), ref_value);
+	
+	/* We don't know what the other fields of these regs are, so
+	 * leave them in place.
+	 */
+	/* 
+	 * The BIT 14:13 of 0x8010/0x8030 is used to select the ref clk
+	 * for the pipe A/B. Display spec 1.06 has wrong definition.
+	 * Correct definition is like below:
+	 *
+	 * refclka mean use clock from same PLL
+	 *
+	 * if DPLLA sets 01 and DPLLB sets 01, they use clock from their pll
+	 *
+	 * if DPLLA sets 01 and DPLLB sets 02, both use clk from DPLLA
+	 *
+	 */  
+	ret = psb_sb_read(dev, ref_sfr, &ref_value);
+	if (ret)
+		return ret;
+	ref_value &= ~(REF_CLK_MASK);
+
+	/* use DPLL_A for pipeB on CRT/HDMI */
+
+	if (pipe == 1 && !is_lvds && !(ddi_select & DP_MASK)) {
+		DRM_DEBUG_KMS("use DPLLA for pipe B\n");
+		ref_value |= REF_CLK_DPLLA;
+	} else {
+		DRM_DEBUG_KMS("use their DPLL for pipe A/B\n");
+		ref_value |= REF_CLK_DPLL;
+	}
+	ret = psb_sb_write(dev, ref_sfr, ref_value);
+	if (ret)
+		return ret;
+	
+	ret = psb_sb_read(dev, SB_M(pipe), &m);
+	if (ret)
+		return ret;
+	m &= ~SB_M_DIVIDER_MASK;
+	m |= ((clock->m2) << SB_M_DIVIDER_SHIFT);
+	ret = psb_sb_write(dev, SB_M(pipe), m);
+	if (ret)
+		return ret;
+
+	ret = psb_sb_read(dev, SB_N_VCO(pipe), &n_vco);
+	if (ret)
+		return ret;
+
+	/* Follow the BIOS to program the N_DIVIDER REG */
+	n_vco &= 0xFFFF;
+	n_vco |= 0x107;
+	n_vco &= ~(SB_N_VCO_SEL_MASK |
+		   SB_N_DIVIDER_MASK |
+		   SB_N_CB_TUNE_MASK);
+
+	n_vco |= ((clock->n) << SB_N_DIVIDER_SHIFT);
+
+	if (clock->vco < 2250000) {
+		n_vco |= (2 << SB_N_CB_TUNE_SHIFT);
+		n_vco |= (0 << SB_N_VCO_SEL_SHIFT);
+	} else if (clock->vco < 2750000) {
+		n_vco |= (1 << SB_N_CB_TUNE_SHIFT);
+		n_vco |= (1 << SB_N_VCO_SEL_SHIFT);
+	} else if (clock->vco < 3300000) {
+		n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
+		n_vco |= (2 << SB_N_VCO_SEL_SHIFT);
+	} else {
+		n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
+		n_vco |= (3 << SB_N_VCO_SEL_SHIFT);
+	}
+
+	ret = psb_sb_write(dev, SB_N_VCO(pipe), n_vco);
+	if (ret)
+		return ret;
+
+	ret = psb_sb_read(dev, SB_P(pipe), &p);
+	if (ret)
+		return ret;
+	p &= ~(SB_P2_DIVIDER_MASK | SB_P1_DIVIDER_MASK);
+	p |= SET_FIELD(clock->p1, SB_P1_DIVIDER);
+	switch (clock->p2) {
+	case 5:
+		p |= SET_FIELD(SB_P2_5, SB_P2_DIVIDER);
+		break;
+	case 10:
+		p |= SET_FIELD(SB_P2_10, SB_P2_DIVIDER);
+		break;
+	case 14:
+		p |= SET_FIELD(SB_P2_14, SB_P2_DIVIDER);
+		break;
+	case 7:
+		p |= SET_FIELD(SB_P2_7, SB_P2_DIVIDER);
+		break;
+	default:
+		DRM_ERROR("Bad P2 clock: %d\n", clock->p2);
+		return -EINVAL;
+	}
+	ret = psb_sb_write(dev, SB_P(pipe), p);
+	if (ret)
+		return ret;
+
+	/* Issue Title: 
+	 *     DP/HDMI lanes were dead during cold temperature.
+	 *
+	 * Reason for this failure: 
+	 *     Reference Clk required to power these lanes were not sufficient enough
+	 *     and hence in cold temperature the lanes were failing. Now EV team came
+	 *     up with a work around which utilizes a different alt ref path and to 
+	 *     disable Op Amp (which was previously generating reference clk) and 
+	 *     enable Alt_Ref Path.
+	 */
+	ref_value = 0x14100300;
+	ret = psb_sb_write(dev, SB_ALT_REF(pipe), ref_value);
+	if (ret)
+		return ret;
+
+	ref_value = 0x1FFB0010;
+	ret = psb_sb_write(dev, SB_MISC_DFX(pipe), ref_value);
+	if (ret)
+		return ret;
+
+	ref_value = 0x10100300;
+	ret = psb_sb_write(dev, SB_ALT_REF(pipe), ref_value);
+	if (ret)
+		return ret;
+
+	if (ddi_select) {
+		if ((ddi_select & DDI_MASK) == DDI0_SELECT) {
+			lane_reg = PSB_LANE0;
+			psb_sb_read(dev, lane_reg, &lane_value);
+			lane_value &= ~(LANE_PLL_MASK);
+			lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
+			psb_sb_write(dev, lane_reg, lane_value);
+
+			lane_reg = PSB_LANE1;
+			psb_sb_read(dev, lane_reg, &lane_value);
+			lane_value &= ~(LANE_PLL_MASK);
+			lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
+			psb_sb_write(dev, lane_reg, lane_value);
+		} else {
+			lane_reg = PSB_LANE2;
+			psb_sb_read(dev, lane_reg, &lane_value);
+			lane_value &= ~(LANE_PLL_MASK);
+			lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
+			psb_sb_write(dev, lane_reg, lane_value);
+
+			lane_reg = PSB_LANE3;
+			psb_sb_read(dev, lane_reg, &lane_value);
+			lane_value &= ~(LANE_PLL_MASK);
+			lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
+			psb_sb_write(dev, lane_reg, lane_value);
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/cdv/drv/psb_intel_drv.h b/drivers/staging/cdv/drv/psb_intel_drv.h
new file mode 100644
index 0000000..7b1443d
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_drv.h
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ */
+
+#ifndef __INTEL_DRV_H__
+#define __INTEL_DRV_H__
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <linux/gpio.h>
+
+/*
+ * Display related stuff
+ */
+
+/* store information about an Ixxx DVO */
+/* The i830->i865 use multiple DVOs with multiple i2cs */
+/* the i915, i945 have a single sDVO i2c bus - which is different */
+#define MAX_OUTPUTS 6
+/* maximum connectors per crtcs in the mode set */
+#define INTELFB_CONN_LIMIT 4
+
+#define INTEL_I2C_BUS_DVO 1
+#define INTEL_I2C_BUS_SDVO 2
+
+/* these are outputs from the chip - integrated only
+ * external chips are via DVO or SDVO output */
+#define INTEL_OUTPUT_UNUSED 0
+#define INTEL_OUTPUT_ANALOG 1
+#define INTEL_OUTPUT_DVO 2
+#define INTEL_OUTPUT_SDVO 3
+#define INTEL_OUTPUT_LVDS 4
+#define INTEL_OUTPUT_TVOUT 5
+#define INTEL_OUTPUT_HDMI 6
+#define INTEL_OUTPUT_DISPLAYPORT 7
+#define INTEL_OUTPUT_EDP 8
+
+#define INTEL_DVO_CHIP_NONE 0
+#define INTEL_DVO_CHIP_LVDS 1
+#define INTEL_DVO_CHIP_TMDS 2
+#define INTEL_DVO_CHIP_TVOUT 4
+
+struct psb_intel_clock_t
+{
+	/* given values */
+	int n;
+	int m1, m2;
+	int p1, p2;
+	/* derived values */
+	int dot;
+	int vco;
+	int m;
+	int p;
+};
+/**
+ * Hold information useally put on the device driver privates here,
+ * since it needs to be shared across multiple of devices drivers privates.
+*/
+struct psb_intel_mode_device {
+
+	/*
+	 * Abstracted memory manager operations
+	 */
+	void *(*bo_from_handle) (struct drm_device *dev,
+				 struct drm_file *file_priv,
+				 unsigned int handle);
+	size_t(*bo_size) (struct drm_device *dev, void *bo);
+	size_t(*bo_offset) (struct drm_device *dev, void *bo);
+	int (*bo_pin_for_scanout) (struct drm_device *dev, void *bo);
+	int (*bo_unpin_for_scanout) (struct drm_device *dev, void *bo);
+
+	/*
+	 * Cursor
+	 */
+	int cursor_needs_physical;
+
+	/*
+	 * LVDS info
+	 */
+	int backlight_duty_cycle;	/* restore backlight to this value */
+	int backlight_enabled;
+	bool panel_wants_dither;
+	struct drm_display_mode *panel_fixed_mode;
+	struct drm_display_mode *panel_fixed_mode2;
+	struct drm_display_mode *vbt_mode;	/* if any */
+
+	uint32_t saveBLC_PWM_CTL;
+};
+
+struct psb_intel_i2c_chan {
+	/* for getting at dev. private (mmio etc.) */
+	struct drm_device *drm_dev;
+	u32 reg;		/* GPIO reg */
+	struct i2c_adapter adapter;
+	struct i2c_algo_bit_data algo;
+	u8 slave_addr;
+};
+
+#define DDI0_SELECT	1
+#define DDI1_SELECT	2
+#define DP_MASK		0x8000
+#define DDI_MASK	0x3
+
+struct psb_intel_output {
+	struct drm_connector base;
+
+	struct drm_encoder enc;
+	int type;
+#if 1 /*MDFLD_HDMI_JLIU7*/
+	struct i2c_adapter *hdmi_i2c_adapter;	/* for control functions */
+#endif
+	struct psb_intel_i2c_chan *i2c_bus;	/* for control functions */
+	struct psb_intel_i2c_chan *ddc_bus;	/* for DDC only stuff */
+	bool load_detect_temp;
+	void *dev_priv;
+	u32	ddi_select;
+
+	struct psb_intel_mode_device *mode_dev;
+
+};
+
+struct psb_intel_crtc_state {
+	uint32_t saveDSPCNTR;
+	uint32_t savePIPECONF;
+	uint32_t savePIPESRC;
+	uint32_t saveDPLL;
+	uint32_t saveFP0;
+	uint32_t saveFP1;
+	uint32_t saveHTOTAL;
+	uint32_t saveHBLANK;
+	uint32_t saveHSYNC;
+	uint32_t saveVTOTAL;
+	uint32_t saveVBLANK;
+	uint32_t saveVSYNC;
+	uint32_t saveDSPSTRIDE;
+	uint32_t saveDSPSIZE;
+	uint32_t saveDSPPOS;
+	uint32_t saveDSPBASE;
+	uint32_t savePalette[256];
+};
+
+struct psb_intel_crtc {
+	struct drm_crtc base;
+	int pipe;
+	int plane;
+	uint32_t cursor_addr;
+	u8 lut_r[256], lut_g[256], lut_b[256];
+	u8 lut_adj[256];
+	struct psb_intel_framebuffer *fbdev_fb;
+	/* a mode_set for fbdev users on this crtc */
+	struct drm_mode_set mode_set;
+
+	/* current bo we scanout from */
+	void *scanout_bo;
+
+	/* current bo we cursor from */
+	void *cursor_bo;
+	void *cursor_handle;
+
+	struct drm_display_mode saved_mode;
+	struct drm_display_mode saved_adjusted_mode;
+
+	struct psb_intel_mode_device *mode_dev;
+
+	/*crtc mode setting flags*/
+	u32 mode_flags;
+
+/*FIXME: Workaround to avoid MRST block.*/
+	/* Saved Crtc HW states */
+	struct psb_intel_crtc_state *crtc_state;
+
+	bool active;
+};
+
+#define to_psb_intel_crtc(x)	\
+		container_of(x, struct psb_intel_crtc, base)
+#define to_psb_intel_output(x)	\
+		container_of(x, struct psb_intel_output, base)
+#define enc_to_psb_intel_output(x)	\
+		container_of(x, struct psb_intel_output, enc)
+#define to_psb_intel_framebuffer(x)	\
+		container_of(x, struct psb_intel_framebuffer, base)
+
+struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
+					const u32 reg, const char *name);
+void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan);
+int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output);
+extern bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output);
+
+extern void psb_intel_crtc_init(struct drm_device *dev, int pipe,
+			    struct psb_intel_mode_device *mode_dev);
+extern void psb_intel_crt_init(struct drm_device *dev,
+			    struct psb_intel_mode_device *mode_dev);
+extern void psb_intel_tv_init(struct drm_device *dev);
+extern void psb_intel_lvds_init(struct drm_device *dev,
+			    struct psb_intel_mode_device *mode_dev);
+extern void mdfld_hdmi_init(struct drm_device *dev,
+			   struct psb_intel_mode_device *mode_dev, int reg);
+
+extern void psb_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int output_reg);
+
+extern void psb_intel_crtc_load_lut(struct drm_crtc *crtc);
+extern void psb_intel_encoder_prepare(struct drm_encoder *encoder);
+extern void psb_intel_encoder_commit(struct drm_encoder *encoder);
+
+extern struct drm_encoder *psb_intel_best_encoder(struct drm_connector
+					      *connector);
+
+extern struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
+						    struct drm_crtc *crtc);
+extern void psb_intel_wait_for_vblank(struct drm_device *dev);
+extern int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
+extern struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev,
+						 int pipe);
+extern int intelfb_probe(struct drm_device *dev);
+extern int intelfb_remove(struct drm_device *dev,
+			  struct drm_framebuffer *fb);
+extern struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device
+							*dev, struct
+							drm_mode_fb_cmd
+							*mode_cmd,
+							void *mm_private);
+extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode);
+extern int psb_intel_lvds_mode_valid(struct drm_connector *connector,
+				     struct drm_display_mode *mode);
+extern int psb_intel_lvds_set_property(struct drm_connector *connector,
+					struct drm_property *property,
+					uint64_t value);
+extern void psb_intel_lvds_destroy(struct drm_connector *connector);
+extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs;
+
+extern uint8_t blc_pol;
+extern uint8_t blc_freq;
+
+extern int psb_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
+				  struct psb_intel_clock_t *clock, bool is_lvds, u32 ddi_select);
+extern int
+psb_sb_read(struct drm_device *dev, u32 reg, u32 *val);
+extern void
+psb_sb_reset(struct drm_device *dev);
+extern int
+psb_sb_write(struct drm_device *dev, u32 reg, u32 val);
+
+extern void psb_intel_dp_set_m_n(struct drm_crtc *crtc,
+					struct drm_display_mode *mode,
+					struct drm_display_mode *adjusted_mode);
+
+extern void psb_intel_attach_force_audio_property(struct drm_connector *connector);
+extern void psb_intel_attach_broadcast_rgb_property(struct drm_connector *connector);
+
+void
+psb_intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
+		       struct drm_display_mode *adjusted_mode);
+
+extern void psb_intel_panel_enable_backlight(struct drm_device *dev);
+extern void psb_intel_panel_disable_backlight(struct drm_device *dev);
+
+extern void psb_intel_panel_set_backlight(struct drm_device *dev, int level);
+/* psb_intel_panel.c */
+extern u32 psb_intel_panel_get_max_backlight(struct drm_device *dev);
+extern u32 psb_intel_panel_get_backlight(struct drm_device *dev);
+
+extern void psb_intel_panel_destroy_backlight(struct drm_device *dev);
+extern int psb_intel_panel_setup_backlight(struct drm_device *dev);
+
+extern void psb_intel_clock_gating (struct drm_device *dev);
+#endif				/* __INTEL_DRV_H__ */
diff --git a/drivers/staging/cdv/drv/psb_intel_hdmi.c b/drivers/staging/cdv/drv/psb_intel_hdmi.c
new file mode 100644
index 0000000..63c0bbb
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_hdmi.c
@@ -0,0 +1,686 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	jim liu <jim.liu@intel.com>
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include "psb_intel_drv.h"
+#include "psb_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_hdmi_reg.h"
+#include "psb_intel_hdmi_edid.h"
+#include "psb_intel_hdmi.h"
+#include <linux/pm_runtime.h>
+
+static void mdfld_hdmi_mode_set(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+	struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
+	u32 hdmib;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
+	PSB_DEBUG_ENTRY("\n");
+
+	hdmib = (2 << 10);
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		hdmib |= SDVO_VSYNC_ACTIVE_HIGH;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		hdmib |= SDVO_HSYNC_ACTIVE_HIGH;
+
+	if (intel_crtc->pipe == 1)
+		hdmib |= HDMIB_PIPE_B_SELECT;
+
+	if (hdmi_priv->has_hdmi_audio) {
+		hdmib |= HDMI_AUDIO_ENABLE;
+		hdmib |= HDMI_NULL_PACKETS_DURING_VSYNC;
+	}
+		
+	REG_WRITE(hdmi_priv->hdmi_reg, hdmib);
+	REG_READ(hdmi_priv->hdmi_reg);
+}
+
+static bool mdfld_hdmi_mode_fixup(struct drm_encoder *encoder,
+				  struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode)
+{
+
+       return true;
+}
+
+
+static void mdfld_hdmi_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+	struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
+	u32 hdmib;
+
+	PSB_DEBUG_ENTRY("%s \n", mode == DRM_MODE_DPMS_ON ? "on" : "off");
+
+	hdmib = REG_READ(hdmi_priv->hdmi_reg);
+
+	if (mode != DRM_MODE_DPMS_ON) {
+		REG_WRITE(hdmi_priv->hdmi_reg, hdmib & ~HDMIB_PORT_EN);
+	} else {
+		REG_WRITE(hdmi_priv->hdmi_reg, hdmib | HDMIB_PORT_EN);
+	}
+	REG_READ(hdmi_priv->hdmi_reg);
+}
+
+static void mdfld_hdmi_save(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct psb_intel_output *output = to_psb_intel_output(connector);
+	struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg);
+}
+
+static void mdfld_hdmi_restore(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct psb_intel_output *output = to_psb_intel_output(connector);
+	struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB);
+	REG_READ(hdmi_priv->hdmi_reg);
+}
+
+#if 0
+
+/* HDMI DIP related stuff */
+static int mdfld_hdmi_get_cached_edid_block(struct drm_connector *connector, uint32_t num_block, uint8_t *edid_block, uint32_t size)
+{
+    struct drm_display_info *displayinfo = &(connector->display_info);
+    if (num_block >= MAX_EDID_BLOCKS)
+    {
+	DRM_ERROR("mdfld_hdmi_get_cached_edid_block() - Invalid EDID block\n");
+        return 0; 
+    }
+    edid_block = &displayinfo->raw_edid[EDID_BLOCK_SIZE*num_block];
+    return 1;
+}
+
+/////////////////////////////////////////////////////////////////////////
+//    INTHDMIENCODER_CreateEELDPacket():
+//    This function parses v1.3 base EDID and CEA-861b EDID Timing Extension
+//    Version3 and creates EELD (Enhanced EDID Like Data) packet. This EELD data contains
+//    audio configuration information and other details read EDID.This can also contain Vendor specific Data
+//
+/////////////////////////////////////////////////////////////////////////
+static int mdfld_hdmi_create_eeld_packet(struct drm_connector *connector)
+{
+    struct psb_intel_output *output = to_psb_intel_output(connector);
+    struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
+    uint8_t ucEdidBlock[128];
+    hdmi_eeld_t *pEEld                = NULL;
+    baseedid_1_x_t *pEdid        = NULL;
+    ce_edid_t *pCeEdid        = NULL;
+    int dwNumOfBytes        = 0;
+    int sizeOfCEADataBlock    = 0;
+    uint8_t * pDataBlock        = NULL;
+    edid_dtd_timing_t *pDTD    = NULL;
+    uint8_t *pData            = NULL;
+    uint8_t ucDataBlockTag    = 0;
+    cea_861b_adb_t *pADB        = NULL;
+    uint8_t i                    = 0;
+    uint8_t j                    = 0;
+    uint8_t * pSADBlocks = NULL;
+    uint8_t * pCurrentSADBlocks = NULL;
+    uint32_t ulNumSADBytes = 0;
+    //vsdb_byte6_to_byte8_t *pVSDB = NULL;
+    uint32_t ulIndex = 0;
+    //uint8_t b48kHzCADPresent = false;
+
+    pEEld = (hdmi_eeld_t *) &hdmi_priv->eeld;
+
+    // Fill Version info
+    pEEld->cea_edid_rev_id = HDMI_EELD_CEA_EDID_VERSION;
+    pEEld->eld_ver = HDMI_EELD_VERSION;
+
+    // Fill BaseLine ELD length
+    // This is 80 bytes as per EELD proposal
+    pEEld->baseline_eld_length = HDMI_EELD_BASELINE_DATA_LENGTH;
+
+    //Zero out EDID block buffer
+    memset(ucEdidBlock, 0, sizeof(ucEdidBlock));
+
+    // Get Extn EDID
+    if(!mdfld_hdmi_get_cached_edid_block(connector, 1, ucEdidBlock, EDID_BLOCK_SIZE))
+    {
+        return 0;
+    }    
+
+    pCeEdid = (ce_edid_t *) ucEdidBlock;
+
+    //allocate memory (48 bytes) for SAD Blocks buffer
+    pSADBlocks = kcalloc(1, 48, GFP_KERNEL);
+
+    if(pSADBlocks == NULL)
+    {
+	DRM_ERROR("mdfld_hdmi_create_eld_packaet() - Failed to allocate mem for pSADBlocks\n");
+        return 0;
+    }
+
+    pCurrentSADBlocks = pSADBlocks;
+
+    // Now pull out data from CEA Extension EDID
+    // If Offset <= 4, we will not have CEA DataBlocks
+    if(pCeEdid->ucDTDOffset > CEA_EDID_HEADER_SZIE)
+    {
+        sizeOfCEADataBlock = pCeEdid->ucDTDOffset - CEA_EDID_HEADER_SZIE;
+
+        pDataBlock = (uint8_t *)pCeEdid;
+
+        // skip header (first 4 bytes) in CEA EDID Timing Extension
+        // and set pointer to start of DataBlocks collection
+        pDataBlock += CEA_EDID_HEADER_SZIE;
+
+        // General Format of CEA Data Block Collection
+        // -----------+--------------------+-----------------------------------------+
+        //            |Byte#   |bits5-7    |       bits 0-4                          |
+        // -----------|--------------------+-----------------------------------------+
+        //            |  1     | Video Tag |Length = total #of video bytes following |
+        //            |        |    Code   |this byte (L1)                           |
+        //            |--------------------+-----------------------------------------+
+        //  Video     |  2     | CEA Short Video Descriptor 1                        |
+        //  Data      |--------+-----------------------------------------------------|
+        //  Block     |  3     | CEA Short Video Descriptor 2                        |
+        //            |--------+-----------------------------------------------------|
+        //            | ...    | ...                                                 |
+        //            |--------------------------------------------------------------+
+        //            | 1+L1   | CEA Short Video Descriptor L1                       |
+        // -----------+--------------------+-----------------------------------------+
+        //            | 2+L1   | Audio Tag |Length = total #of audio bytes following |
+        //            |        |    Code   |this byte (L2)                           |
+        //            |--------------------+-----------------------------------------+
+        //  Audio     | 3+L1   |                                                     |
+        //  Data      |--------+                                                     |
+        //  Block     | 4+L1   | CEA Short Audio Descriptor 1                        |
+        //            |--------+                                                     |
+        //            | 5+L1   |                                                     |
+        //            |--------------------------------------------------------------+
+        //            | ...    |                                                     |
+        //            |        |                                                     |
+        //            |        |                                                     |
+        //            | ...    |                                                     |
+        //            |---------------------------------------------------------------
+        //            |L1+L2   |                                                     |
+        //            |--------|                                                     |
+        //            |1+L1+L2 | CEA Short Audio Descriptor L2/3                     |
+        //            |--------|                                                     |
+        //            |2+L1+L2 |                                                     |
+        // -----------+--------------------------------------------------------------+
+        //            |3+L1+L2 |  Speaker  |Length = total #of SA bytes following    |
+        //            |        | Tag Code  |this byte (L1)                           |
+        //  Speaker   |--------------------------------------------------------------+
+        //  Allocation|4+L1+L2 |                                                     |
+        //  Data      |--------|                                                     |
+        //  Block     |5+L1+L2 | Speaker Allocation Data Block Payload(3 bytes)      |
+        //            |--------|                                                     |
+        //            |6+L1+L2 |                                                     |
+        // -----------+--------------------------------------------------------------+
+        //            |7+L1+L2 | VSDB  Tag |Length = total #of VSDB bytes following  |
+        //            |        |    Code   |this byte (L1)                           |
+        //  Vendor    |--------------------------------------------------------------+
+        //  Specific  |8+L1+L2 |                                                     |
+        //  Data      |--------|                                                     |
+        //  Block     |9+L1+L2 | 24-bit IEEE Registration Identifier (LSB first)     |
+        //            |--------|                                                     |
+        //            |10+L1+L2|                                                     |
+        //            |--------------------------------------------------------------+
+        //            | ...    | Vendor Specific Data block Payload                  |
+        // -----------+--------------------------------------------------------------+
+
+        while(sizeOfCEADataBlock > 0)
+        {
+            // Get the Size of CEA DataBlock in bytes and TAG
+            dwNumOfBytes = *pDataBlock & CEA_DATABLOCK_LENGTH_MASK;
+            ucDataBlockTag = (*pDataBlock & CEA_DATABLOCK_TAG_MASK) >> 5;
+
+            switch(ucDataBlockTag)
+            {
+                case CEA_AUDIO_DATABLOCK:
+                    // move beyond tag/length byte
+                    ++pDataBlock;
+                    for (i = 0; i < (dwNumOfBytes / 3); ++i, pDataBlock += 3)
+                    {
+                        pADB = (cea_861b_adb_t*)pDataBlock;
+                        switch(pADB->audio_format_code)
+                        {
+                            // uncompressed audio (Linear PCM)
+                            case AUDIO_LPCM:
+                                memcpy(&(hdmi_priv->lpcm_sad),pDataBlock,3);
+                                //save these blocks
+                                memcpy(pCurrentSADBlocks, pDataBlock, 3);
+                                // move pointer in SAD blocks buffer
+                                pCurrentSADBlocks += 3;
+                                // update SADC field
+                                pEEld->sadc += 1;
+                                break;
+                            // compressed audio
+                            case AUDIO_AC3:
+                            case AUDIO_MPEG1:
+                            case AUDIO_MP3:
+                            case AUDIO_MPEG2:
+                            case AUDIO_AAC:
+                            case AUDIO_DTS:
+                            case AUDIO_ATRAC:
+                            case AUDIO_OBA:
+                            case AUDIO_DOLBY_DIGITAL:
+                            case AUDIO_DTS_HD:
+                            case AUDIO_MAT:
+                            case AUDIO_DST:
+                            case AUDIO_WMA_PRO:
+                                //save these blocks
+                                memcpy(pCurrentSADBlocks, pDataBlock, 3);
+                                // move pointer in SAD blocks buffer
+                                pCurrentSADBlocks += 3;
+                                // update SADC field
+                                pEEld->sadc += 1;
+                                break;
+                        }
+                    }
+                    break;
+
+                case CEA_VENDOR_DATABLOCK:
+                    // audio wants data from 6th byte of VSDB onwards
+                    //Sighting 94842: 
+
+                    // | Byte # |    bits[7-0]                                              |
+                    // |--------------------------------------------------------------------|
+                    // | 1-3    |24-bit IEEE Registration Identifier (0x000C03)             |
+                    // |--------------------------------------------------------------------|
+                    // | 4-5    |       Source Physical Address                             |
+                    // |--------------------------------------------------------------------|
+                    // | 6      |SupportsAI|DC48bit|DC36bit|Dc30bit|DCY444|Rsvd|Rsvd|DVIDual|
+                    // |--------------------------------------------------------------------|
+                    // | 7      |   Max TMDS clock                                          |
+                    // |--------------------------------------------------------------------|
+                    // | 8      |Latency_Field |I_Latency_Field| Reserved bits 5-0          |
+                    // |        |   _Present   |  _Present     |                            |
+                    // |--------------------------------------------------------------------|
+                    // | 9      |               Video Latency                               |
+                    // |--------------------------------------------------------------------|
+                    // | 10     |               Audio Latency                               |
+                    // |--------------------------------------------------------------------|
+                    // | 11     |            Interlaced Video Latency                       |
+                    // |--------------------------------------------------------------------|
+                    // | 12     |            Interlaced Audio Latency                       |
+                    // |--------------------------------------------------------------------|
+
+                    ++pDataBlock;
+                    // move pointer to next CEA Datablock
+                    pDataBlock += dwNumOfBytes;
+                    break;                 
+
+                case CEA_SPEAKER_DATABLOCK:
+                    pEEld->speaker_allocation_block = *(++pDataBlock);
+                    // move pointer to next CEA Datablock
+                    pDataBlock += dwNumOfBytes;
+                    break;                       
+
+                default:
+                    // Move pointer to next CEA DataBlock
+                    pDataBlock += (dwNumOfBytes + 1);
+            }
+            // Decrement size of CEA DataBlock
+            sizeOfCEADataBlock -= (dwNumOfBytes + 1);
+        }    
+    }
+
+    //Copy all the saved SAD blocks at the end of ELD
+    //SAD blocks should be written after the Monitor name and VSDB.
+    //See ELD definition in iHDMI.h
+    ulNumSADBytes = (pEEld->sadc) * 3; //Size of each SAD block is 3 bytes
+
+    //DCN 460119: Audio does not play on displays which do not provide SAB in EDID.
+    //Solution: Graphics driver should create a default SAB in ELD with front left and front right
+    //speakers enabled if the display supports basic audio. 
+    pDataBlock = (uint8_t *)pCeEdid;
+    if((*(pDataBlock + HDMI_CEA_EXTENSION_BLOCK_BYTE_3) & HDMI_BASIC_AUDIO_SUPPORTED) && (pEEld->speaker_allocation_block == 0)) 
+    {
+        pEEld->flr = 1;
+    }
+    //End of DCN 460119
+
+    // zero out local buffers
+    memset(ucEdidBlock, 0, sizeof(ucEdidBlock));
+
+    // Get base EDID
+    if(!mdfld_hdmi_get_cached_edid_block(connector, 0, ucEdidBlock, EDID_BLOCK_SIZE))
+    {
+        return 0;
+    }
+
+    pEdid = (baseedid_1_x_t*) ucEdidBlock;
+    pDTD = &pEdid->DTD[1];
+
+    //Update the Manufacturer ID and Product Code here
+    memcpy(pEEld->manufacturer_id,pEdid->ManufacturerID,2);
+    memcpy(pEEld->product_id,pEdid->ProductID,2);
+
+    // Now Fill the monitor string name
+    // Search through DTD blocks, looking for monitor name
+    for (i = 0; i < MAX_BASEEDID_DTD_BLOCKS - 1; ++i, ++pDTD)
+    {
+        // Set a uint8_t pointer to DTD data
+        pData = (uint8_t *)pDTD;
+
+        // Check the Flag (the first two bytes) to determine
+        // if this block is used as descriptor
+        if (pData[0] == 0x00 && pData[1] == 0x00)
+        {
+            // And now check Data Type Tag within this descriptor
+            // Tag = 0xFC, then monitor name stored as ASCII
+            if (pData[3] == 0xFC)
+            {
+                ulIndex = 0;
+                // Copy monitor name
+                for (j = 0; (j < 13) && (pData[j+5] != 0x0A); ++j)
+                {
+                    pEEld->mn_sand_sads[ulIndex] = pData[j+5];
+                    ulIndex++;
+                }
+                pEEld->mnl = j;
+                break;
+            }
+        }
+    }
+
+    //Check if number of SAD Bytes > 0 and for size within limits of allowed Base line Data size as per EELD spec
+    if((ulNumSADBytes > 0) && (ulNumSADBytes <= 64))
+    {
+        //Copy the SADs immediately after the Monitor Name String
+        memcpy(&pEEld->mn_sand_sads[j], pSADBlocks, ulNumSADBytes);
+    }
+
+
+    // Header = 4, Baseline Data = 60 and Vendor (INTEL) specific = 2
+    // 4 + 60 + 2 = 66
+    hdmi_priv->hdmi_eeld_size = HDMI_EELD_SIZE;
+    
+    //free the buffer allocated for SAD blocks
+    kfree(pSADBlocks);
+    pSADBlocks = NULL;
+    pCurrentSADBlocks = NULL;
+    return 1;
+}
+
+#endif
+
+static enum drm_connector_status mdfld_hdmi_detect(struct drm_connector *connector, bool force)
+{
+	struct psb_intel_output *psb_intel_output = to_psb_intel_output(connector);
+	struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_output->dev_priv;
+	struct edid *edid = NULL;
+	enum drm_connector_status status = connector_status_disconnected;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	edid = drm_get_edid(&psb_intel_output->base,
+			 psb_intel_output->hdmi_i2c_adapter);
+
+	hdmi_priv->has_hdmi_sink = false;
+	hdmi_priv->has_hdmi_audio = false;
+	if (edid) {
+		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+			status = connector_status_connected;
+			hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
+			hdmi_priv->has_hdmi_audio = drm_detect_monitor_audio(edid);
+		}
+
+		psb_intel_output->base.display_info.raw_edid = NULL;
+		kfree(edid);
+	}
+
+	return status;
+}
+
+static int mdfld_hdmi_set_property(struct drm_connector *connector,
+				       struct drm_property *property,
+				       uint64_t value)
+{
+	struct drm_encoder *pEncoder = connector->encoder;
+
+	PSB_DEBUG_ENTRY("connector info, type = %d, type_id=%d, base=0x%p, base.id=0x%x. \n", connector->connector_type, connector->connector_type_id, &connector->base, connector->base.id);
+	PSB_DEBUG_ENTRY("encoder info, base.id=%d, encoder_type=%d, dev=0x%p, base=0x%p, possible_clones=0x%x. \n", pEncoder->base.id, pEncoder->encoder_type, pEncoder->dev, &pEncoder->base, pEncoder->possible_clones);
+	PSB_DEBUG_ENTRY("encoder info, possible_crtcs=0x%x, crtc=0x%p.  \n", pEncoder->possible_crtcs, pEncoder->crtc);
+
+	if (!strcmp(property->name, "scaling mode") && pEncoder) {
+		PSB_DEBUG_ENTRY("scaling mode \n");
+	} else if (!strcmp(property->name, "backlight") && pEncoder) {
+		PSB_DEBUG_ENTRY("backlight \n");
+	} else if (!strcmp(property->name, "DPMS") && pEncoder) {
+		PSB_DEBUG_ENTRY("DPMS \n");
+	}
+
+	if (!strcmp(property->name, "scaling mode") && pEncoder) {
+		struct psb_intel_crtc *pPsbCrtc = to_psb_intel_crtc(pEncoder->crtc);
+		bool bTransitionFromToCentered;
+		uint64_t curValue;
+
+		if (!pPsbCrtc)
+			goto set_prop_error;
+
+		switch (value) {
+		case DRM_MODE_SCALE_FULLSCREEN:
+			break;
+		case DRM_MODE_SCALE_NO_SCALE:
+			break;
+		case DRM_MODE_SCALE_ASPECT:
+			break;
+		default:
+			goto set_prop_error;
+		}
+
+		if (drm_connector_property_get_value(connector, property, &curValue))
+			goto set_prop_error;
+
+		if (curValue == value)
+			goto set_prop_done;
+
+		if (drm_connector_property_set_value(connector, property, value))
+			goto set_prop_error;
+
+		bTransitionFromToCentered = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
+			(value == DRM_MODE_SCALE_NO_SCALE);
+
+		if (pPsbCrtc->saved_mode.hdisplay != 0 &&
+		    pPsbCrtc->saved_mode.vdisplay != 0) {
+			if (bTransitionFromToCentered) {
+				if (!drm_crtc_helper_set_mode(pEncoder->crtc, &pPsbCrtc->saved_mode,
+					    pEncoder->crtc->x, pEncoder->crtc->y, pEncoder->crtc->fb))
+					goto set_prop_error;
+			} else {
+				struct drm_encoder_helper_funcs *pEncHFuncs  = pEncoder->helper_private;
+				pEncHFuncs->mode_set(pEncoder, &pPsbCrtc->saved_mode,
+						     &pPsbCrtc->saved_adjusted_mode);
+			}
+		}
+	}
+set_prop_done:
+    return 0;
+set_prop_error:
+    return -1;
+}
+
+/**
+ * Return the list of HDMI DDC modes if available.
+ */
+static int mdfld_hdmi_get_modes(struct drm_connector *connector)
+{
+	struct psb_intel_output *psb_intel_output = to_psb_intel_output(connector);
+	struct edid *edid = NULL;
+	int ret = 0;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	edid = drm_get_edid(&psb_intel_output->base,
+			 psb_intel_output->hdmi_i2c_adapter);
+	if (edid) {
+		drm_mode_connector_update_edid_property(&psb_intel_output->
+							base, edid);
+		ret = drm_add_edid_modes(&psb_intel_output->base, edid);
+		kfree(edid);
+	}
+
+	return ret;
+}
+
+static int mdfld_hdmi_mode_valid(struct drm_connector *connector,
+				 struct drm_display_mode *mode)
+{
+
+	PSB_DEBUG_ENTRY("display info. hdisplay = %d, vdisplay = %d. \n", mode->hdisplay, mode->vdisplay);
+
+	if (mode->clock > 165000)
+		return MODE_CLOCK_HIGH;
+	if (mode->clock < 20000)
+		return MODE_CLOCK_HIGH;
+
+	/* just in case */
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+		return MODE_NO_DBLESCAN;
+
+	/* just in case */
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_NO_INTERLACE;
+
+	return MODE_OK;
+}
+
+static const struct drm_encoder_helper_funcs mdfld_hdmi_helper_funcs = {
+	.dpms = mdfld_hdmi_dpms,
+	.mode_fixup = mdfld_hdmi_mode_fixup,
+	.prepare = psb_intel_encoder_prepare,
+	.mode_set = mdfld_hdmi_mode_set,
+	.commit = psb_intel_encoder_commit,
+};
+
+static const struct drm_connector_helper_funcs mdfld_hdmi_connector_helper_funcs = {
+	.get_modes = mdfld_hdmi_get_modes,
+	.mode_valid = mdfld_hdmi_mode_valid,
+	.best_encoder = psb_intel_best_encoder,
+};
+
+static const struct drm_connector_funcs mdfld_hdmi_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.save = mdfld_hdmi_save,
+	.restore = mdfld_hdmi_restore,
+	.detect = mdfld_hdmi_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = mdfld_hdmi_set_property,
+	.destroy = psb_intel_lvds_destroy,
+};
+
+void mdfld_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int reg)
+{
+	struct psb_intel_output *psb_intel_output;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	struct mid_intel_hdmi_priv *hdmi_priv;
+	int ddc_bus;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
+			       sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL);
+	if (!psb_intel_output)
+		return;
+
+	hdmi_priv = (struct mid_intel_hdmi_priv *)(psb_intel_output + 1);
+	psb_intel_output->mode_dev = mode_dev;
+	connector = &psb_intel_output->base;
+	encoder = &psb_intel_output->enc;
+	drm_connector_init(dev, &psb_intel_output->base,
+			   &mdfld_hdmi_connector_funcs,
+			   DRM_MODE_CONNECTOR_DVID);
+
+	drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_mode_connector_attach_encoder(&psb_intel_output->base,
+					  &psb_intel_output->enc);
+	psb_intel_output->type = INTEL_OUTPUT_HDMI;
+	hdmi_priv->hdmi_reg = reg;
+	hdmi_priv->has_hdmi_sink = false;
+	psb_intel_output->dev_priv = hdmi_priv;
+
+	drm_encoder_helper_add(encoder, &mdfld_hdmi_helper_funcs);
+	drm_connector_helper_add(connector,
+				 &mdfld_hdmi_connector_helper_funcs);
+	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+	connector->interlace_allowed = false;
+	connector->doublescan_allowed = false;
+
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
+
+	switch (reg) {
+	case SDVOB:
+		ddc_bus = GPIOE;
+		psb_intel_output->ddi_select = DDI0_SELECT;
+		break;
+	case SDVOC:
+		ddc_bus = GPIOD;
+		psb_intel_output->ddi_select = DDI1_SELECT;
+		break;
+	default:
+		DRM_ERROR("unknown reg 0x%x for HDMI\n", reg);
+		goto failed_ddc;
+		break;
+	}
+
+	psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
+						ddc_bus, (reg == SDVOB) ? "HDMIB":"HDMIC");
+
+	if (!psb_intel_output->ddc_bus) {
+		DRM_ERROR("No ddc adapter available!\n");
+		goto failed_ddc;
+	}
+	psb_intel_output->hdmi_i2c_adapter = &(psb_intel_output->ddc_bus->adapter);
+
+	hdmi_priv->is_hdcp_supported = true;
+	hdmi_priv->dev = dev; 
+	drm_sysfs_connector_add(connector);
+	return;
+
+failed_ddc:
+	drm_encoder_cleanup(&psb_intel_output->enc);
+	drm_connector_cleanup(&psb_intel_output->base);
+	kfree(psb_intel_output);
+}
diff --git a/drivers/staging/cdv/drv/psb_intel_hdmi.h b/drivers/staging/cdv/drv/psb_intel_hdmi.h
new file mode 100644
index 0000000..175b706
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_hdmi.h
@@ -0,0 +1,935 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Chunfeng Zhao <chunfeng.zhao@intel.com>
+ *	Jim Liu <jim.liu@intel.com>
+ */
+
+#ifndef __PSB_INTEL_HDMI_H__
+#define __PSB_INTEL_HDMI_H__
+
+/*
+ * HDMI Parameters
+ */
+
+/* GUID HDMI Parameters */
+#if 0
+//#ifdef DEFINE_GUID
+//#undef DEFINE_GUID
+#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
+//#endif /* DEFINE_GUID */
+
+#define HDMI_PARAMETERS_GUID "{6FD3BE0E-80F9-4206-86B7-3714FA439634}"
+DEFINE_GUID(GUID_HDMI_PARAMETERS, 0x6fd3be0e, 0x80f9, 0x4206, 0x86, 0xb7, 0x37, 0x14, 0xfa, 0x43, 0x96, 0x34);
+
+#define AVI_INFOFRAME_GUID "{DFCB113B-E54F-49A2-B5E3-78D0C6B4F4CB}"
+DEFINE_GUID(GUID_AVI_INFOFRAME, 0xdfcb113b, 0xe54f, 0x49a2, 0xb5, 0xe3, 0x78, 0xd0, 0xc6, 0xb4, 0xf4, 0xcb);
+#endif
+
+#define HDMI_DEVICE_NAME "ABC_VEND"
+#define HDMI_DEVICE_DESC "XZ05 PC VIDEO"
+
+#define HDMI_MAX_PIXEL_REPETITION 0x04     // On Cantiga only upto 4X pixel repetition is supported
+#define HDMI_HBR_AUDIO_SAMPLE_RATE 192000  // 192kHz is the sample rate corresponding to the HBR audio formats
+#define HDMI_AUDIO_CLOCK_PACKET_RATE 1500  // Audio clock packet rate of 1.5kHz has to be considered while calculating audio BW
+
+#define HDMI_BAR_INFO_LENGTH 8 // 8 bytes of barinfo
+
+#define HDMI_MONITOR_NAME_LENGTH 20
+
+// BaseLineDataLength.
+// Total size is in multiple of 4 bytes. i.e, 80/4 = 20
+#define HDMI_EELD_BASELINE_DATA_LENGTH 0x14
+
+// Header = 4, Baseline Data = 80 and Vendor (INTEL) specific = 2 as per EELD spec
+// 4 + 80 + = 84
+#define HDMI_EELD_SIZE 84
+
+//
+// HDMI command types
+//
+typedef enum
+{
+    HDMI_COMMAND_GET,
+    HDMI_COMMAND_SET
+} hdmi_command_t;
+
+#define HDMI_AVI_FLAG_ITCONTENT 0x00800000
+#define HDMI_AVI_FLAG_RGB_QUANT_RANGE 0x00040000
+#define HDMI_AVI_FLAG_SCAN_INFO 0x00000001
+#define HDMI_AVI_FLAG_BAR_INFO 0x00000010
+//
+// CEA-861b definitions
+//
+#define HDMI_CEA_VERSION             0x00
+#define HDMI_ELD_VERSION             0x01
+#define HDMI_EELD_VERSION            0x02
+#define HDMI_BASE_ELD_SIZE           0x0E
+#define HDMI_CEA_EDID_HEADER_SIZE    0x04
+#define HDMI_EELD_CEA_EDID_VERSION   0x03
+#define HDMI_CEA_EDID_BLOCK_SIZE     128
+
+//
+//Basic Audio support definitions
+//
+
+#define HDMI_BASIC_AUDIO_SUPPORTED                0x40
+#define HDMI_CEA_EXTENSION_BLOCK_BYTE_3            3
+#define HDMI_FL_AND_FR_SPEAKERS_CONNECTED        0x1
+
+//
+// HDMI buffer/information types
+//
+typedef enum {
+    // Non-standard or non-HDMI type
+    HDMI_ELD_TYPE   = 0x00,     // ELD buffer type
+    HDMI_EELD_TYPE  = 0x01,     // EELD buffer type
+    
+    // Per HDMI Spec, refer Table 2-1 in HDMI EDS 
+    // or Table 5-8 in HDMI spec
+    HDMI_VS_TYPE    = 0x81,     // Vendor-Specific InfoFrame type
+    HDMI_AVI_TYPE   = 0x82,     // AVI InfoFrame type
+    HDMI_SPD_TYPE   = 0x83,     // SPD InfoFrame type
+    HDMI_AUDIO_TYPE = 0x84,     // Audio InfoFrame type
+    HDMI_MS_TYPE    = 0x85,     // MPEG Source InfoFrame type
+    
+    // Non-standard or non-HDMI types
+    HDMI_PR_PE_TYPE = 0x86,     // Pixel Replication & Pixel Encoding(colorimetry) type
+    HDMI_AUDIO_CAPS_TYPE = 0x87, // Encoder Audio Capabilities type
+    HDMI_AUDIO_ENABLE_FLAGS_TYPE = 0x88 // Flags for enabling / disabling audio
+} hdmi_info_type_t;
+
+//
+// InfoFrame Version Information
+//
+typedef enum {
+    HDMI_VS_VERSION    = 1,  // Vendor-Specific InfoFrame Version 1
+    HDMI_AVI_VERSION   = 1,  // AVI InfoFrame Version 1
+    HDMI_AVI_VERSION2  = 2,  // AVI InfoFrame Version 2
+    HDMI_SPD_VERSION   = 1,  // SPD InfoFrame Version 1
+    HDMI_AUDIO_VERSION = 1,  // Audio InfoFrame Version 1
+    HDMI_MS_VERSION    = 1   // MPEG Source InfoFrame Version 1
+} infoframe_version_t;
+
+//
+// InfoFrame Payload Length in bytes
+//
+typedef enum {
+    HDMI_VS_MAX_LENGTH     = 27,   // Vendor-Specific InfoFrame Payload Length, including IEEE reg ID
+    HDMI_AVI_LENGTH        = 13,  // AVI InfoFrame Payload Length
+    HDMI_SPD_LENGTH        = 25,  // SPD InfoFrame Payload Length
+    HDMI_AUDIO_LENGTH      = 10,  // Audio InfoFrame Payload Length
+    HDMI_MS_LENGTH         = 10,  // MPEG Source InfoFrame Payload Length
+    HDMI_PR_PE_LENGTH      = 4,   // Length of PR_PE_TYPE
+    HDMI_AUDIO_CAPS_LENGTH = 4    // Length of AUDIO_CAPS_TYPE
+} infoframe_length_t;
+
+//
+// InfoFrame TOTAL Length in bytes (includes header + payload)
+//
+typedef enum {
+    HDMI_VS_MAX_TOTAL_LENGTH     = HDMI_VS_MAX_LENGTH + 4,   // Max Total size of Vendor-Specific InfoFrame
+    HDMI_AVI_TOTAL_LENGTH        = HDMI_AVI_LENGTH + 4,  // Total size of AVI InfoFrame
+    HDMI_SPD_TOTAL_LENGTH        = HDMI_SPD_LENGTH + 4,  // Total size of SPD InfoFrame
+    HDMI_AUDIO_TOTAL_LENGTH      = HDMI_AUDIO_LENGTH + 4,  // Total size of Audio InfoFrame
+    HDMI_MS_TOTAL_LENGTH         = HDMI_MS_LENGTH + 4,  // Total size of MPEG Source InfoFrame
+} infoframe_total_length_t;
+
+
+//
+// Pixel Replication multipliers
+//
+typedef enum {
+    HDMI_PR_ONE = 0,    // No repetition (ie., pixel sent once)
+    HDMI_PR_TWO,        // Pixel sent 2 times (ie.,repeated once)
+    HDMI_PR_THREE,      // Pixel sent 3 times
+    HDMI_PR_FOUR,       // Pixel sent 4 times
+    HDMI_PR_FIVE,       // Pixel sent 5 times
+    HDMI_PR_SIX,        // Pixel sent 6 times
+    HDMI_PR_SEVEN,      // Pixel sent 7 times
+    HDMI_PR_EIGHT,      // Pixel sent 8 times
+    HDMI_PR_NINE,       // Pixel sent 9 times
+    HDMI_PR_TEN         // Pixel sent 10 times
+} hdmi_pixel_replication_t;
+
+//
+// Pixel encoding modes
+//
+//typedef typedef enum  {
+  //  HDMI_RGB256 = 0x01,
+  //  HDMI_RGB220 = 0x02,
+  //  HDMI_YCrCb422 = 0x04,
+  //  HDMI_YCrCb444 = 0x08
+//}HDMI_COLORIMETRY;
+
+//
+// Pixel encoding modes
+//
+typedef enum {
+    HDMI_COLORIMETRY_RGB256 = 0x01,
+    HDMI_COLORIMETRY_RGB220 = 0x02,
+    HDMI_COLORIMETRY_YCrCb422 = 0x04,
+    HDMI_COLORIMETRY_YCrCb444 = 0x08
+} hdmi_colorimetry_t;
+
+//
+// AVI InfoFrame definitions - start
+//
+// Scan Info
+typedef enum {
+    HDMI_AVI_SCAN_NODATA     = 0,     // No data
+    HDMI_AVI_SCAN_OVERSCAN   = 1,     // Overscanned (TV)
+    HDMI_AVI_SCAN_UNDERSCAN  = 2,     // Underscanned (Computer)
+    HDMI_AVI_SCAN_FUTURE     = 3      // Future
+} avi_scan_info_t;
+
+// Bar Info
+typedef enum {
+    HDMI_AVI_BAR_INVALID         = 0,      // Bar data not valid
+    HDMI_AVI_BAR_VALID_VERTICAL  = 1,      // Vertical Bar data valid
+    HDMI_AVI_BAR_VALID_HORIZONTAL= 2,      // Horizontal Bar data valid
+    HDMI_AVI_BAR_VALID_BOTH      = 3       // Vertical & Horizontal Bar data valid
+} avi_bar_info_t;
+
+// Active Format Information
+typedef enum {
+    HDMI_AVI_AFI_INVALID = 0,    // No data
+    HDMI_AVI_AFI_VALID   = 1     // Active Format Information valid
+} avi_fi_info_t;
+
+// AVI Pixel Encoding modes
+typedef enum {
+    HDMI_AVI_RGB_MODE      = 0,  // RGB pixel encoding mode
+    HDMI_AVI_YCRCB422_MODE = 1,  // YCrCb 4:2:2 mode
+    HDMI_AVI_YCRCB444_MODE = 2,  // YCrCb 4:4:4 mode
+    HDMI_AVI_FUTURE_MODE   = 3   // Future mode
+} avi_encoding_mode_t;
+
+// AVI Active Format Aspect Ratio
+typedef enum {
+    HDMI_AVI_AFAR_SAME   = 8,     // same as picture aspect ratio
+    HDMI_AVI_AFAR_4_3    = 9,     // 4:3 center
+    HDMI_AVI_AFAR_16_9   = 10,    // 16:9 center
+    HDMI_AVI_AFAR_14_9   = 11     // 14:9 center
+} avi_afar_info_t;
+
+// AVI Picture Aspect Ratio
+typedef enum {
+    HDMI_AVI_PAR_NODATA  = 0,      // No Data
+    HDMI_AVI_PAR_4_3     = 1,      // 4:3
+    HDMI_AVI_PAR_16_9    = 2,      // 16:9
+    HDMI_AVI_PAR_FUTURE  = 3       // Future
+} avi_par_info_t;
+
+// AVI Colorimetry Information
+typedef enum  {
+    HDMI_AVI_COLOR_NODATA = 0,    // No data
+    HDMI_AVI_COLOR_ITU601 = 1,    // SMPTE 170M, ITU601
+    HDMI_AVI_COLOR_ITU709 = 2,    // ITU709
+    HDMI_AVI_COLOR_FUTURE = 3     // Future
+} avi_color_info_t;
+
+// AVI Non-uniform Picture Scaling Info
+typedef enum {
+    HDMI_AVI_SCALING_NODATA      = 0,  // No scaling
+    HDMI_AVI_SCALING_HORIZONTAL  = 1,  // horizontal scaling
+    HDMI_AVI_SCALING_VERTICAL    = 2,  // vertical scaling
+    HDMI_AVI_SCALING_BOTH        = 3   // horizontal & vertical scaling
+} avi_scaling_infp_t;
+
+// AVI RGB Quantization Range
+typedef enum {
+    HDMI_AVI_RGBQUANT_DEFAULT = 0,  // Default value
+    HDMI_AVI_RGBQUANT_LIMITED = 1,  // Limited Range
+    HDMI_AVI_RGBQUANT_FULL    = 2,  // Full Range
+    HDMI_AVI_RGBQUANT_FUTURE  = 3   // Future use
+} avi_rgbquant_range_t;
+
+// AVI IT Content
+typedef enum {
+    HDMI_AVI_ITC_NODATA    = 0,  // No Data
+    HDMI_AVI_ITC_ITCONTENT = 1   //IT Content
+} avi_it_content_t;
+
+//
+// AVI InfoFrame definitions - end
+//
+
+//
+// SPD InfoFrame definitions - start
+//
+// SPD InfoFrame Data Byte 25, refer Table-17 in CEA-861b
+typedef enum {
+    HDMI_SPD_SRC_UNKNOWN     = 0x00,   // unknown
+    HDMI_SPD_SRC_DIGITAL_STB = 0x01,   // Digital STB
+    HDMI_SPD_SRC_DVD         = 0x02,   // DVD
+    HDMI_SPD_SRC_DVHS        = 0x03,   // D-VHS
+    HDMI_SPD_SRC_HDD_VIDEO   = 0x04,   // HDD Video
+    HDMI_SPD_SRC_DVC         = 0x05,   // DVC
+    HDMI_SPD_SRC_DSC         = 0x06,   // DSC
+    HDMI_SPD_SRC_VCD         = 0x07,   // Video CD
+    HDMI_SPD_SRC_GAME        = 0x08,   // Game
+    HDMI_SPD_SRC_PC          = 0x09    // PC General
+} spd_src_type_t;
+
+// SPD InfoFrame Vendor Name & Descriptor Length in bytes
+typedef enum {
+    HDMI_SPD_VNAME_LENGTH = 8,   // SPD Vendor Name Length in bytes
+    HDMI_SPD_VDESC_LENGTH = 16,  // SPD Vendor Descriptor Length in bytes
+} spd_namedesc_length_info_t;
+
+//
+// SPD InfoFrame definitions - end
+//
+
+//
+// InfoFrame Packet Header - generic
+//
+typedef struct _if_header {
+    uint8_t type;       // InfoFrame Type
+    uint8_t version;    // InfoFrame Version
+    uint8_t length;     // InfoFrame Length
+    uint8_t chksum;     // Checksum of the InfoFrame
+} if_header_t;
+
+//
+// AVI InfoFrame structure
+//
+typedef union _avi_if {
+    uint8_t avi_buf[HDMI_AVI_TOTAL_LENGTH];
+    #pragma pack(1)
+    struct
+    {
+        if_header_t avi_if_header;            // AVI header data
+        union
+        {
+            uint8_t byte1;
+            struct
+            {
+                uint8_t scan_info:2;     // scan information
+                uint8_t bar_info :2;     // bar information
+                uint8_t format  :1;     // active format information
+                uint8_t enc_mode :2;     // pixel encoding (RGB or YCrCb)
+                uint8_t b1rsvd  :1;     // reserved
+            };
+        };
+        union
+        {
+            uint8_t byte2;
+            struct
+            {
+                uint8_t afar        :4; // Active Format Aspect Ratio
+                uint8_t par         :2; // Picture Aspect Ratio
+                uint8_t colorimetry :2; // colorimetry
+            };
+        };
+        union
+        {
+            uint8_t byte3;
+            struct
+            {
+                uint8_t scaling_info    :2; // Scaling information
+                uint8_t rgbquant_range  :2; // RGB Quantization Range
+                uint8_t ext_colorimetry :3; //Extended Colorimetry
+                uint8_t it_content      :1; //IT Content
+            };
+        };
+        union
+        {
+            uint8_t byte4;
+            struct
+            {
+                uint8_t vic         :7; // Video Identification code (refer Table 13 in CEA-861b)
+                uint8_t b4rsvd      :1; // reserved
+            };
+        };
+        union
+        {
+            uint8_t byte5;
+            struct
+            {
+                uint8_t pr          :4; // pixel repetition (refer Table 15 in CEA-861b)
+                uint8_t b5rsvd      :4; // reserved
+            };
+        };
+        uint8_t byte6;                  // end of top bar(lower), set to "00"
+        uint8_t byte7;                  // end of top bar(upper), set to "00"
+        uint8_t byte8;                  // start of bottom bar(lower), set to "00"
+        uint8_t byte9;                  // start of bottom bar(upper), set to "00"
+        uint8_t byte10;                 // end of left bar(lower), set to "00"
+        uint8_t byte11;                 // end of left bar(upper), set to "00"
+        uint8_t byte12;                 // start of right bar(lower), set to "00"
+        uint8_t byte13;                 // start of right bar(upper), set to "00"
+    };
+    #pragma pack()
+} avi_if_t;
+
+//
+// SPD InfoFrame structure
+//
+typedef union _spd_if {
+    uint8_t spd_buf[HDMI_SPD_TOTAL_LENGTH];
+    #pragma pack(1)
+    struct
+    {
+        if_header_t spd_if_header; // SPD header data
+        uint8_t name[8];    // Vendor Name, 8 characters
+        uint8_t desc[16];   // Product Description, 16 characters
+        uint8_t sdi;        // Source Device Information
+    };
+    #pragma pack()
+} spd_if_t;
+
+//
+// Vendor Specific InfoFrame structure
+//
+typedef union _vs_if
+{
+    uint8_t vs_buf[HDMI_VS_MAX_TOTAL_LENGTH];
+    #pragma pack(1)
+    struct
+    {
+        if_header_t vs_if_header; // VS header data
+        uint8_t ieee_reg_id[3];   // 3-byte IEEE registration ID
+        uint8_t pay_load[24];        // Payload bytes
+    };
+    #pragma pack()
+} vs_if_t;
+
+//
+// AVI Infoframe structure for customization
+//
+
+typedef struct _avi_infoframe_custom {
+    //GUID        guid;                   // GUID
+    int32_t     command;              // Command
+    int32_t     flags;                // Flags
+    uint32_t    type_code;             // Type code of AVI Infoframe
+    uint32_t    version;              // Version of AVI Infoframe
+    uint32_t    length;               // Length of AVI Info Frame 
+    uint8_t     r3r0_valid;             // Reserved
+    uint8_t     it_content;             // IT Content
+    uint8_t     bar_info[8];           // Reserved
+    int32_t     active_format_aspect_ratio;// Reserved 
+    int32_t     non_uniform_scaling;     // Reserved 
+    int32_t     rgb_ycc_indicator;       // Reserved 
+    int32_t     ext_colorimetry;        // Reserved 
+    int32_t     pixel_factor;           // Reserved 
+    int32_t     bar_info_valid;           // Reserved 
+    int32_t     colorimetry;           // Reserved 
+    int32_t     aspect_ratio;           // Reserved 
+    int32_t     quant_range;            // Quantization Range
+    int32_t     video_code;             // Reserved 
+    int32_t     scan_info;              // Scan Information
+} avi_infoframe_custom_t;
+
+
+//
+// LinearPCM Consolidated Audio Data(CAD) structure
+//
+typedef union _lpcm_cad {
+    uint8_t value;
+    struct {
+        uint8_t maxch_cp_on       :3; // Max channels-1 supported with CP turned ON
+        uint8_t maxch_cp_off      :3; // Max channels-1 supported with CP turned OFF
+        uint8_t sp_20bit       :1; // 20-bit sample support
+        uint8_t sp_24bit       :1; // 24-bit sample support
+    };
+} lpcm_cad_t;
+
+//
+// CEA Short Audio Descriptor
+// 
+typedef struct _cea_861b_adb {
+#pragma pack(1)
+    union
+    {
+        uint8_t byte1;
+        struct
+        {
+            uint8_t   max_channels        :3; // Bits[0-2]
+            uint8_t   audio_format_code   :4;    // Bits[3-6], see AUDIO_FORMAT_CODES
+            uint8_t   b1reserved          :1;    // Bit[7] - reserved
+        };
+    };
+    union
+    {
+        uint8_t    byte2;
+        struct
+        {
+            uint8_t   sp_rate_32kHz             :1;    // Bit[0] sample rate = 32kHz
+            uint8_t   sp_rate_44kHz             :1;    // Bit[1] sample rate = 44kHz
+            uint8_t   sp_rate_48kHz             :1;    // Bit[2] sample rate = 48kHz
+            uint8_t   sp_rate_88kHz             :1;    // Bit[3] sample rate = 88kHz
+            uint8_t   sp_rate_96kHz             :1;    // Bit[4] sample rate = 96kHz
+            uint8_t   sp_rate_176kHz            :1;    // Bit[5] sample rate = 176kHz
+            uint8_t   sp_rate_192kHz            :1;    // Bit[6] sample rate = 192kHz
+            uint8_t   sp_rate_b2reserved        :1;    // Bit[7] - reserved
+        };
+    };
+    union
+    {
+        uint8_t   byte3;    // maximum bit rate divided by 8kHz
+        // following is the format of 3rd byte for uncompressed(LPCM) audio
+        struct
+        {
+            uint8_t    bit_rate_16bit                :1;    // Bit[0]
+            uint8_t    bit_rate_20bit                :1;    // Bit[1]
+            uint8_t    bit_rate_24bit                :1;    // Bit[2]
+            uint8_t    bit_rate_b3reserved        :5;    // Bits[3-7]
+        };
+    };
+#pragma pack()
+}cea_861b_adb_t; 
+
+//
+// Enhanced EDID Like Data aka EELD structure
+//
+typedef union _hdmi_eeld {
+    uint8_t eeld[HDMI_EELD_SIZE];
+    #pragma pack(1)
+    struct
+    {
+        // Byte[0] = ELD Version Number
+        union
+        {
+            uint8_t   byte0;          
+            struct
+            {
+                uint8_t reserved:3;      // Reserf
+                uint8_t eld_ver:5;      // ELD Version Number
+                                        //  00000b - reserved
+                                        //  00001b - first rev
+                                        //  00010b:11111b - reserved for future
+            };
+        };
+
+        // Byte[1] = Vendor Version Field
+		union
+		{
+			uint8_t vendor_version;
+			struct
+			{
+				uint8_t reserved1:3;
+				uint8_t veld_ver:5; // Version number of the ELD extension.
+				                    // This value is provisioned and unique to each vendor.
+			};
+		};
+
+		// Byte[2] = Baseline Lenght field
+		uint8_t baseline_eld_length; // Length of the Baseline structure divided by Four.
+
+		// Byte [3] = Reserved for future use
+		uint8_t byte3;
+
+		// Starting of the BaseLine EELD structure
+		// Byte[4] = Monitor Name Length 
+		union
+		{
+			uint8_t byte4;
+			struct
+			{
+				uint8_t mnl:5;
+				uint8_t cea_edid_rev_id:3;
+			};
+		};
+
+		// Byte[5] = Capabilities
+		union
+		{
+			uint8_t capabilities;
+			struct
+			{
+				uint8_t hdcp:1; // Indicates HDCP support
+				uint8_t ai_support:1;   // Inidcates AI support
+				uint8_t connection_type:2; // Indicates Connection type 
+				                          // 00 - HDMI
+				                          // 01 - DP
+				                          // 10 -11  Reserved for future connection types
+				uint8_t sadc:4; // Indicates number of 3 bytes Short Audio Descriptors. 
+			};
+		};
+
+		// Byte[6] = Audio Synch Delay
+		uint8_t audio_synch_delay; // Amount of time reported by the sink that the video trails audio in milliseconds.
+
+		// Byte[7] = Speaker Allocation Block
+		union
+		{
+			uint8_t speaker_allocation_block;
+			struct
+			{
+				uint8_t flr:1; // Front Left and Right channels
+				uint8_t lfe:1; // Low Frequency Effect channel
+				uint8_t fc:1;  // Center transmission channel
+				uint8_t rlr:1; // Rear Left and Right channels
+				uint8_t rc:1; // Rear Center channel
+				uint8_t flrc:1; // Front left and Right of Center transmission channels
+				uint8_t rlrc:1; // Rear left and Right of Center transmission channels
+				uint8_t reserved3:1; // Reserved
+			};
+		};
+
+		// Byte[8 - 15] - 8 Byte port identification value
+		uint8_t port_id_value[8];
+
+        // Byte[16 - 17] - 2 Byte Manufacturer ID
+        uint8_t manufacturer_id[2];
+
+        // Byte[18 - 19] - 2 Byte Product ID
+        uint8_t product_id[2];
+
+		// Byte [20-83] - 64 Bytes of BaseLine Data
+	uint8_t mn_sand_sads[64]; // This will include
+		                        // - ASCII string of Monitor name
+                                // - List of 3 byte SADs
+		                        // - Zero padding
+
+		// Vendor ELD Block should continue here!
+        // No Vendor ELD block defined as of now. 
+	};
+    #pragma pack()
+} hdmi_eeld_t;
+
+//
+// Data structure for misc HDMI data
+//
+typedef struct _misc_hdmi_data {
+    int32_t colorimetry   :4; // 
+    int32_t pr            :4; // pixel repetition value
+    int32_t reserved      :24;// reserved bits
+} misc_hdmi_data_t;
+
+//
+// Audio capability structure
+//
+typedef struct _device_audio_caps {
+    int32_t npl_design :8; // max number of audio packets device can
+                        // deliver per line
+    int32_t k0        :8; // The overhead(in pixels) per line requied
+                        // by device for setting up audio packets when
+                        // CP is disabled
+    int32_t k1        :8; // The overhead(in pixels) per line requied
+                        // by device for setting up audio packets when
+                        // CP is enabled
+    // Misc data
+    int32_t pr        :4; // Pixel Replication value
+    int32_t is_hdcp   :1; // Driver, Device and Receiver support HDCP
+    int32_t is_rptr   :1; // Receiver is HDCP repeater
+    int32_t reserved  :2; // reserved bits
+} device_audio_caps_t;
+
+typedef struct _audio_enable_flags {
+    int32_t is_hdmi_display    :1; //1 if HDMI display, 0 if not HDMI display
+    int32_t is_eld_valid       :1; //1 if ELD valid, 0 if ELD not valid
+    int32_t reserved1          :30;
+} audio_enable_flags_t;
+
+//
+// Data structure to exchange HDMI data through GetSetParameters interface
+//
+typedef struct _hdmi_parameters {
+    //GUID              Guid;
+    hdmi_command_t    command;
+    uint8_t           type;
+    uint8_t           size;
+    union {
+        hdmi_eeld_t    eeld_buffer;
+        avi_if_t       avi_infoframe;
+        spd_if_t       spd_infoframe;
+        vs_if_t        vs_infoframe;
+        union {
+            int32_t              gen_data;
+            device_audio_caps_t  audio_caps;
+            misc_hdmi_data_t     misc_data;
+            audio_enable_flags_t fl_audio_enable_flags;
+        };
+    };
+} hdmi_parameters_t;
+
+//
+// Audio format codes
+//
+typedef enum {
+    AUDIO_LPCM      = 0x0001,   // Linear PCM (eg. IEC60958)
+    AUDIO_AC3       = 0x0002,   // AC-3
+    AUDIO_MPEG1     = 0x0003,   // MPEG1 (Layers 1 & 2)
+    AUDIO_MP3       = 0x0004,   // MP3   (MPEG1 Layer 3)
+    AUDIO_MPEG2     = 0x0005,   // MPEG2 (multichannel)
+    AUDIO_AAC       = 0x0006,   // AAC
+    AUDIO_DTS       = 0x0007,   // DTS
+    AUDIO_ATRAC     = 0x0008,    // ATRAC
+    AUDIO_OBA       = 0x0009,   // One Bit Audio
+    AUDIO_DOLBY_DIGITAL = 0x000A, // Dolby Digital
+    AUDIO_DTS_HD    = 0x000B,    // DTS-HD
+    AUDIO_MAT       = 0x000C,    // MAT (MLP)
+    AUDIO_DST       = 0x000D,    // DST
+    AUDIO_WMA_PRO   = 0x000E     // WMA Pro
+} audio_format_codes_t;
+
+//
+// Data structure for byte #6 to 8 which has fixed definition
+//
+typedef struct _vsdb_char6_to_char8
+{
+    #pragma pack(1)
+
+    union
+    {
+        uint8_t byte1;
+        struct
+        {
+            uint8_t dvi_dual      :1; // Bit[0]
+            uint8_t b1reserved    :2; // Bits[1-2]
+            uint8_t dcy444        :1; // Bit[3] YCBCR 4:4:4 in Deep Color modes.
+            uint8_t dc30bit       :1; //Bit[4]
+            uint8_t dc36bit       :1; //Bit[5]
+            uint8_t dc48bit       :1; //Bit[6]
+            uint8_t supports_ai   :1; // Bit[7]
+        };
+        };
+
+    uint8_t max_tmds_clock;
+
+    union
+    {
+        uint8_t byte3;
+        struct
+        {
+            uint8_t b3reserved               :6; // Bit[0-5] reserved
+            uint8_t i_latency_field_present  :1;// Bit[6]
+            uint8_t latency_field_present    :1;// Bits[7]
+        };
+    };
+
+    #pragma pack()
+} vsdb_byte6_to_byte8_t;
+
+
+//
+// Gamut metadata structure
+//
+// Note : The data is written in big endian format
+#if 0
+// GUID for calling GBD interface
+// {EEE24BDF-6D30-40bf-9BA2-139F0FFFC797}
+#define DXVA_HDMI13_GBD_P0_GUID "{EEE24BDF-6D30-40BF-9BA2-139F0FFFC797}"
+DEFINE_GUID(GUID_DXVA_HDMI13_GBD_P0, 0xeee24bdf, 0x6d30, 0x40bf, 0x9b, 0xa2, 0x13, 0x9f, 0xf, 0xff, 0xc7, 0x97);
+#endif
+
+#define HDMI_GBD_PKT_TYPE 0x0A
+#define HDMI_GBD_P0_DATA_SIZE 27
+#define HDMI_MAX_VERTICES_DATA 25
+#define HDMI_MAX_FACET_DATA 25
+
+typedef enum {
+    VERTICES_AND_FACETS = 0,
+    RGB_MIN_MAX_RANGE    = 1
+} gbd_format_flag_t;
+
+typedef enum {
+    GBD_8BIT_PRECISION   = 0,
+    GBD_10BIT_PRECISION  = 1,
+    GBD_12BIT_PRECISION  = 2
+} gbd_color_precision_t;
+
+typedef enum {
+    RGB_BT709 = 0,
+    XVY_CC601 = 1,
+    XVY_CC709 = 2,
+    RESERVED_COLORSPACE
+} gbd_color_space_t;
+
+typedef enum {
+    MIN_RED_INDEX    = 0,
+    MAX_RED_INDEX    = 1,
+    MIN_GREEN_INDEX  = 2,
+    MAX_GREEN_INDEX  = 3,
+    MIN_BLUE_INDEX   = 4,
+    MAX_BLUE_INDEX   = 5,
+    MAX_RANGE_DATA_INDEX_LIMIT = 6
+} gbd_rgb_range_data_index_t;
+    
+//
+// App needs to feel the data in this structure
+//
+typedef struct _gbd_p0_hdmi_1_3 {
+    uint8_t enable;      // Enable/Disable GBD profile sending
+    gbd_format_flag_t     format_flag;         // uses GBD_FORMAT_FLAG_EN, this defines the gamut data format
+    gbd_color_precision_t color_precision;     // uses GBD_COLOR_PRECISION, this is the bit precision of GBD vertex and range data
+    gbd_color_space_t     color_space;         // uses GBD_COLOR_SPACE_EN, this defines the color space being represented
+
+    union 
+    {
+        // If bFormatFlag is 0
+        struct {
+            uint8_t facet_mode;     // spec supports 0 alone right now
+            uint16_t num_vertices;   // Number of vertices 
+            uint16_t num_facets;     // Number of faces
+            
+            // For 4 vertices of 12bits size is 18
+            // Max possible with 0 facets and 28 bytes of GBD is 28-5=23 bytes
+            uint16_t vertices_data[HDMI_MAX_VERTICES_DATA];   // Vertices data representation
+            uint16_t facets_data[HDMI_MAX_FACET_DATA];        // kept it as input data but to be defined based on future spec
+        } vertices_facets_data;
+
+
+        // If eFormatFlag is 1
+        struct {
+            uint16_t rgb_primary_data[MAX_RANGE_DATA_INDEX_LIMIT];
+        } rgb_range_data;
+    };    
+
+} gbd_p0_hdmi_1_3_t;
+
+#define HDMI_GBD_MAX_SEQ_NUM_INDEX 16
+
+// various GBD profiles
+typedef enum {
+    P0_PROFILE = 0,
+    P1_PROFILE = 1,
+    P2_PROFILE = 2,
+    P3_PROFILE = 3,
+    INVALID_PROFILE
+} gbd_profile_type_t;
+
+// various packet transmission options
+typedef enum {
+    INTERMEDIATE_PKT_IN_SEQ   = 0,
+    FIRST_PKT_IN_SEQ          = 1,
+    LAST_PKT_IN_SEQ           = 2,
+    ONLY_PKT_IN_SEQ           = 3
+} gbd_pkt_seq_t;
+
+//
+// Packet header defn as per HDMI spec
+//
+typedef struct _gamut_pkt_header {
+    uint8_t pkt_type; // Defines the pkt type
+    union{
+        uint8_t field_byte;
+        struct{
+            uint8_t affected_gamut_info  :4; // BIT 3:0
+            uint8_t gbd_profile          :3; // BIT 6:4 ; uses GBD_PROFILE_TYPE_EN
+            uint8_t next_field           :1; // BIT7
+        };
+    };
+
+    union{
+        uint8_t gbd_seq_info;
+        struct{
+            uint8_t current_gamut_info    :4; // BIT 3:0
+            uint8_t packet_seq            :2; // BIT 5:4 ; use GBD_PKT_SEQ_EN
+            uint8_t reserved2             :1; // BIT 6
+            uint8_t no_current_gbd        :1; // BIT 7
+        };
+    };
+} gamut_pkt_header_t;
+        
+//
+// Gamut structure contains data in following format
+// 
+typedef struct _gamut_metadata_struct {
+    #pragma pack(1)
+    gamut_pkt_header_t pkt_hdr;           // Gamut Metadata header data
+    union
+    {
+        uint8_t byte1;
+        struct
+        {
+            uint8_t gbd_color_space       :3; 
+            // Note: GBD buffer is formatted based upon the color precision
+            // 8 bit precision : 1 sign bit, 2 bits of integer, 5 bits of fraction
+            // 10 bit precision : 1 sign bit, 2 bits of integer, 7 bits of fraction
+            // 12 bit precision : 1 sign bit, 2 bits of integer, 9 bits of fraction
+            uint8_t gbd_color_precision   :2; 
+            uint8_t reserved3            :1; 
+            uint8_t facet_mode            :1;  // 0 - No facet info in GBD; 1 - Facet info in GBD
+            uint8_t format_flag          :1; // uses GBD_FORMAT_FLAG_EN
+        };
+    };
+
+    // For P0 profile below is the syntax in which data will be filled
+    // If Format is YUV
+    // char 2 : Higher 8 bits of number of vertices
+    // char 3 : Lower 8 bits of number of vertices
+    // char 4 to VSIZE+2 : Vertex data of size VSIZE, 
+    // where VSIZE = 3*number of vertices*GBD color precision/8 + 0.99999
+    // char VSIZE+3: Higher 8 bits of number of facets
+    // char VSIZE+4: Lower 8 bits of number of facets
+    // char VSIZE+5 to VSIZE+FSIZE+4 : Facet data
+    // where VSIZE = number of facet data
+    uint8_t   gbd_data[HDMI_GBD_P0_DATA_SIZE];         // data will be filled
+            
+    #pragma pack()
+} gamut_metadata_st_t;
+
+struct mid_intel_hdmi_priv {
+	u32 hdmi_reg;
+	u32 save_HDMIB;
+	bool has_hdmi_sink;
+	bool has_hdmi_audio;
+	/* Should set this when detect hotplug */
+	bool hdmi_device_connected;
+	struct mdfld_hdmi_i2c *i2c_bus;
+	/* EELD packet holder*/
+	hdmi_eeld_t eeld;
+	u32 hdmi_eeld_size;
+	cea_861b_adb_t lpcm_sad;
+	bool is_hdcp_supported;
+	struct i2c_adapter *hdmi_i2c_adapter;	/* for control functions */
+	struct drm_device *dev;
+};
+
+struct hdmi_edid_info {
+	char monitor_name[HDMI_MONITOR_NAME_LENGTH];
+	char *edid_info;
+};
+
+#define HDMI_EDID_INFO(nm, info) \
+	.monitor_name = nm, .edid_info = info
+
+#define MSIC_IRQLVL1_STATUS 0x02
+  #define VREG_STATUS (1 << 5)
+#define MSIC_VRINT_STATUS 0x0d
+  #define HDMI_HPD_STATUS (1 << 3)
+  #define HDMI_OCP_STATUS (1 << 2)
+  #define VR_OCP_STATUS (1 << 1)
+  #define VR_OVP_STATUS (1 << 0)
+#define MSIC_VRINT_MASK 0x1c
+  #define HDMI_HPD_MASK (1 << 3)
+  #define HDMI_OCP_MASK (1 << 2)
+  #define VR_OCP_MASK (1 << 1)
+  #define VR_OVP_MASK (1 << 0)
+#define MSIC_IRQLVL1_MASK 0x21
+  #define VREG_MASK (1 << 5)
+#define MSIC_VCC330CNT 0xd3
+  #define VCC330_OFF 0x24
+  #define VCC330_ON 0x37
+#define MSIC_VHDMICNT 0xde
+  #define VHDMI_OFF 0x25
+  #define VHDMI_ON 0xa5
+#define MSIC_HDMI_STATUS 0x281
+  #define HPD_SIGNAL_STATUS (1 << 0)
+
+#endif //__IHDMI_H__
diff --git a/drivers/staging/cdv/drv/psb_intel_hdmi_edid.h b/drivers/staging/cdv/drv/psb_intel_hdmi_edid.h
new file mode 100644
index 0000000..583abb2
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_hdmi_edid.h
@@ -0,0 +1,1057 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	
+ */
+/* chunfeng.zhao@intel.com
+  */
+#ifndef PSB_INTEL_HDMI_EDID_H
+#define PSB_INTEL_HDMI_EDID_H
+
+//#include "..\\..\\Common\\Platform.h"
+
+////////////////////////////////////////////
+//
+// Max number of EDID extensions possible
+//
+////////////////////////////////////////////
+#define MAX_EDID_EXTENSIONS				254  //Max EDID blocks minus Block 0
+#define NUM_BASEEDID_STANDARD_TIMING	8
+#define MAX_BASEEDID_DTD_BLOCKS			4
+
+#define MAX_VIC_DEFINED					128  
+
+// New Macros for supporting EDID 1.4
+
+// Macros for EDID Revision and Version
+#define EDID_VERSION_1 0x01
+#define EDID_REVISION_4 0x04
+
+// Macros for CVT and GTF related support in Monitor descriptor
+#define EDID14_CVT_TIMING_SUPPORTED 0x04
+#define EDID14_DEFAULT_GTF_SUPPORTED 0x00
+#define EDID14_SECONDARY_GTF_SUPPORTED 0x02
+
+// Macros for display device data block in CEA.
+#define EDID14_DISPLAY_DEVICE_DATA_TAG 0xFF
+#define EDID14_DISPLAY_DEVICE_DATA_CHILD_TAG 0x02
+#define EDID14_DISPLAY_DEVICE_DATA_LENGTH 0x20
+#define EDID14_DISPLAY_PORT_INTERFACE 0x09
+
+// Macros indicating digital interfaces supported by the display. 
+#define EDID14_DVI_SUPPORTED 0x01
+#define EDID14_DISPLAY_PORT_SUPPORTED 0x05
+#define EDID14_HDMI_A_SUPPORTED 0x02
+#define EDID14_HDMI_B_SUPPORTED 0x03
+
+#define EDID14_MAX_MONITOR_DESCRIPTORS 0x03
+
+// Macros related to EDID 1.4 Color Bit Depth support
+#define EDID14_COLOR_BIT_DEPTH_UNDEFINED         0x00
+#define EDID14_SIX_BITS_PER_PRIMARY_COLOR        0x06
+#define EDID14_EIGHT_BITS_PER_PRIMARY_COLOR      0x08
+#define EDID14_TEN_BITS_PER_PRIMARY_COLOR        0x0A
+#define EDID14_TWELVE_BITS_PER_PRIMARY_COLOR     0x0C
+#define EDID14_FOURTEEN_BITS_PER_PRIMARY_COLOR   0x0E
+#define EDID14_SIXTEEN_BITS_PER_PRIMARY_COLOR    0x10
+#define EDID14_INVALID_COLOR_BIT_DEPTH           0x07
+
+// Macro for showing Color Bit Depth support for existing displays
+#define EDID_EIGHT_BITS_PER_PRIMARY_COLOR        0x08
+
+// Macro for Established Timings III Block descriptor 
+#define EST_TIMINGS_III_BLOCK_TAG                0xF7
+#define EST_TIMINGS_III_BLOCK_DATA_LENGTH        0x06
+
+// Macro for indicating byte length
+#define BYTE_LENGTH                              0x08
+
+////////////////////////////////////////////
+//
+// Max number of EDID Blocks
+//
+////////////////////////////////////////////
+#define MAX_EDID_BLOCKS					255 //According to E-EDID Standard doc.
+#define EDID_BLOCK_SIZE					128
+
+// Macros for EDID Revision and Version for EDID 1.3
+#define EDID_VERSION_1_3 0x01
+#define EDID_REVISION_1_3 0x03
+
+////////////////////////////////////////////
+// Base EDID header
+////////////////////////////////////////////
+static const unsigned char BASEEDID_Header[8] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
+
+// Display Range Limits Offset Flags.
+// Applicable only from EDID 1.4 onwards
+typedef union _edid_range_limits_flags {
+	uint8_t	ucRangeLimitOffsetFlags;	// Range Limits Offset Flags
+	struct {
+		uint8_t	ucVerticalRateOffset   : 2; // Vertical Rate Offset
+		uint8_t	ucHorizontalRateOffset : 2; // Horizontal Rate Offset
+		uint8_t	ucReserved             : 4; // Reserved.
+		};
+} edid_range_limits_flags_t;
+
+////////////////////////////////////////////
+//
+//	18-byte DTD block
+//  Refer Table 3.16, 3.17 & 3.18 of 
+//  EDID spec
+//
+////////////////////////////////////////////
+typedef struct _edid_dtd_timing {
+#pragma pack(1)
+
+	int16_t wPixelClock;					// Pixel clock / 10000
+
+	uint8_t ucHA_low;						// Lower 8 bits of H. active pixels
+	uint8_t ucHBL_low;					// Lower 8 bits of H. blanking
+	union {
+		uint8_t ucHAHBL_high;
+		struct {
+			uint8_t	ucHBL_high : 4;		// Upper 4 bits of H. blanking
+			uint8_t	ucHA_high  : 4;		// Upper 4 bits of H. active pixels
+		};
+	};
+
+	uint8_t ucVA_low;						// Lower 8 bits of V. active lines
+	uint8_t ucVBL_low;					// Lower 8 bits of V. blanking
+	union {
+		uint8_t ucVAVBL_high;
+		struct {
+			uint8_t	ucVBL_high : 4;		// Upper 4 bits of V. blanking
+			uint8_t	ucVA_high  : 4;		// Upper 4 bits of V. active pixels
+		};
+	};
+
+	uint8_t ucHSO_low;					// Lower 8 bits of H. sync offset
+	uint8_t ucHSPW_low;					// Lower 8 bits of H. sync pulse width
+	union {
+		uint8_t ucVSOVSPW_low;
+		struct {
+			uint8_t	ucVSPW_low : 4;		// Lower 4 bits of V. sync pulse width
+			uint8_t	ucVSO_low  : 4;		// Lower 4 bits of V. sync offset
+		};
+	};
+	union {
+		uint8_t ucHSVS_high;
+		struct {
+			uint8_t	ucVSPW_high : 2;	// Upper 2 bits of V. sync pulse width
+			uint8_t	ucVSO_high  : 2;	// Upper 2 bits of V. sync offset
+			uint8_t	ucHSPW_high : 2;	// Upper 2 bits of H. sync pulse width
+			uint8_t	ucHSO_high  : 2;	// Upper 2 bits of H. sync offset
+		};
+	};
+
+	uint8_t ucHIS_low;					// Lower 8 bits of H. image size in mm
+	uint8_t ucVIS_low;					// Lower 8 bits of V. image size in mm
+	union {
+		uint8_t ucHISVIS_high;
+		struct {
+			uint8_t	ucVIS_high : 4;		// Upper 4 bits of V. image size
+			uint8_t	ucHIS_high : 4;		// Upper 4 bits of H. image size
+		};
+	};
+
+	uint8_t ucHBorder;					// H. border in pixels
+	uint8_t ucVBorder;					// V. border in pixels
+
+	union {
+		uint8_t ucFlags;					// Hsync & Vsync polarity, etc. flags
+		struct {
+			uint8_t	ucStereo1	 : 1;	// Stereo definition with bit[6:5]
+			uint8_t	ucHSync_Pol  : 1;	// Hsync polarity (0: Neg, 1: Pos)
+			uint8_t	ucVSync_Pol  : 1;	// Vsync polarity (0: Neg, 1: Pos)
+			uint8_t	ucSync_Conf  : 2;	// Sync configuration
+										// 00 : Analog composite
+										// 01 : Bipolar analog composite
+										// 00 : Digital composite
+										// 00 : Digital separate
+			uint8_t	ucStereo2	 : 2;	// Stereo definition
+										// 00 : Normal display, no stereo 
+										// xx : Stereo definition with bit0
+			uint8_t	ucInterlaced : 1;	// Interlaced / Non-interlaced
+										// 0 : Non-interlaced
+										// 1 : Interlaced
+		};
+	};
+
+#pragma pack()
+} edid_dtd_timing_t;
+
+
+////////////////////////////////////////////
+//
+//	Standard timing identification
+//  Refer Table 3.15 of EDID spec
+//
+////////////////////////////////////////////
+typedef union _edid_std_timing {
+	uint16_t  usStdTiming;
+
+	struct {
+#pragma pack(1)
+		uint8_t	ucHActive;				// (HActive/8) - 31;
+		struct {
+			uint8_t	ucRefreshRate : 6;	// Refresh Rate - 60
+			uint8_t	ucAspectRatio : 2;	// Aspect ratio (HActive/VActive)
+										// 00:  1:1 Aspect ratio
+										// 01:  4:3 Aspect ratio
+										// 10:  5:4 Aspect ratio
+										// 11: 16:9 Aspect ratio
+		};
+	};
+#pragma pack()
+
+} edid_std_timing_t;
+////////////////////////////////////////////////////////
+// Aspect Ratio def's as per Edid 1.3 Standard Timings
+////////////////////////////////////////////////////////
+#define EDID_STD_ASPECT_RATIO_16_10   0x0
+#define EDID_STD_ASPECT_RATIO_4_3     0x1
+#define EDID_STD_ASPECT_RATIO_5_4     0x2
+#define EDID_STD_ASPECT_RATIO_16_9    0x3
+
+
+////////////////////////////////////////////
+//
+//	Monitor range limits
+//
+////////////////////////////////////////////
+typedef struct _monitor_range_limits {	
+#pragma pack(1)
+
+	uint8_t ucMin_vert_rate;			//Min Vertical Rate,in Hz
+	uint8_t ucMax_vert_rate;			//Max Vertical Rate, in Hz
+	uint8_t ucMin_horz_rate;			//Min Horizontal Rate, in Hz
+	uint8_t ucMax_horz_rate;			//Max Horizontal Rate, in Hz
+	uint8_t ucMax_pixel_clock;		//Max Pixel Clock,Value/10 Mhz
+	uint8_t ucTiming_formula_support;	//00 - No Secondary Timing Formula Supported
+									//02 - Secondary GTF Curve Supported
+									//In EDID 1.4, this may indicate CVT support as well
+	//If timing_formula_support is 02
+	uint8_t ucReserved;				//00h
+	uint8_t ucStart_freq;				//Horizontal Freq, Value/2, KHz
+	uint8_t ucByte_C;					//C*2
+	uint8_t ucLSB_M;					//LSB of M Value
+	uint8_t ucMSB_M;					//MSB of M Value
+	uint8_t ucByte_K;					//K Value
+	uint8_t ucByte_J;					//J*2
+
+#pragma pack()
+} monitor_range_limits_t;
+
+////////////////////////////////////////////
+//
+// Color point
+//
+////////////////////////////////////////////
+typedef struct _color_point {
+#pragma pack(1)
+
+	uint8_t ucWhite_point_index_number_1;
+	uint8_t ucWhite_low_bits_1;
+	uint8_t ucWhite_x_1;
+	uint8_t ucWhite_y_1;
+	uint8_t ucWhite_gamma_1;
+	uint8_t ucWhite_point_index_number_2;
+	uint8_t ucWhite_low_bits_2;
+	uint8_t ucWhite_x_2;
+	uint8_t ucWhite_y_2;
+	uint8_t ucWhite_gamma_2;
+	uint8_t ucByte_15;
+	uint8_t ucByte_16_17[2];
+
+#pragma pack()
+} color_point_t;
+
+////////////////////////////////////////////
+//
+//	Monitor description descriptor
+//  Refer Table 3.19 & 3.20 of EDID spec
+//
+////////////////////////////////////////////
+#define BASEEDID_MONITORSN_MDDATATYPE			0xFF
+#define BASEEDID_ASCIISTRING_MDDATATYPE			0xFE
+#define BASEEDID_MONITORRANGELIMIT_MDDATATYPE	0xFD
+#define BASEEDID_MONITORNAME_MDDATATYPE			0xFC
+#define BASEEDID_COLORPOINT_MDDATATYPE			0xFB
+#define BASEEDID_STDTIMINGS_MDDATATYPE			0xFA
+
+// Structure definition for Established Timings III monitor block
+typedef struct _est_timings_iii_block {
+#pragma pack(1)
+	// The first byte will show the VESA DMTS Standard Version. 
+	// The following six bytes will have the Timings Bit Mask.
+	// Right now only 6 bytes are used for this!!!
+	// Rest is reserved.
+	uint8_t ucVesaDMTVersion;	//Byte 0 indicating the VESA DMT Version.
+	uint8_t ucTimingBitMask[6];// Next 6 bytes indicating the Timing Bit Mask Bytes used in Est Timing III.
+	uint8_t bReserved[6];//Next 6 bytes are reserved
+#pragma pack()
+} est_timings_iii_block_t;
+
+typedef struct _monitor_descriptor {
+#pragma pack(1)
+
+	int16_t wFlag;			// = 0000 when block is used as descriptor
+	uint8_t ucFlag0;		// Reserved
+
+	uint8_t ucDataTypeTag;
+
+	uint8_t ucFlag1;		// 00 for descriptor
+	
+	union {
+
+		// Monitor S/N (ucDataTypeTag = FF)
+		uint8_t ucMonitorSerialNumber[13];
+
+		// ASCII string (ucDataTypeTag = FE)
+		uint8_t ucASCIIString[13];
+
+		// Monitor range limit (ucDataTypeTag = FD)
+		monitor_range_limits_t MonitorRangeLimits;
+
+		// Monitor name (ucDataTypeTag = FC)
+		uint8_t ucMonitorName[13];
+
+		// Color point (ucDataTypeTag = FB)
+		color_point_t ColorPoint;
+
+		// ESTABLISHED TIMINGS III BLOCK = F7 (Added for EDID 1.4)
+		est_timings_iii_block_t stEstTimingsIIIBlock;
+
+		// Standard timings (ucDataTypeTag = FA)
+		struct {
+			edid_std_timing_t ExtraStdTiming[6];
+			uint8_t ucFixedValueOfA0;		// Should be 0xA0
+		};
+
+		// Manufacturer specific value (ucDataTypeTag = 0F-00)
+		uint8_t ucMfgSpecificData[13];
+	};
+
+#pragma pack()
+} monitor_descriptor_t;
+
+////////////////////////////////////////////
+//
+//	EDID PnP ID fields
+//
+////////////////////////////////////////////
+typedef union _baseedid_pnpid {
+	uint8_t		VendorProductID[10];	// Vendor / Product identification
+
+	struct {
+		uint8_t ManufacturerID[2];	// Bytes 8, 9: Manufacturer ID 
+		uint8_t ProductID[2];			// Bytes 10, 11: Product ID
+		uint8_t SerialNumber[4];		// Bytes 12-15: Serial numbers
+		uint8_t WeekOfManufacture;	// Byte 16: Week of manufacture
+		uint8_t YearOfManufacture;	// Byte 17: Year of manufacture
+	};
+} baseedid_pnpid_t;
+
+//
+// Chromaticity structure
+// Table 3.12 of Base Block for details
+//
+typedef struct _baseedid_chromaticity_block {
+    union{
+            uint8_t RedGreenLowBits;           // Byte 1
+           struct{
+                uint8_t ucGreenYLowBits   : 2; // bit 1:0
+                uint8_t ucGreenXLowBits   : 2; // bit 3:2
+                uint8_t ucRedYLowBits     : 2; // bit 5:4
+                uint8_t ucRedXLowBits     : 2; // bit 7:6
+            };
+        };
+
+    union{
+            uint8_t ucBlueWhiteLowBits;       // Byte 2
+           struct{
+                uint8_t ucWhiteYLowBits   : 2; // bit 1:0
+                uint8_t ucWhiteXLowBits   : 2; // bit 3:2
+                uint8_t ucBlueYLowBits    : 2; // bit 5:4
+                uint8_t ucBlueXLowBits    : 2; // bit 7:6
+            };
+        };
+
+    uint8_t ucRedXUpperBits; // bit 9:2          Byte 3
+    uint8_t ucRedYUpperBits; // bit 9:2          Byte 4
+
+    uint8_t ucGreenXUpperBits; // bit 9:2        Byte 5
+    uint8_t ucGreenYUpperBits; // bit 9:2        Byte 6
+
+    uint8_t ucBlueXUpperBits; // bit 9:2         Byte 7
+    uint8_t ucBlueYUpperBits; // bit 9:2         Byte 8
+
+    uint8_t ucWhiteXUpperBits; // bit 9:2        Byte 9
+    uint8_t ucWhiteYUpperBits; // bit 9:2        Byte 10
+} baseedid_chromaticity_block_t;
+
+////////////////////////////////////////////
+//
+//	128-byte EDID 1.x block0 structure
+//
+////////////////////////////////////////////
+typedef struct _baseedid_1_x {
+#pragma pack(1)
+
+	//
+	// Header: 8 bytes (Table 3.3 of EDID spec)
+	char		Header[8];		// EDID1.x header "0 FFh FFh FFh FFh FFh FFh 0"
+	
+	//
+	// Vendor/Product ID: 10 bytes (Table 3.4, 3.5 & 3.6 of EDID spec)
+	//baseedid_pnpid_t;
+	union {
+		uint8_t		VendorProductID[10];	// Vendor / Product identification
+		struct {
+			uint8_t ManufacturerID[2];	// Bytes 8, 9: Manufacturer ID 
+			uint8_t ProductID[2];			// Bytes 10, 11: Product ID
+			uint8_t SerialNumber[4];		// Bytes 12-15: Serial numbers
+			uint8_t WeekOfManufacture;	// Byte 16: Week of manufacture
+			uint8_t YearOfManufacture;	// Byte 17: Year of manufacture
+		};
+	};
+	
+	//
+	// EDID structure Version/Revision: 2 bytes (Table 3.7 of EDID spec)
+	uint8_t		ucVersion;		// EDID version no.
+	uint8_t		ucRevision;		// EDID revision no.
+	
+	//
+	// Basic display parameters & features: 5 bytes (Table 3.8 of EDID spec)
+	union {
+		uint8_t	ucVideoInput;	// Video input definition (Refer Table 3.9 of EDID spec)
+
+		struct {
+			uint8_t	ucSyncInput	 : 4;	// Sync input supported (iff ucDigitInput = 0)
+			uint8_t	ucSetup		 : 1;	// Display setup (iff ucDigitInput = 0)
+			uint8_t	ucSigLevStd	 : 2;	// Signal level Standard (iff ucDigitInput = 0)
+
+			uint8_t	ucDigitInput : 1;	// 1: Digital input; 0: Analog input
+		};
+	};
+	
+	// Image size (Table 3.10 of EDID spec)
+	uint8_t		ucMaxHIS;		// Maximum H. image size in cm
+	uint8_t		ucMaxVIS;		// Maximum V. image size in cm
+	
+	// Gamma (display transfer characteristic)
+	uint8_t		ucGamma;		// Display gamma value	[= (gamma*100)-100]
+	
+	// Feature support (Table 3.11 of EDID spec)
+	union {
+		uint8_t	ucDMPSFeature;	// DPMS feature support
+		
+		struct {
+			uint8_t	ucGTFSupport : 1;	// GTF timing support (1: Yes)
+			uint8_t	ucPTM		 : 1;	// Preferred timing is 1st DTD (1: Yes) [Must if EDID >= 1.3]
+			uint8_t	ucColorSpace : 1;	// Use STD color space (1:Yes) [If set ColorChars should match sRGB values in EDID spec Appendix A]
+			uint8_t	ucDispType	 : 2;	// Display type
+										// 00: Monochrome
+										// 01: R/G/B color display
+										// 10: Non R/G/B multicolor display
+										// 11: Undefined
+			uint8_t	ucActiveOff	 : 1;	// Active off (Display consumes less power/blanks out when it receives an out of range timing)
+			uint8_t	ucSuspend	 : 1;	// Suspend	(Refer VESA DPMS spec)
+			uint8_t	ucStandBy	 : 1;	// Stand-by	(Refer VESA DPMS spec)
+		};
+	};
+
+	//
+	// Phosphor or Filter Chromaticity: 10 bytes
+	uint8_t		ColorChars[10];	// Color characteristics	(Refer Table 3.12 of EDID spec)
+
+	//
+	// Established timings: 3 bytes (Table 3.14 of EDID spec)
+	union {
+		uint8_t EstTiming1;
+		struct {
+			uint8_t bSupports800x600_60	: 1;
+			uint8_t bSupports800x600_56	: 1;
+			uint8_t bSupports640x480_75	: 1;
+			uint8_t bSupports640x480_72	: 1;
+			uint8_t bSupports640x480_67	: 1;
+			uint8_t bSupports640x480_60	: 1;
+			uint8_t bSupports720x400_88	: 1;
+			uint8_t bSupports720x400_70	: 1;
+		};
+	};
+	union {
+		uint8_t EstTiming2;
+		struct {
+			uint8_t bSupports1280x1024_75	: 1;
+			uint8_t bSupports1024x768_75	: 1;
+			uint8_t bSupports1024x768_70	: 1;
+			uint8_t bSupports1024x768_60	: 1;
+			uint8_t bSupports1024x768_87i : 1;
+			uint8_t bSupports832x624_75	: 1;
+			uint8_t bSupports800x600_75	: 1;
+			uint8_t bSupports800x600_72	: 1;
+		};
+	};
+	union {
+		uint8_t MfgTimings;
+		struct {
+			uint8_t bMfgReservedTimings	: 7;
+			uint8_t bSupports1152x870_75	: 1;
+		};
+	};
+
+	//
+	// Standard timings: 8 bytes (Table 3.15 of EDID spec)
+	edid_std_timing_t	StdTiming[NUM_BASEEDID_STANDARD_TIMING];	// 8 Standard timing support
+
+	//
+	// Detailed timing section - 72 bytes (4*18 bytes)
+	union {
+		edid_dtd_timing_t	DTD[MAX_BASEEDID_DTD_BLOCKS];			// Four DTD data blocks
+
+		monitor_descriptor_t MonitorInfo[MAX_BASEEDID_DTD_BLOCKS];
+	};
+	
+	uint8_t		ucNumExtBlocks;	// Number of extension EDID blocks
+	uint8_t		ucChecksum;		// Checksum of the EDID block
+
+#pragma pack()
+} baseedid_1_x_t;
+
+////////////////////////////////////////////
+//
+//	128-byte EDID 1.4 block0 structure
+//  EDID 1.4 block0 structure is different from 1.3 block0
+//  Thats why this new structure has been added 
+//  Changes are commented in the structure itself
+//
+////////////////////////////////////////////
+typedef struct _baseedid_1_4 {
+#pragma pack(1)
+
+	//
+	// Header: 8 bytes (Table 3.3 of EDID spec)
+	char		Header[8];		// EDID1.x header "0 FFh FFh FFh FFh FFh FFh 0"
+	
+	//
+	// Vendor/Product ID: 10 bytes (Table 3.4, 3.5 & 3.6 of EDID spec)
+	union {
+		uint8_t		VendorProductID[10];	// Vendor / Product identification
+		struct {
+			uint8_t ManufacturerID[2];	// Bytes 8, 9: Manufacturer ID 
+			uint8_t ProductID[2];			// Bytes 10, 11: Product ID
+			uint8_t SerialNumber[4];		// Bytes 12-15: Serial numbers
+			uint8_t WeekOfManufacture;	// Byte 16: Week of manufacture
+			uint8_t YearOfManufacture;	// Byte 17: Year of manufacture
+		};
+	};
+	
+	//
+	// EDID structure Version/Revision: 2 bytes (Table 3.7 of EDID spec)
+	uint8_t		ucVersion;		// EDID version no.
+	uint8_t		ucRevision;		// EDID revision no.
+	
+	//
+	// Basic display parameters & features: 5 bytes (Table 3.8 of EDID spec)
+	union {
+		uint8_t	ucVideoInput;	// Video input definition (Refer Table 3.9 of EDID spec)
+
+		struct {
+			uint8_t	ucSyncInput	 : 4;	// Sync input supported (iff ucDigitInput = 0)
+			uint8_t	ucSetup		 : 1;	// Display setup (iff ucDigitInput = 0)
+			uint8_t	ucSigLevStd	 : 2;	// Signal level Standard (iff ucDigitInput = 0)
+
+			uint8_t	ucDigitInput : 1;	// 1: Digital input; 0: Analog input
+		};
+		// This structure has been introduced to reflect the changes in EDID 1.4 spec
+		// This sturcture shows new meaning of VIDEO INPUT DEFINITION when input is digital 
+		struct {
+			uint8_t	ucDigitalVideoInterface : 4;	// Digital Video Interface Standard Supported.
+			uint8_t	ucColorBitDepth			: 3;	// Color Bit Depth. 
+													// 0 0 0 -- Color Bit Depth is undefined
+													// 0 0 1 -- 6 Bits per Primary Color
+													// 0 1 0 -- 8 Bits per Primary Color
+													// 0 1 1 -- 10 Bits per Primary Color
+													// 1 0 0 -- 12 Bits per Primary Color
+													// 1 0 1 -- 14 Bits per Primary Color
+													// 1 1 0 -- 16 Bits per Primary Color
+													// 1 1 1 -- Reserved (Do Not Use)
+			uint8_t	bIsDigitalVideoSignalInterface	: 1; // Bit 7
+		};
+	};
+	
+	// As per the EDID spec 1.4, the following two fields can be aspect ratios as well. 
+	union {
+			uint8_t ucMaxHIS; // Maximum H. image size in cm 
+			uint8_t ucARLandscape; // Landscape Aspect raio as per EDID 1.4 spec
+	};
+	union {
+			uint8_t ucMaxVIS; // Maximum V. image size in cm 
+			uint8_t ucARPortrait; // Portrait Aspect raio as per EDID 1.4 spec
+	};
+	
+	// Gamma (display transfer characteristic)
+	uint8_t		ucGamma;		// Display gamma value	[= (gamma*100)-100]
+	
+	// Feature support (Table 3.11 of EDID spec)
+	union {
+		uint8_t	ucDMPSFeature;	// DPMS feature support
+		
+		struct {
+			uint8_t	ucContinuousDisplay : 1;	// Display is continuous or non-continuous (1: Yes)
+			uint8_t	ucPTM		 : 1;	// Preferred timing mode indicates native pixel format and native RR. 
+			uint8_t	ucColorSpace : 1;	// Use STD color space (1:Yes) [If set ColorChars should match sRGB values in EDID spec Appendix A]
+			uint8_t	ucDispType	 : 2;	// Display type
+										// 00: Monochrome
+										// 01: R/G/B color display
+										// 10: Non R/G/B multicolor display
+										// 11: Undefined
+			uint8_t	ucActiveOff	 : 1;	// Active off (Display consumes less power/blanks out when it receives an out of range timing)
+			uint8_t	ucSuspend	 : 1;	// Suspend	(Refer VESA DPMS spec)
+			uint8_t	ucStandBy	 : 1;	// Stand-by	(Refer VESA DPMS spec)
+		};
+
+		struct {
+			uint8_t	bReserved0 : 1;
+			uint8_t	bReserved1 : 1;
+			uint8_t	bReserved2 : 1;
+			uint8_t	ucColorEncodingFormat	 : 2;	// Supported Color Encoding Format if Video Input is digital
+													// 00: RGB 4:4:4
+													// 01: RGB 4:4:4 & YCrCb 4:4:4
+													// 10: RGB 4:4:4 & YCrCb 4:2:2
+													// 11: RGB 4:4:4 & YCrCb 4:4:4 & YCrCb 4:2:2
+			uint8_t	bReserved3 : 1;
+			uint8_t	bReserved4 : 1;
+			uint8_t	bReserved5 : 1;
+		};
+	};
+
+	//
+	// Phosphor or Filter Chromaticity: 10 bytes
+	uint8_t		ColorChars[10];	// Color characteristics	(Refer Table 3.12 of EDID spec)
+
+	//
+	// Established timings: 3 bytes (Table 3.14 of EDID spec)
+	union {
+		uint8_t EstTiming1;
+		struct {
+			uint8_t bSupports800x600_60	: 1;
+			uint8_t bSupports800x600_56	: 1;
+			uint8_t bSupports640x480_75	: 1;
+			uint8_t bSupports640x480_72	: 1;
+			uint8_t bSupports640x480_67	: 1;
+			uint8_t bSupports640x480_60	: 1;
+			uint8_t bSupports720x400_88	: 1;
+			uint8_t bSupports720x400_70	: 1;
+		};
+	};
+	union {
+		uint8_t EstTiming2;
+		struct {
+			uint8_t bSupports1280x1024_75	: 1;
+			uint8_t bSupports1024x768_75	: 1;
+			uint8_t bSupports1024x768_70	: 1;
+			uint8_t bSupports1024x768_60	: 1;
+			uint8_t bSupports1024x768_87i : 1;
+			uint8_t bSupports832x624_75	: 1;
+			uint8_t bSupports800x600_75	: 1;
+			uint8_t bSupports800x600_72	: 1;
+		};
+	};
+	union {
+		uint8_t MfgTimings;
+		struct {
+			uint8_t bMfgReservedTimings	: 7;
+			uint8_t bSupports1152x870_75	: 1;
+		};
+	};
+
+	//
+	// Standard timings: 8 bytes (Table 3.15 of EDID spec)
+	edid_std_timing_t StdTiming[NUM_BASEEDID_STANDARD_TIMING];	// 8 Standard timing support
+
+	// Detailed timing section - 72 bytes (4*18 bytes)
+	// As per the new spec 1.4, the first Detailed Timing Section should contain the PREFERED TIMING BLOCK
+	edid_dtd_timing_t PreferedTimingMode;
+	// The rest 54 bytes of the Detailed Timing Section. 
+	union {
+		edid_dtd_timing_t DTD[MAX_BASEEDID_DTD_BLOCKS - 1];			// Three DTD data blocks
+
+		monitor_descriptor_t MonitorInfo[MAX_BASEEDID_DTD_BLOCKS - 1]; // Three Monitor Descriptor blocks
+	};
+	
+	uint8_t		ucNumExtBlocks;	// Number of extension EDID blocks
+	uint8_t		ucChecksum;		// Checksum of the EDID block
+
+#pragma pack()
+} baseedid_1_4_t;
+
+
+//*****************************************************
+//*****************************************************
+//
+// DATA STRUCTURES AND DEFINITIONS FOR CE-EXTENSION
+//
+//*****************************************************
+//*****************************************************
+
+/////////////////////////////////
+//
+//CE - Extension Block Structure
+//
+/////////////////////////////////
+typedef struct _ce_edid {
+	uint8_t	ucTag;
+	uint8_t	ucRevision;
+	uint8_t	ucDTDOffset;
+	uint8_t	ucCapabilty;
+	uint8_t	data[123];
+	uint8_t   ucCheckSum;   
+} ce_edid_t;
+
+////////////////////////////////////////////
+//
+//CE - Video Capability Data block structure
+//
+////////////////////////////////////////////
+typedef union _video_cap_data_block {
+    uint8_t ucValue;
+    struct
+    {
+        uint8_t ucCEScanBehavior        :2; // Indicates scan behavior of CE mode
+        uint8_t ucITScanBehavior        :2; // Indicates scan behavior of IT mode
+        uint8_t ucPTScanBehavior        :2; // Indicates scan behavior of Preferred mode
+        uint8_t ucQuantRangeSelectable  :1; // Indicates if RGB Quantization Range can be overridden
+        uint8_t ucReserved              :1;
+    };
+} video_cap_data_block_t;
+
+////////////////////////////////////////////
+//
+//CEA Extn Block Byte3 structure
+//
+////////////////////////////////////////////
+typedef union _cea_ext_capability {
+    uint8_t ucValue;
+    struct
+    {
+        uint8_t ucTotalNativeDTDs     :4; // Total number of DTDs in extension block
+        uint8_t ucSupportsYCBCR422    :1; // Indicates support for YCBCR 4:2:2
+        uint8_t ucSupportsYCBCR444    :1; // Indicates support for YCBCR 4:4:4
+        uint8_t ucSupportsBasicAudio  :1; // Indicates support for Basic audio
+        uint8_t ucUnderscansITFormats :1; // Indicates underscan behavior of IT formats
+    };
+} cea_ext_capability_t;
+
+////////////////////////////////////////////
+//
+//CE - Video Capability Data block structure
+//
+////////////////////////////////////////////
+typedef enum {
+    FORMAT_NOT_SUPPORTED        = 0, // Format is not supported
+    ALWAYS_OVERSCANNED          = 1, // Format is always overscanned
+    ALWAYS_UNDERSCANNED         = 2, // Format is always underscanned
+    SUPPORTS_OVER_AND_UNDERSCAN = 3  // Sink supports both overscan and underscan
+} cea_scan_behavior_t;
+
+
+/////////////////////////////////
+//
+// #defines required for CE Etxn
+//
+/////////////////////////////////
+#define CEA_EXT_TAG 0x02
+#define CEA_EXT_SUPPORTED_VERSION 0x03
+#define CEA_EXT_861_REVISION 0x01
+
+#define CEA_USE_EXTENDED_TAG   0x7
+
+#define CEA_AUDIO_DATABLOCK         0x1
+#define CEA_VIDEO_DATABLOCK         0x2
+#define CEA_VENDOR_DATABLOCK        0x3
+#define CEA_SPEAKER_DATABLOCK       0x4
+#define CEA_VIDEO_CAP_DATABLOCK     0x0
+
+#define CEA_DATABLOCK_TAG_MASK                  0xE0
+#define CEA_DATABLOCK_LENGTH_MASK               0x1F
+#define CEA_SHORT_VIDEO_DESCRIPTOR_CODE_MASK    0x7F
+#define CEA_NATIVE_FORMAT_BIT_MASK              0x80
+
+#define CEA_HDMI_IEEE_REG_ID    0x00000C03
+#define CEA_EDID_HEADER_SZIE    0x04
+
+// Extended Data block type
+// This bit definitions are as per CE 861-D spec
+#define CEA_COLORIMETRY_DATABLOCK   0x5
+    #define CE_COLORIMETRY_MD0_MASK BIT0     
+    #define CE_COLORIMETRY_MD1_MASK BIT1
+    #define CE_COLORIMETRY_MD2_MASK BIT3
+#if 0
+//==================================================================================
+//==================================================================================
+//	DATA Structure definitions for VTB parsing.....
+//  Reference VESA Documents are VTB Extension(Release A) & CVT standard version 1.1
+//===================================================================================
+//	#defines for VTB-EXT
+//===================================================================================
+
+#define VTB_EXT_TAG	0x10
+#define	VTB_EXT_SUPPORTED_VERSION 0x03
+
+#define	VTB_MAX_DTD_TIMINGS			 6
+#define	VTB_MAX_CVT_TIMINGS			40
+#define	VTB_MAX_STANDARD_TIMINGS	61
+
+#define VTB_DTD_OFFSET		5
+#define VTB_DTD_SIZE		18
+#define	VTB_CVT_SIZE		3
+#define VTB_ST_SIZE			2
+
+// This struct is for VTB Extension block.
+typedef struct _VTB_EXT
+{
+	uint8_t	ucTag;
+	uint8_t	ucVersion;
+	uint8_t	ulNumDTD;
+	uint8_t	ulNumCVT;
+	uint8_t	ulNumST;
+	uint8_t	DATA[122];
+	uint8_t	ucChecksum;
+}VTB_EXT, *PVTB_EXT;
+
+// Following struct is for CVT descriptor (Version 1.1)
+typedef struct _VTB_CVT_TIMING 
+{
+#pragma pack(1)	
+
+	uint8_t	ucVA_low;		// Lower 8 bits of Vertical size. This Vsize = (vertical active lines/2)-1. 
+							//	Range for VA lines is 2 to 8192. CVT supprts only an even no. of active lines per frame.
+	
+	union {					
+		uint8_t	ucVA_high_AR;
+		struct {
+		
+			uint8_t	ucReserved00	:2;		//Bits 1-0 are reserved and set to 00h
+			uint8_t	ucAspectRatio	:2;		//	Aspect Ratio specifier bits.
+											// 00:	 4:3 Aspect ratio
+											// 01:	16:9 Aspect ratio
+											// 10:	16:10 Aspect ratio
+											// 11: Undefined (Reserved)
+			
+			
+			uint8_t	ucVA_high	:4;			//	Upper 4 bits of Vertical Size.
+		};
+	};
+
+	union {
+		uint8_t	ucRefresh_Rate_Bits;
+		struct	{
+			
+			uint8_t	ucRR_60Hz_RB	:1;		// When set, indicates 60Hz support with Reduced Blanking.
+			uint8_t	ucRR_85Hz	:1;			//				||	   85Hz				||												.
+			uint8_t	ucRR_75Hz	:1;			//				||	   75Hz				||												.
+			uint8_t	ucRR_60Hz	:1;			//				||	   60Hz				||												.
+			uint8_t	ucRR_50Hz	:1;			// When set, indicates 50Hz Refrash Rate with CRT Blanking supports specified pixel format.
+			uint8_t	ucPreferredRefresh_Rate	:2;		// Preferred Refresh Rate specifier bits.
+											// 00:	50 Hz
+											// 01:	60 Hz (this means either CRT blanking or Reduced Blanking whichever is supported. 
+											//				If both are supported, then RB is preferred.)
+											// 10:	75 Hz
+											// 11:	85 Hz	
+			
+			uint8_t	ucReserved0	:1;			// This bit is reserved and set to '0'.
+			
+		};
+	};
+#pragma	pack()
+} VTB_CVT_TIMING, *PVTB_CVT_TIMING;
+
+
+// This struct is for storing extracted Info from CVT descriptor....
+// This is defined by author.....not based on CVT specs.
+typedef struct _CVT_INFO		
+{
+	ULONG ulYRes;
+	ULONG ulXRes;
+	ULONG ulRRate[5];			//As max 5 Refresh Rates can be supported.
+	BOOLEAN bRed_Blank_Req[5];
+	BOOLEAN bPreferred_RR[5];   //To set flag for Preffered RR
+	ULONG ulNumRates;			//Number of Refresh rates Supported. (Max. 5)
+} CVT_INFO, *PCVT_INFO;
+#endif 
+// This structure is for stroing the Display device Data retreived from CEA block
+// This is defined as per the Display Device Data Block standard.
+typedef struct _display_device_data {
+#pragma pack (1)
+	union 
+	{
+		uint8_t ucTagAndLength; // Data Block Tag and Block Length. should be 0xFF
+		struct
+		{
+			uint8_t ucLength : 5;
+			uint8_t ucTag : 3;
+		};
+	};
+	uint8_t ucChildTag; // Child tag required as per CEA spec  should be 0x02
+	union
+	{
+		uint8_t ucInterfaceType;
+		struct
+		{
+			uint8_t ucNumOfChannels : 4;// Number of channels supported
+			uint8_t ucInterfaceCode : 4;// Interface code 
+		};
+	};
+	union
+	{
+		uint8_t ucVerAndRel;
+		struct
+		{
+			uint8_t ucRelease : 4;// Release 
+			uint8_t ucVersion : 4;// Version.
+		};
+	};
+	uint8_t ucContentProtectionSuppFlag;// Flag indicating support for content protection. 
+	union
+	{
+		uint16_t usClockFrequency;// Clock Frequency
+		struct
+		{
+			uint16_t usMinClockFrequency : 6; // First 6 bits indicates Min frequency
+			uint16_t usMaxClockFrequency : 10;// Next 10 bits indicates Max frequency
+		};
+	};
+	union
+	{
+		uint8_t ucNativePixelFormat[4];// Pixel Format
+		struct
+		{
+			uint8_t ucHorizontalPixelCntLower;// Lower byte value of the Horizontal pixel count
+			uint8_t ucHorizontalPixelCntUpper;// Upper byte value of the Horizontal pixel count
+			uint8_t ucVerticalPixelCntLower;//  Lower byte value of the vertical pixel count
+			uint8_t ucVerticalPixelCntUpper; // Upper byte value of the vertical pixel count
+		};
+	};
+	uint8_t ucAspectRatio;// Byte indicating Aspect ratio. 
+	union 
+	{
+		uint8_t ucOrientationAndRotation;
+		struct
+		{
+			uint8_t ucScanDirection : 2;// Scan direction.
+			uint8_t ucZeroPixelLocation : 2;// Zero Pixel Location.
+			uint8_t ucRotationCapability : 2;// Indicates rotation capability
+			uint8_t ucDefaultOrientation : 2;// Default Orientation.
+		};
+	};
+	uint8_t ucSubPixelInfo;// Sub-Pixle Information.
+	uint8_t ucHorizontalPitch;// Horizontal Pitch
+	uint8_t ucVerticalPitch;// Vertical Pitch
+	union
+	{
+		uint8_t ucMiscDisplayCapabilities;
+		struct
+		{
+			uint8_t bReserved : 3;
+			uint8_t ucDeinterlacing : 1;// indicates deinterlacing support
+			uint8_t ucOverdriverNotRecommended : 1;
+			uint8_t ucDirectDrive : 1;// indicates DirectDrive support
+			uint8_t ucDithering : 2;// indicates Dithering support.
+		};
+	};
+	union
+	{
+		uint8_t ucAudioFlags;// Flags indicating Audio details
+		struct
+		{
+			uint8_t bReserved1 : 4;
+			uint8_t ucAudioInputOverride : 1;// Indicates Audio Input Override
+			uint8_t ucSeparateAudioInputs : 1;// Indicates Separate Audio Inputs
+			uint8_t ucAudioInputOnVideoInterface : 1;// Shows whether Audio input is through the video interface.
+		};
+	};
+	union
+	{
+		uint8_t ucAudioDelayFlags; // Audio Delay Flags
+		struct
+		{
+			uint8_t ucAudioDelay : 7;// Absolute offset between the audio and video signals.
+			uint8_t ucAudioSign : 1;// Indicates positive or negative delay.
+		};
+	};
+	union
+	{
+		uint8_t ucFrameRateAndModeConversion;
+		struct
+		{
+			uint8_t ucFrameRateRange : 6;//Device Frame rate Range
+			uint8_t ucFrameRateConversion : 2;//00 � No dedicated rate conversion hardware is provided;
+											//01 � The display provides a single frame buffer
+											//10 � The display provides double-buffering
+											//11- The display provides frame-rate conversion involving interframe interpolation
+		};
+	};
+	uint8_t ucDeviceNativeRate;// Device Native Frame rate
+	union
+	{
+		uint8_t ucColorBitDepth;// Color bit depth
+		struct
+		{
+			uint8_t ucDisplayDeviceColBitDepth : 4; // Color bit depth of the display device
+			uint8_t ucInterfaceColBitDepth : 4;// color bit depth supported by the interface.h
+		};
+	};
+	uint8_t ucAddPrimaryChromaticities[8];// Additional Primary Chromaticities.
+	union
+	{
+		uint8_t ucResponseTimeFlags;
+		struct
+		{
+			uint8_t ucResponseTime : 7;// Time for transition.
+			uint8_t ucBlackToWhite : 1;// if 1, then transition from black to white
+									// if 0, then transition from white to black
+		};
+	};
+	union
+	{
+		uint8_t ucOverscanInformation;
+		struct
+		{
+			uint8_t ucVerticalPercentage : 4;// Percentage of Overscan in vertical direction.
+			uint8_t ucHorizontalPercentage : 4;// Percentage of Overscan in horizontal direction.
+		};
+	};
+#pragma pack()
+} display_device_data_t;
+
+//=========================================================================
+//=========================================================================
+// #defines for Block Map Ext.
+//=========================================================================
+//=========================================================================
+#define BLOCK_MAP_EXT_TAG 0xF0
+
+#endif // EDIDSTRUCTS_H
diff --git a/drivers/staging/cdv/drv/psb_intel_hdmi_reg.h b/drivers/staging/cdv/drv/psb_intel_hdmi_reg.h
new file mode 100644
index 0000000..6a3c83e
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_hdmi_reg.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	
+ */
+/* chunfeng.zhao@intel.com
+  */
+
+#ifndef PSB_INTEL_HDMI_REG_H
+#define PSB_INTEL_HDMI_REG_H
+
+//////////////////////////////////////////
+//
+// Integrated HDMI specific registers
+//
+/////////////////////////////////////////
+
+#define RESERVED2(x,y)  x##y
+#define RESERVED1(x,y)  RESERVED2(x,y)
+#define RANDOMNUMBER	__LINE__	// __COUNTER__
+#define UNIQUENAME(ValueName) RESERVED1(ValueName, RANDOMNUMBER)
+
+/** Requird for HDMI operation */
+#define   HDMI_NULL_PACKETS_DURING_VSYNC (1 << 9)
+#define   HDMI_BORDER_ENABLE		(1 << 7)
+#define   HDMI_AUDIO_ENABLE		(1 << 6)
+/** New with 965, default is to be set */
+#define   HDMI_VSYNC_ACTIVE_HIGH	(1 << 4)
+/** New with 965, default is to be set */
+#define   HDMI_HSYNC_ACTIVE_HIGH	(1 << 3)
+#define   HDMIB_PCIE_CONCURRENCY	(1 << 3)
+#define   HDMI_DETECTED			(1 << 2)
+/* Bits to be preserved when writing */
+#if 0
+#define   HDMIB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26))
+#define   HDMIC_PRESERVE_MASK ((1 << 17) | (1 << 26))
+#endif 
+//
+//AUDIO configuration register
+//
+#define MDFLD_AUD_CONFIG_REG 0x69000
+	#define MDFLD_AUD_CONFIG_REG_RESERVED_BITS	BITRANGE(31,25)
+typedef union _mdfld_aud_config {
+	uint32_t value;
+	
+	struct
+	{
+		const uint32_t disable_ncts 	        : 1;	//Bit 0
+		uint32_t lay_out 		        : 1;	//Bit 1 (0 - layout 0 1 - layout 1)
+		uint32_t format     		        : 2;	/*Bit [3:2] 
+									 * 00 - l-PCM or IEC 61937 
+                                                                         * 01 - High bit rate IEC 61937 stream packet)
+                                                                         * 10 - Not supported
+                                                                         * 11 - Not supported
+                                                                         */
+		uint32_t num_audio_ch                   : 2;	/*Bit [5:4]
+									 * 00 - 2 channels(stereo)
+									 * 01 - 3 or 4 channels
+									 * 10 - 5 or 6 channels
+									 * 11 - 7 or 8 channels
+									 */				
+		uint32_t UNIQUENAME(Reserved)		: 1;	//Bit 6
+		uint32_t b_bit_enabled		        : 1;	/* Bit 7 (0 - B bit set only for sub-packet 0
+ 								 *        1 - B bit set for all valid sub packet)
+								 */
+		uint32_t sample_flat_bit	        : 1;	//Bit 8
+        	uint32_t validity_bit                   : 1;    //Bit 9 (1 - set V bit in sub-frame 0 - clear V bit(debugging, testing))
+		uint32_t user_bit			: 1;	//Bit 10 (1 - set U bit in sub frame 0 - clear U bit(default)
+		uint32_t underrun_packet_bit	        : 1;	//Bit 11 (1 - send underrun packet 0 - send null packet)
+		uint32_t UNIQUENAME(Reserved)		: 20;	//Bit [31:12]
+	};
+} mdfld_aud_config_t;
+
+//
+// Audio control state register
+//
+#define MDFLD_AUD_CNTL_ST_REG 0x69060
+	#define MDFLD_AUD_CNTL_ST_RESERVED_BITS	(BITRANGE(14,4) | BITRANGE(31,25))
+// Note => DIP : Data Island Packet
+typedef union _mdfld_aud_cntl {
+	uint32_t value;
+
+	struct
+	{
+		uint32_t dip_ram_access_address		:4; // bit 3:0
+		uint32_t UNIQUENAME(Reserved)		:11; // bit 14:4
+		uint32_t cp_ready 			:1;	// bit 15 
+		uint32_t video_dip_trans_freq		:2;	// bit 17:16
+		uint32_t dip_buffer_index		:3;	// bit 20:18
+		uint32_t enable_dip_type		:4;	// bit 24:21
+		uint32_t UNIQUENAME(Reserved)		:7;	// bit 31:25
+	};
+	
+} mdfld_aud_cntl_t;
+
+
+// HDMI Audio Data Island Packet Data
+//
+#define MDFLD_HDMI_AUDPAC_DATA_REG 0x69114
+
+typedef union _mdfld_hdmi_audpac_data {
+	uint32_t value;
+
+	struct
+	{
+		uint32_t audio_dip_data				:32; // bit 31:0
+	};
+} mdfld_hdmi_audpac_data_t;
+
+#endif // PSB_INTEL_HDMI_REG_H
diff --git a/drivers/staging/cdv/drv/psb_intel_i2c.c b/drivers/staging/cdv/drv/psb_intel_i2c.c
new file mode 100644
index 0000000..02c9f1c
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_i2c.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+#include "psb_drv.h"
+#include "psb_intel_reg.h"
+
+/*
+ * Intel GPIO access functions
+ */
+
+#define I2C_RISEFALL_TIME 20
+
+static int get_clock(void *data)
+{
+	struct psb_intel_i2c_chan *chan = data;
+	struct drm_device *dev = chan->drm_dev;
+	u32 val;
+
+	val = REG_READ(chan->reg);
+	return (val & GPIO_CLOCK_VAL_IN) != 0;
+}
+
+static int get_data(void *data)
+{
+	struct psb_intel_i2c_chan *chan = data;
+	struct drm_device *dev = chan->drm_dev;
+	u32 val;
+
+	val = REG_READ(chan->reg);
+	return (val & GPIO_DATA_VAL_IN) != 0;
+}
+
+static void set_clock(void *data, int state_high)
+{
+	struct psb_intel_i2c_chan *chan = data;
+	struct drm_device *dev = chan->drm_dev;
+	u32 reserved = 0, clock_bits;
+
+	/* On most chips, these bits must be preserved in software. */
+	if (!IS_I830(dev) && !IS_845G(dev))
+		reserved =
+		    REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
+					   GPIO_CLOCK_PULLUP_DISABLE);
+
+	if (state_high)
+		clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
+	else
+		clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
+		    GPIO_CLOCK_VAL_MASK;
+	REG_WRITE(chan->reg, reserved | clock_bits);
+	udelay(I2C_RISEFALL_TIME);	/* wait for the line to change state */
+}
+
+static void set_data(void *data, int state_high)
+{
+	struct psb_intel_i2c_chan *chan = data;
+	struct drm_device *dev = chan->drm_dev;
+	u32 reserved = 0, data_bits;
+
+	/* On most chips, these bits must be preserved in software. */
+	if (!IS_I830(dev) && !IS_845G(dev))
+		reserved =
+		    REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
+					   GPIO_CLOCK_PULLUP_DISABLE);
+
+	if (state_high)
+		data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
+	else
+		data_bits =
+		    GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
+		    GPIO_DATA_VAL_MASK;
+
+	REG_WRITE(chan->reg, reserved | data_bits);
+	udelay(I2C_RISEFALL_TIME);	/* wait for the line to change state */
+}
+
+/**
+ * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
+ * @dev: DRM device
+ * @output: driver specific output device
+ * @reg: GPIO reg to use
+ * @name: name for this bus
+ *
+ * Creates and registers a new i2c bus with the Linux i2c layer, for use
+ * in output probing and control (e.g. DDC or SDVO control functions).
+ *
+ * Possible values for @reg include:
+ *   %GPIOA
+ *   %GPIOB
+ *   %GPIOC
+ *   %GPIOD
+ *   %GPIOE
+ *   %GPIOF
+ *   %GPIOG
+ *   %GPIOH
+ * see PRM for details on how these different busses are used.
+ */
+struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
+					const u32 reg, const char *name)
+{
+	struct psb_intel_i2c_chan *chan;
+
+	chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL);
+	if (!chan)
+		goto out_free;
+
+	chan->drm_dev = dev;
+	chan->reg = reg;
+	snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
+	chan->adapter.owner = THIS_MODULE;
+	chan->adapter.algo_data = &chan->algo;
+	chan->adapter.dev.parent = &dev->pdev->dev;
+	chan->algo.setsda = set_data;
+	chan->algo.setscl = set_clock;
+	chan->algo.getsda = get_data;
+	chan->algo.getscl = get_clock;
+	chan->algo.udelay = 20;
+	chan->algo.timeout = usecs_to_jiffies(2200);
+	chan->algo.data = chan;
+
+	i2c_set_adapdata(&chan->adapter, chan);
+
+	if (i2c_bit_add_bus(&chan->adapter))
+		goto out_free;
+
+	/* JJJ:  raise SCL and SDA? */
+	set_data(chan, 1);
+	set_clock(chan, 1);
+	udelay(20);
+
+	return chan;
+
+out_free:
+	kfree(chan);
+	return NULL;
+}
+
+/**
+ * psb_intel_i2c_destroy - unregister and free i2c bus resources
+ * @output: channel to free
+ *
+ * Unregister the adapter from the i2c layer, then free the structure.
+ */
+void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan)
+{
+	if (!chan)
+		return;
+
+	i2c_del_adapter(&chan->adapter);
+	kfree(chan);
+}
diff --git a/drivers/staging/cdv/drv/psb_intel_lvds.c b/drivers/staging/cdv/drv/psb_intel_lvds.c
new file mode 100644
index 0000000..93a8b9f
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_lvds.c
@@ -0,0 +1,678 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ *	Dave Airlie <airlied@linux.ie>
+ *	Jesse Barnes <jesse.barnes@intel.com>
+ */
+
+#include <linux/i2c.h>
+#include <linux/dmi.h>
+/* #include <drm/drm_crtc.h> */
+/* #include <drm/drm_edid.h> */
+#include <drm/drmP.h>
+
+#include "psb_intel_bios.h"
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_powermgmt.h"
+#include <linux/pm_runtime.h>
+
+/* MRST defines start */
+uint8_t blc_freq;
+uint8_t blc_minbrightness;
+uint8_t blc_i2caddr;
+uint8_t blc_brightnesscmd;
+int lvds_backlight;		/* restore backlight to this value */
+
+u32 CoreClock;
+u32 PWMControlRegFreq;
+
+/**
+ * LVDS I2C backlight control macros
+ */
+#define BLC_I2C_TYPE	0x01
+#define BLC_PWM_TYPT	0x02
+
+#define BLC_POLARITY_NORMAL 0
+#define BLC_POLARITY_INVERSE 1
+
+#define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
+#define PSB_BLC_MIN_PWM_REG_FREQ	(0x2)
+#define PSB_BLC_PWM_PRECISION_FACTOR	(10)
+#define PSB_BACKLIGHT_PWM_MODULATION_MASK	(0xFFFF0000)
+#define PSB_BACKLIGHT_PWM_CTL_SHIFT	(16)
+#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
+
+struct psb_intel_lvds_priv {
+	/**
+	 * Saved LVDO output states
+	 */
+	uint32_t savePP_ON;
+	uint32_t savePP_OFF;
+	uint32_t saveLVDS;
+	uint32_t savePP_CONTROL;
+	uint32_t savePP_CYCLE;
+	uint32_t savePFIT_CONTROL;
+	uint32_t savePFIT_PGM_RATIOS;
+	uint32_t saveBLC_PWM_CTL;
+};
+
+
+
+/**
+ * Sets the power state for the panel.
+ */
+static void psb_intel_lvds_set_power(struct drm_device *dev,
+				 struct psb_intel_output *output, bool on)
+{
+	u32 pp_status;
+
+	if (on) {
+
+		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
+			  POWER_TARGET_ON);
+		do {
+			pp_status = REG_READ(PP_STATUS);
+		} while ((pp_status & PP_ON) == 0);
+
+		psb_intel_panel_enable_backlight(dev);
+	} else {
+		psb_intel_panel_disable_backlight(dev);
+
+		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
+			  ~POWER_TARGET_ON);
+		do {
+			pp_status = REG_READ(PP_STATUS);
+		} while (pp_status & PP_ON);
+	}
+}
+
+static void psb_intel_lvds_enable(struct drm_device *dev, struct psb_intel_output *output)
+{
+	REG_WRITE(LVDS, REG_READ(LVDS) | LVDS_PORT_EN);
+
+	psb_intel_lvds_set_power(dev, output, true);
+}
+
+static void psb_intel_lvds_disable(struct drm_device *dev, struct psb_intel_output *output)
+{
+	psb_intel_lvds_set_power(dev, output, false);
+
+	REG_WRITE(LVDS, REG_READ(LVDS) & ~LVDS_PORT_EN);
+}
+
+static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+
+	if (mode == DRM_MODE_DPMS_ON)
+		psb_intel_lvds_enable(dev, output);
+	else
+		psb_intel_lvds_disable(dev, output);
+
+	/* XXX: We never power down the LVDS pairs. */
+}
+
+static void psb_intel_lvds_save(struct drm_connector *connector)
+{
+	return;
+}
+
+static void psb_intel_lvds_restore(struct drm_connector *connector)
+{
+	return;
+}
+
+int psb_intel_lvds_mode_valid(struct drm_connector *connector,
+				 struct drm_display_mode *mode)
+{
+	struct psb_intel_output *psb_intel_output =
+				to_psb_intel_output(connector);
+	struct drm_display_mode *fixed_mode =
+	    psb_intel_output->mode_dev->panel_fixed_mode;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	/* just in case */
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+		return MODE_NO_DBLESCAN;
+
+	/* just in case */
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_NO_INTERLACE;
+
+	if (fixed_mode) {
+		if (mode->hdisplay > fixed_mode->hdisplay)
+			return MODE_PANEL;
+		if (mode->vdisplay > fixed_mode->vdisplay)
+			return MODE_PANEL;
+	}
+	return MODE_OK;
+}
+
+bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
+				  struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode)
+{
+	struct psb_intel_mode_device *mode_dev =
+	    enc_to_psb_intel_output(encoder)->mode_dev;
+	struct drm_device *dev = encoder->dev;
+	struct psb_intel_crtc *psb_intel_crtc =
+				to_psb_intel_crtc(encoder->crtc);
+	struct drm_encoder *tmp_encoder;
+	struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
+	struct psb_intel_output *psb_intel_output = enc_to_psb_intel_output(encoder);
+
+	PSB_DEBUG_ENTRY("type = 0x%x, pipe = %d.\n",psb_intel_output->type, psb_intel_crtc->pipe);
+
+	/* Should never happen!! */
+	if (IS_MID(dev) && !IS_CDV(dev) && psb_intel_crtc->pipe == 1) {
+		DRM_ERROR("Can't support LVDS/MIPI on pipe B on MRST\n");
+		return false;
+	} else if (!IS_MID(dev) && !IS_I965G(dev)
+		   && psb_intel_crtc->pipe == 0) {
+		DRM_ERROR("Can't support LVDS on pipe A\n");
+		return false;
+	}
+
+	/* Should never happen!! */
+	list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
+			    head) {
+		if (tmp_encoder != encoder
+		    && tmp_encoder->crtc == encoder->crtc) {
+			DRM_ERROR("Can't enable LVDS and another "
+			       "encoder on the same pipe\n");
+			return false;
+		}
+	}
+
+	/*
+	 * If we have timings from the BIOS for the panel, put them in
+	 * to the adjusted mode.  The CRTC will be set up for this mode,
+	 * with the panel scaling set up to source from the H/VDisplay
+	 * of the original mode.
+	 */
+	if (panel_fixed_mode != NULL)
+		psb_intel_fixed_panel_mode(panel_fixed_mode, adjusted_mode);
+
+	/*
+	 * XXX: It would be nice to support lower refresh rates on the
+	 * panels to reduce power consumption, and perhaps match the
+	 * user's requested refresh rate.
+	 */
+
+	return true;
+}
+
+static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+
+	PSB_DEBUG_ENTRY("\n");
+
+	psb_intel_lvds_set_power(dev, output, false);
+}
+
+static void psb_intel_lvds_commit(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+
+	PSB_DEBUG_ENTRY("\n");
+
+	if (dev_priv->backlight_level == 0)
+		dev_priv->backlight_level = psb_intel_panel_get_max_backlight(dev);
+
+	psb_intel_lvds_set_power(dev, output, true);
+}
+
+static void psb_intel_lvds_mode_set(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(
+							encoder->crtc);
+	u32 pfit_control;
+
+	/*
+	 * The LVDS pin pair will already have been turned on in the
+	 * psb_intel_crtc_mode_set since it has a large impact on the DPLL
+	 * settings.
+	 */
+
+	/*
+	 * Enable automatic panel scaling so that non-native modes fill the
+	 * screen.  Should be enabled before the pipe is enabled, according to
+	 * register description and PRM.
+	 */
+	if (mode->hdisplay != adjusted_mode->hdisplay ||
+	    mode->vdisplay != adjusted_mode->vdisplay)
+		pfit_control = PFIT_ENABLE;
+	else
+		pfit_control = 0;
+
+	pfit_control |= psb_intel_crtc->pipe << PFIT_PIPE_SHIFT;
+
+	REG_WRITE(PFIT_CONTROL, pfit_control);
+}
+
+/**
+ * Detect the LVDS connection.
+ *
+ * This always returns CONNECTOR_STATUS_CONNECTED.
+ * This connector should only have
+ * been set up if the LVDS was actually connected anyway.
+ */
+static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector *connector, bool force)
+{
+	return connector_status_connected;
+}
+
+/**
+ * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
+ */
+static int psb_intel_lvds_get_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct psb_intel_output *psb_intel_output =
+					to_psb_intel_output(connector);
+	struct psb_intel_mode_device *mode_dev =
+					psb_intel_output->mode_dev;
+	int ret = 0;
+
+	ret = psb_intel_ddc_get_modes(psb_intel_output);
+
+	if (ret)
+		return ret;
+
+	/* Didn't get an EDID, so
+	 * Set wide sync ranges so we get all modes
+	 * handed to valid_mode for checking
+	 */
+	connector->display_info.min_vfreq = 0;
+	connector->display_info.max_vfreq = 200;
+	connector->display_info.min_hfreq = 0;
+	connector->display_info.max_hfreq = 200;
+
+	if (mode_dev->panel_fixed_mode != NULL) {
+		struct drm_display_mode *mode =
+		    drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
+		drm_mode_probed_add(connector, mode);
+		return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * psb_intel_lvds_destroy - unregister and free LVDS structures
+ * @connector: connector to free
+ *
+ * Unregister the DDC bus for this connector then free the driver private
+ * structure.
+ */
+void psb_intel_lvds_destroy(struct drm_connector *connector)
+{
+	struct psb_intel_output *psb_intel_output =
+					to_psb_intel_output(connector);
+
+	psb_intel_panel_destroy_backlight(connector->dev);
+
+	if (psb_intel_output->ddc_bus)
+		psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
+	drm_sysfs_connector_remove(connector);
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+int psb_intel_lvds_set_property(struct drm_connector *connector,
+				       struct drm_property *property,
+				       uint64_t value)
+{
+	struct drm_encoder *pEncoder = connector->encoder;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	if (!strcmp(property->name, "scaling mode") && pEncoder) {
+		struct psb_intel_crtc *pPsbCrtc =
+					to_psb_intel_crtc(pEncoder->crtc);
+		uint64_t curValue;
+
+		PSB_DEBUG_ENTRY("scaling mode \n");
+
+		if (!pPsbCrtc)
+			goto set_prop_error;
+
+		switch (value) {
+		case DRM_MODE_SCALE_FULLSCREEN:
+			break;
+		case DRM_MODE_SCALE_NO_SCALE:
+			break;
+		case DRM_MODE_SCALE_ASPECT:
+			break;
+		default:
+			goto set_prop_error;
+		}
+
+		if (drm_connector_property_get_value(connector,
+						     property,
+						     &curValue))
+			goto set_prop_error;
+
+		if (curValue == value)
+			goto set_prop_done;
+
+		if (drm_connector_property_set_value(connector,
+							property,
+							value))
+			goto set_prop_error;
+
+		if (pPsbCrtc->saved_mode.hdisplay != 0 &&
+		    pPsbCrtc->saved_mode.vdisplay != 0) {
+			if (!drm_crtc_helper_set_mode(pEncoder->crtc,
+						      &pPsbCrtc->saved_mode,
+						      pEncoder->crtc->x,
+						      pEncoder->crtc->y,
+						      pEncoder->crtc->fb))
+				goto set_prop_error;
+		}
+	} 
+
+set_prop_done:
+	return 0;
+set_prop_error:
+	return -1;
+}
+
+static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = {
+	.dpms = psb_intel_lvds_encoder_dpms,
+	.mode_fixup = psb_intel_lvds_mode_fixup,
+	.prepare = psb_intel_lvds_prepare,
+	.mode_set = psb_intel_lvds_mode_set,
+	.commit = psb_intel_lvds_commit,
+};
+
+static const struct drm_connector_helper_funcs psb_intel_lvds_connector_helper_funcs = {
+	.get_modes = psb_intel_lvds_get_modes,
+	.mode_valid = psb_intel_lvds_mode_valid,
+	.best_encoder = psb_intel_best_encoder,
+};
+
+static const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.save = psb_intel_lvds_save,
+	.restore = psb_intel_lvds_restore,
+	.detect = psb_intel_lvds_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = psb_intel_lvds_set_property,
+	.destroy = psb_intel_lvds_destroy,
+};
+
+
+static void psb_intel_lvds_enc_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = {
+	.destroy = psb_intel_lvds_enc_destroy,
+};
+
+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the LVDS is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it assumes that the LVDS is present.
+ */
+static bool lvds_is_present_in_vbt(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	int i;
+
+	if (!dev_priv->child_dev_num)
+		return true;
+
+	for (i = 0; i < dev_priv->child_dev_num; i++) {
+		struct child_device_config *child = dev_priv->child_dev + i;
+
+		/* If the device type is not LFP, continue.
+		 * We have to check both the new identifiers as well as the
+		 * old for compatibility with some BIOSes.
+		 */
+		if (child->device_type != DEVICE_TYPE_INT_LFP &&
+		    child->device_type != DEVICE_TYPE_LFP)
+			continue;
+
+
+		/* However, we cannot trust the BIOS writers to populate
+		 * the VBT correctly.  Since LVDS requires additional
+		 * information from AIM blocks, a non-zero addin offset is
+		 * a good indicator that the LVDS is actually present.
+		 */
+		if (child->addin_offset)
+			return true;
+
+		/* But even then some BIOS writers perform some black magic
+		 * and instantiate the device without reference to any
+		 * additional data.  Trust that if the VBT was written into
+		 * the OpRegion then they have validated the LVDS's existence.
+		 */
+		if (dev_priv->opregion.vbt)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * psb_intel_lvds_init - setup LVDS connectors on this device
+ * @dev: drm device
+ *
+ * Create the connector, register the LVDS DDC bus, and try to figure out what
+ * modes we can display on the LVDS panel (if present).
+ */
+void psb_intel_lvds_init(struct drm_device *dev,
+		     struct psb_intel_mode_device *mode_dev)
+{
+	struct psb_intel_output *psb_intel_output;
+	struct psb_intel_lvds_priv *lvds_priv;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	struct drm_display_mode *scan;	/* *modes, *bios_mode; */
+	struct drm_crtc *crtc;
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private;
+	u32 lvds;
+	int pipe;
+
+	if (!lvds_is_present_in_vbt(dev)) {
+		DRM_DEBUG_KMS("LVDS is not present in VBT\n");
+		return;
+	}
+
+	psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
+				   sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
+	if (!psb_intel_output)
+		return;
+
+	lvds_priv = (struct psb_intel_lvds_priv *)(psb_intel_output + 1);
+
+	psb_intel_output->dev_priv = lvds_priv;
+
+	psb_intel_output->mode_dev = mode_dev;
+	connector = &psb_intel_output->base;
+	encoder = &psb_intel_output->enc;
+	drm_connector_init(dev, &psb_intel_output->base,
+			   &psb_intel_lvds_connector_funcs,
+			   DRM_MODE_CONNECTOR_LVDS);
+
+	drm_encoder_init(dev, &psb_intel_output->enc,
+			 &psb_intel_lvds_enc_funcs,
+			 DRM_MODE_ENCODER_LVDS);
+
+	drm_mode_connector_attach_encoder(&psb_intel_output->base,
+					  &psb_intel_output->enc);
+	psb_intel_output->type = INTEL_OUTPUT_LVDS;
+
+	drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs);
+	drm_connector_helper_add(connector,
+				 &psb_intel_lvds_connector_helper_funcs);
+	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+	connector->interlace_allowed = false;
+	connector->doublescan_allowed = false;
+
+	/*Attach connector properties*/
+	drm_connector_attach_property(connector,
+				      dev->mode_config.scaling_mode_property,
+				      DRM_MODE_SCALE_FULLSCREEN);
+
+	/**
+	 * Set up I2C bus
+	 * FIXME: distroy i2c_bus when exit
+	 */
+	psb_intel_output->i2c_bus = psb_intel_i2c_create(dev,
+							 GPIOB,
+							 "LVDSBLC_B");
+	if (!psb_intel_output->i2c_bus) {
+		DRM_ERROR("I2C bus registration failed.\n");
+		goto failed_blc_i2c;
+	}
+	psb_intel_output->i2c_bus->slave_addr = 0x2C;
+	dev_priv->lvds_i2c_bus =  psb_intel_output->i2c_bus;
+
+	/*
+	 * LVDS discovery:
+	 * 1) check for EDID on DDC
+	 * 2) check for VBT data
+	 * 3) check to see if LVDS is already on
+	 *    if none of the above, no panel
+	 * 4) make sure lid is open
+	 *    if closed, act like it's not there for now
+	 */
+
+	/* Set up the DDC bus. */
+	psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
+							 GPIOC,
+							 "LVDSDDC_C");
+	if (!psb_intel_output->ddc_bus) {
+		DRM_ERROR("DDC bus registration failed.\n");
+		goto failed_ddc;
+	}
+
+	/*
+	 * Attempt to get the fixed panel mode from DDC.  Assume that the
+	 * preferred mode is the right one.
+	 */
+	psb_intel_ddc_get_modes(psb_intel_output);
+	list_for_each_entry(scan, &connector->probed_modes, head) {
+		DRM_DEBUG("scan type: %d hdisplay: %d vdisplay %d", scan->type, scan->hdisplay, scan->vdisplay);
+		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
+			mode_dev->panel_fixed_mode = drm_mode_duplicate(dev, scan);
+			goto out;	/* FIXME: check for quirks */
+		}
+	}
+
+	/* Failed to get EDID, what about VBT? do we need this?*/
+
+	if (dev_priv->lfp_lvds_vbt_mode) {
+		mode_dev->panel_fixed_mode = drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
+		if (mode_dev->panel_fixed_mode) {
+			mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
+			goto out;	/* FIXME: check for quirks */
+		}
+	}
+
+	/*
+	 * If we didn't get EDID, try checking if the panel is already turned
+	 * on.	If so, assume that whatever is currently programmed is the
+	 * correct mode.
+	 */
+	lvds = REG_READ(LVDS);
+	pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
+	crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
+
+	if (crtc && (lvds & LVDS_PORT_EN)) {
+		mode_dev->panel_fixed_mode = psb_intel_crtc_mode_get(dev, crtc);
+		if (mode_dev->panel_fixed_mode) {
+			mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
+			goto out;	/* FIXME: check for quirks */
+		}
+	}
+
+	/* If we still don't have a mode after all that, give up. */
+	if (!mode_dev->panel_fixed_mode) {
+		DRM_DEBUG("Found no modes on the lvds, ignoring the LVDS\n");
+		goto failed_find;
+	}
+
+	/* setup PWM */
+	{
+		u32 pwm;
+
+		pwm = REG_READ(BLC_PWM_CTL2);
+		if (pipe == 1)
+			pwm |= PWM_PIPE_B;
+		else
+			pwm &= ~PWM_PIPE_B;
+		pwm |= PWM_ENABLE;
+		REG_WRITE(BLC_PWM_CTL2, pwm);
+	}
+
+out:
+	drm_sysfs_connector_add(connector);
+
+	dev_priv->int_lvds_connector = connector;
+	psb_intel_panel_setup_backlight(dev);
+
+	PSB_DEBUG_ENTRY("hdisplay = %d\n",
+		 mode_dev->panel_fixed_mode->hdisplay);
+	PSB_DEBUG_ENTRY(" vdisplay = %d\n",
+		 mode_dev->panel_fixed_mode->vdisplay);
+	PSB_DEBUG_ENTRY(" hsync_start = %d\n",
+		 mode_dev->panel_fixed_mode->hsync_start);
+	PSB_DEBUG_ENTRY(" hsync_end = %d\n",
+		 mode_dev->panel_fixed_mode->hsync_end);
+	PSB_DEBUG_ENTRY(" htotal = %d\n",
+		 mode_dev->panel_fixed_mode->htotal);
+	PSB_DEBUG_ENTRY(" vsync_start = %d\n",
+		 mode_dev->panel_fixed_mode->vsync_start);
+	PSB_DEBUG_ENTRY(" vsync_end = %d\n",
+		 mode_dev->panel_fixed_mode->vsync_end);
+	PSB_DEBUG_ENTRY(" vtotal = %d\n",
+		 mode_dev->panel_fixed_mode->vtotal);
+	PSB_DEBUG_ENTRY(" clock = %d\n",
+		 mode_dev->panel_fixed_mode->clock);
+
+	return;
+
+failed_find:
+	if (psb_intel_output->ddc_bus)
+		psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
+failed_ddc:
+	if (psb_intel_output->i2c_bus)
+		psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
+failed_blc_i2c:
+	drm_encoder_cleanup(encoder);
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
diff --git a/drivers/staging/cdv/drv/psb_intel_modes.c b/drivers/staging/cdv/drv/psb_intel_modes.c
new file mode 100644
index 0000000..ada7d48
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_modes.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authers: Jesse Barnes <jesse.barnes@intel.com>
+ */
+
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+/**
+ * psb_intel_ddc_probe
+ *
+ */
+bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output)
+{
+	u8 out_buf[] = { 0x0, 0x0 };
+	u8 buf[2];
+	int ret;
+	struct i2c_msg msgs[] = {
+		{
+		 .addr = 0x50,
+		 .flags = 0,
+		 .len = 1,
+		 .buf = out_buf,
+		 },
+		{
+		 .addr = 0x50,
+		 .flags = I2C_M_RD,
+		 .len = 1,
+		 .buf = buf,
+		 }
+	};
+
+	ret = i2c_transfer(&psb_intel_output->ddc_bus->adapter, msgs, 2);
+	if (ret == 2)
+		return true;
+
+	return false;
+}
+
+/**
+ * psb_intel_ddc_get_modes - get modelist from monitor
+ * @connector: DRM connector device to use
+ *
+ * Fetch the EDID information from @connector using the DDC bus.
+ */
+int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output)
+{
+	struct edid *edid;
+	int ret = 0;
+
+	edid =
+	    drm_get_edid(&psb_intel_output->base,
+			 &psb_intel_output->ddc_bus->adapter);
+	if (edid) {
+		drm_mode_connector_update_edid_property(&psb_intel_output->
+							base, edid);
+		ret = drm_add_edid_modes(&psb_intel_output->base, edid);
+		kfree(edid);
+	}
+	return ret;
+}
+
+
+static const char *force_audio_names[] = {
+	"off",
+	"auto",
+	"on",
+};
+
+void psb_intel_attach_force_audio_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct drm_property *prop;
+	int i;
+
+	prop = dev_priv->force_audio_property;
+	if (prop == NULL) {
+		prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+					   "audio",
+					   ARRAY_SIZE(force_audio_names));
+		if (prop == NULL)
+			return;
+
+		for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
+			drm_property_add_enum(prop, i, i-1, force_audio_names[i]);
+
+		dev_priv->force_audio_property = prop;
+	}
+	drm_connector_attach_property(connector, prop, 0);
+}
+
+
+static const char *broadcast_rgb_names[] = {
+	"Full",
+	"Limited 16:235",
+};
+
+void
+psb_intel_attach_broadcast_rgb_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct drm_property *prop;
+	int i;
+
+	prop = dev_priv->broadcast_rgb_property;
+	if (prop == NULL) {
+		prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+					   "Broadcast RGB",
+					   ARRAY_SIZE(broadcast_rgb_names));
+		if (prop == NULL)
+			return;
+
+		for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++)
+			drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]);
+
+		dev_priv->broadcast_rgb_property = prop;
+	}
+
+	drm_connector_attach_property(connector, prop, 0);
+}
diff --git a/drivers/staging/cdv/drv/psb_intel_opregion.c b/drivers/staging/cdv/drv/psb_intel_opregion.c
new file mode 100644
index 0000000..0f588ed
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_opregion.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifdef CONFIG_ACPI
+#include <linux/acpi.h>
+#include <linux/acpi_io.h>
+#endif
+#include "psb_drv.h"
+
+#define PCI_ASLE 0xe4
+#define PCI_ASLS 0xfc
+
+#define OPREGION_HEADER_OFFSET 0
+#define OPREGION_ACPI_OFFSET   0x100
+#define   ACPI_CLID 0x01ac /* current lid state indicator */
+#define   ACPI_CDCK 0x01b0 /* current docking state indicator */
+#define OPREGION_SWSCI_OFFSET  0x200
+#define OPREGION_ASLE_OFFSET   0x300
+#define OPREGION_VBT_OFFSET    0x400
+
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+#define MBOX_ACPI      (1<<0)
+#define MBOX_SWSCI     (1<<1)
+#define MBOX_ASLE      (1<<2)
+
+struct opregion_header {
+	u8 signature[16];
+	u32 size;
+	u32 opregion_ver;
+	u8 bios_ver[32];
+	u8 vbios_ver[16];
+	u8 driver_ver[16];
+	u32 mboxes;
+	u8 reserved[164];
+} __attribute__((packed));
+
+/* OpRegion mailbox #1: public ACPI methods */
+struct opregion_acpi {
+       u32 drdy;       /* driver readiness */
+       u32 csts;       /* notification status */
+       u32 cevt;       /* current event */
+       u8 rsvd1[20];
+       u32 didl[8];    /* supported display devices ID list */
+       u32 cpdl[8];    /* currently presented display list */
+       u32 cadl[8];    /* currently active display list */
+       u32 nadl[8];    /* next active devices list */
+       u32 aslp;       /* ASL sleep time-out */
+       u32 tidx;       /* toggle table index */
+       u32 chpd;       /* current hotplug enable indicator */
+       u32 clid;       /* current lid state*/
+       u32 cdck;       /* current docking state */
+       u32 sxsw;       /* Sx state resume */
+       u32 evts;       /* ASL supported events */
+       u32 cnot;       /* current OS notification */
+       u32 nrdy;       /* driver status */
+       u8 rsvd2[60];
+} __attribute__((packed));
+
+/* OpRegion mailbox #2: SWSCI */
+struct opregion_swsci {
+	/*FIXME: add it later*/
+} __attribute__((packed));
+
+/* OpRegion mailbox #3: ASLE */
+struct opregion_asle {
+	u32 ardy;	/* driver readiness */
+	u32 aslc;	/* ASLE interrupt command */
+	u32 tche;	/* technology enabled indicator */
+	u32 alsi;	/* current ALS illuminance reading */
+	u32 bclp;	/* backlight brightness to set */
+	u32 pfit;	/* panel fitting state */
+	u32 cblv;	/* current brightness level */
+	u16 bclm[20];	/* backlight level duty cycle mapping table */
+	u32 cpfm;	/* current panel fitting mode */
+	u32 epfm;	/* enabled panel fitting modes */
+	u8 plut[74];	/* panel LUT and identifier */
+	u32 pfmb;	/* PWM freq and min brightness */
+	u8 rsvd[102];
+} __attribute__((packed));
+
+/* ASLE irq request bits */
+#define ASLE_SET_ALS_ILLUM     (1 << 0)
+#define ASLE_SET_BACKLIGHT     (1 << 1)
+#define ASLE_SET_PFIT          (1 << 2)
+#define ASLE_SET_PWM_FREQ      (1 << 3)
+#define ASLE_REQ_MSK           0xf
+
+/* response bits of ASLE irq request */
+#define ASLE_ALS_ILLUM_FAILED   (1<<10)
+#define ASLE_BACKLIGHT_FAILED   (1<<12)
+#define ASLE_PFIT_FAILED        (1<<14)
+#define ASLE_PWM_FREQ_FAILED    (1<<16)
+
+/* ASLE backlight brightness to set */
+#define ASLE_BCLP_VALID                (1<<31)
+#define ASLE_BCLP_MSK          (~(1<<31))
+
+/* ASLE panel fitting request */
+#define ASLE_PFIT_VALID         (1<<31)
+#define ASLE_PFIT_CENTER (1<<0)
+#define ASLE_PFIT_STRETCH_TEXT (1<<1)
+#define ASLE_PFIT_STRETCH_GFX (1<<2)
+
+/* response bits of ASLE irq request */
+#define ASLE_ALS_ILLUM_FAILED	(1<<10)
+#define ASLE_BACKLIGHT_FAILED	(1<<12)
+#define ASLE_PFIT_FAILED	(1<<14)
+#define ASLE_PWM_FREQ_FAILED	(1<<16)
+
+/* ASLE backlight brightness to set */
+#define ASLE_BCLP_VALID                (1<<31)
+#define ASLE_BCLP_MSK          (~(1<<31))
+
+/* ASLE panel fitting request */
+#define ASLE_PFIT_VALID         (1<<31)
+#define ASLE_PFIT_CENTER (1<<0)
+#define ASLE_PFIT_STRETCH_TEXT (1<<1)
+#define ASLE_PFIT_STRETCH_GFX (1<<2)
+
+/* PWM frequency and minimum brightness */
+#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
+#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
+#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
+#define ASLE_PFMB_PWM_VALID (1<<31)
+
+#define ASLE_CBLV_VALID         (1<<31)
+
+static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+	u32 max;
+
+	DRM_DEBUG_DRIVER("asle set backlight %x\n", bclp);
+
+	if (!(bclp & ASLE_BCLP_VALID))
+		return ASLE_BACKLIGHT_FAILED;
+
+	bclp &= ASLE_BCLP_MSK;
+	if (bclp > 255)
+		return ASLE_BACKLIGHT_FAILED;
+
+	max = psb_intel_panel_get_max_backlight(dev);
+	psb_intel_panel_set_backlight(dev, bclp * max / 255);
+	asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
+
+	return 0;
+}
+
+void psb_intel_opregion_asle_intr(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+	u32 asle_stat = 0;
+	u32 asle_req;
+
+	if (!asle)
+		return;
+
+	asle_req = asle->aslc & ASLE_REQ_MSK;
+	if (!asle_req) {
+		DRM_DEBUG_DRIVER("non asle set request??\n");
+		return;
+	}
+
+	if (asle_req & ASLE_SET_BACKLIGHT)
+		asle_stat |= asle_set_backlight(dev, asle->bclp);
+
+	asle->aslc = asle_stat;
+}
+
+#define ASLE_ALS_EN    (1<<0)
+#define ASLE_BLC_EN    (1<<1)
+#define ASLE_PFIT_EN   (1<<2)
+#define ASLE_PFMB_EN   (1<<3)
+
+void psb_intel_opregion_enable_asle(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+
+	if (asle) {
+		/* XXX enable asle interrupt
+		 * should only for cdv mobile device
+		 */
+		psb_intel_enable_asle(dev);
+
+		asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | ASLE_PFMB_EN;
+		asle->ardy = 1;
+	}
+}
+
+#define ACPI_EV_DISPLAY_SWITCH (1<<0)
+#define ACPI_EV_LID            (1<<1)
+#define ACPI_EV_DOCK           (1<<2)
+
+static struct psb_intel_opregion *system_opregion;
+
+static int psb_intel_opregion_video_event(struct notifier_block *nb,
+					  unsigned long val, void *data)
+{
+	/* The only video events relevant to opregion are 0x80. These indicate
+	   either a docking event, lid switch or display switch request. In
+	   Linux, these are handled by the dock, button and video drivers.
+	   We might want to fix the video driver to be opregion-aware in
+	   future, but right now we just indicate to the firmware that the
+	   request has been handled */
+
+	struct opregion_acpi *acpi;
+
+	if (!system_opregion)
+		return NOTIFY_DONE;
+
+	acpi = system_opregion->acpi;
+	acpi->csts = 0;
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block psb_intel_opregion_notifier = {
+	.notifier_call = psb_intel_opregion_video_event,
+};
+
+void psb_intel_opregion_init(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct psb_intel_opregion *opregion = &dev_priv->opregion;
+
+	if (!opregion->header)
+		return;
+
+	if (opregion->acpi) {
+		/* Notify BIOS we are ready to handle ACPI video ext notifs.
+		 * Right now, all the events are handled by the ACPI video module.
+		 * We don't actually need to do anything with them. */
+		opregion->acpi->csts = 0;
+		opregion->acpi->drdy = 1;
+
+		system_opregion = opregion;
+		register_acpi_notifier(&psb_intel_opregion_notifier);
+	}
+
+	if (opregion->asle)
+		psb_intel_opregion_enable_asle(dev);
+}
+
+void psb_intel_opregion_fini(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct psb_intel_opregion *opregion = &dev_priv->opregion;
+
+	if (!opregion->header)
+		return;
+
+	if (opregion->acpi) {
+		opregion->acpi->drdy = 0;
+
+		system_opregion = NULL;
+		unregister_acpi_notifier(&psb_intel_opregion_notifier);
+	}
+
+	/* just clear all opregion memory pointers now */
+	iounmap(opregion->header);
+	opregion->header = NULL;
+	opregion->acpi = NULL;
+	opregion->swsci = NULL;
+	opregion->asle = NULL;
+	opregion->vbt = NULL;
+}
+
+int psb_intel_opregion_setup(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct psb_intel_opregion *opregion = &dev_priv->opregion;
+	u32 opregion_phy, mboxes;
+	void *base;
+	int err = 0;
+
+	pci_read_config_dword(dev->pdev, PCI_ASLS, &opregion_phy);
+	if (opregion_phy == 0) {
+		DRM_DEBUG_DRIVER("ACPI Opregion not supported\n");
+		return -ENOTSUPP;
+	}
+	DRM_DEBUG_DRIVER("OpRegion detected at 0x%8x\n", opregion_phy);
+#ifdef CONFIG_ACPI
+	base = acpi_os_ioremap(opregion_phy, 8*1024);
+#else
+	base = ioremap(opregion_phy, 8*1024);
+#endif
+	if (!base)
+		return -ENOMEM;
+
+	if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+		DRM_DEBUG_DRIVER("opregion signature mismatch\n");
+		err = -EINVAL;
+		goto err_out;
+	}
+
+	opregion->header = base;
+	opregion->vbt = base + OPREGION_VBT_OFFSET;
+
+	opregion->lid_state = base + ACPI_CLID;
+
+	mboxes = opregion->header->mboxes;
+	if (mboxes & MBOX_ACPI) {
+		DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
+		opregion->acpi = base + OPREGION_ACPI_OFFSET;
+	}
+
+	if (mboxes & MBOX_ASLE) {
+		DRM_DEBUG_DRIVER("ASLE supported\n");
+		opregion->asle = base + OPREGION_ASLE_OFFSET;
+	}
+
+	return 0;
+
+err_out:
+	iounmap(base);
+	return err;
+}
diff --git a/drivers/staging/cdv/drv/psb_intel_panel.c b/drivers/staging/cdv/drv/psb_intel_panel.c
new file mode 100644
index 0000000..9e02670
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_panel.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2006-2012 Intel Corporation
+ * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ *      Dave Airlie <airlied@linux.ie>
+ *      Jesse Barnes <jesse.barnes@intel.com>
+ *      Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "psb_drv.h"
+#include "psb_intel_reg.h"
+
+void
+psb_intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
+		       struct drm_display_mode *adjusted_mode)
+{
+	adjusted_mode->hdisplay = fixed_mode->hdisplay;
+	adjusted_mode->hsync_start = fixed_mode->hsync_start;
+	adjusted_mode->hsync_end = fixed_mode->hsync_end;
+	adjusted_mode->htotal = fixed_mode->htotal;
+
+	adjusted_mode->vdisplay = fixed_mode->vdisplay;
+	adjusted_mode->vsync_start = fixed_mode->vsync_start;
+	adjusted_mode->vsync_end = fixed_mode->vsync_end;
+	adjusted_mode->vtotal = fixed_mode->vtotal;
+
+	adjusted_mode->clock = fixed_mode->clock;
+
+	drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+}
+
+
+static int is_backlight_combination_mode(struct drm_device *dev)
+{
+	return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE;
+}
+
+static u32 psb_intel_get_pwm_ctl(struct drm_device *dev)
+{
+	u32 val;
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private;
+
+	val = REG_READ(BLC_PWM_CTL);
+
+	if (dev_priv->saveBLC_PWM_CTL == 0) {
+		dev_priv->saveBLC_PWM_CTL = val;
+		dev_priv->saveBLC_PWM_CTL2 = REG_READ(BLC_PWM_CTL2);
+	} else if (val == 0) {
+		REG_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
+		REG_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
+		val = dev_priv->saveBLC_PWM_CTL;
+	}
+	return val;
+}
+
+u32 psb_intel_panel_get_backlight(struct drm_device *dev)
+{
+	u32 val;
+
+	val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+
+	if (is_backlight_combination_mode(dev)) {
+		u8 lbpc;
+
+		val &= ~1;
+		pci_read_config_byte(dev->pdev, 0xF4, &lbpc);
+		val *= lbpc;
+	}
+
+	return val;
+}
+
+/**
+ *  * Returns the maximum level of the backlight duty cycle field.
+ *   */
+u32 psb_intel_panel_get_max_backlight(struct drm_device *dev)
+{
+	u32 max;
+
+	max = psb_intel_get_pwm_ctl(dev);
+
+	if (max == 0) {
+		DRM_DEBUG_KMS("LVDS Panel PWM value is 0!\n");
+	       	/* i915 does this, I believe which means that we should not
+		 * smash PWM control as firmware will take control of it. */
+		return 1;
+	}
+
+	max >>= 16;
+	if (is_backlight_combination_mode(dev))
+		max *= 0xff;
+
+	return max;
+}
+
+static void psb_intel_panel_set_actual_backlight(struct drm_device *dev, int level)
+{
+	u32 blc_pwm_ctl;
+
+	if (is_backlight_combination_mode(dev)) {
+		u32 max = psb_intel_panel_get_max_backlight(dev);
+		u8 lbpc;
+
+		lbpc = level * 0xfe / max + 1;
+		level /= lbpc;
+
+		pci_write_config_byte(dev->pdev, 0xF4, lbpc);
+	}
+
+	blc_pwm_ctl = REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
+}
+
+void psb_intel_panel_enable_backlight(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;
+	
+	if (dev_priv->backlight_level == 0)
+		dev_priv->backlight_level =
+			psb_intel_panel_get_max_backlight(dev);
+	
+	dev_priv->backlight_enabled = 1;
+	psb_intel_panel_set_actual_backlight(dev, dev_priv->backlight_level);	
+}
+
+void psb_intel_panel_disable_backlight(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;
+	
+	dev_priv->backlight_enabled = 0;
+	psb_intel_panel_set_actual_backlight(dev, 0);	
+}
+
+void psb_intel_panel_set_backlight(struct drm_device *dev, int level)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;
+
+	dev_priv->backlight_level = level;
+	if (dev_priv->backlight_enabled)
+		psb_intel_panel_set_actual_backlight(dev, level);
+}
+
+static void psb_intel_panel_init_backlight(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	dev_priv->backlight_level = psb_intel_panel_get_backlight(dev);
+	dev_priv->backlight_enabled = dev_priv->backlight_level != 0;
+}
+
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+static int psb_intel_panel_update_status(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+	psb_intel_panel_set_backlight(dev, bd->props.brightness);
+	return 0;
+}
+
+static int psb_intel_panel_get_brightness(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+	return psb_intel_panel_get_backlight(dev);
+}
+
+static const struct backlight_ops psb_intel_panel_bl_ops = {
+	.update_status = psb_intel_panel_update_status,
+	.get_brightness = psb_intel_panel_get_brightness,
+};
+
+int psb_intel_panel_setup_backlight(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct backlight_properties props;
+	struct drm_connector *connector;
+
+	if (dev_priv->int_lvds_connector)
+                connector = dev_priv->int_lvds_connector;
+        else if (dev_priv->int_edp_connector)
+                connector = dev_priv->int_edp_connector;
+        else
+                return -ENODEV;
+
+	psb_intel_panel_init_backlight(dev);
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = psb_intel_panel_get_max_backlight(dev);
+	dev_priv->backlight = backlight_device_register("psb_intel_backlight",
+							&connector->kdev, dev,
+							&psb_intel_panel_bl_ops, &props);
+
+	if (IS_ERR(dev_priv->backlight)) {
+		DRM_ERROR("Failed to register backlight: %ld\n",
+				PTR_ERR(dev_priv->backlight));
+		dev_priv->backlight = NULL;
+		return -ENODEV;
+	}
+	dev_priv->backlight->props.brightness = psb_intel_panel_get_backlight(dev);
+	return 0;
+}
+
+void psb_intel_panel_destroy_backlight(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	if (dev_priv->backlight)
+		backlight_device_unregister(dev_priv->backlight);
+}
+#else
+int psb_intel_panel_setup_backlight(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	if (!dev_priv->int_lvds_connector && !dev_priv->int_edp_connector)
+                return -ENODEV;
+
+	psb_intel_panel_init_backlight(dev);
+	return 0;
+}
+
+void psb_intel_panel_destroy_backlight(struct drm_device *dev)
+{
+	return;
+}
+#endif
diff --git a/drivers/staging/cdv/drv/psb_intel_reg.h b/drivers/staging/cdv/drv/psb_intel_reg.h
new file mode 100644
index 0000000..f0bfb0c
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_intel_reg.h
@@ -0,0 +1,1690 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ * 
+ * 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 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.
+ */
+#ifndef __PSB_INTEL_REG_H__
+#define __PSB_INTEL_REG_H__
+
+#define BLC_PWM_CTL		0x61254
+#define BLC_PWM_CTL2		0x61250
+#define  PWM_ENABLE		(1 << 31)
+#define  PWM_LEGACY_MODE	(1 << 30)
+#define  PWM_PIPE_B		(1 << 29)
+#define BLC_PWM_CTL_C		0x62254
+#define BLC_PWM_CTL2_C		0x62250
+#define BACKLIGHT_MODULATION_FREQ_SHIFT		(17)
+/**
+ * This is the most significant 15 bits of the number of backlight cycles in a
+ * complete cycle of the modulated backlight control.
+ *
+ * The actual value is this field multiplied by two.
+ */
+#define BACKLIGHT_MODULATION_FREQ_MASK		(0x7fff << 17)
+#define BLM_LEGACY_MODE				(1 << 16)
+/**
+ * This is the number of cycles out of the backlight modulation cycle for which
+ * the backlight is on.
+ *
+ * This field must be no greater than the number of cycles in the complete
+ * backlight modulation cycle.
+ */
+#define BACKLIGHT_DUTY_CYCLE_SHIFT		(0)
+#define BACKLIGHT_DUTY_CYCLE_MASK		(0xffff)
+
+#define I915_GCFGC			0xf0
+#define I915_LOW_FREQUENCY_ENABLE		(1 << 7)
+#define I915_DISPLAY_CLOCK_190_200_MHZ		(0 << 4)
+#define I915_DISPLAY_CLOCK_333_MHZ		(4 << 4)
+#define I915_DISPLAY_CLOCK_MASK			(7 << 4)
+
+#define I855_HPLLCC			0xc0
+#define I855_CLOCK_CONTROL_MASK			(3 << 0)
+#define I855_CLOCK_133_200			(0 << 0)
+#define I855_CLOCK_100_200			(1 << 0)
+#define I855_CLOCK_100_133			(2 << 0)
+#define I855_CLOCK_166_250			(3 << 0)
+
+/* I830 CRTC registers */
+#define HTOTAL_A	0x60000
+#define HBLANK_A	0x60004
+#define HSYNC_A 	0x60008
+#define VTOTAL_A	0x6000c
+#define VBLANK_A	0x60010
+#define VSYNC_A 	0x60014
+#define PIPEASRC	0x6001c
+#define BCLRPAT_A	0x60020
+#define VSYNCSHIFT_A	0x60028
+
+#define HTOTAL_B	0x61000
+#define HBLANK_B	0x61004
+#define HSYNC_B 	0x61008
+#define VTOTAL_B	0x6100c
+#define VBLANK_B	0x61010
+#define VSYNC_B 	0x61014
+#define PIPEBSRC	0x6101c
+#define BCLRPAT_B	0x61020
+#define VSYNCSHIFT_B	0x61028
+
+#define HTOTAL_C	0x62000
+#define HBLANK_C	0x62004
+#define HSYNC_C 	0x62008
+#define VTOTAL_C	0x6200c
+#define VBLANK_C	0x62010
+#define VSYNC_C 	0x62014
+#define PIPECSRC	0x6201c
+#define BCLRPAT_C	0x62020
+#define VSYNCSHIFT_C	0x62028
+
+#define PP_STATUS	0x61200
+# define PP_ON					(1 << 31)
+/**
+ * Indicates that all dependencies of the panel are on:
+ *
+ * - PLL enabled
+ * - pipe enabled
+ * - LVDS/DVOB/DVOC on
+ */
+# define PP_READY				(1 << 30)
+# define PP_SEQUENCE_NONE			(0 << 28)
+# define PP_SEQUENCE_ON				(1 << 28)
+# define PP_SEQUENCE_OFF			(2 << 28)
+# define PP_SEQUENCE_MASK			0x30000000
+# define   PP_CYCLE_DELAY_ACTIVE	(1 << 27)
+# define   PP_SEQUENCE_STATE_ON_IDLE (1 << 3)
+# define   PP_SEQUENCE_STATE_MASK 0x0000000f
+
+#define PP_CONTROL	0x61204
+# define POWER_TARGET_ON			(1 << 0)
+#define  PANEL_UNLOCK_REGS	(0xabcd << 16)
+#define  PANEL_UNLOCK_MASK	(0xffff << 16)
+#define  EDP_FORCE_VDD		(1 << 3)
+#define  EDP_BLC_ENABLE		(1 << 2)
+#define  PANEL_POWER_RESET	(1 << 1)
+#define  PANEL_POWER_OFF	(0 << 0)
+#define  PANEL_POWER_ON		(1 << 0)
+
+#define PP_ON_DELAYS    0x61208
+
+#define  PANEL_PORT_SELECT_MASK (3 << 30)
+#define  PANEL_PORT_SELECT_LVDS (0 << 30)
+#define  PANEL_PORT_SELECT_EDP  (1 << 30)
+#define  PANEL_POWER_UP_DELAY_MASK      (0x1fff0000)
+#define  PANEL_POWER_UP_DELAY_SHIFT     16
+#define  PANEL_LIGHT_ON_DELAY_MASK      (0x1fff)
+#define  PANEL_LIGHT_ON_DELAY_SHIFT     0
+
+#define PP_OFF_DELAYS   0x6120c
+#define  PANEL_POWER_DOWN_DELAY_MASK    (0x1fff0000)
+#define  PANEL_POWER_DOWN_DELAY_SHIFT   16
+#define  PANEL_LIGHT_OFF_DELAY_MASK     (0x1fff)
+#define  PANEL_LIGHT_OFF_DELAY_SHIFT    0
+
+#define PP_DIVISOR      0x61210
+#define  PP_REFERENCE_DIVIDER_MASK      (0xffffff00)
+#define  PP_REFERENCE_DIVIDER_SHIFT     8
+#define  PANEL_POWER_CYCLE_DELAY_MASK   (0x1f)
+#define  PANEL_POWER_CYCLE_DELAY_SHIFT  0
+
+#define PFIT_CONTROL	0x61230
+# define PFIT_ENABLE				(1 << 31)
+# define PFIT_PIPE_MASK				(3 << 29)
+# define PFIT_PIPE_SHIFT			29
+# define PFIT_PIPE_SELECT_A			(0 << PFIT_PIPE_SHIFT)
+# define PFIT_PIPE_SELECT_B			(1 << PFIT_PIPE_SHIFT)
+# define PFIT_PIPE_SELECT_C			(2 << PFIT_PIPE_SHIFT)
+# define PFIT_PIPE_SELECT_D			(3 << PFIT_PIPE_SHIFT)
+# define PFIT_SCALING_MODE_PILLARBOX            (1 << 27)
+# define PFIT_SCALING_MODE_LETTERBOX            (3 << 26)
+# define VERT_INTERP_DISABLE			(0 << 10)
+# define VERT_INTERP_BILINEAR			(1 << 10)
+# define VERT_INTERP_MASK			(3 << 10)
+# define VERT_AUTO_SCALE			(1 << 9)
+# define HORIZ_INTERP_DISABLE			(0 << 6)
+# define HORIZ_INTERP_BILINEAR			(1 << 6)
+# define HORIZ_INTERP_MASK			(3 << 6)
+# define HORIZ_AUTO_SCALE			(1 << 5)
+# define PANEL_8TO6_DITHER_ENABLE		(1 << 3)
+
+#define PFIT_PGM_RATIOS	0x61234
+# define PFIT_VERT_SCALE_MASK			0xfff00000
+# define PFIT_HORIZ_SCALE_MASK			0x0000fff0
+
+#define PFIT_AUTO_RATIOS	0x61238
+
+
+#define DPLL_A		0x06014
+#define DPLL_B		0x06018
+# define DPLL_VCO_ENABLE			(1 << 31)
+# define DPLL_DVO_HIGH_SPEED			(1 << 30)
+# define DPLL_SYNCLOCK_ENABLE			(1 << 29)
+# define DPLL_VGA_MODE_DIS			(1 << 28)
+# define DPLLB_MODE_DAC_SERIAL			(1 << 26)	/* i915 */
+# define DPLLB_MODE_LVDS			(2 << 26)	/* i915 */
+# define DPLL_MODE_MASK				(3 << 26)
+# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10	(0 << 24)	/* i915 */
+# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5		(1 << 24)	/* i915 */
+# define DPLLB_LVDS_P2_CLOCK_DIV_14		(0 << 24)	/* i915 */
+# define DPLLB_LVDS_P2_CLOCK_DIV_7		(1 << 24)	/* i915 */
+# define DPLL_P2_CLOCK_DIV_MASK			0x03000000	/* i915 */
+# define DPLL_FPA01_P1_POST_DIV_MASK		0x00ff0000	/* i915 */
+# define DPLL_LOCK				(1 << 15)	/* CDV */
+/**
+ *  The i830 generation, in DAC/serial mode, defines p1 as two plus this
+ * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830	0x001f0000
+/**
+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
+ * this field (only one bit may be set).
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS	0x003f0000
+# define DPLL_FPA01_P1_POST_DIV_SHIFT		16
+# define PLL_P2_DIVIDE_BY_4		(1 << 23)	/* i830, required
+							 * in DVO non-gang */
+# define PLL_P1_DIVIDE_BY_TWO			(1 << 21)	/* i830 */
+# define PLL_REF_INPUT_DREFCLK			(0 << 13)
+# define PLL_REF_INPUT_TVCLKINA			(1 << 13)	/* i830 */
+# define PLL_REF_INPUT_TVCLKINBC		(2 << 13)	/* SDVO
+								 * TVCLKIN */
+# define PLLB_REF_INPUT_SPREADSPECTRUMIN	(3 << 13)
+# define PLL_REF_INPUT_MASK			(3 << 13)
+# define PLL_LOAD_PULSE_PHASE_SHIFT		9
+/*
+ * Parallel to Serial Load Pulse phase selection.
+ * Selects the phase for the 10X DPLL clock for the PCIe
+ * digital display port. The range is 4 to 13; 10 or more
+ * is just a flip delay. The default is 6
+ */
+# define PLL_LOAD_PULSE_PHASE_MASK	(0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
+# define DISPLAY_RATE_SELECT_FPA1	(1 << 8)
+
+/**
+ * SDVO multiplier for 945G/GM. Not used on 965.
+ *
+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
+ */
+# define SDVO_MULTIPLIER_MASK			0x000000ff
+# define SDVO_MULTIPLIER_SHIFT_HIRES		4
+# define SDVO_MULTIPLIER_SHIFT_VGA		0
+
+/** @defgroup DPLL_MD
+ * @{
+ */
+/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
+#define DPLL_A_MD		0x0601c
+/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
+#define DPLL_B_MD		0x06020
+/**
+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
+ *
+ * Value is pixels minus 1.  Must be set to 1 pixel for SDVO.
+ */
+# define DPLL_MD_UDI_DIVIDER_MASK		0x3f000000
+# define DPLL_MD_UDI_DIVIDER_SHIFT		24
+/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
+# define DPLL_MD_VGA_UDI_DIVIDER_MASK		0x003f0000
+# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT		16
+/**
+ * SDVO/UDI pixel multiplier.
+ *
+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
+ * clock rate is 10 times the DPLL clock.  At low resolution/refresh rate
+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
+ * dummy bytes in the datastream at an increased clock rate, with both sides of
+ * the link knowing how many bytes are fill.
+ *
+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
+ * rate to 130Mhz to get a bus rate of 1.30Ghz.  The DPLL clock rate would be
+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
+ * through an SDVO command.
+ *
+ * This register field has values of multiplication factor minus 1, with
+ * a maximum multiplier of 5 for SDVO.
+ */
+# define DPLL_MD_UDI_MULTIPLIER_MASK		0x00003f00
+# define DPLL_MD_UDI_MULTIPLIER_SHIFT		8
+/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
+ * This best be set to the default value (3) or the CRT won't work. No,
+ * I don't entirely understand what this does...
+ */
+# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK	0x0000003f
+# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT	0
+/** @} */
+
+#define DPLL_TEST		0x606c
+# define DPLLB_TEST_SDVO_DIV_1			(0 << 22)
+# define DPLLB_TEST_SDVO_DIV_2			(1 << 22)
+# define DPLLB_TEST_SDVO_DIV_4			(2 << 22)
+# define DPLLB_TEST_SDVO_DIV_MASK		(3 << 22)
+# define DPLLB_TEST_N_BYPASS			(1 << 19)
+# define DPLLB_TEST_M_BYPASS			(1 << 18)
+# define DPLLB_INPUT_BUFFER_ENABLE		(1 << 16)
+# define DPLLA_TEST_N_BYPASS			(1 << 3)
+# define DPLLA_TEST_M_BYPASS			(1 << 2)
+# define DPLLA_INPUT_BUFFER_ENABLE		(1 << 0)
+
+#define ADPA			0x61100
+#define ADPA_DAC_ENABLE 	(1<<31)
+#define ADPA_DAC_DISABLE	0
+#define ADPA_PIPE_SELECT_MASK	(1<<30)
+#define ADPA_PIPE_A_SELECT	0
+#define ADPA_PIPE_B_SELECT	(1<<30)
+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
+#define ADPA_SETS_HVPOLARITY	0
+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
+#define ADPA_VSYNC_CNTL_ENABLE	0
+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
+#define ADPA_HSYNC_CNTL_ENABLE	0
+#define ADPA_VSYNC_ACTIVE_HIGH	(1<<4)
+#define ADPA_VSYNC_ACTIVE_LOW	0
+#define ADPA_HSYNC_ACTIVE_HIGH	(1<<3)
+#define ADPA_HSYNC_ACTIVE_LOW	0
+
+#define FPA0		0x06040
+#define FPA1		0x06044
+#define FPB0		0x06048
+#define FPB1		0x0604c
+# define FP_N_DIV_MASK				0x003f0000
+# define FP_N_DIV_SHIFT				16
+# define FP_M1_DIV_MASK				0x00003f00
+# define FP_M1_DIV_SHIFT			8
+# define FP_M2_DIV_MASK				0x0000003f
+# define FP_M2_DIV_SHIFT			0
+
+
+#define PORT_HOTPLUG_EN		0x61110
+# define HDMIB_HOTPLUG_INT_EN			(1 << 29)
+# define HDMIC_HOTPLUG_INT_EN			(1 << 28)
+# define HDMID_HOTPLUG_INT_EN			(1 << 27)
+# define SDVOB_HOTPLUG_INT_EN			(1 << 26)
+# define SDVOC_HOTPLUG_INT_EN			(1 << 25)
+# define TV_HOTPLUG_INT_EN			(1 << 18)
+# define CRT_HOTPLUG_INT_EN			(1 << 9)
+# define CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
+
+#define CRT_HOTPLUG_ACTIVATION_PERIOD_64	(1 << 8)
+#define CRT_HOTPLUG_DAC_ON_TIME_2M		(0 << 7)
+#define CRT_HOTPLUG_DAC_ON_TIME_4M		(1 << 7)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_40		(0 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_50		(1 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_60		(2 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_70		(3 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK	(3 << 5)
+#define CRT_HOTPLUG_DETECT_DELAY_1G		(0 << 4)
+#define CRT_HOTPLUG_DETECT_DELAY_2G		(1 << 4)
+#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV	(0 << 2)
+#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV	(1 << 2)
+#define CRT_HOTPLUG_DETECT_MASK			0x000000F8
+
+#define PORT_HOTPLUG_STAT	0x61114
+# define HDMIB_HOTPLUG_INT_STATUS		(1 << 29)
+# define DPB_HOTPLUG_INT_STATUS			(1 << 29)
+# define HDMIC_HOTPLUG_INT_STATUS		(1 << 28)
+# define DPC_HOTPLUG_INT_STATUS			(1 << 28)
+# define HDMID_HOTPLUG_INT_STATUS		(1 << 27)
+# define DPD_HOTPLUG_INT_STATUS			(1 << 27)
+# define CRT_HOTPLUG_INT_STATUS			(1 << 11)
+# define TV_HOTPLUG_INT_STATUS			(1 << 10)
+# define CRT_HOTPLUG_MONITOR_MASK		(3 << 8)
+# define CRT_HOTPLUG_MONITOR_COLOR		(3 << 8)
+# define CRT_HOTPLUG_MONITOR_MONO		(2 << 8)
+# define CRT_HOTPLUG_MONITOR_NONE		(0 << 8)
+# define SDVOC_HOTPLUG_INT_STATUS		(1 << 7)
+# define SDVOB_HOTPLUG_INT_STATUS		(1 << 6)
+
+#define SDVOB			0x61140
+#define SDVOC			0x61160
+#define SDVO_ENABLE				(1 << 31)
+#define SDVO_PIPE_B_SELECT			(1 << 30)
+#define SDVO_STALL_SELECT			(1 << 29)
+#define SDVO_INTERRUPT_ENABLE			(1 << 26)
+/** New with 965, default is to be set */
+#define   SDVO_VSYNC_ACTIVE_HIGH        (1 << 4)
+/** New with 965, default is to be set */
+#define   SDVO_HSYNC_ACTIVE_HIGH        (1 << 3)
+
+/**
+ * 915G/GM SDVO pixel multiplier.
+ *
+ * Programmed value is multiplier - 1, up to 5x.
+ *
+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
+ */
+#define SDVO_PORT_MULTIPLY_MASK			(7 << 23)
+#define SDVO_PORT_MULTIPLY_SHIFT		23
+#define SDVO_PHASE_SELECT_MASK			(15 << 19)
+#define SDVO_PHASE_SELECT_DEFAULT		(6 << 19)
+#define SDVO_CLOCK_OUTPUT_INVERT		(1 << 18)
+#define SDVOC_GANG_MODE				(1 << 16)
+#define SDVO_BORDER_ENABLE			(1 << 7)
+#define SDVOB_PCIE_CONCURRENCY			(1 << 3)
+#define SDVO_DETECTED				(1 << 2)
+/* Bits to be preserved when writing */
+#define SDVOB_PRESERVE_MASK		((1 << 17) | (1 << 16) | (1 << 14))
+#define SDVOC_PRESERVE_MASK			(1 << 17)
+
+/** @defgroup LVDS
+ * @{
+ */
+/**
+ * This register controls the LVDS output enable, pipe selection, and data
+ * format selection.
+ *
+ * All of the clock/data pairs are force powered down by power sequencing.
+ */
+#define LVDS			0x61180
+/**
+ * Enables the LVDS port.  This bit must be set before DPLLs are enabled, as
+ * the DPLL semantics change when the LVDS is assigned to that pipe.
+ */
+# define LVDS_PORT_EN			(1 << 31)
+/** Selects pipe B for LVDS data.  Must be set on pre-965. */
+# define LVDS_PIPEB_SELECT		(1 << 30)
+
+/** Turns on border drawing to allow centered display. */
+# define LVDS_BORDER_EN                 (1 << 15)
+
+/**
+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
+ * pixel.
+ */
+# define LVDS_A0A2_CLKA_POWER_MASK	(3 << 8)
+# define LVDS_A0A2_CLKA_POWER_DOWN	(0 << 8)
+# define LVDS_A0A2_CLKA_POWER_UP	(3 << 8)
+/**
+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
+ * mode.  Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
+ * on.
+ */
+# define LVDS_A3_POWER_MASK		(3 << 6)
+# define LVDS_A3_POWER_DOWN		(0 << 6)
+# define LVDS_A3_POWER_UP		(3 << 6)
+/**
+ * Controls the CLKB pair.  This should only be set when LVDS_B0B3_POWER_UP
+ * is set.
+ */
+# define LVDS_CLKB_POWER_MASK		(3 << 4)
+# define LVDS_CLKB_POWER_DOWN		(0 << 4)
+# define LVDS_CLKB_POWER_UP		(3 << 4)
+
+/**
+ * Controls the B0-B3 data pairs.  This must be set to match the DPLL p2
+ * setting for whether we are in dual-channel mode.  The B3 pair will
+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
+ */
+# define LVDS_B0B3_POWER_MASK		(3 << 2)
+# define LVDS_B0B3_POWER_DOWN		(0 << 2)
+# define LVDS_B0B3_POWER_UP		(3 << 2)
+
+#define PIPEACONF 0x70008
+#define PIPEACONF_ENABLE	(1<<31)
+#define PIPEACONF_DISABLE	0
+#define PIPEACONF_DOUBLE_WIDE	(1<<30)
+#define PIPECONF_ACTIVE		(1<<30)
+#define I965_PIPECONF_ACTIVE	(1<<30)
+#define PIPECONF_DSIPLL_LOCK	(1<<29)
+#define PIPEACONF_SINGLE_WIDE	0
+#define PIPEACONF_PIPE_UNLOCKED 0
+#define PIPEACONF_DSR		(1<<26)
+#define PIPEACONF_PIPE_LOCKED	(1<<25)
+#define PIPEACONF_PALETTE	0
+#define PIPECONF_FORCE_BORDER	(1<<25)
+#define PIPEACONF_GAMMA 	(1<<24)
+#define PIPECONF_PROGRESSIVE	(0 << 21)
+#define PIPECONF_INTERLACE_W_FIELD_INDICATION	(6 << 21)
+#define PIPECONF_INTERLACE_FIELD_0_ONLY		(7 << 21)
+#define PIPECONF_PLANE_OFF 	(1<<19)
+#define PIPECONF_CURSOR_OFF 	(1<<18)
+
+
+#define PIPEBCONF 0x71008
+#define PIPEBCONF_ENABLE	(1<<31)
+#define PIPEBCONF_DISABLE	0
+#define PIPEBCONF_DOUBLE_WIDE	(1<<30)
+#define PIPEBCONF_DISABLE	0
+#define PIPEBCONF_GAMMA 	(1<<24)
+#define PIPEBCONF_PALETTE	0
+
+#define PIPECCONF 0x72008
+
+#define PIPEBGCMAXRED		0x71010
+#define PIPEBGCMAXGREEN		0x71014
+#define PIPEBGCMAXBLUE		0x71018
+
+#define PIPEASTAT               0x70024
+#define PIPEBSTAT		0x71024
+#define PIPECSTAT		0x72024
+
+#define PIPE_FIFO_UNDERRUN		     (1UL<<31)
+#define PIPE_VBLANK_INTERRUPT_STATUS         (1UL<<1)
+#define PIPE_START_VBLANK_INTERRUPT_STATUS   (1UL<<2)
+#define PIPE_VBLANK_CLEAR                    (1 << 1)
+#define PIPE_VBLANK_STATUS                   (1 << 1)
+#define PIPE_LEGACY_BLC_EVENT_STATUS	     (1UL<<6)
+#define PIPE_DPST_EVENT_STATUS		     (1UL<<7)
+#define PIPE_VSYNC_CLEAR                     (1UL<<9)
+#define PIPE_VSYNC_STATUS                    (1UL<<9)
+#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS      (1UL<<10)
+#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS   (1UL<<11)
+#define PIPE_VBLANK_INTERRUPT_ENABLE         (1UL<<17)
+#define PIPE_START_VBLANK_INTERRUPT_ENABLE   (1UL<<18)
+#define PIPE_LEGACY_BLC_EVENT_ENABLE	     (1UL<<22)
+#define PIPE_DPST_EVENT_ENABLE               (1UL<<23)
+#define PIPE_VSYNC_ENABL                     (1UL<<25)
+#define PIPE_HDMI_AUDIO_UNDERRUN             (1UL<<26)
+#define PIPE_HDMI_AUDIO_BUFFER_DONE          (1UL<<27)
+#define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | PIPE_HDMI_AUDIO_BUFFER_DONE)
+#define PIPE_EVENT_MASK (BIT29|BIT28|BIT27|BIT26|BIT24|BIT23|BIT22|BIT21|BIT20|BIT16)
+#define PIPE_VBLANK_MASK (BIT25|BIT24|BIT18|BIT17)
+#define HISTOGRAM_INT_CONTROL		0x61268
+#define HISTOGRAM_BIN_DATA		0X61264
+#define HISTOGRAM_LOGIC_CONTROL		0x61260
+#define PWM_CONTROL_LOGIC		0x61250
+#define PIPE_HOTPLUG_INTERRUPT_STATUS	(1UL<<10)
+#define HISTOGRAM_INTERRUPT_ENABLE	(1UL<<31)
+#define HISTOGRAM_LOGIC_ENABLE		(1UL<<31)
+#define PWM_LOGIC_ENABLE		(1UL<<31)
+#define PWM_PHASEIN_ENABLE		(1UL<<25)
+#define PWM_PHASEIN_INT_ENABLE		(1UL<<24)
+#define PWM_PHASEIN_VB_COUNT		0x00001f00
+#define PWM_PHASEIN_INC			0x0000001f
+#define HISTOGRAM_INT_CTRL_CLEAR	(1UL<<30)
+#define DPST_YUV_LUMA_MODE		0
+
+struct dpst_ie_histogram_control {
+	union {
+		uint32_t data;
+		struct {
+			uint32_t bin_reg_index:7;
+			uint32_t reserved:4;
+			uint32_t bin_reg_func_select:1;
+			uint32_t sync_to_phase_in:1;
+			uint32_t alt_enhancement_mode:2;
+			uint32_t reserved1:1;
+			uint32_t sync_to_phase_in_count:8;
+			uint32_t histogram_mode_select:1;
+			uint32_t reserved2:4;
+			uint32_t ie_pipe_assignment:1;
+			uint32_t ie_mode_table_enabled:1;
+			uint32_t ie_histogram_enable:1;
+		};
+	};
+};
+
+struct dpst_guardband {
+	union {
+		uint32_t data;
+		struct {
+			uint32_t guardband:22;
+			uint32_t guardband_interrupt_delay:8;
+			uint32_t interrupt_status:1;
+			uint32_t interrupt_enable:1;
+		};
+	};
+};
+
+#define PIPEAFRAMEHIGH		0x70040
+#define PIPEAFRAMEPIXEL		0x70044
+#define PIPEBFRAMEHIGH		0x71040
+#define PIPEBFRAMEPIXEL		0x71044
+#define PIPECFRAMEHIGH		0x72040
+#define PIPECFRAMEPIXEL		0x72044
+#define PIPE_FRAME_HIGH_MASK    0x0000ffff
+#define PIPE_FRAME_HIGH_SHIFT   0
+#define PIPE_FRAME_LOW_MASK     0xff000000
+#define PIPE_FRAME_LOW_SHIFT    24
+#define PIPE_PIXEL_MASK         0x00ffffff
+#define PIPE_PIXEL_SHIFT        0
+
+#define FW_BLC_SELF	0x20e0 
+#define   FW_BLC_SELF_EN           (1<<15)
+
+#define DSPARB			0x70030
+#define DSPFW1			0x70034
+#define DSP_FIFO_SR_WM_MASK	0xFF800000
+#define DSP_FIFO_SR_WM_SHIFT	23
+#define CURSOR_B_FIFO_WM_MASK	0x003F0000
+#define CURSOR_B_FIFO_WM_SHIFT	16
+
+#define DSPFW2			0x70038
+#define CURSOR_A_FIFO_WM_MASK	0x3F00
+#define CURSOR_A_FIFO_WM_SHIFT	8
+#define DSP_PLANE_C_FIFO_WM_MASK	0x7F
+#define DSP_PLANE_C_FIFO_WM_SHIFT	0
+
+#define DSPFW3			0x7003c
+#define DSPFW4			0x70070
+
+#define DSPFW5			0x70074
+#define DSP_PLANE_B_FIFO_WM1_SHIFT	24
+#define DSP_PLANE_A_FIFO_WM1_SHIFT	16
+#define CURSOR_B_FIFO_WM1_SHIFT		8
+#define CURSOR_FIFO_SR_WM1_SHIFT	0
+
+#define DSPFW6			0x70078
+#define DSPCHICKENBIT		0x70400
+#define DSPACNTR		0x70180
+#define DSPBCNTR		0x71180
+#define DSPCCNTR		0x72180
+#define DISPLAY_PLANE_ENABLE 			(1<<31)
+#define DISPLAY_PLANE_DISABLE			0
+#define DISPPLANE_GAMMA_ENABLE			(1<<30)
+#define DISPPLANE_GAMMA_DISABLE			0
+#define DISPPLANE_PIXFORMAT_MASK		(0xf<<26)
+#define DISPPLANE_8BPP				(0x2<<26)
+#define DISPPLANE_15_16BPP			(0x4<<26)
+#define DISPPLANE_16BPP				(0x5<<26)
+#define DISPPLANE_32BPP_NO_ALPHA 		(0x6<<26)
+#define DISPPLANE_32BPP				(0x7<<26)
+#define DISPPLANE_STEREO_ENABLE			(1<<25)
+#define DISPPLANE_STEREO_DISABLE		0
+#define DISPPLANE_SEL_PIPE_MASK			(1<<24)
+#define DISPPLANE_SEL_PIPE_POS			24
+#define DISPPLANE_SEL_PIPE_A			0
+#define DISPPLANE_SEL_PIPE_B			(1<<24)
+#define DISPPLANE_SRC_KEY_ENABLE		(1<<22)
+#define DISPPLANE_SRC_KEY_DISABLE		0
+#define DISPPLANE_LINE_DOUBLE			(1<<20)
+#define DISPPLANE_NO_LINE_DOUBLE		0
+#define DISPPLANE_STEREO_POLARITY_FIRST		0
+#define DISPPLANE_STEREO_POLARITY_SECOND	(1<<18)
+/* plane B only */
+#define DISPPLANE_ALPHA_TRANS_ENABLE		(1<<15)
+#define DISPPLANE_ALPHA_TRANS_DISABLE		0
+#define DISPPLANE_SPRITE_ABOVE_DISPLAYA		0
+#define DISPPLANE_SPRITE_ABOVE_OVERLAY		(1)
+#define DISPPLANE_BOTTOM			(4)
+
+#define DSPABASE		0x70184
+#define DSPALINOFF		0x70184
+#define DSPASTRIDE		0x70188
+
+#define DSPBBASE		0x71184
+#define DSPBLINOFF		0X71184
+#define DSPBADDR		DSPBBASE
+#define DSPBSTRIDE		0x71188
+
+#define DSPCBASE		0x72184
+#define DSPCLINOFF		0x72184
+#define DSPCSTRIDE		0x72188
+
+#define DSPAKEYVAL		0x70194
+#define DSPAKEYMASK		0x70198
+
+#define DSPAPOS			0x7018C	/* reserved */
+#define DSPASIZE		0x70190
+#define DSPBPOS			0x7118C
+#define DSPBSIZE		0x71190
+#define DSPCPOS			0x7218C
+#define DSPCSIZE		0x72190
+
+#define DSPASURF		0x7019C
+#define DSPATILEOFF		0x701A4
+
+#define DSPBSURF		0x7119C
+#define DSPBTILEOFF		0x711A4
+
+#define DSPCSURF		0x7219C
+#define DSPCTILEOFF		0x721A4
+#define DSPCKEYMAXVAL 		0x721A0
+#define DSPCKEYMINVAL 		0x72194
+#define DSPCKEYMSK 		0x72198
+
+/*
+ * GPIO regs
+ */
+#define GPIOA			0x5010
+#define GPIOB			0x5014
+#define GPIOC			0x5018
+#define GPIOD			0x501c
+#define GPIOE			0x5020
+#define GPIOF			0x5024
+#define GPIOG			0x5028
+#define GPIOH			0x502c
+# define GPIO_CLOCK_DIR_MASK		(1 << 0)
+# define GPIO_CLOCK_DIR_IN		(0 << 1)
+# define GPIO_CLOCK_DIR_OUT		(1 << 1)
+# define GPIO_CLOCK_VAL_MASK		(1 << 2)
+# define GPIO_CLOCK_VAL_OUT		(1 << 3)
+# define GPIO_CLOCK_VAL_IN		(1 << 4)
+# define GPIO_CLOCK_PULLUP_DISABLE	(1 << 5)
+# define GPIO_DATA_DIR_MASK		(1 << 8)
+# define GPIO_DATA_DIR_IN		(0 << 9)
+# define GPIO_DATA_DIR_OUT		(1 << 9)
+# define GPIO_DATA_VAL_MASK		(1 << 10)
+# define GPIO_DATA_VAL_OUT		(1 << 11)
+# define GPIO_DATA_VAL_IN		(1 << 12)
+# define GPIO_DATA_PULLUP_DISABLE	(1 << 13)
+
+#define GMBUS0			0x5100 /* clock/port select */
+#define   GMBUS_RATE_100KHZ	(0<<8)
+#define   GMBUS_RATE_50KHZ	(1<<8)
+#define   GMBUS_RATE_400KHZ	(2<<8) /* reserved on Pineview */
+#define   GMBUS_RATE_1MHZ	(3<<8) /* reserved on Pineview */
+#define   GMBUS_HOLD_EXT	(1<<7) /* 300ns hold time, rsvd on Pineview */
+#define   GMBUS_PORT_DISABLED	0
+#define   GMBUS_PORT_SSC	1
+#define   GMBUS_PORT_VGADDC	2
+#define   GMBUS_PORT_PANEL	3
+#define   GMBUS_PORT_DPC	4 /* HDMIC */
+#define   GMBUS_PORT_DPB	5 /* SDVO, HDMIB */
+				  /* 6 reserved */
+#define   GMBUS_PORT_DPD	7 /* HDMID */
+#define   GMBUS_NUM_PORTS       8
+#define GMBUS1			0x5104 /* command/status */
+#define   GMBUS_SW_CLR_INT	(1<<31)
+#define   GMBUS_SW_RDY		(1<<30)
+#define   GMBUS_ENT		(1<<29) /* enable timeout */
+#define   GMBUS_CYCLE_NONE	(0<<25)
+#define   GMBUS_CYCLE_WAIT	(1<<25)
+#define   GMBUS_CYCLE_INDEX	(2<<25)
+#define   GMBUS_CYCLE_STOP	(4<<25)
+#define   GMBUS_BYTE_COUNT_SHIFT 16
+#define   GMBUS_SLAVE_INDEX_SHIFT 8
+#define   GMBUS_SLAVE_ADDR_SHIFT 1
+#define   GMBUS_SLAVE_READ	(1<<0)
+#define   GMBUS_SLAVE_WRITE	(0<<0)
+#define GMBUS2			0x5108 /* status */
+#define   GMBUS_INUSE		(1<<15)
+#define   GMBUS_HW_WAIT_PHASE	(1<<14)
+#define   GMBUS_STALL_TIMEOUT	(1<<13)
+#define   GMBUS_INT		(1<<12)
+#define   GMBUS_HW_RDY		(1<<11)
+#define   GMBUS_SATOER		(1<<10)
+#define   GMBUS_ACTIVE		(1<<9)
+#define GMBUS3			0x510c /* data buffer bytes 3-0 */
+#define GMBUS4			0x5110 /* interrupt mask (Pineview+) */
+#define   GMBUS_SLAVE_TIMEOUT_EN (1<<4)
+#define   GMBUS_NAK_EN		(1<<3)
+#define   GMBUS_IDLE_EN		(1<<2)
+#define   GMBUS_HW_WAIT_EN	(1<<1)
+#define   GMBUS_HW_RDY_EN	(1<<0)
+#define GMBUS5			0x5120 /* byte index */
+#define   GMBUS_2BYTE_INDEX_EN	(1<<31)
+
+#define VGACNTRL		0x71400
+# define VGA_DISP_DISABLE			(1 << 31)
+# define VGA_2X_MODE				(1 << 30)
+# define VGA_PIPE_B_SELECT			(1 << 29)
+
+#define VGA_SR_INDEX 0x3c4
+#define VGA_SR_DATA 0x3c5
+
+/*
+ * Overlay registers
+ */
+#define OV_C_OFFSET		0x08000
+#define OV_OVADD		0x30000
+#define OV_DOVASTA              0x30008
+# define OV_PIPE_SELECT				(BIT6|BIT7)
+# define OV_PIPE_SELECT_POS			6
+# define OV_PIPE_A				0
+# define OV_PIPE_C				1
+#define OV_OGAMC5		0x30010
+#define OV_OGAMC4		0x30014
+#define OV_OGAMC3		0x30018
+#define OV_OGAMC2		0x3001C
+#define OV_OGAMC1		0x30020
+#define OV_OGAMC0		0x30024
+#define OVC_OVADD		0x38000
+#define OVC_DOVCSTA             0x38008
+#define OVC_OGAMC5		0x38010
+#define OVC_OGAMC4		0x38014
+#define OVC_OGAMC3		0x38018
+#define OVC_OGAMC2		0x3801C
+#define OVC_OGAMC1		0x38020
+#define OVC_OGAMC0		0x38024
+
+/*
+ * Some BIOS scratch area registers.  The 845 (and 830?) store the amount
+ * of video memory available to the BIOS in SWF1.
+ */ 
+#define SWF0			0x71410
+#define SWF1			0x71414
+#define SWF2			0x71418
+#define SWF3			0x7141c
+#define SWF4			0x71420
+#define SWF5			0x71424
+#define SWF6			0x71428
+
+/*
+ * 855 scratch registers.
+ */
+#define SWF00			0x70410
+#define SWF01			0x70414
+#define SWF02			0x70418
+#define SWF03			0x7041c
+#define SWF04			0x70420
+#define SWF05			0x70424
+#define SWF06			0x70428
+
+#define SWF10			SWF0
+#define SWF11			SWF1
+#define SWF12			SWF2
+#define SWF13			SWF3
+#define SWF14			SWF4
+#define SWF15			SWF5
+#define SWF16			SWF6
+
+#define SWF30			0x72414
+#define SWF31			0x72418
+#define SWF32			0x7241c
+
+
+/*
+ * Palette registers
+ */
+#define PALETTE_A		0x0a000
+#define PALETTE_B		0x0a800
+#define PALETTE_C		0x0ac00
+
+#define IS_I830(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82830_CGC)
+#define IS_845G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82845G_IG)
+#define IS_I85X(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG)
+#define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG)
+#define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG)
+
+
+/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G) */
+#define IS_I915G(dev) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)
+#define IS_I915GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG)
+#define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG)
+#define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG)
+
+#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \
+		       (dev)->pci_device == 0x2982 || \
+		       (dev)->pci_device == 0x2992 || \
+		       (dev)->pci_device == 0x29A2 || \
+		       (dev)->pci_device == 0x2A02 || \
+		       (dev)->pci_device == 0x2A12)
+
+#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
+
+#define IS_G33(dev)    ((dev)->pci_device == 0x29C2 ||	\
+			(dev)->pci_device == 0x29B2 ||	\
+			(dev)->pci_device == 0x29D2)
+
+#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
+		      IS_I945GM(dev) || IS_I965G(dev))
+
+#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
+			IS_I945GM(dev) || IS_I965GM(dev))
+
+/* Cursor A & B regs */
+#define CURACNTR		0x70080
+#define   CURSOR_MODE_DISABLE   0x00
+#define   CURSOR_MODE_64_32B_AX 0x07
+#define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define   MCURSOR_GAMMA_ENABLE  (1 << 26)
+#define CURABASE		0x70084
+#define CURAPOS			0x70088
+#define   CURSOR_POS_MASK       0x007FF
+#define   CURSOR_POS_SIGN       0x8000
+#define   CURSOR_X_SHIFT        0
+#define   CURSOR_Y_SHIFT        16
+#define CURBCNTR		0x700c0
+#define CURBBASE		0x700c4
+#define CURBPOS			0x700c8
+#define CURCCNTR		0x700e0
+#define CURCBASE		0x700e4
+#define CURCPOS			0x700e8
+
+/*
+ * Interrupt Registers
+ */
+#define IER 0x020a0
+#define IIR 0x020a4
+#define IMR 0x020a8
+#define ISR 0x020ac
+
+/*
+ * MOORESTOWN delta registers
+ */
+#define MRST_DPLL_A		0x0f014
+#define MDFLD_DPLL_B		0x0f018
+#define MDFLD_INPUT_REF_SEL	(1 << 14) 
+#define MDFLD_VCO_SEL		(1 << 16) 
+#define DPLLA_MODE_LVDS		(2 << 26)	/* mrst */
+#define MDFLD_PLL_LATCHEN	(1 << 28) 
+#define MDFLD_PWR_GATE_EN	(1 << 30) 
+#define MDFLD_P1_MASK		(0x1FF << 17) 
+#define MRST_FPA0		0x0f040
+#define MRST_FPA1		0x0f044
+#define MDFLD_DPLL_DIV0		0x0f048
+#define MDFLD_DPLL_DIV1		0x0f04c
+#define MRST_PERF_MODE		0x020f4
+
+/* MEDFIELD HDMI registers */
+#define HDMIPHYMISCCTL   	0x61134
+# define HDMI_PHY_POWER_DOWN	0x7f
+#define HDMIB_CONTROL   	0x61140
+# define HDMIB_PORT_EN			(1 << 31)
+# define HDMIB_PIPE_B_SELECT		(1 << 30)
+# define HDMIB_NULL_PACKET		(1 << 9)
+#define HDMIB_HDCP_PORT (1 << 5)
+/** Requird for HDMI operation */
+#define   HDMI_NULL_PACKETS_DURING_VSYNC (1 << 9)
+#define   HDMI_BORDER_ENABLE            (1 << 7)
+#define   HDMI_AUDIO_ENABLE             (1 << 6)
+
+
+/* #define LVDS			0x61180 */
+# define MRST_PANEL_8TO6_DITHER_ENABLE		(1 << 25)
+# define MRST_PANEL_24_DOT_1_FORMAT		(1 << 24)
+# define LVDS_A3_POWER_UP_0_OUTPUT		(1 << 6)
+
+#define MIPI			0x61190
+#define MIPI_C			0x62190
+# define MIPI_PORT_EN			(1 << 31)
+/** Turns on border drawing to allow centered display. */
+# define SEL_FLOPPED_HSTX		(1 << 23)
+# define PASS_FROM_SPHY_TO_AFE 		(1 << 16)
+# define MIPI_BORDER_EN			(1 << 15)
+# define MIPIA_3LANE_MIPIC_1LANE	0x1
+# define MIPIA_2LANE_MIPIC_2LANE	0x2
+# define TE_TRIGGER_DSI_PROTOCOL	(1 << 2)
+# define TE_TRIGGER_GPIO_PIN		(1 << 3)
+#define MIPI_TE_COUNT			0x61194
+
+/* #define PP_CONTROL	0x61204 */
+# define POWER_DOWN_ON_RESET		(1 << 1)
+
+/* #define PFIT_CONTROL	0x61230 */
+# define PFIT_PIPE_SELECT				(3 << 29)
+# define PFIT_PIPE_SELECT_SHIFT			(29)
+
+/* #define BLC_PWM_CTL		0x61254 */
+#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT		(16)
+#define MRST_BACKLIGHT_MODULATION_FREQ_MASK		(0xffff << 16)
+
+/* #define PIPEACONF 0x70008 */
+#define PIPEACONF_PIPE_STATE	(1<<30)
+/* #define DSPACNTR		0x70180 */
+#if 0				/*FIXME JLIU7 need to define the following */
+1000 = 32 - bit RGBX(10 : 10 : 10 : 2)
+pixel format.Ignore alpha.1010 = BGRX 10 : 10 : 10 : 2 1100 = 64 - bit RGBX
+(16 : 16 : 16 : 16) 16 bit floating point pixel format.
+Ignore alpha.1110 = 32 - bit RGBX(8 : 8 : 8 : 8) pixel format.
+    Ignore
+    alpha.
+#endif				/*FIXME JLIU7 need to define the following */
+
+#define MRST_DSPABASE		0x7019c
+#define MRST_DSPBBASE		0x7119c
+#define MDFLD_DSPCBASE		0x7219c
+
+/*
+ * MOORESTOWN reserved registers
+ */
+#if 0
+#define DSPAPOS			0x7018C	/* reserved */
+#define DSPASIZE		0x70190
+#endif
+/*
+ * Moorestown registers.
+ */
+/*===========================================================================
+; General Constants
+;--------------------------------------------------------------------------*/
+#define BIT0  0x00000001
+#define BIT1  0x00000002
+#define BIT2  0x00000004
+#define BIT3  0x00000008
+#define BIT4  0x00000010
+#define BIT5  0x00000020
+#define BIT6  0x00000040
+#define BIT7  0x00000080
+#define BIT8  0x00000100
+#define BIT9  0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+/*===========================================================================
+; MIPI IP registers
+;--------------------------------------------------------------------------*/
+#define MIPIC_REG_OFFSET             0x800
+#define DEVICE_READY_REG             0xb000
+#define LP_OUTPUT_HOLD               BIT16
+#define EXIT_ULPS_DEV_READY          0x3
+#define LP_OUTPUT_HOLD_RELEASE       0x810000
+# define ENTERING_ULPS		(2 << 1)
+# define EXITING_ULPS		(1 << 1)
+# define ULPS_MASK		(3 << 1)
+# define BUS_POSSESSION		(1 << 3)
+#define INTR_STAT_REG                0xb004
+#define RX_SOT_ERROR BIT0
+#define RX_SOT_SYNC_ERROR BIT1
+#define RX_ESCAPE_MODE_ENTRY_ERROR BIT3
+#define RX_LP_TX_SYNC_ERROR BIT4
+#define RX_HS_RECEIVE_TIMEOUT_ERROR BIT5
+#define RX_FALSE_CONTROL_ERROR BIT6
+#define RX_ECC_SINGLE_BIT_ERROR BIT7
+#define RX_ECC_MULTI_BIT_ERROR BIT8
+#define RX_CHECKSUM_ERROR BIT9
+#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED BIT10
+#define RX_DSI_VC_ID_INVALID BIT11
+#define TX_FALSE_CONTROL_ERROR BIT12
+#define TX_ECC_SINGLE_BIT_ERROR BIT13
+#define TX_ECC_MULTI_BIT_ERROR BIT14
+#define TX_CHECKSUM_ERROR BIT15
+#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED BIT16
+#define TX_DSI_VC_ID_INVALID BIT17
+#define HIGH_CONTENTION BIT18
+#define LOW_CONTENTION BIT19
+#define DPI_FIFO_UNDER_RUN BIT20
+#define HS_TX_TIMEOUT BIT21
+#define LP_RX_TIMEOUT BIT22
+#define TURN_AROUND_ACK_TIMEOUT BIT23
+#define ACK_WITH_NO_ERROR BIT24
+#define HS_GENERIC_WR_FIFO_FULL BIT27
+#define LP_GENERIC_WR_FIFO_FULL BIT28
+#define SPL_PKT_SENT			BIT30
+#define INTR_EN_REG                  0xb008
+#define DSI_FUNC_PRG_REG             0xb00c
+#define DPI_CHANNEL_NUMBER_POS   0x03
+#define DBI_CHANNEL_NUMBER_POS   0x05
+#define FMT_DPI_POS              0x07
+#define FMT_DBI_POS              0x0A
+#define DBI_DATA_WIDTH_POS       0x0D
+/* DPI PIXEL FORMATS */
+#define RGB_565_FMT		     0x01	/* RGB 565 FORMAT */
+#define RGB_666_FMT		     0x02	/* RGB 666 FORMAT */
+#define LRGB_666_FMT		     0x03	/* RGB LOOSELY PACKED
+						 * 666 FORMAT
+						 */
+#define RGB_888_FMT		     0x04	/* RGB 888 FORMAT */
+#define VIRTUAL_CHANNEL_NUMBER_0	0x00	/* Virtual channel 0 */
+#define VIRTUAL_CHANNEL_NUMBER_1	0x01	/* Virtual channel 1 */
+#define VIRTUAL_CHANNEL_NUMBER_2	0x02	/* Virtual channel 2 */
+#define VIRTUAL_CHANNEL_NUMBER_3	0x03	/* Virtual channel 3 */
+#define DBI_NOT_SUPPORTED		0x00	/* command mode
+						 * is not supported
+						 */
+#define DBI_DATA_WIDTH_16BIT		0x01	/* 16 bit data */
+#define DBI_DATA_WIDTH_9BIT			0x02	/* 9 bit data */
+#define DBI_DATA_WIDTH_8BIT			0x03	/* 8 bit data */
+#define DBI_DATA_WIDTH_OPT1		0x04	/* option 1 */
+#define DBI_DATA_WIDTH_OPT2		0x05	/* option 2 */
+#define HS_TX_TIMEOUT_REG            0xb010
+#define LP_RX_TIMEOUT_REG            0xb014
+#define TURN_AROUND_TIMEOUT_REG      0xb018
+#define DEVICE_RESET_REG             0xb01C
+#define DPI_RESOLUTION_REG           0xb020
+#define RES_V_POS                0x10
+#define DBI_RESOLUTION_REG           0xb024 /* Reserved for MDFLD */
+#define HORIZ_SYNC_PAD_COUNT_REG     0xb028
+#define HORIZ_BACK_PORCH_COUNT_REG   0xb02C
+#define HORIZ_FRONT_PORCH_COUNT_REG  0xb030
+#define HORIZ_ACTIVE_AREA_COUNT_REG  0xb034
+#define VERT_SYNC_PAD_COUNT_REG      0xb038
+#define VERT_BACK_PORCH_COUNT_REG    0xb03c
+#define VERT_FRONT_PORCH_COUNT_REG   0xb040
+#define HIGH_LOW_SWITCH_COUNT_REG    0xb044
+#define DPI_CONTROL_REG              0xb048
+#define DPI_SHUT_DOWN            BIT0
+#define DPI_TURN_ON              BIT1
+#define DPI_COLOR_MODE_ON        BIT2
+#define DPI_COLOR_MODE_OFF       BIT3
+#define DPI_BACK_LIGHT_ON        BIT4
+#define DPI_BACK_LIGHT_OFF       BIT5
+#define DPI_LP                   BIT6
+#define DPI_DATA_REG                 0xb04c
+#define DPI_BACK_LIGHT_ON_DATA   0x07
+#define DPI_BACK_LIGHT_OFF_DATA  0x17
+#define INIT_COUNT_REG               0xb050
+#define MAX_RET_PAK_REG              0xb054
+#define VIDEO_FMT_REG                0xb058
+#define COMPLETE_LAST_PCKT       BIT2
+#define EOT_DISABLE_REG              0xb05c
+#define ENABLE_CLOCK_STOPPING    BIT1
+#define LP_BYTECLK_REG               0xb060
+#define LP_GEN_DATA_REG              0xb064
+#define HS_GEN_DATA_REG              0xb068
+#define LP_GEN_CTRL_REG              0xb06C
+#define HS_GEN_CTRL_REG              0xb070
+#define DCS_CHANNEL_NUMBER_POS   0x06
+#define MCS_COMMANDS_POS	0x8
+#define WORD_COUNTS_POS		0x8
+#define MCS_PARAMETER_POS	0x10
+#define GEN_FIFO_STAT_REG            0xb074
+#define HS_DATA_FIFO_FULL        BIT0
+#define HS_DATA_FIFO_HALF_EMPTY  BIT1
+#define HS_DATA_FIFO_EMPTY       BIT2
+#define LP_DATA_FIFO_FULL        BIT8
+#define LP_DATA_FIFO_HALF_EMPTY  BIT9
+#define LP_DATA_FIFO_EMPTY       BIT10
+#define HS_CTRL_FIFO_FULL        BIT16
+#define HS_CTRL_FIFO_HALF_EMPTY  BIT17
+#define HS_CTRL_FIFO_EMPTY       BIT18
+#define LP_CTRL_FIFO_FULL        BIT24
+#define LP_CTRL_FIFO_HALF_EMPTY  BIT25
+#define LP_CTRL_FIFO_EMPTY       BIT26
+#define DBI_FIFO_EMPTY           BIT27
+#define DPI_FIFO_EMPTY           BIT28
+#define HS_LS_DBI_ENABLE_REG         0xb078
+#define TXCLKESC_REG		     0xb07c
+#define DPHY_PARAM_REG               0xb080
+#define DBI_BW_CTRL_REG              0xb084
+#define CLK_LANE_SWT_REG             0xb088
+/*===========================================================================
+; MIPI Adapter registers
+;--------------------------------------------------------------------------*/
+#define MIPI_CONTROL_REG             0xb104
+#define MIPI_2X_CLOCK_BITS       (BIT0 | BIT1)
+#define MIPI_DATA_ADDRESS_REG        0xb108
+#define MIPI_DATA_LENGTH_REG         0xb10C
+#define MIPI_COMMAND_ADDRESS_REG     0xb110
+#define MIPI_COMMAND_LENGTH_REG      0xb114
+#define MIPI_READ_DATA_RETURN_REG0   0xb118
+#define MIPI_READ_DATA_RETURN_REG1   0xb11C
+#define MIPI_READ_DATA_RETURN_REG2   0xb120
+#define MIPI_READ_DATA_RETURN_REG3   0xb124
+#define MIPI_READ_DATA_RETURN_REG4   0xb128
+#define MIPI_READ_DATA_RETURN_REG5   0xb12C
+#define MIPI_READ_DATA_RETURN_REG6   0xb130
+#define MIPI_READ_DATA_RETURN_REG7   0xb134
+#define MIPI_READ_DATA_VALID_REG     0xb138
+/* DBI COMMANDS */
+#define soft_reset                   0x01
+/* ************************************************************************* *\
+The display module performs a software reset.
+Registers are written with their SW Reset default values.
+\* ************************************************************************* */
+#define get_power_mode               0x0a
+/* ************************************************************************* *\
+The display module returns the current power mode
+\* ************************************************************************* */
+#define get_address_mode             0x0b
+/* ************************************************************************* *\
+The display module returns the current status.
+\* ************************************************************************* */
+#define get_pixel_format             0x0c
+/* ************************************************************************* *\
+This command gets the pixel format for the RGB image data
+used by the interface.
+\* ************************************************************************* */
+#define get_display_mode             0x0d
+/* ************************************************************************* *\
+The display module returns the Display Image Mode status.
+\* ************************************************************************* */
+#define get_signal_mode              0x0e
+/* ************************************************************************* *\
+The display module returns the Display Signal Mode.
+\* ************************************************************************* */
+#define get_diagnostic_result        0x0f
+/* ************************************************************************* *\
+The display module returns the self-diagnostic results following
+a Sleep Out command.
+\* ************************************************************************* */
+#define enter_sleep_mode             0x10
+/* ************************************************************************* *\
+This command causes the display module to enter the Sleep mode.
+In this mode, all unnecessary blocks inside the display module are disabled
+except interface communication. This is the lowest power mode
+the display module supports.
+\* ************************************************************************* */
+#define exit_sleep_mode              0x11
+/* ************************************************************************* *\
+This command causes the display module to exit Sleep mode.
+All blocks inside the display module are enabled.
+\* ************************************************************************* */
+#define enter_partial_mode           0x12
+/* ************************************************************************* *\
+This command causes the display module to enter the Partial Display Mode.
+The Partial Display Mode window is described by the set_partial_area command.
+\* ************************************************************************* */
+#define enter_normal_mode            0x13
+/* ************************************************************************* *\
+This command causes the display module to enter the Normal mode.
+Normal Mode is defined as Partial Display mode and Scroll mode are off
+\* ************************************************************************* */
+#define exit_invert_mode             0x20
+/* ************************************************************************* *\
+This command causes the display module to stop inverting the image data on
+the display device. The frame memory contents remain unchanged.
+No status bits are changed.
+\* ************************************************************************* */
+#define enter_invert_mode            0x21
+/* ************************************************************************* *\
+This command causes the display module to invert the image data only on
+the display device. The frame memory contents remain unchanged.
+No status bits are changed.
+\* ************************************************************************* */
+#define set_gamma_curve              0x26
+/* ************************************************************************* *\
+This command selects the desired gamma curve for the display device.
+Four fixed gamma curves are defined in section DCS spec.
+\* ************************************************************************* */
+#define set_display_off              0x28
+/* ************************************************************************* *\
+This command causes the display module to stop displaying the image data
+on the display device. The frame memory contents remain unchanged.
+No status bits are changed.
+\* ************************************************************************* */
+#define set_display_on               0x29
+/* ************************************************************************* *\
+This command causes the display module to start displaying the image data
+on the display device. The frame memory contents remain unchanged.
+No status bits are changed.
+\* ************************************************************************* */
+#define set_column_address           0x2a
+/* ************************************************************************* *\
+This command defines the column extent of the frame memory accessed by the
+hostprocessor with the read_memory_continue and write_memory_continue commands.
+No status bits are changed.
+\* ************************************************************************* */
+#define set_page_addr             0x2b
+/* ************************************************************************* *\
+This command defines the page extent of the frame memory accessed by the host
+processor with the write_memory_continue and read_memory_continue command.
+No status bits are changed.
+\* ************************************************************************* */
+#define write_mem_start              0x2c
+/* ************************************************************************* *\
+This command transfers image data from the host processor to the display
+module s frame memory starting at the pixel location specified by
+preceding set_column_address and set_page_address commands.
+\* ************************************************************************* */
+#define set_partial_area             0x30
+/* ************************************************************************* *\
+This command defines the Partial Display mode s display area.
+There are two parameters associated with
+this command, the first defines the Start Row (SR) and the second the End Row
+(ER). SR and ER refer to the Frame Memory Line Pointer.
+\* ************************************************************************* */
+#define set_scroll_area              0x33
+/* ************************************************************************* *\
+This command defines the display modules Vertical Scrolling Area.
+\* ************************************************************************* */
+#define set_tear_off                 0x34
+/* ************************************************************************* *\
+This command turns off the display modules Tearing Effect output signal on
+the TE signal line.
+\* ************************************************************************* */
+#define set_tear_on                  0x35
+/* ************************************************************************* *\
+This command turns on the display modules Tearing Effect output signal
+on the TE signal line.
+\* ************************************************************************* */
+#define set_address_mode             0x36
+/* ************************************************************************* *\
+This command sets the data order for transfers from the host processor to
+display modules frame memory,bits B[7:5] and B3, and from the display
+modules frame memory to the display device, bits B[2:0] and B4.
+\* ************************************************************************* */
+#define set_scroll_start             0x37
+/* ************************************************************************* *\
+This command sets the start of the vertical scrolling area in the frame memory.
+The vertical scrolling area is fully defined when this command is used with
+the set_scroll_area command The set_scroll_start command has one parameter,
+the Vertical Scroll Pointer. The VSP defines the line in the frame memory
+that is written to the display device as the first line of the vertical
+scroll area.
+\* ************************************************************************* */
+#define exit_idle_mode               0x38
+/* ************************************************************************* *\
+This command causes the display module to exit Idle mode.
+\* ************************************************************************* */
+#define enter_idle_mode              0x39
+/* ************************************************************************* *\
+This command causes the display module to enter Idle Mode.
+In Idle Mode, color expression is reduced. Colors are shown on the display
+device using the MSB of each of the R, G and B color components in the frame
+memory
+\* ************************************************************************* */
+#define set_pixel_format             0x3a
+/* ************************************************************************* *\
+This command sets the pixel format for the RGB image data used by the interface.
+Bits D[6:4]  DPI Pixel Format Definition
+Bits D[2:0]  DBI Pixel Format Definition
+Bits D7 and D3 are not used.
+\* ************************************************************************* */
+  #define DCS_PIXEL_FORMAT_3bbp	 	0x1
+  #define DCS_PIXEL_FORMAT_8bbp 	0x2
+  #define DCS_PIXEL_FORMAT_12bbp 	0x3
+  #define DCS_PIXEL_FORMAT_16bbp	0x5 
+  #define DCS_PIXEL_FORMAT_18bbp	0x6 
+  #define DCS_PIXEL_FORMAT_24bbp 	0x7
+#define write_mem_cont               0x3c
+/* ************************************************************************* *\
+This command transfers image data from the host processor to the display
+module's frame memory continuing from the pixel location following the
+previous write_memory_continue or write_memory_start command.
+\* ************************************************************************* */
+#define set_tear_scanline            0x44
+/* ************************************************************************* *\
+This command turns on the display modules Tearing Effect output signal on the
+TE signal line when the display module reaches line N.
+\* ************************************************************************* */
+#define get_scanline                 0x45
+/* ************************************************************************* *\
+The display module returns the current scanline, N, used to update the
+display device. The total number of scanlines on a display device is
+defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as
+the first line of V Sync and is denoted as Line 0.
+When in Sleep Mode, the value returned by get_scanline is undefined.
+\* ************************************************************************* */
+
+/* MCS or Generic COMMANDS */
+/* MCS/generic data type */
+#define GEN_SHORT_WRITE_0	0x03  /* generic short write, no parameters */
+#define GEN_SHORT_WRITE_1	0x13  /* generic short write, 1 parameters */
+#define GEN_SHORT_WRITE_2	0x23  /* generic short write, 2 parameters */
+#define GEN_READ_0		0x04  /* generic read, no parameters */
+#define GEN_READ_1		0x14  /* generic read, 1 parameters */
+#define GEN_READ_2		0x24  /* generic read, 2 parameters */
+#define GEN_LONG_WRITE		0x29  /* generic long write */
+#define MCS_SHORT_WRITE_0	0x05  /* MCS short write, no parameters */
+#define MCS_SHORT_WRITE_1	0x15  /* MCS short write, 1 parameters */
+#define MCS_READ		0x06  /* MCS read, no parameters */
+#define MCS_LONG_WRITE		0x39  /* MCS long write */
+/* MCS/generic commands */
+/*****TPO MCS**********/
+#define write_display_profile		0x50
+#define write_display_brightness	0x51
+#define write_ctrl_display		0x53
+#define write_ctrl_cabc			0x55
+  #define UI_IMAGE		0x01
+  #define STILL_IMAGE		0x02
+  #define MOVING_IMAGE		0x03
+#define write_hysteresis		0x57
+#define write_gamma_setting		0x58
+#define write_cabc_min_bright		0x5e
+#define write_kbbc_profile		0x60
+/*****TMD MCS**************/
+#define tmd_write_display_brightness 0x8c
+
+/* ************************************************************************* *\
+This command is used to control ambient light, panel backlight brightness and
+gamma settings.
+\* ************************************************************************* */
+#define BRIGHT_CNTL_BLOCK_ON	BIT5
+#define AMBIENT_LIGHT_SENSE_ON	BIT4
+#define DISPLAY_DIMMING_ON	BIT3
+#define BACKLIGHT_ON		BIT2
+#define DISPLAY_BRIGHTNESS_AUTO	BIT1
+#define GAMMA_AUTO		BIT0
+
+/* DCS Interface Pixel Formats */
+#define DCS_PIXEL_FORMAT_3BPP         0x1
+#define DCS_PIXEL_FORMAT_8BPP         0x2
+#define DCS_PIXEL_FORMAT_12BPP        0x3
+#define DCS_PIXEL_FORMAT_16BPP        0x5
+#define DCS_PIXEL_FORMAT_18BPP        0x6
+#define DCS_PIXEL_FORMAT_24BPP        0x7
+/* ONE PARAMETER READ DATA */
+#define addr_mode_data           0xfc
+#define diag_res_data            0x00
+#define disp_mode_data           0x23
+#define pxl_fmt_data             0x77
+#define pwr_mode_data            0x74
+#define sig_mode_data            0x00
+/* TWO PARAMETERS READ DATA */
+#define scanline_data1           0xff
+#define scanline_data2           0xff
+#define NON_BURST_MODE_SYNC_PULSE	0x01	/* Non Burst Mode
+						 * with Sync Pulse
+						 */
+#define NON_BURST_MODE_SYNC_EVENTS	0x02	/* Non Burst Mode
+						 * with Sync events
+						 */
+#define BURST_MODE			0x03	/* Burst Mode */
+#define DBI_COMMAND_BUFFER_SIZE		0x240  /* 0x32 */    /* 0x120 */	/* Allocate at least
+						 * 0x100 Byte with 32
+						 * byte alignment
+						 */
+#define DBI_DATA_BUFFER_SIZE		0x120	/* Allocate at least
+						 * 0x100 Byte with 32
+						 * byte alignment
+						 */
+#define DBI_CB_TIME_OUT 0xFFFF
+#define GEN_FB_TIME_OUT 2000 
+#define ALIGNMENT_32BYTE_MASK		(~(BIT0|BIT1|BIT2|BIT3|BIT4))
+#define SKU_83 						0x01
+#define SKU_100 					0x02
+#define SKU_100L 					0x04
+#define SKU_BYPASS 					0x08
+
+
+/* Some handy macros for playing with bitfields. */
+#define PSB_MASK(high, low) (((1<<((high)-(low)+1))-1)<<(low))
+#define SET_FIELD(value, field) (((value) << field ## _SHIFT) & field ## _MASK)
+#define GET_FIELD(word, field) (((word)  & field ## _MASK) >> field ## _SHIFT)
+
+#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
+
+/* PCI config space */
+
+#define SB_PCKT         0x02100 /* cedarview */
+# define SB_OPCODE_MASK                         PSB_MASK(31, 16)
+# define SB_OPCODE_SHIFT                        16
+# define SB_OPCODE_READ                         0
+# define SB_OPCODE_WRITE                        1
+# define SB_DEST_MASK                           PSB_MASK(15, 8)
+# define SB_DEST_SHIFT                          8
+# define SB_DEST_DPLL                           0x88
+# define SB_BYTE_ENABLE_MASK                    PSB_MASK(7, 4)
+# define SB_BYTE_ENABLE_SHIFT                   4
+# define SB_BUSY                                (1 << 0)
+
+#define DSPCLK_GATE_D		0x6200
+# define VRHUNIT_CLOCK_GATE_DISABLE		(1 << 28) /* Fixed value on CDV */
+# define DPOUNIT_CLOCK_GATE_DISABLE		(1 << 11)
+# define DPIOUNIT_CLOCK_GATE_DISABLE		(1 << 6)
+# define DPUNIT_PIPEB_GATE_DISABLE		(1 << 30)
+# define DPUNIT_PIPEA_GATE_DISABLE		(1 << 25)
+# define DPCUNIT_CLOCK_GATE_DISABLE		(1 << 24)
+# define DPLSUNIT_CLOCK_GATE_DISABLE		(1 << 13)
+
+
+#define RAMCLK_GATE_D		0x6210
+
+
+/* 32-bit value read/written from the DPIO reg. */
+#define SB_DATA		0x02104 /* cedarview */
+/* 32-bit address of the DPIO reg to be read/written. */
+#define SB_ADDR		0x02108 /* cedarview */
+#define DPIO_CFG	0x02110 /* cedarview */
+# define DPIO_MODE_SELECT_1			(1 << 3)
+# define DPIO_MODE_SELECT_0			(1 << 2)
+# define DPIO_SFR_BYPASS			(1 << 1)
+/* reset is active low */
+# define DPIO_CMN_RESET_N			(1 << 0)
+
+/* Cedarview sideband registers */
+#define _SB_M_A			0x8008
+#define _SB_M_B			0x8028
+#define SB_M(pipe) _PIPE(pipe, _SB_M_A, _SB_M_B)
+# define SB_M_DIVIDER_MASK			(0xFF << 24)
+# define SB_M_DIVIDER_SHIFT			24
+
+#define _SB_N_VCO_A		0x8014
+#define _SB_N_VCO_B		0x8034
+#define SB_N_VCO(pipe) _PIPE(pipe, _SB_N_VCO_A, _SB_N_VCO_B)
+# define SB_N_VCO_SEL_MASK			PSB_MASK(31, 30)
+# define SB_N_VCO_SEL_SHIFT			30
+# define SB_N_DIVIDER_MASK			PSB_MASK(29, 26)
+# define SB_N_DIVIDER_SHIFT			26
+# define SB_N_CB_TUNE_MASK			PSB_MASK(25, 24)
+# define SB_N_CB_TUNE_SHIFT			24
+
+/* the bit 14:13 is used to select between the different reference clock for Pipe A/B */
+#define SB_REF_DPLLA		0x8010
+#define SB_REF_DPLLB		0x8030
+#define	REF_CLK_MASK		(0x3 << 13)
+#define REF_CLK_CORE		(0 << 13)
+#define REF_CLK_DPLL		(1 << 13)
+#define REF_CLK_DPLLA		(2 << 13)
+/* For the DPLL B, it will use the reference clk from DPLL A when using (2 << 13) */
+
+#define _SB_REF_A		0x8018
+#define _SB_REF_B		0x8038
+#define SB_REF_SFR(pipe)	_PIPE(pipe, _SB_REF_A, _SB_REF_B)
+
+#define _SB_P_A			0x801c
+#define _SB_P_B			0x803c
+#define SB_P(pipe) _PIPE(pipe, _SB_P_A, _SB_P_B)
+# define SB_P2_DIVIDER_MASK			PSB_MASK(31, 30)
+# define SB_P2_DIVIDER_SHIFT			30
+# define SB_P2_10				0 /* HDMI, DP, DAC */
+# define SB_P2_5				1 /* DAC */
+# define SB_P2_14				2 /* LVDS single */
+# define SB_P2_7				3 /* LVDS double */
+# define SB_P1_DIVIDER_MASK			PSB_MASK(15, 12)
+# define SB_P1_DIVIDER_SHIFT			12
+
+#define PSB_LANE0		0x120
+#define PSB_LANE1		0x220
+#define PSB_LANE2		0x2320
+#define PSB_LANE3		0x2420
+
+#define LANE_PLL_MASK		(0x7 << 20)
+#define LANE_PLL_ENABLE		(0x1 << 20)
+#define LANE_PLL_PIPE(p)	((p == 0) ? (1 << 21) : (0 << 21))
+
+#define _SB_ALT_REF_A		0x813c
+#define _SB_ALT_REF_B		0x823c
+#define SB_ALT_REF(pipe)	_PIPE(pipe, _SB_ALT_REF_A, _SB_ALT_REF_B)
+
+#define _SB_MISC_DFX_A		0x812c
+#define _SB_MISC_DFX_B		0x822c
+#define SB_MISC_DFX(pipe)	_PIPE(pipe, _SB_MISC_DFX_A, _SB_MISC_DFX_B)
+
+#define INTEL_CDV_DISP_CLK_FREQ		0x20c8
+
+#if 0
+/* ************************************************************************* *\
+DSI command data structure
+\* ************************************************************************* */
+union DSI_LONG_PACKET_HEADER {
+	u32 DSI_longPacketHeader;
+	struct {
+		u8 dataID;
+		u16 wordCount;
+		u8 ECC;
+	};
+#if 0				/*FIXME JLIU7 */
+	struct {
+		u8 DT:6;
+		u8 VC:2;
+	};
+#endif				/*FIXME JLIU7 */
+};
+
+union MIPI_ADPT_CMD_LNG_REG {
+	u32 commnadLengthReg;
+	struct {
+		u8 command0;
+		u8 command1;
+		u8 command2;
+		u8 command3;
+	};
+};
+
+struct SET_COLUMN_ADDRESS_DATA {
+	u8 command;
+	u16 SC;			/* Start Column */
+	u16 EC;			/* End Column */
+};
+
+struct SET_PAGE_ADDRESS_DATA {
+	u8 command;
+	u16 SP;			/* Start Page */
+	u16 EP;			/* End Page */
+};
+#endif
+
+#define DP_B				0x64100
+#define DP_C				0x64200
+
+#define   DP_PORT_EN			(1 << 31)
+#define   DP_PIPEB_SELECT		(1 << 30)
+#define   DP_PIPE_MASK			(1 << 30)
+
+/* Link training mode - select a suitable mode for each stage */
+#define   DP_LINK_TRAIN_PAT_1		(0 << 28)
+#define   DP_LINK_TRAIN_PAT_2		(1 << 28)
+#define   DP_LINK_TRAIN_PAT_IDLE	(2 << 28)
+#define   DP_LINK_TRAIN_OFF		(3 << 28)
+#define   DP_LINK_TRAIN_MASK		(3 << 28)
+#define   DP_LINK_TRAIN_SHIFT		28
+
+/* Signal voltages. These are mostly controlled by the other end */
+#define   DP_VOLTAGE_0_4		(0 << 25)
+#define   DP_VOLTAGE_0_6		(1 << 25)
+#define   DP_VOLTAGE_0_8		(2 << 25)
+#define   DP_VOLTAGE_1_2		(3 << 25)
+#define   DP_VOLTAGE_MASK		(7 << 25)
+#define   DP_VOLTAGE_SHIFT		25
+
+/* Signal pre-emphasis levels, like voltages, the other end tells us what
+ * they want
+ */
+#define   DP_PRE_EMPHASIS_0		(0 << 22)
+#define   DP_PRE_EMPHASIS_3_5		(1 << 22)
+#define   DP_PRE_EMPHASIS_6		(2 << 22)
+#define   DP_PRE_EMPHASIS_9_5		(3 << 22)
+#define   DP_PRE_EMPHASIS_MASK		(7 << 22)
+#define   DP_PRE_EMPHASIS_SHIFT		22
+
+/* How many wires to use. I guess 3 was too hard */
+#define   DP_PORT_WIDTH_1		(0 << 19)
+#define   DP_PORT_WIDTH_2		(1 << 19)
+#define   DP_PORT_WIDTH_4		(3 << 19)
+#define   DP_PORT_WIDTH_MASK		(7 << 19)
+
+/* Mystic DPCD version 1.1 special mode */
+#define   DP_ENHANCED_FRAMING		(1 << 18)
+
+/** locked once port is enabled */
+#define   DP_PORT_REVERSAL		(1 << 15)
+
+/** sends the clock on lane 15 of the PEG for debug */
+#define   DP_CLOCK_OUTPUT_ENABLE	(1 << 13)
+
+#define   DP_SCRAMBLING_DISABLE		(1 << 12)
+#define   DP_SCRAMBLING_DISABLE_IRONLAKE	(1 << 7)
+
+/** limit RGB values to avoid confusing TVs */
+#define   DP_COLOR_RANGE_16_235		(1 << 8)
+
+/** Turn on the audio link */
+#define   DP_AUDIO_OUTPUT_ENABLE	(1 << 6)
+
+/** vs and hs sync polarity */
+#define   DP_SYNC_VS_HIGH		(1 << 4)
+#define   DP_SYNC_HS_HIGH		(1 << 3)
+
+/** A fantasy */
+#define   DP_DETECTED			(1 << 2)
+
+/** The aux channel provides a way to talk to the
+ * signal sink for DDC etc. Max packet size supported
+ * is 20 bytes in each direction, hence the 5 fixed
+ * data registers
+ */
+#define DPB_AUX_CH_CTL			0x64110
+#define DPB_AUX_CH_DATA1		0x64114
+#define DPB_AUX_CH_DATA2		0x64118
+#define DPB_AUX_CH_DATA3		0x6411c
+#define DPB_AUX_CH_DATA4		0x64120
+#define DPB_AUX_CH_DATA5		0x64124
+
+#define DPC_AUX_CH_CTL			0x64210
+#define DPC_AUX_CH_DATA1		0x64214
+#define DPC_AUX_CH_DATA2		0x64218
+#define DPC_AUX_CH_DATA3		0x6421c
+#define DPC_AUX_CH_DATA4		0x64220
+#define DPC_AUX_CH_DATA5		0x64224
+
+#define   DP_AUX_CH_CTL_SEND_BUSY	    (1 << 31)
+#define   DP_AUX_CH_CTL_DONE		    (1 << 30)
+#define   DP_AUX_CH_CTL_INTERRUPT	    (1 << 29)
+#define   DP_AUX_CH_CTL_TIME_OUT_ERROR	    (1 << 28)
+#define   DP_AUX_CH_CTL_TIME_OUT_400us	    (0 << 26)
+#define   DP_AUX_CH_CTL_TIME_OUT_600us	    (1 << 26)
+#define   DP_AUX_CH_CTL_TIME_OUT_800us	    (2 << 26)
+#define   DP_AUX_CH_CTL_TIME_OUT_1600us	    (3 << 26)
+#define   DP_AUX_CH_CTL_TIME_OUT_MASK	    (3 << 26)
+#define   DP_AUX_CH_CTL_RECEIVE_ERROR	    (1 << 25)
+#define   DP_AUX_CH_CTL_MESSAGE_SIZE_MASK    (0x1f << 20)
+#define   DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT   20
+#define   DP_AUX_CH_CTL_PRECHARGE_2US_MASK   (0xf << 16)
+#define   DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT  16
+#define   DP_AUX_CH_CTL_AUX_AKSV_SELECT	    (1 << 15)
+#define   DP_AUX_CH_CTL_MANCHESTER_TEST	    (1 << 14)
+#define   DP_AUX_CH_CTL_SYNC_TEST	    (1 << 13)
+#define   DP_AUX_CH_CTL_DEGLITCH_TEST	    (1 << 12)
+#define   DP_AUX_CH_CTL_PRECHARGE_TEST	    (1 << 11)
+#define   DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK    (0x7ff)
+#define   DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT   0
+
+
+/*
+ * Computing GMCH M and N values for the Display Port link
+ *
+ * GMCH M/N = dot clock * bytes per pixel / ls_clk * # of lanes
+ *
+ * ls_clk (we assume) is the DP link clock (1.62 or 2.7 GHz)
+ *
+ * The GMCH value is used internally
+ *
+ * bytes_per_pixel is the number of bytes coming out of the plane,
+ * which is after the LUTs, so we want the bytes for our color format.
+ * For our current usage, this is always 3, one byte for R, G and B.
+ */
+
+#define _PIPEA_GMCH_DATA_M			0x70050
+#define _PIPEB_GMCH_DATA_M			0x71050
+
+/* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */
+#define   PIPE_GMCH_DATA_M_TU_SIZE_MASK		(0x3f << 25)
+#define   PIPE_GMCH_DATA_M_TU_SIZE_SHIFT	25
+
+#define   PIPE_GMCH_DATA_M_MASK			(0xffffff)
+
+#define _PIPEA_GMCH_DATA_N			0x70054
+#define _PIPEB_GMCH_DATA_N			0x71054
+#define   PIPE_GMCH_DATA_N_MASK			(0xffffff)
+
+/*
+ * Computing Link M and N values for the Display Port link
+ *
+ * Link M / N = pixel_clock / ls_clk
+ *
+ * (the DP spec calls pixel_clock the 'strm_clk')
+ *
+ * The Link value is transmitted in the Main Stream
+ * Attributes and VB-ID.
+ */
+
+#define _PIPEA_DP_LINK_M				0x70060
+#define _PIPEB_DP_LINK_M				0x71060
+#define   PIPEA_DP_LINK_M_MASK			(0xffffff)
+
+#define _PIPEA_DP_LINK_N				0x70064
+#define _PIPEB_DP_LINK_N				0x71064
+#define   PIPEA_DP_LINK_N_MASK			(0xffffff)
+
+#define PIPE_GMCH_DATA_M(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_M, _PIPEB_GMCH_DATA_M)
+#define PIPE_GMCH_DATA_N(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_N, _PIPEB_GMCH_DATA_N)
+#define PIPE_DP_LINK_M(pipe) _PIPE(pipe, _PIPEA_DP_LINK_M, _PIPEB_DP_LINK_M)
+#define PIPE_DP_LINK_N(pipe) _PIPE(pipe, _PIPEA_DP_LINK_N, _PIPEB_DP_LINK_N)
+
+#define   PIPE_BPC_MASK				(7 << 5)
+#define   PIPE_8BPC				(0 << 5)
+#define   PIPE_10BPC				(1 << 5)
+#define   PIPE_6BPC				(2 << 5)
+
+#endif
diff --git a/drivers/staging/cdv/drv/psb_irq.c b/drivers/staging/cdv/drv/psb_irq.c
new file mode 100644
index 0000000..0230f9f
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_irq.c
@@ -0,0 +1,689 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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 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.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ **************************************************************************/
+/*
+ */
+
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_reg.h"
+#include "psb_msvdx.h"
+#include "psb_intel_reg.h"
+#include "psb_powermgmt.h"
+
+
+/*
+ * inline functions
+ */
+static inline u32
+psb_pipestat(int pipe)
+{
+	if (pipe == 0)
+		return PIPEASTAT;
+	if (pipe == 1)
+		return PIPEBSTAT;
+	BUG();
+}
+
+static inline u32
+psb_pipe_event(int pipe)
+{
+	if (pipe == 0)
+		return PSB_IRQ_PIPEA_EVENT;
+	if (pipe == 1)
+		return PSB_IRQ_PIPEB_EVENT;
+	BUG();
+}
+
+static inline u32
+psb_pipeconf(int pipe)
+{
+	if (pipe == 0)
+		return PIPEACONF;
+	if (pipe == 1)
+		return PIPEBCONF;
+	BUG();
+}
+
+void
+psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
+{
+	if ((dev_priv->pipestat[pipe] & mask) != mask) {
+		u32 reg = psb_pipestat(pipe);
+		u32 writeVal = PSB_RVDC32(reg);
+
+		dev_priv->pipestat[pipe] |= mask;
+		/* Enable the interrupt, clear any pending status */
+		writeVal |= (mask | (mask >> 16));
+		PSB_WVDC32(writeVal, reg);
+		(void) PSB_RVDC32(reg);
+	}
+}
+
+void
+psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
+{
+	if ((dev_priv->pipestat[pipe] & mask) != 0) {
+		u32 reg = psb_pipestat(pipe);
+		u32 writeVal = PSB_RVDC32(reg);
+
+		dev_priv->pipestat[pipe] &= ~mask;
+		writeVal &= ~mask;
+		PSB_WVDC32(writeVal, reg);
+		(void) PSB_RVDC32(reg);
+	}
+}
+
+void
+mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
+{
+	u32 pipe_event = psb_pipe_event(pipe);
+	dev_priv->vdc_irq_mask |= pipe_event;
+	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
+	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+}
+
+void
+mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
+{
+	if (dev_priv->pipestat[pipe] == 0) {
+		u32 pipe_event = psb_pipe_event(pipe);
+		dev_priv->vdc_irq_mask &= ~pipe_event;
+		PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
+		PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+	}
+}
+
+/**
+ * Display controller interrupt handler for vsync/vblank.
+ *
+ */
+static void mid_vblank_handler(struct drm_device *dev, uint32_t pipe)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	/**
+	 * Using TE interrupt for B0 + command mode panels
+	 */
+
+	drm_handle_vblank(dev, pipe);
+	
+	if( dev_priv->psb_vsync_handler != NULL)
+		(*dev_priv->psb_vsync_handler)(dev,pipe);
+}
+
+/**
+ * Display controller interrupt handler for pipe event.
+ *
+ */
+#define WAIT_STATUS_CLEAR_LOOP_COUNT 0xffff
+static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+
+	uint32_t pipe_stat_val = 0;
+	uint32_t pipe_stat_reg = psb_pipestat(pipe);
+	uint32_t pipe_enable = dev_priv->pipestat[pipe];
+	uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16;
+	uint32_t i = 0, temp;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irq_flags);
+
+	pipe_stat_val = PSB_RVDC32(pipe_stat_reg);
+	pipe_stat_val &= pipe_enable | pipe_status;
+	pipe_stat_val &= pipe_stat_val >> 16;
+
+
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irq_flags);
+	temp = PSB_RVDC32(pipe_stat_reg);
+        temp &=~(0xFFFF);
+        if (temp & PIPE_FIFO_UNDERRUN) {
+		DRM_DEBUG_KMS("Fifo underrun on pipe %d\n", pipe);
+                PSB_WVDC32(temp | PIPE_FIFO_UNDERRUN, pipe_stat_reg);
+		PSB_RVDC32(pipe_stat_reg);
+	}
+	/* clear the 2nd level interrupt status bits */
+	/**
+	* FIXME: shouldn't use while loop here. However, the interrupt
+	* status 'sticky' bits cannot be cleared by setting '1' to that
+	* bit once...
+	*/
+	for (i = 0; i < WAIT_STATUS_CLEAR_LOOP_COUNT; i ++) {
+		PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg);
+		(void) PSB_RVDC32(pipe_stat_reg);
+
+		if ((PSB_RVDC32(pipe_stat_reg) & pipe_status) == 0)
+			break;
+	}
+
+	if (i == WAIT_STATUS_CLEAR_LOOP_COUNT)
+		DRM_ERROR("%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x. \n",
+			__FUNCTION__, PSB_RVDC32(pipe_stat_reg));
+
+	if ((pipe_stat_val & PIPE_DPST_EVENT_STATUS) &&
+	   (dev_priv->psb_dpst_state != NULL)) {
+		uint32_t pwm_reg = 0;
+		uint32_t hist_reg = 0;
+		u32 irqCtrl = 0;
+		struct dpst_guardband guardband_reg;
+		struct dpst_ie_histogram_control ie_hist_cont_reg;
+
+		hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+
+		/* Determine if this is histogram or pwm interrupt */
+		if(hist_reg & HISTOGRAM_INT_CTRL_CLEAR) {
+			/* Notify UM of histogram interrupt */
+			psb_dpst_notify_change_um(DPST_EVENT_HIST_INTERRUPT,
+			dev_priv->psb_dpst_state);
+
+			/* disable dpst interrupts */
+			guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+			guardband_reg.interrupt_enable = 0;
+			guardband_reg.interrupt_status = 1;
+			PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
+
+			ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
+			ie_hist_cont_reg.ie_histogram_enable = 0;
+			PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
+
+			irqCtrl = PSB_RVDC32(PIPEASTAT);
+			irqCtrl &= ~PIPE_DPST_EVENT_ENABLE;
+			PSB_WVDC32(irqCtrl, PIPEASTAT);
+		}
+		pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
+		if((pwm_reg & PWM_PHASEIN_INT_ENABLE) &&
+		   !(pwm_reg & PWM_PHASEIN_ENABLE)) {
+			/* Notify UM of the phase complete */
+			psb_dpst_notify_change_um(DPST_EVENT_PHASE_COMPLETE,
+			dev_priv->psb_dpst_state);
+
+			/* Temporarily get phase mngr ready to generate
+			 * another interrupt until this can be moved to
+			 * user mode */
+			/* PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE,
+				   PWM_CONTROL_LOGIC); */
+		}
+	}
+
+	if (pipe_stat_val & PIPE_VBLANK_STATUS) {
+		mid_vblank_handler(dev, pipe);
+	}
+}
+
+/**
+ * Display controller interrupt handler.
+ */
+static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
+{
+	if (vdc_stat & PSB_IRQ_ASLE)
+		psb_intel_opregion_asle_intr(dev);
+
+	if (vdc_stat & PSB_IRQ_PIPEA_EVENT)
+		mid_pipe_event_handler(dev, 0);
+
+	if (vdc_stat & PSB_IRQ_PIPEB_EVENT)
+		mid_pipe_event_handler(dev, 1);
+}
+
+static void psb_hotplug_work_func(struct work_struct *work)
+{
+        struct drm_psb_private *dev_priv = container_of(work, struct drm_psb_private,
+							hotplug_work);                 
+        struct drm_device *dev = dev_priv->dev;
+
+        /* Just fire off a uevent and let userspace tell us what to do */
+        drm_helper_hpd_irq_event(dev);
+}                       
+
+irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
+{
+	struct drm_device *dev = (struct drm_device *) arg;
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private;
+	uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, msvdx_int = 0, hotplug_int = 0;
+	int handled = 0;
+	unsigned long irq_flags;
+
+/*	PSB_DEBUG_ENTRY("\n"); */
+
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irq_flags);
+
+	vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
+
+	if (vdc_stat & _PSB_DISP_ALL_IRQ_FLAG) {
+		PSB_DEBUG_IRQ("Got DISP interrupt\n");
+		dsp_int = 1;
+	}
+
+	if (vdc_stat & _PSB_IRQ_SGX_FLAG) {
+		PSB_DEBUG_IRQ("Got SGX interrupt\n");
+		sgx_int = 1;
+	}
+
+	if (vdc_stat & _PSB_IRQ_MSVDX_FLAG) {
+		PSB_DEBUG_IRQ("Got MSVDX interrupt\n");
+		msvdx_int = 1;
+	}
+
+	if (vdc_stat & PSB_IRQ_DISP_HOTSYNC) {
+		PSB_DEBUG_IRQ("Got hotplug interrupt\n");
+		hotplug_int = 1;
+	}
+
+	vdc_stat &= dev_priv->vdc_irq_mask;
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irq_flags);
+
+	if (dsp_int) {
+		psb_vdc_interrupt(dev, vdc_stat);
+		handled = 1;
+	}
+
+	if (msvdx_int && ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
+		psb_msvdx_interrupt(dev);
+		handled = 1;
+	}
+
+	if (sgx_int) {
+		if (SYSPVRServiceSGXInterrupt(dev) != 0)
+			handled = 1;
+	}
+
+	if (hotplug_int) {
+		/* use system wq for now*/
+		schedule_work(&dev_priv->hotplug_work);
+		REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
+		handled = 1;
+	}
+
+	PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
+	(void) PSB_RVDC32(PSB_INT_IDENTITY_R);
+	DRM_READMEMORYBARRIER();
+
+	if (!handled)
+		return IRQ_NONE;
+
+	return IRQ_HANDLED;
+}
+
+void psb_irq_preinstall(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private;
+	psb_irq_preinstall_islands(dev, OSPM_ALL_ISLANDS);
+
+	INIT_WORK(&dev_priv->hotplug_work, psb_hotplug_work_func);
+	
+	REG_WRITE(PORT_HOTPLUG_EN, 0);
+	REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
+}
+
+/**
+ * FIXME: should I remove display irq enable here??
+ */
+void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	unsigned long irqflags;
+
+	/* PSB_DEBUG_ENTRY("\n"); */
+
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
+
+	if (dev->vblank_enabled[0])
+		dev_priv->vdc_irq_mask |= PSB_IRQ_PIPEA_EVENT;
+	if (dev->vblank_enabled[1])
+		dev_priv->vdc_irq_mask |= PSB_IRQ_PIPEB_EVENT;
+
+	if (hw_islands & OSPM_GRAPHICS_ISLAND) {
+		dev_priv->vdc_irq_mask |= _PSB_IRQ_SGX_FLAG;
+	}
+
+	if (hw_islands & OSPM_VIDEO_DEC_ISLAND)
+		if (ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))
+			dev_priv->vdc_irq_mask |= _PSB_IRQ_MSVDX_FLAG;
+
+	/* display hotplug */
+	dev_priv->vdc_irq_mask |= PSB_IRQ_DISP_HOTSYNC;
+
+	/* asle interrupt */
+	dev_priv->vdc_irq_mask |= PSB_IRQ_ASLE;
+
+	/*This register is safe even if display island is off*/
+	/* unmask all */
+	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
+
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+}
+
+int psb_irq_postinstall(struct drm_device *dev)
+{
+	return psb_irq_postinstall_islands(dev, OSPM_ALL_ISLANDS);
+}
+
+int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands)
+{
+
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	unsigned long irqflags;
+	u32 temp;
+
+	/* PSB_DEBUG_ENTRY("\n"); */
+
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
+
+	/*This register is safe even if display island is off*/
+	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+
+	if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) {	
+		if (dev->vblank_enabled[0])
+			psb_enable_pipestat(dev_priv, 0,
+					    PIPE_VBLANK_INTERRUPT_ENABLE);
+		else
+			psb_disable_pipestat(dev_priv, 0,
+					     PIPE_VBLANK_INTERRUPT_ENABLE);
+
+		if (dev->vblank_enabled[1])
+			psb_enable_pipestat(dev_priv, 1,
+					    PIPE_VBLANK_INTERRUPT_ENABLE);
+		else
+			psb_disable_pipestat(dev_priv, 1,
+					     PIPE_VBLANK_INTERRUPT_ENABLE);
+	}
+
+	/* Just enable all display ports for now.
+	 * This can be optimized to only enable ports that really exists.
+	 */
+	temp = REG_READ(PORT_HOTPLUG_EN);
+	temp |= HDMIB_HOTPLUG_INT_EN; 
+	temp |= HDMIC_HOTPLUG_INT_EN; 
+	temp |= HDMID_HOTPLUG_INT_EN; 
+	temp |= CRT_HOTPLUG_INT_EN; 
+	REG_WRITE(PORT_HOTPLUG_EN, temp);
+
+	if (hw_islands & OSPM_VIDEO_DEC_ISLAND)
+		if (true/*powermgmt_is_hw_on(dev->pdev, PSB_VIDEO_DEC_ISLAND)*/)
+			psb_msvdx_enableirq(dev);
+
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+
+	return 0;
+}
+
+void psb_irq_uninstall(struct drm_device *dev)
+{
+	psb_irq_uninstall_islands(dev, OSPM_ALL_ISLANDS);
+}
+
+void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	unsigned long irqflags;
+
+	/* PSB_DEBUG_ENTRY("\n"); */
+
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
+	
+	if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) {
+		if (dev->vblank_enabled[0])
+			psb_disable_pipestat(dev_priv, 0,
+					     PIPE_VBLANK_INTERRUPT_ENABLE);
+
+		if (dev->vblank_enabled[1])
+			psb_disable_pipestat(dev_priv, 1,
+					     PIPE_VBLANK_INTERRUPT_ENABLE);
+
+	}
+
+	psb_disable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE);
+
+	REG_WRITE(PORT_HOTPLUG_EN, 0);
+	REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
+
+	dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
+				  _PSB_IRQ_MSVDX_FLAG;
+
+	/*TODO: remove follwoing code*/
+	if (hw_islands & OSPM_GRAPHICS_ISLAND) {
+		dev_priv->vdc_irq_mask &= ~_PSB_IRQ_SGX_FLAG;
+	}
+
+	if ((hw_islands & OSPM_VIDEO_DEC_ISLAND))
+		dev_priv->vdc_irq_mask &= ~_PSB_IRQ_MSVDX_FLAG;
+
+	/*These two registers are safe even if display island is off*/
+	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
+	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+
+	wmb();
+
+	/*This register is safe even if display island is off*/
+	PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
+
+	if (hw_islands & OSPM_VIDEO_DEC_ISLAND)
+		if (ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))
+			psb_msvdx_disableirq(dev);
+
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+}
+
+void psb_irq_turn_on_dpst(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;
+	u32 hist_reg;
+	u32 pwm_reg;
+
+	PSB_WVDC32(BIT31, HISTOGRAM_LOGIC_CONTROL);
+	hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
+	PSB_WVDC32(BIT31, HISTOGRAM_INT_CONTROL);
+	hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+
+	PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC);
+	pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
+	PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE | PWM_PHASEIN_INT_ENABLE,
+		   PWM_CONTROL_LOGIC);
+	pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
+
+	/* pipe B */
+	psb_enable_pipestat(dev_priv, 1, PIPE_DPST_EVENT_ENABLE);
+
+	hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+	PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR,HISTOGRAM_INT_CONTROL);
+	pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
+	PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE, PWM_CONTROL_LOGIC);
+		
+}
+
+int psb_irq_enable_dpst(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;
+	unsigned long irqflags;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
+
+	/* enable DPST */
+	/* DPST always on LVDS pipe B */
+	mid_enable_pipe_event(dev_priv, 1);
+	psb_irq_turn_on_dpst(dev);
+
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+	return 0;
+}
+
+void psb_irq_turn_off_dpst(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	u32 pwm_reg;
+
+	PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
+
+	/* on pipe B */
+	psb_disable_pipestat(dev_priv, 1, PIPE_DPST_EVENT_ENABLE);
+
+	pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
+	PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), PWM_CONTROL_LOGIC);
+	pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
+}
+
+int psb_irq_disable_dpst(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	unsigned long irqflags;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
+
+	/* on pipe B */
+	mid_disable_pipe_event(dev_priv, 1);
+	psb_irq_turn_off_dpst(dev);
+
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+
+	return 0;
+}
+
+/*
+ * It is used to enable VBLANK interrupt
+ */
+int psb_enable_vblank(struct drm_device *dev, int pipe)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	unsigned long irqflags;
+	uint32_t reg_val = 0;
+	uint32_t pipeconf_reg = psb_pipeconf(pipe);
+
+	PSB_DEBUG_ENTRY("\n");
+
+
+	reg_val = REG_READ(pipeconf_reg);
+
+	if (!(reg_val & PIPEACONF_ENABLE))
+		return -EINVAL;
+
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
+
+	mid_enable_pipe_event(dev_priv, pipe);
+	psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
+
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+
+	return 0;
+}
+
+/*
+ * It is used to disable VBLANK interrupt
+ */
+void psb_disable_vblank(struct drm_device *dev, int pipe)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	unsigned long irqflags;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
+
+	mid_disable_pipe_event(dev_priv, pipe);
+	psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
+
+	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+}
+
+/* Called from drm generic code, passed a 'crtc', which
+ * we use as a pipe index
+ */
+u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)
+{
+	uint32_t high_frame = PIPEAFRAMEHIGH;
+	uint32_t low_frame = PIPEAFRAMEPIXEL;
+	uint32_t pipeconf_reg = PIPEACONF;
+	uint32_t reg_val = 0;
+	uint32_t high1 = 0, high2 = 0, low = 0, count = 0;
+
+	switch (pipe) {
+	case 0:
+		break;
+	case 1:
+		high_frame = PIPEBFRAMEHIGH;
+		low_frame = PIPEBFRAMEPIXEL;
+		pipeconf_reg = PIPEBCONF;
+		break;
+	case 2:
+		high_frame = PIPECFRAMEHIGH;
+		low_frame = PIPECFRAMEPIXEL;
+		pipeconf_reg = PIPECCONF;
+		break;
+	default:
+		DRM_ERROR("%s, invalded pipe. \n", __FUNCTION__);
+		return 0;
+	}
+
+	reg_val = REG_READ(pipeconf_reg);
+
+	if (!(reg_val & PIPEACONF_ENABLE)) {
+		DRM_DEBUG_DRIVER("trying to get vblank count for disabled pipe %d\n", pipe);
+		goto psb_get_vblank_counter_exit;
+	}
+
+	/*
+	 * High & low register fields aren't synchronized, so make sure
+	 * we get a low value that's stable across two reads of the high
+	 * register.
+	 */
+	do {
+		high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+			 PIPE_FRAME_HIGH_SHIFT);
+		low =  ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
+			PIPE_FRAME_LOW_SHIFT);
+		high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+			 PIPE_FRAME_HIGH_SHIFT);
+	} while (high1 != high2);
+
+	count = (high1 << 8) | low;
+
+psb_get_vblank_counter_exit:
+
+	return count;
+}
+
+/* 
+ * psb_intel_enable_asle - enable ASLE interrupt for OpRegion
+ */
+void psb_intel_enable_asle(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private;
+
+	DRM_DEBUG_DRIVER("enable ASLE\n");
+
+	/* Only enable for pipe B which LVDS always binds to */
+	psb_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE);
+}
+
diff --git a/drivers/staging/cdv/drv/psb_irq.h b/drivers/staging/cdv/drv/psb_irq.h
new file mode 100644
index 0000000..c1ce91f
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_irq.h
@@ -0,0 +1,49 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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 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.
+ *
+ * Authors:
+ *    Benjamin Defnet <benjamin.r.defnet@intel.com>
+ *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
+ *
+ **************************************************************************/
+
+#ifndef _SYSIRQ_H_
+#define _SYSIRQ_H_
+
+#include <drm/drmP.h>
+
+bool sysirq_init(struct drm_device *dev);
+void sysirq_uninit(struct drm_device *dev);
+
+void psb_irq_preinstall(struct drm_device *dev);
+int  psb_irq_postinstall(struct drm_device *dev);
+void psb_irq_uninstall(struct drm_device *dev);
+irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
+
+void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands);
+int  psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands);
+void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
+
+int psb_irq_enable_dpst(struct drm_device *dev);
+int psb_irq_disable_dpst(struct drm_device *dev);
+void psb_irq_turn_on_dpst(struct drm_device *dev);
+void psb_irq_turn_off_dpst(struct drm_device *dev);
+int  psb_enable_vblank(struct drm_device *dev, int pipe);
+void psb_disable_vblank(struct drm_device *dev, int pipe);
+u32  psb_get_vblank_counter(struct drm_device *dev, int pipe);
+
+#endif //_SYSIRQ_H_
diff --git a/drivers/staging/cdv/drv/psb_powermgmt.c b/drivers/staging/cdv/drv/psb_powermgmt.c
new file mode 100644
index 0000000..33ead94
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_powermgmt.c
@@ -0,0 +1,884 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * All Rights Reserved.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Benjamin Defnet <benjamin.r.defnet@intel.com>
+ *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
+ *
+ */
+#include "psb_powermgmt.h"
+#include "psb_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_msvdx.h"
+#include <linux/mutex.h>
+#include <asm/intel_scu_ipc.h>
+#include <linux/pm_runtime.h>
+
+extern IMG_UINT32 gui32SGXDeviceID;
+extern IMG_UINT32 gui32MRSTDisplayDeviceID;
+extern IMG_UINT32 gui32MRSTMSVDXDeviceID;
+extern IMG_UINT32 gui32MRSTTOPAZDeviceID;
+
+struct drm_device *gpDrmDevice = NULL;
+static struct mutex g_ospm_mutex;
+static bool gbSuspendInProgress = false;
+static bool gbResumeInProgress = false;
+static int g_hw_power_status_mask;
+static atomic_t g_graphics_access_count;
+static atomic_t g_videodec_access_count;
+int allow_runtime_pm = 0;
+
+void ospm_power_island_up(int hw_islands);
+void ospm_power_island_down(int hw_islands);
+static bool gbSuspended = false;
+bool gbgfxsuspended = false;
+extern int enter_dsr;
+
+#if 1
+static int ospm_runtime_check_msvdx_hw_busy(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	int ret = 1;
+	
+	if (!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
+		/*printk(KERN_ALERT "%s VIDEO DEC HW is not on\n", __func__); */
+		ret = -1;
+		goto out;
+	}
+	
+	msvdx_priv->msvdx_hw_busy = REG_READ(0x20D0) & (0x1 << 9);
+	if (psb_check_msvdx_idle(dev)){
+		/*printk(KERN_ALERT "%s video decode hw busy\n", __func__); */
+		ret = 1;
+	}
+	else {
+		/*printk(KERN_ALERT "%s video decode hw idle\n", __func__); */
+		ret = 0;
+	}
+out:
+	return ret;
+}
+
+static int ospm_runtime_pm_msvdx_suspend(struct drm_device *dev)
+{
+	int ret = 0;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	/*printk(KERN_ALERT "enter %s\n", __func__);*/
+
+	if (!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
+		/*printk(KERN_ALERT "%s VIDEO DEC HW is not on\n", __func__);*/
+		goto out;
+	}
+
+	if (atomic_read(&g_videodec_access_count)) {
+		/*printk(KERN_ALERT "%s videodec access count exit\n", __func__);*/
+		ret = -1;
+		goto out;
+	}
+
+	msvdx_priv->msvdx_hw_busy = REG_READ(0x20D0) & (0x1 << 9);
+	if (psb_check_msvdx_idle(dev)){
+		/*printk(KERN_ALERT "%s video decode hw busy exit\n", __func__);*/
+		ret = -2;
+		goto out;
+	}
+	
+	MSVDX_NEW_PMSTATE(dev, msvdx_priv, PSB_PMSTATE_POWERDOWN);
+	psb_irq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
+	psb_msvdx_save_context(dev);
+	ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
+	/*printk(KERN_ALERT "%s done\n", __func__);*/
+out:
+	return ret;
+}
+
+static int ospm_runtime_pm_msvdx_resume(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	
+	/*printk(KERN_ALERT "ospm_runtime_pm_msvdx_resume\n");*/
+	
+	MSVDX_NEW_PMSTATE(dev, msvdx_priv, PSB_PMSTATE_POWERUP);
+	
+	psb_msvdx_restore_context(dev);
+
+	return 0;
+}
+
+#endif
+
+#ifdef FIX_OSPM_POWER_DOWN
+void ospm_apm_power_down_msvdx(struct drm_device *dev)
+{
+	return;
+	mutex_lock(&g_ospm_mutex);
+
+	if (atomic_read(&g_videodec_access_count))
+		goto out;
+	if (psb_check_msvdx_idle(dev))
+		goto out;
+
+	gbSuspendInProgress = true;
+	psb_msvdx_save_context(dev);
+#ifdef FIXME_MRST_VIDEO_DEC
+	ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
+#endif
+	gbSuspendInProgress = false;
+out:
+	mutex_unlock(&g_ospm_mutex);
+	return;
+}
+
+#else
+void ospm_apm_power_down_msvdx(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	mutex_lock(&g_ospm_mutex);
+	if (!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))
+		goto out;
+	
+	if (atomic_read(&g_videodec_access_count))
+		goto out;
+	if (psb_check_msvdx_idle(dev))
+		goto out;
+
+	gbSuspendInProgress = true;
+	psb_msvdx_save_context(dev);
+	ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
+	gbSuspendInProgress = false;
+	MSVDX_NEW_PMSTATE(dev, msvdx_priv, PSB_PMSTATE_POWERDOWN);
+out:
+	mutex_unlock(&g_ospm_mutex);
+	return;
+}
+
+#endif
+/*
+ * ospm_power_init
+ *
+ * Description: Initialize this ospm power management module
+ */
+void ospm_power_init(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private;
+
+	gpDrmDevice = dev;
+
+	if (IS_CDV(dev))
+	{
+		dev_priv->apm_reg = CDV_MSG_READ32(PSB_PUNIT_PORT, PSB_APMBA);
+		dev_priv->ospm_base = CDV_MSG_READ32(PSB_PUNIT_PORT, PSB_OSPMBA);
+	}
+
+	DRM_DEBUG_KMS("CDV: power apm io base 0x%x, ospm io base 0x%x\n", dev_priv->apm_reg,
+		  dev_priv->ospm_base);
+
+	dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
+	dev_priv->ospm_base &= 0xffff;
+
+	mutex_init(&g_ospm_mutex);
+	g_hw_power_status_mask = OSPM_GRAPHICS_ISLAND | OSPM_VIDEO_DEC_ISLAND;
+	atomic_set(&g_graphics_access_count, 0);
+	atomic_set(&g_videodec_access_count, 0);
+
+#ifdef OSPM_STAT
+	dev_priv->graphics_state = PSB_PWR_STATE_ON;
+	dev_priv->gfx_last_mode_change = jiffies;
+	dev_priv->gfx_on_time = 0;
+	dev_priv->gfx_off_time = 0;
+#endif
+}
+
+/*
+ * ospm_power_uninit
+ *
+ * Description: Uninitialize this ospm power management module
+ */
+void ospm_power_uninit(void)
+{
+	mutex_destroy(&g_ospm_mutex);
+    	pm_runtime_disable(&gpDrmDevice->pdev->dev);
+	pm_runtime_set_suspended(&gpDrmDevice->pdev->dev);
+}
+
+/*
+ * helper function to turn on/off outputs.
+ */
+static void ospm_output_dpms(struct drm_device *dev, bool on)
+{
+	int state = on ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF;
+	struct drm_connector *connector;
+	
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+		connector->funcs->dpms(connector, state);
+}
+
+/*
+ * powermgmt_suspend_display
+ *
+ * Description: Suspend the display hardware saving state and disabling
+ * as necessary.
+ */
+void ospm_suspend_display(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	DRM_DEBUG_KMS("\n");
+
+	pci_read_config_byte(dev->pdev, 0xF4, &dev_priv->saveLBB);
+
+	mutex_lock(&dev->struct_mutex);
+
+	dev_priv->saveDSPCLK_GATE_D = REG_READ(DSPCLK_GATE_D);
+	dev_priv->saveRAMCLK_GATE_D = REG_READ(RAMCLK_GATE_D);
+
+	dev_priv->saveDSPARB = REG_READ(DSPARB);
+	dev_priv->saveDSPFW[0] = REG_READ(DSPFW1);
+	dev_priv->saveDSPFW[1] = REG_READ(DSPFW2);
+	dev_priv->saveDSPFW[2] = REG_READ(DSPFW3);
+	dev_priv->saveDSPFW[3] = REG_READ(DSPFW4);
+	dev_priv->saveDSPFW[4] = REG_READ(DSPFW5);
+	dev_priv->saveDSPFW[5] = REG_READ(DSPFW6);
+
+	dev_priv->saveADPA = REG_READ(ADPA);
+
+	dev_priv->savePP_CONTROL = REG_READ(PP_CONTROL);
+	dev_priv->savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS);
+	dev_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
+	dev_priv->saveBLC_PWM_CTL2 = REG_READ(BLC_PWM_CTL2);
+	dev_priv->saveLVDS = REG_READ(LVDS);
+
+	dev_priv->savePFIT_CONTROL = REG_READ(PFIT_CONTROL);
+
+	dev_priv->savePP_ON_DELAYS = REG_READ(PP_ON_DELAYS);
+	dev_priv->savePP_OFF_DELAYS = REG_READ(PP_OFF_DELAYS);
+	dev_priv->savePP_DIVISOR = REG_READ(PP_DIVISOR);
+
+	dev_priv->saveVGACNTRL = REG_READ(VGACNTRL);
+
+	dev_priv->saveIER = REG_READ(PSB_INT_ENABLE_R);
+	dev_priv->saveIMR = REG_READ(PSB_INT_MASK_R);
+
+	ospm_output_dpms(dev, false);
+ 
+	mutex_unlock(&dev->struct_mutex);
+}
+
+/*
+ * ospm_resume_display
+ *
+ * Description: Resume the display hardware restoring state and enabling
+ * as necessary.
+ */
+void ospm_resume_display(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	u32 temp;
+
+	DRM_DEBUG_KMS("\n");
+
+	/* just restore page table ptr */
+	PSB_WVDC32(dev_priv->pg->pge_ctl | _PSB_PGETBL_ENABLED,
+		   PSB_PGETBL_CTL);
+	(void) PSB_RVDC32(PSB_PGETBL_CTL);
+
+	pci_write_config_byte(dev->pdev, 0xF4, dev_priv->saveLBB);
+
+	mutex_lock(&dev->struct_mutex);
+
+	REG_WRITE(DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
+	REG_WRITE(RAMCLK_GATE_D, dev_priv->saveRAMCLK_GATE_D); 
+
+	/* BIOS does below anyway */
+	REG_WRITE(DPIO_CFG, 0);
+	REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N);
+
+	temp = REG_READ(DPLL_A);
+	if ((temp & DPLL_SYNCLOCK_ENABLE) == 0) {
+		REG_WRITE(DPLL_A, temp | DPLL_SYNCLOCK_ENABLE);
+		REG_READ(DPLL_A);
+	}
+
+	temp = REG_READ(DPLL_B);
+	if ((temp & DPLL_SYNCLOCK_ENABLE) == 0) {
+		REG_WRITE(DPLL_B, temp | DPLL_SYNCLOCK_ENABLE);
+		REG_READ(DPLL_B);
+	}
+ 
+	udelay(500);
+
+	REG_WRITE(DSPFW1, dev_priv->saveDSPFW[0]);
+	REG_WRITE(DSPFW2, dev_priv->saveDSPFW[1]);
+	REG_WRITE(DSPFW3, dev_priv->saveDSPFW[2]);
+	REG_WRITE(DSPFW4, dev_priv->saveDSPFW[3]);
+	REG_WRITE(DSPFW5, dev_priv->saveDSPFW[4]);
+	REG_WRITE(DSPFW6, dev_priv->saveDSPFW[5]);
+
+	REG_WRITE(DSPARB, dev_priv->saveDSPARB);
+	REG_WRITE(ADPA, dev_priv->saveADPA);
+
+	REG_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
+	REG_WRITE(LVDS, dev_priv->saveLVDS);
+	REG_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
+	REG_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
+	REG_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
+	REG_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
+	REG_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
+	REG_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
+	REG_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
+
+	REG_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
+
+	REG_WRITE(PSB_INT_ENABLE_R, dev_priv->saveIER);
+	REG_WRITE(PSB_INT_MASK_R, dev_priv->saveIMR);
+
+	mutex_unlock(&dev->struct_mutex);
+
+	psb_intel_display_wa(dev);
+
+	drm_mode_config_reset(dev);                                                                                                                                               
+	ospm_output_dpms(dev, true);
+
+	/* Resume the modeset for every activated CRTC */                                                                                                                         
+	drm_helper_resume_force_mode(dev);
+}
+
+/*
+ * ospm_suspend_pci
+ *
+ * Description: Suspend the pci device saving state and disabling
+ * as necessary.
+ */
+static void ospm_suspend_pci(struct pci_dev *pdev)
+{
+
+	if (gbSuspended)
+		return;
+
+	DRM_DEBUG_KMS("\n");
+
+	pci_save_state(pdev);
+
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
+
+	gbSuspended = true;
+	gbgfxsuspended = true;
+}
+
+/*
+ * ospm_resume_pci
+ *
+ * Description: Resume the pci device restoring state and enabling
+ * as necessary.
+ */
+static bool ospm_resume_pci(struct pci_dev *pdev)
+{
+	int ret = 0;
+
+	if (!gbSuspended)
+		return true;
+
+	DRM_DEBUG_KMS("\n");
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+
+	ret = pci_enable_device(pdev);
+
+	if (ret != 0)
+		DRM_ERROR("ospm_resume_pci: pci_enable_device failed: %d\n", ret);
+	else
+		gbSuspended = false;
+
+	pci_set_master(pdev);
+
+	return !gbSuspended;
+}
+
+/*
+ * ospm_power_suspend
+ *
+ * Description: OSPM is telling our driver to suspend so save state
+ * and power down all hardware.
+ */
+int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+        int ret = 0;
+        int graphics_access_count;
+        int videodec_access_count;
+    	bool suspend_pci = true; 
+
+	if(gbSuspendInProgress || gbResumeInProgress)
+        {
+                DRM_ERROR("OSPM_GFX_DPK: %s system BUSY \n", __func__);
+                return  -EBUSY;
+        }
+
+        mutex_lock(&g_ospm_mutex);
+
+        if (!gbSuspended) {
+                graphics_access_count = atomic_read(&g_graphics_access_count);
+                videodec_access_count = atomic_read(&g_videodec_access_count);
+
+                if (!ret) {
+                        gbSuspendInProgress = true;
+
+			ospm_suspend_display(gpDrmDevice);
+
+			drm_irq_uninstall(gpDrmDevice);
+			
+			/* Turn off PVR service and power */
+			PVRSRVDriverSuspend(gpDrmDevice, state);
+
+			/* FIXME: video driver support for Linux Runtime PM */
+                        if (ospm_runtime_pm_msvdx_suspend(gpDrmDevice) != 0) {
+				suspend_pci = false;
+                        }
+
+			psb_intel_opregion_fini(gpDrmDevice);
+
+                        if (suspend_pci == true) {
+				ospm_suspend_pci(pdev);
+                        }
+                        gbSuspendInProgress = false;
+                } else {
+                        DRM_DEBUG_KMS("ospm_power_suspend: device busy: graphics %d videodec %d\n",
+				  graphics_access_count, videodec_access_count);
+                }
+        }
+
+
+        mutex_unlock(&g_ospm_mutex);
+        return ret;
+}
+
+static void ospm_power_island_wait(u32 reg, u32 mask, u32 target)
+{
+	int loop_count = 5;
+	u32 pwr_sts;
+
+	while (loop_count--) {
+		pwr_sts = inl(reg);
+
+		if ((pwr_sts & mask) == target)
+			break;
+		else
+			udelay(10);
+	}
+}
+
+/*
+ * ospm_power_island_up
+ *
+ * Description: Restore power to the specified island(s) (powergating)
+ */
+void ospm_power_island_up(int hw_islands)
+{
+	u32 pwr_cnt = 0;
+	u32 pwr_mask = 0;
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) gpDrmDevice->dev_private;
+
+	if (hw_islands & ~(OSPM_GRAPHICS_ISLAND | OSPM_VIDEO_DEC_ISLAND))
+		return;
+
+	pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
+
+	pwr_mask = 0;
+
+	if (hw_islands & OSPM_GRAPHICS_ISLAND) {
+		pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
+		/* Only the BIT1 is used */
+		pwr_cnt |= PSB_PWRGT_GFX_ON;
+		pwr_mask = PSB_PWRGT_GFX_MASK;
+
+#ifdef OSPM_STAT
+			if (dev_priv->graphics_state == PSB_PWR_STATE_OFF) {
+				dev_priv->gfx_off_time += (jiffies - dev_priv->gfx_last_mode_change) * 1000 / HZ;
+				dev_priv->gfx_last_mode_change = jiffies;
+				dev_priv->graphics_state = PSB_PWR_STATE_ON;
+				dev_priv->gfx_on_cnt++;
+			}
+#endif
+		outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
+		ospm_power_island_wait(dev_priv->apm_base + PSB_APM_STS, pwr_mask, PSB_PWRGT_GFX_D0);
+	}
+
+	if (hw_islands & OSPM_VIDEO_DEC_ISLAND) {
+		pwr_cnt &= ~PSB_PWRGT_VID_DEC_MASK;
+		pwr_cnt |= PSB_PWRGT_VID_DEC_ON; 
+		pwr_mask = PSB_PWRGT_VID_DEC_MASK;
+
+		outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
+		ospm_power_island_wait(dev_priv->apm_base + PSB_APM_STS, pwr_mask, PSB_PWRGT_VID_DEC_D0);
+	}
+
+	g_hw_power_status_mask |= hw_islands;
+}
+
+/*
+ * ospm_power_resume
+ */
+int ospm_power_resume(struct pci_dev *pdev)
+{
+	if(gbSuspendInProgress || gbResumeInProgress)
+        {
+                DRM_ERROR("OSPM_GFX_DPK: %s hw_island: Suspend || gbResumeInProgress!!!! \n", __func__);
+                return 0;
+        }
+
+        mutex_lock(&g_ospm_mutex);
+
+	DRM_DEBUG_KMS("\n");
+
+  	gbResumeInProgress = true;
+
+        ospm_resume_pci(pdev);
+
+	psb_intel_clock_gating(gpDrmDevice);
+
+	psb_intel_opregion_setup(gpDrmDevice);
+
+	/* resume PVR power island and service */
+	PVRSRVDriverResume(gpDrmDevice);
+
+	ospm_resume_display(gpDrmDevice->pdev);
+
+        mutex_unlock(&g_ospm_mutex);
+
+	drm_irq_install(gpDrmDevice);
+
+	psb_intel_opregion_init(gpDrmDevice);
+	
+	gbResumeInProgress = false;
+
+	return 0;
+}
+
+
+/*
+ * ospm_power_island_down
+ *
+ * Description: Cut power to the specified island(s) (powergating)
+ */
+void ospm_power_island_down(int islands)
+{
+	u32 pwr_cnt = 0;
+	u32 pwr_mask = 0;
+
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) gpDrmDevice->dev_private;
+
+	if (islands & ~(OSPM_GRAPHICS_ISLAND | OSPM_VIDEO_DEC_ISLAND))
+		return;
+
+	pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
+
+	g_hw_power_status_mask &= ~islands;
+
+	if (islands & OSPM_GRAPHICS_ISLAND) {
+		/* Turn off the SGX Power Island */
+		pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
+		pwr_cnt |= PSB_PWRGT_GFX_OFF;
+		pwr_mask = PSB_PWRGT_GFX_MASK;
+
+#ifdef OSPM_STAT
+		if (dev_priv->graphics_state == PSB_PWR_STATE_ON) {
+			dev_priv->gfx_on_time += (jiffies - dev_priv->gfx_last_mode_change) * 1000 / HZ;
+			dev_priv->gfx_last_mode_change = jiffies;
+			dev_priv->graphics_state = PSB_PWR_STATE_OFF;
+			dev_priv->gfx_off_cnt++;
+		}
+#endif
+		outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
+
+		ospm_power_island_wait(dev_priv->apm_base + PSB_APM_STS, pwr_mask, PSB_PWRGT_GFX_D3);
+
+	}
+
+	if (islands & OSPM_VIDEO_DEC_ISLAND) {
+		/* Turn off the MSVDX power island */
+		pwr_cnt &= ~PSB_PWRGT_VID_DEC_MASK;
+		pwr_cnt |= PSB_PWRGT_VID_DEC_OFF;
+		pwr_mask = PSB_PWRGT_VID_DEC_MASK;
+
+		outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
+
+		ospm_power_island_wait(dev_priv->apm_base + PSB_APM_STS, pwr_mask, PSB_PWRGT_VID_DEC_D3);
+	}
+}
+
+
+/*
+ * ospm_power_is_hw_on
+ *
+ * Description: do an instantaneous check for if the specified islands
+ * are on.  Only use this in cases where you know the g_state_change_mutex
+ * is already held such as in irq install/uninstall.  Otherwise, use
+ * ospm_power_using_hw_begin().
+ */
+bool ospm_power_is_hw_on(int hw_islands)
+{
+	return ((g_hw_power_status_mask & hw_islands) == hw_islands) ? true:false;
+}
+
+/*
+ * ospm_power_using_hw_begin
+ *
+ * Description: Notify PowerMgmt module that you will be accessing the
+ * specified island's hw so don't power it off.  If force_on is true,
+ * this will power on the specified island if it is off.
+ * Otherwise, this will return false and the caller is expected to not
+ * access the hw.  
+ * 
+ * NOTE *** If this is called from and interrupt handler or other atomic 
+ * context, then it will return false if we are in the middle of a
+ * power state transition and the caller will be expected to handle that
+ * even if force_on is set to true.
+ */
+bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage)
+{
+	bool ret = true;
+	bool island_is_off = false;
+	bool b_atomic = (in_interrupt() || in_atomic());
+	bool locked = true;
+	struct pci_dev *pdev = gpDrmDevice->pdev;
+	bool force_on = usage ? true: false;
+	/*quick path, not 100% race safe, but should be enough comapre to current other code in this file */
+	if (!force_on) {
+		if (hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask))
+			return false;
+		else {
+			locked = false;
+			goto increase_count;
+		}
+	}
+
+#ifdef CONFIG_PM_RUNTIME
+	/* Anyway, increment pm_runtime_refcount firstly. 
+	 * If the return value is false, decrease pm_rumtime_refcount. 
+	 */
+	pm_runtime_get(&pdev->dev);
+#endif
+	if (!b_atomic)
+		mutex_lock(&g_ospm_mutex);
+
+	island_is_off = hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask);
+
+	if (b_atomic && (gbSuspendInProgress || gbResumeInProgress || gbSuspended) && force_on && island_is_off)
+		ret = false;
+
+	if (ret && island_is_off && !force_on)
+		ret = false;
+
+	if (ret && island_is_off && force_on) {
+		gbResumeInProgress = true;
+
+		ret = ospm_resume_pci(pdev);
+
+		if (ret) {
+			switch(hw_island)
+			{
+			case OSPM_GRAPHICS_ISLAND:
+				ospm_power_island_up(OSPM_GRAPHICS_ISLAND);
+				psb_irq_preinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
+				psb_irq_postinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
+				break;
+			case OSPM_VIDEO_DEC_ISLAND:
+				if(!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
+					/* printk(KERN_ALERT "%s power on video decode\n", __func__); */
+					ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND);
+					ospm_runtime_pm_msvdx_resume(gpDrmDevice);
+					psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
+					psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
+				}
+				else{
+					/* printk(KERN_ALERT "%s video decode is already on\n", __func__); */
+				}
+
+				break;
+			default:
+				DRM_ERROR("unknown island !\n");
+				break;
+			}
+
+		}
+
+		if (!ret)
+			DRM_ERROR("ospm_power_using_hw_begin: forcing on %d failed\n", hw_island);
+
+		gbResumeInProgress = false;
+	}
+increase_count:
+	if (ret) {
+		switch(hw_island)
+		{
+		case OSPM_GRAPHICS_ISLAND:
+			atomic_inc(&g_graphics_access_count);
+			break;
+		case OSPM_VIDEO_DEC_ISLAND:
+			atomic_inc(&g_videodec_access_count);
+			break;
+		}
+	} 
+#ifdef CONFIG_PM_RUNTIME
+	else {
+		/* decrement pm_runtime_refcount */
+		pm_runtime_put(&pdev->dev);
+	}
+#endif
+
+	if (!b_atomic && locked)
+		mutex_unlock(&g_ospm_mutex);
+
+	return ret;
+}
+
+
+/*
+ * ospm_power_using_hw_end
+ *
+ * Description: Notify PowerMgmt module that you are done accessing the
+ * specified island's hw so feel free to power it off.  Note that this
+ * function doesn't actually power off the islands.
+ */
+void ospm_power_using_hw_end(int hw_island)
+{
+	switch(hw_island)
+	{
+	case OSPM_GRAPHICS_ISLAND:
+		atomic_dec(&g_graphics_access_count);
+		break;
+	case OSPM_VIDEO_DEC_ISLAND:
+		atomic_dec(&g_videodec_access_count);
+		break;
+	}
+
+#ifdef CONFIG_PM_RUNTIME
+	/* decrement runtime pm ref count */
+	pm_runtime_put(&gpDrmDevice->pdev->dev);
+#endif
+
+	WARN_ON(atomic_read(&g_graphics_access_count) < 0);
+	WARN_ON(atomic_read(&g_videodec_access_count) < 0);
+}
+
+int ospm_runtime_pm_allow(struct drm_device * dev)
+{
+	struct drm_psb_private * dev_priv = dev->dev_private;
+
+	PSB_DEBUG_ENTRY("%s\n", __FUNCTION__);
+
+	if(dev_priv->rpm_enabled)
+		return 0;
+
+	return 0;
+}
+
+void ospm_runtime_pm_forbid(struct drm_device * dev)
+{
+	struct drm_psb_private * dev_priv = dev->dev_private;
+
+	DRM_INFO("%s\n", __FUNCTION__);
+
+	pm_runtime_forbid(&dev->pdev->dev);
+	dev_priv->rpm_enabled = 0;
+}
+
+int psb_runtime_suspend(struct device *dev)
+{
+	pm_message_t state;
+	int ret = 0;
+	state.event = 0;
+
+	DRM_DEBUG_KMS("\n");
+
+        if (atomic_read(&g_graphics_access_count)
+		|| atomic_read(&g_videodec_access_count)){
+                DRM_ERROR("OSPM_GFX_DPK: GFX: %d VED: %d DSR: %d \n", atomic_read(&g_graphics_access_count),
+			  atomic_read(&g_videodec_access_count), 0);
+                return -EBUSY;
+        }
+        else
+		ret = ospm_power_suspend(gpDrmDevice->pdev, state);
+
+	return ret;
+}
+
+int psb_runtime_resume(struct device *dev)
+{
+	/* Notify HDMI Audio sub-system about the resume. */
+#ifdef CONFIG_SND_INTELMID_HDMI_AUDIO
+	struct drm_psb_private* dev_priv = gpDrmDevice->dev_private;
+
+       if(dev_priv->had_pvt_data)
+               dev_priv->had_interface->resume(dev_priv->had_pvt_data);
+#endif
+
+	/* Nop for GFX */
+	return 0;
+}
+
+int psb_runtime_idle(struct device *dev)
+{
+#ifdef CONFIG_SND_INTELMID_HDMI_AUDIO
+	struct drm_psb_private* dev_priv = gpDrmDevice->dev_private;
+	int hdmi_audio_busy = 0;
+	pm_event_t hdmi_audio_event;
+#endif
+
+#if 1
+	int msvdx_hw_busy = 0;
+
+	msvdx_hw_busy = ospm_runtime_check_msvdx_hw_busy(gpDrmDevice);
+#endif
+
+#ifdef CONFIG_SND_INTELMID_HDMI_AUDIO
+       if(dev_priv->had_pvt_data){
+               hdmi_audio_event.event = 0;
+               hdmi_audio_busy = dev_priv->had_interface->suspend(dev_priv->had_pvt_data, hdmi_audio_event);
+       }
+#endif
+	/*printk (KERN_ALERT "lvds:%d,mipi:%d\n", dev_priv->is_lvds_on, dev_priv->is_mipi_on);*/
+	if (atomic_read(&g_graphics_access_count)
+		|| atomic_read(&g_videodec_access_count)
+#ifdef CONFIG_SND_INTELMID_HDMI_AUDIO
+		|| hdmi_audio_busy
+#endif
+
+#if 1
+		|| (msvdx_hw_busy == 1))
+#endif
+			return 1;
+		else
+			return 0;
+}
+
diff --git a/drivers/staging/cdv/drv/psb_powermgmt.h b/drivers/staging/cdv/drv/psb_powermgmt.h
new file mode 100644
index 0000000..11f9154
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_powermgmt.h
@@ -0,0 +1,98 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * All Rights Reserved.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Benjamin Defnet <benjamin.r.defnet@intel.com>
+ *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
+ *
+ */
+#ifndef _PSB_POWERMGMT_H_
+#define _PSB_POWERMGMT_H_
+
+#include <linux/pci.h>
+#include <drm/drmP.h>
+
+#define OSPM_GRAPHICS_ISLAND	0x1
+#define OSPM_VIDEO_DEC_ISLAND	0x2
+#define OSPM_VIDEO_ENC_ISLAND	0x4
+#define OSPM_ALL_ISLANDS	0x7
+
+/* IPC message and command defines used to enable/disable mipi panel voltages */
+#define IPC_MSG_PANEL_ON_OFF    0xE9
+#define IPC_CMD_PANEL_ON        1
+#define IPC_CMD_PANEL_OFF       0
+
+typedef enum _UHBUsage
+{
+    OSPM_UHB_ONLY_IF_ON = 0,
+    OSPM_UHB_FORCE_POWER_ON,
+} UHBUsage;
+
+//extern int psb_check_msvdx_idle(struct drm_device *dev);
+//extern int lnc_check_topaz_idle(struct drm_device *dev);
+/* Use these functions to power down video HW for D0i3 purpose  */
+void ospm_apm_power_down_msvdx(struct drm_device *dev);
+void ospm_apm_power_down_topaz(struct drm_device *dev);
+
+void ospm_power_init(struct drm_device *dev);
+void ospm_power_uninit(void);
+
+
+/*
+ * OSPM will call these functions
+ */
+int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state);
+int ospm_power_resume(struct pci_dev *pdev);
+
+/*
+ * These are the functions the driver should use to wrap all hw access
+ * (i.e. register reads and writes)
+ */
+bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage);
+void ospm_power_using_hw_end(int hw_island);
+
+/*
+ * Use this function to do an instantaneous check for if the hw is on.
+ * Only use this in cases where you know the g_state_change_mutex
+ * is already held such as in irq install/uninstall and you need to
+ * prevent a deadlock situation.  Otherwise use ospm_power_using_hw_begin().
+ */
+bool ospm_power_is_hw_on(int hw_islands);
+
+/*
+ * Power up/down different hw component rails/islands
+ */
+void ospm_power_island_down(int hw_islands);
+void ospm_power_island_up(int hw_islands);
+void ospm_suspend_graphics(void);
+/*
+ * GFX-Runtime PM callbacks
+ */
+int psb_runtime_suspend(struct device *dev);
+int psb_runtime_resume(struct device *dev);
+int psb_runtime_idle(struct device *dev);
+int ospm_runtime_pm_allow(struct drm_device * dev);
+void ospm_runtime_pm_forbid(struct drm_device * dev);
+
+
+#endif /*_PSB_POWERMGMT_H_*/
diff --git a/drivers/staging/cdv/drv/psb_pvr_glue.c b/drivers/staging/cdv/drv/psb_pvr_glue.c
new file mode 100644
index 0000000..e3782bc
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_pvr_glue.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ */
+
+#include "psb_pvr_glue.h"
+
+/**
+ * FIXME: should NOT use these file under env/linux directly
+ */
+#include "mm.h"
+
+int psb_get_meminfo_by_handle(IMG_HANDLE hKernelMemInfo,
+				PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo)
+{
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
+	PVRSRV_PER_PROCESS_DATA *psPerProc = IMG_NULL;
+	PVRSRV_ERROR eError;
+
+	psPerProc = PVRSRVPerProcessData(OSGetCurrentProcessIDKM());
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+				    (IMG_VOID *)&psKernelMemInfo,
+				    hKernelMemInfo,
+				    PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK) {
+		DRM_ERROR("Cannot find kernel meminfo for handle 0x%x\n",
+			  (IMG_UINT32)hKernelMemInfo);
+		return -EINVAL;
+	}
+
+	*ppsKernelMemInfo = psKernelMemInfo;
+
+	DRM_DEBUG_KMS("Got Kernel MemInfo for handle 0x%x\n",
+		  (IMG_UINT32)hKernelMemInfo);
+	return 0;
+}
+
+IMG_UINT32 psb_get_tgid(void)
+{
+	return OSGetCurrentProcessIDKM();
+}
+
+int psb_get_pages_by_mem_handle(IMG_HANDLE hOSMemHandle, struct page ***pages)
+{
+	LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+	struct page **page_list;
+
+	if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ALLOC_PAGES) {
+		DRM_ERROR("MemArea type is not LINUX_MEM_AREA_ALLOC_PAGES\n");
+		return -EINVAL;
+	}
+
+	page_list = psLinuxMemArea->uData.sPageList.pvPageList;
+	if (!page_list) {
+		DRM_DEBUG_KMS("Page List is NULL\n");
+		return -ENOMEM;
+	}
+
+	*pages = page_list;
+	return 0;
+}
diff --git a/drivers/staging/cdv/drv/psb_pvr_glue.h b/drivers/staging/cdv/drv/psb_pvr_glue.h
new file mode 100644
index 0000000..7c2762c
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_pvr_glue.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ */
+
+#include "psb_drv.h"
+#include "services_headers.h"
+
+extern int psb_get_meminfo_by_handle(IMG_HANDLE hKernelMemInfo,
+				PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo);
+extern IMG_UINT32 psb_get_tgid(void);
+extern int psb_get_pages_by_mem_handle(IMG_HANDLE hOSMemHandle,
+					struct page ***pages);
diff --git a/drivers/staging/cdv/drv/psb_reg.h b/drivers/staging/cdv/drv/psb_reg.h
new file mode 100644
index 0000000..c77a898
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_reg.h
@@ -0,0 +1,596 @@
+/**************************************************************************
+ *
+ * Copyright (c) (2005-2007) Imagination Technologies Limited.
+ * Copyright (c) 2011, Intel Corporation.
+ * 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 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..
+ *
+ **************************************************************************/
+
+#ifndef _PSB_REG_H_
+#define _PSB_REG_H_
+
+#define PSB_CR_CLKGATECTL                0x0000
+#define _PSB_C_CLKGATECTL_AUTO_MAN_REG   (1 << 24)
+#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20)
+#define _PSB_C_CLKGATECTL_USE_CLKG_MASK  (0x3 << 20)
+#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16)
+#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK  (0x3 << 16)
+#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT  (12)
+#define _PSB_C_CLKGATECTL_TA_CLKG_MASK   (0x3 << 12)
+#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8)
+#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK  (0x3 << 8)
+#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4)
+#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK  (0x3 << 4)
+#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT  (0)
+#define _PSB_C_CLKGATECTL_2D_CLKG_MASK   (0x3 << 0)
+#define _PSB_C_CLKGATECTL_CLKG_ENABLED   (0)
+#define _PSB_C_CLKGATECTL_CLKG_DISABLED  (1)
+#define _PSB_C_CLKGATECTL_CLKG_AUTO      (2)
+
+#define PSB_CR_CORE_ID                   0x001C
+#define _PSB_CC_ID_ID_SHIFT              (16)
+#define _PSB_CC_ID_ID_MASK               (0xFFFF << 16)
+#define _PSB_CC_ID_CONFIG_SHIFT          (0)
+#define _PSB_CC_ID_CONFIG_MASK           (0xFFFF << 0)
+
+#define PSB_CR_CORE_REVISION               0x0020
+#define _PSB_CC_REVISION_DESIGNER_SHIFT    (24)
+#define _PSB_CC_REVISION_DESIGNER_MASK     (0xFF << 24)
+#define _PSB_CC_REVISION_MAJOR_SHIFT       (16)
+#define _PSB_CC_REVISION_MAJOR_MASK        (0xFF << 16)
+#define _PSB_CC_REVISION_MINOR_SHIFT       (8)
+#define _PSB_CC_REVISION_MINOR_MASK        (0xFF << 8)
+#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0)
+#define _PSB_CC_REVISION_MAINTENANCE_MASK  (0xFF << 0)
+
+#define PSB_CR_DESIGNER_REV_FIELD1       0x0024
+
+#define PSB_CR_SOFT_RESET                0x0080
+#define _PSB_CS_RESET_TSP_RESET          (1 << 6)
+#define _PSB_CS_RESET_ISP_RESET          (1 << 5)
+#define _PSB_CS_RESET_USE_RESET          (1 << 4)
+#define _PSB_CS_RESET_TA_RESET           (1 << 3)
+#define _PSB_CS_RESET_DPM_RESET          (1 << 2)
+#define _PSB_CS_RESET_TWOD_RESET         (1 << 1)
+#define _PSB_CS_RESET_BIF_RESET          (1 << 0)
+
+#define PSB_CR_DESIGNER_REV_FIELD2       0x002C
+
+#define PSB_CR_EVENT_HOST_ENABLE2        0x0110
+
+#define PSB_CR_EVENT_STATUS2             0x0118
+
+#define PSB_CR_EVENT_HOST_CLEAR2         0x0114
+#define _PSB_CE2_BIF_REQUESTER_FAULT     (1 << 4)
+
+#define PSB_CR_EVENT_STATUS              0x012C
+
+#define PSB_CR_EVENT_HOST_ENABLE         0x0130
+
+#define PSB_CR_EVENT_HOST_CLEAR          0x0134
+#define _PSB_CE_MASTER_INTERRUPT         (1 << 31)
+#define _PSB_CE_TA_DPM_FAULT             (1 << 28)
+#define _PSB_CE_TWOD_COMPLETE            (1 << 27)
+#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS    (1 << 25)
+#define _PSB_CE_DPM_TA_MEM_FREE          (1 << 24)
+#define _PSB_CE_PIXELBE_END_RENDER       (1 << 18)
+#define _PSB_CE_SW_EVENT                 (1 << 14)
+#define _PSB_CE_TA_FINISHED              (1 << 13)
+#define _PSB_CE_TA_TERMINATE             (1 << 12)
+#define _PSB_CE_DPM_REACHED_MEM_THRESH   (1 << 3)
+#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL    (1 << 2)
+#define _PSB_CE_DPM_OUT_OF_MEMORY_MT     (1 << 1)
+#define _PSB_CE_DPM_3D_MEM_FREE          (1 << 0)
+
+
+#define PSB_USE_OFFSET_MASK              0x0007FFFF
+#define PSB_USE_OFFSET_SIZE              (PSB_USE_OFFSET_MASK + 1)
+#define PSB_CR_USE_CODE_BASE0            0x0A0C
+#define PSB_CR_USE_CODE_BASE1            0x0A10
+#define PSB_CR_USE_CODE_BASE2            0x0A14
+#define PSB_CR_USE_CODE_BASE3            0x0A18
+#define PSB_CR_USE_CODE_BASE4            0x0A1C
+#define PSB_CR_USE_CODE_BASE5            0x0A20
+#define PSB_CR_USE_CODE_BASE6            0x0A24
+#define PSB_CR_USE_CODE_BASE7            0x0A28
+#define PSB_CR_USE_CODE_BASE8            0x0A2C
+#define PSB_CR_USE_CODE_BASE9            0x0A30
+#define PSB_CR_USE_CODE_BASE10           0x0A34
+#define PSB_CR_USE_CODE_BASE11           0x0A38
+#define PSB_CR_USE_CODE_BASE12           0x0A3C
+#define PSB_CR_USE_CODE_BASE13           0x0A40
+#define PSB_CR_USE_CODE_BASE14           0x0A44
+#define PSB_CR_USE_CODE_BASE15           0x0A48
+#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2))
+#define _PSB_CUC_BASE_DM_SHIFT           (25)
+#define _PSB_CUC_BASE_DM_MASK            (0x3 << 25)
+#define _PSB_CUC_BASE_ADDR_SHIFT         (0)	/* 1024-bit aligned address? */
+#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT    (7)
+#define _PSB_CUC_BASE_ADDR_MASK          (0x1FFFFFF << 0)
+#define _PSB_CUC_DM_VERTEX		 (0)
+#define _PSB_CUC_DM_PIXEL		 (1)
+#define _PSB_CUC_DM_RESERVED		 (2)
+#define _PSB_CUC_DM_EDM	                 (3)
+
+#define PSB_CR_PDS_EXEC_BASE             0x0AB8
+#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20)	/* 1MB aligned address */
+#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20)
+
+#define PSB_CR_EVENT_KICKER              0x0AC4
+#define _PSB_CE_KICKER_ADDRESS_SHIFT     (4)	/* 128-bit aligned address */
+
+#define PSB_CR_EVENT_KICK                0x0AC8
+#define _PSB_CE_KICK_NOW                 (1 << 0)
+
+
+#define PSB_CR_BIF_DIR_LIST_BASE1        0x0C38
+
+#define PSB_CR_BIF_CTRL                  0x0C00
+#define _PSB_CB_CTRL_CLEAR_FAULT         (1 << 4)
+#define _PSB_CB_CTRL_INVALDC             (1 << 3)
+#define _PSB_CB_CTRL_FLUSH               (1 << 2)
+
+#define PSB_CR_BIF_INT_STAT              0x0C04
+
+#define PSB_CR_BIF_FAULT                 0x0C08
+#define _PSB_CBI_STAT_PF_N_RW            (1 << 14)
+#define _PSB_CBI_STAT_FAULT_SHIFT        (0)
+#define _PSB_CBI_STAT_FAULT_MASK         (0x3FFF << 0)
+#define _PSB_CBI_STAT_FAULT_CACHE        (1 << 1)
+#define _PSB_CBI_STAT_FAULT_TA           (1 << 2)
+#define _PSB_CBI_STAT_FAULT_VDM          (1 << 3)
+#define _PSB_CBI_STAT_FAULT_2D           (1 << 4)
+#define _PSB_CBI_STAT_FAULT_PBE          (1 << 5)
+#define _PSB_CBI_STAT_FAULT_TSP          (1 << 6)
+#define _PSB_CBI_STAT_FAULT_ISP          (1 << 7)
+#define _PSB_CBI_STAT_FAULT_USSEPDS      (1 << 8)
+#define _PSB_CBI_STAT_FAULT_HOST         (1 << 9)
+
+#define PSB_CR_BIF_BANK0                 0x0C78
+
+#define PSB_CR_BIF_BANK1                 0x0C7C
+
+#define PSB_CR_BIF_DIR_LIST_BASE0        0x0C84
+
+#define PSB_CR_BIF_TWOD_REQ_BASE         0x0C88
+#define PSB_CR_BIF_3D_REQ_BASE           0x0CAC
+
+#define PSB_CR_2D_SOCIF                  0x0E18
+#define _PSB_C2_SOCIF_FREESPACE_SHIFT    (0)
+#define _PSB_C2_SOCIF_FREESPACE_MASK     (0xFF << 0)
+#define _PSB_C2_SOCIF_EMPTY              (0x80 << 0)
+
+#define PSB_CR_2D_BLIT_STATUS            0x0E04
+#define _PSB_C2B_STATUS_BUSY             (1 << 24)
+#define _PSB_C2B_STATUS_COMPLETE_SHIFT   (0)
+#define _PSB_C2B_STATUS_COMPLETE_MASK    (0xFFFFFF << 0)
+
+/*
+ * 2D defs.
+ */
+
+/*
+ * 2D Slave Port Data : Block Header's Object Type
+ */
+
+#define	PSB_2D_CLIP_BH                   (0x00000000)
+#define	PSB_2D_PAT_BH                    (0x10000000)
+#define	PSB_2D_CTRL_BH                   (0x20000000)
+#define	PSB_2D_SRC_OFF_BH                (0x30000000)
+#define	PSB_2D_MASK_OFF_BH               (0x40000000)
+#define	PSB_2D_RESERVED1_BH              (0x50000000)
+#define	PSB_2D_RESERVED2_BH              (0x60000000)
+#define	PSB_2D_FENCE_BH                  (0x70000000)
+#define	PSB_2D_BLIT_BH                   (0x80000000)
+#define	PSB_2D_SRC_SURF_BH               (0x90000000)
+#define	PSB_2D_DST_SURF_BH               (0xA0000000)
+#define	PSB_2D_PAT_SURF_BH               (0xB0000000)
+#define	PSB_2D_SRC_PAL_BH                (0xC0000000)
+#define	PSB_2D_PAT_PAL_BH                (0xD0000000)
+#define	PSB_2D_MASK_SURF_BH              (0xE0000000)
+#define	PSB_2D_FLUSH_BH                  (0xF0000000)
+
+/*
+ * Clip Definition block (PSB_2D_CLIP_BH)
+ */
+#define PSB_2D_CLIPCOUNT_MAX             (1)
+#define PSB_2D_CLIPCOUNT_MASK            (0x00000000)
+#define PSB_2D_CLIPCOUNT_CLRMASK         (0xFFFFFFFF)
+#define PSB_2D_CLIPCOUNT_SHIFT           (0)
+/* clip rectangle min & max */
+#define PSB_2D_CLIP_XMAX_MASK            (0x00FFF000)
+#define PSB_2D_CLIP_XMAX_CLRMASK         (0xFF000FFF)
+#define PSB_2D_CLIP_XMAX_SHIFT           (12)
+#define PSB_2D_CLIP_XMIN_MASK            (0x00000FFF)
+#define PSB_2D_CLIP_XMIN_CLRMASK         (0x00FFF000)
+#define PSB_2D_CLIP_XMIN_SHIFT           (0)
+/* clip rectangle offset */
+#define PSB_2D_CLIP_YMAX_MASK            (0x00FFF000)
+#define PSB_2D_CLIP_YMAX_CLRMASK         (0xFF000FFF)
+#define PSB_2D_CLIP_YMAX_SHIFT           (12)
+#define PSB_2D_CLIP_YMIN_MASK            (0x00000FFF)
+#define PSB_2D_CLIP_YMIN_CLRMASK         (0x00FFF000)
+#define PSB_2D_CLIP_YMIN_SHIFT           (0)
+
+/*
+ * Pattern Control (PSB_2D_PAT_BH)
+ */
+#define PSB_2D_PAT_HEIGHT_MASK           (0x0000001F)
+#define PSB_2D_PAT_HEIGHT_SHIFT          (0)
+#define PSB_2D_PAT_WIDTH_MASK            (0x000003E0)
+#define PSB_2D_PAT_WIDTH_SHIFT           (5)
+#define PSB_2D_PAT_YSTART_MASK           (0x00007C00)
+#define PSB_2D_PAT_YSTART_SHIFT          (10)
+#define PSB_2D_PAT_XSTART_MASK           (0x000F8000)
+#define PSB_2D_PAT_XSTART_SHIFT          (15)
+
+/*
+ * 2D Control block (PSB_2D_CTRL_BH)
+ */
+/* Present Flags */
+#define PSB_2D_SRCCK_CTRL                (0x00000001)
+#define PSB_2D_DSTCK_CTRL                (0x00000002)
+#define PSB_2D_ALPHA_CTRL                (0x00000004)
+/* Colour Key Colour (SRC/DST)*/
+#define PSB_2D_CK_COL_MASK               (0xFFFFFFFF)
+#define PSB_2D_CK_COL_CLRMASK            (0x00000000)
+#define PSB_2D_CK_COL_SHIFT              (0)
+/* Colour Key Mask (SRC/DST)*/
+#define PSB_2D_CK_MASK_MASK              (0xFFFFFFFF)
+#define PSB_2D_CK_MASK_CLRMASK           (0x00000000)
+#define PSB_2D_CK_MASK_SHIFT             (0)
+/* Alpha Control (Alpha/RGB)*/
+#define PSB_2D_GBLALPHA_MASK             (0x000FF000)
+#define PSB_2D_GBLALPHA_CLRMASK          (0xFFF00FFF)
+#define PSB_2D_GBLALPHA_SHIFT            (12)
+#define PSB_2D_SRCALPHA_OP_MASK          (0x00700000)
+#define PSB_2D_SRCALPHA_OP_CLRMASK       (0xFF8FFFFF)
+#define PSB_2D_SRCALPHA_OP_SHIFT         (20)
+#define PSB_2D_SRCALPHA_OP_ONE           (0x00000000)
+#define PSB_2D_SRCALPHA_OP_SRC           (0x00100000)
+#define PSB_2D_SRCALPHA_OP_DST           (0x00200000)
+#define PSB_2D_SRCALPHA_OP_SG            (0x00300000)
+#define PSB_2D_SRCALPHA_OP_DG            (0x00400000)
+#define PSB_2D_SRCALPHA_OP_GBL           (0x00500000)
+#define PSB_2D_SRCALPHA_OP_ZERO          (0x00600000)
+#define PSB_2D_SRCALPHA_INVERT           (0x00800000)
+#define PSB_2D_SRCALPHA_INVERT_CLR       (0xFF7FFFFF)
+#define PSB_2D_DSTALPHA_OP_MASK          (0x07000000)
+#define PSB_2D_DSTALPHA_OP_CLRMASK       (0xF8FFFFFF)
+#define PSB_2D_DSTALPHA_OP_SHIFT         (24)
+#define PSB_2D_DSTALPHA_OP_ONE           (0x00000000)
+#define PSB_2D_DSTALPHA_OP_SRC           (0x01000000)
+#define PSB_2D_DSTALPHA_OP_DST           (0x02000000)
+#define PSB_2D_DSTALPHA_OP_SG            (0x03000000)
+#define PSB_2D_DSTALPHA_OP_DG            (0x04000000)
+#define PSB_2D_DSTALPHA_OP_GBL           (0x05000000)
+#define PSB_2D_DSTALPHA_OP_ZERO          (0x06000000)
+#define PSB_2D_DSTALPHA_INVERT           (0x08000000)
+#define PSB_2D_DSTALPHA_INVERT_CLR       (0xF7FFFFFF)
+
+#define PSB_2D_PRE_MULTIPLICATION_ENABLE  (0x10000000)
+#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF)
+#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE   (0x20000000)
+#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK  (0xDFFFFFFF)
+
+/*
+ *Source Offset (PSB_2D_SRC_OFF_BH)
+ */
+#define PSB_2D_SRCOFF_XSTART_MASK        ((0x00000FFF) << 12)
+#define PSB_2D_SRCOFF_XSTART_SHIFT       (12)
+#define PSB_2D_SRCOFF_YSTART_MASK        (0x00000FFF)
+#define PSB_2D_SRCOFF_YSTART_SHIFT       (0)
+
+/*
+ * Mask Offset (PSB_2D_MASK_OFF_BH)
+ */
+#define PSB_2D_MASKOFF_XSTART_MASK       ((0x00000FFF) << 12)
+#define PSB_2D_MASKOFF_XSTART_SHIFT      (12)
+#define PSB_2D_MASKOFF_YSTART_MASK       (0x00000FFF)
+#define PSB_2D_MASKOFF_YSTART_SHIFT      (0)
+
+/*
+ * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored
+ */
+
+/*
+ *Blit Rectangle (PSB_2D_BLIT_BH)
+ */
+
+#define PSB_2D_ROT_MASK                  (3<<25)
+#define PSB_2D_ROT_CLRMASK               (~PSB_2D_ROT_MASK)
+#define PSB_2D_ROT_NONE                  (0<<25)
+#define PSB_2D_ROT_90DEGS                (1<<25)
+#define PSB_2D_ROT_180DEGS               (2<<25)
+#define PSB_2D_ROT_270DEGS               (3<<25)
+
+#define PSB_2D_COPYORDER_MASK            (3<<23)
+#define PSB_2D_COPYORDER_CLRMASK         (~PSB_2D_COPYORDER_MASK)
+#define PSB_2D_COPYORDER_TL2BR           (0<<23)
+#define PSB_2D_COPYORDER_BR2TL           (1<<23)
+#define PSB_2D_COPYORDER_TR2BL           (2<<23)
+#define PSB_2D_COPYORDER_BL2TR           (3<<23)
+
+#define PSB_2D_DSTCK_CLRMASK             (0xFF9FFFFF)
+#define PSB_2D_DSTCK_DISABLE             (0x00000000)
+#define PSB_2D_DSTCK_PASS                (0x00200000)
+#define PSB_2D_DSTCK_REJECT              (0x00400000)
+
+#define PSB_2D_SRCCK_CLRMASK             (0xFFE7FFFF)
+#define PSB_2D_SRCCK_DISABLE             (0x00000000)
+#define PSB_2D_SRCCK_PASS                (0x00080000)
+#define PSB_2D_SRCCK_REJECT              (0x00100000)
+
+#define PSB_2D_CLIP_ENABLE               (0x00040000)
+
+#define PSB_2D_ALPHA_ENABLE              (0x00020000)
+
+#define PSB_2D_PAT_CLRMASK               (0xFFFEFFFF)
+#define PSB_2D_PAT_MASK                  (0x00010000)
+#define PSB_2D_USE_PAT                   (0x00010000)
+#define PSB_2D_USE_FILL                  (0x00000000)
+/*
+ * Tungsten Graphics note on rop codes: If rop A and rop B are
+ * identical, the mask surface will not be read and need not be
+ * set up.
+ */
+
+#define PSB_2D_ROP3B_MASK                (0x0000FF00)
+#define PSB_2D_ROP3B_CLRMASK             (0xFFFF00FF)
+#define PSB_2D_ROP3B_SHIFT               (8)
+/* rop code A */
+#define PSB_2D_ROP3A_MASK                (0x000000FF)
+#define PSB_2D_ROP3A_CLRMASK             (0xFFFFFF00)
+#define PSB_2D_ROP3A_SHIFT               (0)
+
+#define PSB_2D_ROP4_MASK                 (0x0000FFFF)
+/*
+ *	DWORD0:	(Only pass if Pattern control == Use Fill Colour)
+ *	Fill Colour RGBA8888
+ */
+#define PSB_2D_FILLCOLOUR_MASK           (0xFFFFFFFF)
+#define PSB_2D_FILLCOLOUR_SHIFT          (0)
+/*
+ *	DWORD1: (Always Present)
+ *	X Start (Dest)
+ *	Y Start (Dest)
+ */
+#define PSB_2D_DST_XSTART_MASK           (0x00FFF000)
+#define PSB_2D_DST_XSTART_CLRMASK        (0xFF000FFF)
+#define PSB_2D_DST_XSTART_SHIFT          (12)
+#define PSB_2D_DST_YSTART_MASK           (0x00000FFF)
+#define PSB_2D_DST_YSTART_CLRMASK        (0xFFFFF000)
+#define PSB_2D_DST_YSTART_SHIFT          (0)
+/*
+ *	DWORD2: (Always Present)
+ *	X Size (Dest)
+ *	Y Size (Dest)
+ */
+#define PSB_2D_DST_XSIZE_MASK            (0x00FFF000)
+#define PSB_2D_DST_XSIZE_CLRMASK         (0xFF000FFF)
+#define PSB_2D_DST_XSIZE_SHIFT           (12)
+#define PSB_2D_DST_YSIZE_MASK            (0x00000FFF)
+#define PSB_2D_DST_YSIZE_CLRMASK         (0xFFFFF000)
+#define PSB_2D_DST_YSIZE_SHIFT           (0)
+
+/*
+ * Source Surface (PSB_2D_SRC_SURF_BH)
+ */
+/*
+ *      WORD 0
+ */
+
+#define PSB_2D_SRC_FORMAT_MASK           (0x00078000)
+#define PSB_2D_SRC_1_PAL                 (0x00000000)
+#define PSB_2D_SRC_2_PAL                 (0x00008000)
+#define PSB_2D_SRC_4_PAL                 (0x00010000)
+#define PSB_2D_SRC_8_PAL                 (0x00018000)
+#define PSB_2D_SRC_8_ALPHA               (0x00020000)
+#define PSB_2D_SRC_4_ALPHA               (0x00028000)
+#define PSB_2D_SRC_332RGB                (0x00030000)
+#define PSB_2D_SRC_4444ARGB              (0x00038000)
+#define PSB_2D_SRC_555RGB                (0x00040000)
+#define PSB_2D_SRC_1555ARGB              (0x00048000)
+#define PSB_2D_SRC_565RGB                (0x00050000)
+#define PSB_2D_SRC_0888ARGB              (0x00058000)
+#define PSB_2D_SRC_8888ARGB              (0x00060000)
+#define PSB_2D_SRC_8888UYVY              (0x00068000)
+#define PSB_2D_SRC_RESERVED              (0x00070000)
+#define PSB_2D_SRC_1555ARGB_LOOKUP       (0x00078000)
+
+
+#define PSB_2D_SRC_STRIDE_MASK           (0x00007FFF)
+#define PSB_2D_SRC_STRIDE_CLRMASK        (0xFFFF8000)
+#define PSB_2D_SRC_STRIDE_SHIFT          (0)
+/*
+ *  WORD 1 - Base Address
+ */
+#define PSB_2D_SRC_ADDR_MASK             (0x0FFFFFFC)
+#define PSB_2D_SRC_ADDR_CLRMASK          (0x00000003)
+#define PSB_2D_SRC_ADDR_SHIFT            (2)
+#define PSB_2D_SRC_ADDR_ALIGNSHIFT       (2)
+
+/*
+ * Pattern Surface (PSB_2D_PAT_SURF_BH)
+ */
+/*
+ *  WORD 0
+ */
+
+#define PSB_2D_PAT_FORMAT_MASK           (0x00078000)
+#define PSB_2D_PAT_1_PAL                 (0x00000000)
+#define PSB_2D_PAT_2_PAL                 (0x00008000)
+#define PSB_2D_PAT_4_PAL                 (0x00010000)
+#define PSB_2D_PAT_8_PAL                 (0x00018000)
+#define PSB_2D_PAT_8_ALPHA               (0x00020000)
+#define PSB_2D_PAT_4_ALPHA               (0x00028000)
+#define PSB_2D_PAT_332RGB                (0x00030000)
+#define PSB_2D_PAT_4444ARGB              (0x00038000)
+#define PSB_2D_PAT_555RGB                (0x00040000)
+#define PSB_2D_PAT_1555ARGB              (0x00048000)
+#define PSB_2D_PAT_565RGB                (0x00050000)
+#define PSB_2D_PAT_0888ARGB              (0x00058000)
+#define PSB_2D_PAT_8888ARGB              (0x00060000)
+
+#define PSB_2D_PAT_STRIDE_MASK           (0x00007FFF)
+#define PSB_2D_PAT_STRIDE_CLRMASK        (0xFFFF8000)
+#define PSB_2D_PAT_STRIDE_SHIFT          (0)
+/*
+ *  WORD 1 - Base Address
+ */
+#define PSB_2D_PAT_ADDR_MASK             (0x0FFFFFFC)
+#define PSB_2D_PAT_ADDR_CLRMASK          (0x00000003)
+#define PSB_2D_PAT_ADDR_SHIFT            (2)
+#define PSB_2D_PAT_ADDR_ALIGNSHIFT       (2)
+
+/*
+ * Destination Surface (PSB_2D_DST_SURF_BH)
+ */
+/*
+ * WORD 0
+ */
+
+#define PSB_2D_DST_FORMAT_MASK           (0x00078000)
+#define PSB_2D_DST_332RGB                (0x00030000)
+#define PSB_2D_DST_4444ARGB              (0x00038000)
+#define PSB_2D_DST_555RGB                (0x00040000)
+#define PSB_2D_DST_1555ARGB              (0x00048000)
+#define PSB_2D_DST_565RGB                (0x00050000)
+#define PSB_2D_DST_0888ARGB              (0x00058000)
+#define PSB_2D_DST_8888ARGB              (0x00060000)
+#define PSB_2D_DST_8888AYUV              (0x00070000)
+
+#define PSB_2D_DST_STRIDE_MASK           (0x00007FFF)
+#define PSB_2D_DST_STRIDE_CLRMASK        (0xFFFF8000)
+#define PSB_2D_DST_STRIDE_SHIFT          (0)
+/*
+ * WORD 1 - Base Address
+ */
+#define PSB_2D_DST_ADDR_MASK             (0x0FFFFFFC)
+#define PSB_2D_DST_ADDR_CLRMASK          (0x00000003)
+#define PSB_2D_DST_ADDR_SHIFT            (2)
+#define PSB_2D_DST_ADDR_ALIGNSHIFT       (2)
+
+/*
+ * Mask Surface (PSB_2D_MASK_SURF_BH)
+ */
+/*
+ * WORD 0
+ */
+#define PSB_2D_MASK_STRIDE_MASK          (0x00007FFF)
+#define PSB_2D_MASK_STRIDE_CLRMASK       (0xFFFF8000)
+#define PSB_2D_MASK_STRIDE_SHIFT         (0)
+/*
+ *  WORD 1 - Base Address
+ */
+#define PSB_2D_MASK_ADDR_MASK            (0x0FFFFFFC)
+#define PSB_2D_MASK_ADDR_CLRMASK         (0x00000003)
+#define PSB_2D_MASK_ADDR_SHIFT           (2)
+#define PSB_2D_MASK_ADDR_ALIGNSHIFT      (2)
+
+/*
+ * Source Palette (PSB_2D_SRC_PAL_BH)
+ */
+
+#define PSB_2D_SRCPAL_ADDR_SHIFT         (0)
+#define PSB_2D_SRCPAL_ADDR_CLRMASK       (0xF0000007)
+#define PSB_2D_SRCPAL_ADDR_MASK          (0x0FFFFFF8)
+#define PSB_2D_SRCPAL_BYTEALIGN          (1024)
+
+/*
+ * Pattern Palette (PSB_2D_PAT_PAL_BH)
+ */
+
+#define PSB_2D_PATPAL_ADDR_SHIFT         (0)
+#define PSB_2D_PATPAL_ADDR_CLRMASK       (0xF0000007)
+#define PSB_2D_PATPAL_ADDR_MASK          (0x0FFFFFF8)
+#define PSB_2D_PATPAL_BYTEALIGN          (1024)
+
+/*
+ * Rop3 Codes (2 LS bytes)
+ */
+
+#define PSB_2D_ROP3_SRCCOPY              (0xCCCC)
+#define PSB_2D_ROP3_PATCOPY              (0xF0F0)
+#define PSB_2D_ROP3_WHITENESS            (0xFFFF)
+#define PSB_2D_ROP3_BLACKNESS            (0x0000)
+#define PSB_2D_ROP3_SRC                  (0xCC)
+#define PSB_2D_ROP3_PAT                  (0xF0)
+#define PSB_2D_ROP3_DST                  (0xAA)
+
+
+/*
+ * Sizes.
+ */
+
+#define PSB_SCENE_HW_COOKIE_SIZE 16
+#define PSB_TA_MEM_HW_COOKIE_SIZE 16
+
+/*
+ * Scene stuff.
+ */
+
+#define PSB_NUM_HW_SCENES          2
+
+/*
+ * Scheduler completion actions.
+ */
+
+#define PSB_RASTER_BLOCK 0
+#define PSB_RASTER       1
+#define PSB_RETURN       2
+#define PSB_TA       3
+
+
+/*Power management*/
+#define PSB_PUNIT_PORT		    0x04
+#define PSB_OSPMBA		    0x78
+#define PSB_APMBA		    0x7a
+#define PSB_APM_CMD		    0x0
+#define PSB_PWRGT_VID_ENC_MASK	    0x30
+#define PSB_PWRGT_VID_DEC_MASK	    0xc
+#define PSB_PWRGT_VID_DEC_ON	    0x08
+#define PSB_PWRGT_VID_DEC_OFF	    0x04
+#define PSB_PWRGT_GFX_MASK	    0x3
+#define PSB_PWRGT_GFX_ON	    0x02
+#define PSB_PWRGT_GFX_OFF	    0x01
+#define PSB_APM_STS		    0x04
+#define PSB_PWRGT_GFX_D0	    0x0
+#define PSB_PWRGT_GFX_D3	    0x3
+#define PSB_PWRGT_VID_DEC_D0	    0x0
+#define PSB_PWRGT_VID_DEC_D3	    0x3
+
+
+#define PSB_PM_SSC		    0x20
+#define PSB_PM_SSS		    0x30
+#define PSB_PWRGT_DISPLAY_MASK	    0xc /*on a different BA than video/gfx*/
+#define MDFLD_PWRGT_DISPLAY_A_CNTR  0x0000000c 
+#define MDFLD_PWRGT_DISPLAY_B_CNTR  0x0000c000 
+#define MDFLD_PWRGT_DISPLAY_C_CNTR  0x00030000 
+#define MDFLD_PWRGT_DISP_MIPI_CNTR  0x000c0000 
+#define MDFLD_PWRGT_DISPLAY_CNTR    (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR)// 0x000fc00c
+// Display SSS register bits are different in A0 vs. B0
+#define MDFLD_PWRGT_DISPLAY_A_STS  		0x000000c0
+#define MDFLD_PWRGT_DISPLAY_B_STS  		0x00000300
+#define MDFLD_PWRGT_DISPLAY_C_STS  		0x00000c00
+#define PSB_PWRGT_GFX_MASK_B0	   		0xc3
+#define MDFLD_PWRGT_DISPLAY_A_STS_B0	0x0000000c
+#define MDFLD_PWRGT_DISPLAY_B_STS_B0  	0x0000c000
+#define MDFLD_PWRGT_DISPLAY_C_STS_B0  	0x00030000
+#define MDFLD_PWRGT_DISP_MIPI_STS  0x000c0000 
+#define MDFLD_PWRGT_DISPLAY_STS_A0    (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c
+#define MDFLD_PWRGT_DISPLAY_STS_B0    (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c
+#endif
diff --git a/drivers/staging/cdv/drv/psb_reset.c b/drivers/staging/cdv/drv/psb_reset.c
new file mode 100644
index 0000000..2f07be3
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_reset.c
@@ -0,0 +1,144 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ **************************************************************************/
+
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_reg.h"
+#include "psb_intel_reg.h"
+#include "psb_msvdx.h"
+#include <linux/spinlock.h>
+
+
+void psb_schedule_watchdog(struct drm_psb_private *dev_priv)
+{
+	struct timer_list *wt = &dev_priv->watchdog_timer;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
+	if (dev_priv->timer_available && !timer_pending(wt)) {
+		wt->expires = jiffies + PSB_WATCHDOG_DELAY;
+		add_timer(wt);
+	}
+	spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
+}
+
+
+static void psb_watchdog_func(unsigned long data)
+{
+	struct drm_psb_private *dev_priv = (struct drm_psb_private *) data;
+	int msvdx_lockup;
+	int msvdx_idle;
+	unsigned long irq_flags;
+
+	psb_msvdx_lockup(dev_priv, &msvdx_lockup, &msvdx_idle);
+
+	if (msvdx_lockup) {
+		spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
+		dev_priv->timer_available = 0;
+		spin_unlock_irqrestore(&dev_priv->watchdog_lock,
+				       irq_flags);
+		if (msvdx_lockup)
+			schedule_work(&dev_priv->msvdx_watchdog_wq);
+	}
+	if (!msvdx_idle)
+		psb_schedule_watchdog(dev_priv);
+}
+
+void psb_msvdx_flush_cmd_queue(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct psb_msvdx_cmd_queue *msvdx_cmd;
+	struct list_head *list, *next;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	/*Flush the msvdx cmd queue and signal all fences in the queue */
+	list_for_each_safe(list, next, &msvdx_priv->msvdx_queue) {
+		msvdx_cmd =
+		    list_entry(list, struct psb_msvdx_cmd_queue, head);
+		PSB_DEBUG_GENERAL("MSVDXQUE: flushing sequence:%d\n",
+				  msvdx_cmd->sequence);
+		msvdx_priv->msvdx_current_sequence = msvdx_cmd->sequence;
+		psb_fence_error(dev, PSB_ENGINE_VIDEO,
+				msvdx_priv->msvdx_current_sequence,
+				_PSB_FENCE_TYPE_EXE, DRM_CMD_HANG);
+		list_del(list);
+		kfree(msvdx_cmd->cmd);
+		kfree(msvdx_cmd
+			 );
+	}
+}
+
+static void psb_msvdx_reset_wq(struct work_struct *work)
+{
+	struct drm_psb_private *dev_priv =
+	    container_of(work, struct drm_psb_private, msvdx_watchdog_wq);
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	struct psb_scheduler *scheduler = &dev_priv->scheduler;
+	unsigned long irq_flags;
+
+	mutex_lock(&msvdx_priv->msvdx_mutex);
+	msvdx_priv->msvdx_needs_reset = 1;
+	msvdx_priv->msvdx_current_sequence++;
+	PSB_DEBUG_GENERAL
+	    ("MSVDXFENCE: incremented msvdx_current_sequence to :%d\n",
+	     msvdx_priv->msvdx_current_sequence);
+
+	psb_fence_error(scheduler->dev, PSB_ENGINE_VIDEO,
+			msvdx_priv->msvdx_current_sequence,
+			_PSB_FENCE_TYPE_EXE, DRM_CMD_HANG);
+
+	spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
+	dev_priv->timer_available = 1;
+	spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
+
+	spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
+	psb_msvdx_flush_cmd_queue(scheduler->dev);
+	spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+
+	psb_schedule_watchdog(dev_priv);
+	mutex_unlock(&msvdx_priv->msvdx_mutex);
+}
+
+void psb_watchdog_init(struct drm_psb_private *dev_priv)
+{
+	struct timer_list *wt = &dev_priv->watchdog_timer;
+	unsigned long irq_flags;
+
+	spin_lock_init(&dev_priv->watchdog_lock);
+	spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
+	init_timer(wt);
+	INIT_WORK(&dev_priv->msvdx_watchdog_wq, &psb_msvdx_reset_wq);
+	wt->data = (unsigned long) dev_priv;
+	wt->function = &psb_watchdog_func;
+	dev_priv->timer_available = 1;
+	spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
+}
+
+void psb_watchdog_takedown(struct drm_psb_private *dev_priv)
+{
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
+	dev_priv->timer_available = 0;
+	spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
+	(void) del_timer_sync(&dev_priv->watchdog_timer);
+}
+
+
diff --git a/drivers/staging/cdv/drv/psb_schedule.c b/drivers/staging/cdv/drv/psb_schedule.c
new file mode 100644
index 0000000..a8bf33b
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_schedule.c
@@ -0,0 +1,51 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
+ **************************************************************************/
+
+#include <drm/drmP.h>
+#include "psb_drm.h"
+#include "psb_drv.h"
+#include "psb_reg.h"
+#include "ttm/ttm_execbuf_util.h"
+
+
+static void psb_powerdown_msvdx(struct work_struct *work)
+{
+	struct psb_scheduler *scheduler =
+	    container_of(work, struct psb_scheduler, msvdx_suspend_wq.work);
+
+	if (!mutex_trylock(&scheduler->msvdx_power_mutex))
+		return;
+
+	psb_try_power_down_msvdx(scheduler->dev);
+	mutex_unlock(&scheduler->msvdx_power_mutex);
+}
+
+int psb_scheduler_init(struct drm_device *dev,
+		       struct psb_scheduler *scheduler)
+{
+	memset(scheduler, 0, sizeof(*scheduler));
+	scheduler->dev = dev;
+	mutex_init(&scheduler->msvdx_power_mutex);
+
+	INIT_DELAYED_WORK(&scheduler->msvdx_suspend_wq,
+			  &psb_powerdown_msvdx);
+
+	return 0;
+}
+
diff --git a/drivers/staging/cdv/drv/psb_schedule.h b/drivers/staging/cdv/drv/psb_schedule.h
new file mode 100644
index 0000000..7616abe
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_schedule.h
@@ -0,0 +1,79 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
+ **************************************************************************/
+#ifndef _PSB_SCHEDULE_H_
+#define _PSB_SCHEDULE_H_
+
+#include <drm/drmP.h>
+
+struct psb_context;
+
+enum psb_task_type {
+	psb_flip_task
+};
+
+struct drm_psb_private;
+
+/*struct psb_scheduler_seq {
+	uint32_t sequence;
+	int reported;
+};*/
+
+struct psb_scheduler {
+	struct drm_device *dev;
+	/*struct psb_scheduler_seq seq[_PSB_ENGINE_TA_FENCE_TYPES];
+	struct psb_hw_scene hs[PSB_NUM_HW_SCENES];
+	struct mutex task_wq_mutex;*/
+	struct mutex msvdx_power_mutex;
+	/*spinlock_t lock;
+	struct list_head hw_scenes;
+	struct list_head ta_queue;
+	struct list_head raster_queue;
+	struct list_head hp_raster_queue;
+	struct list_head task_done_queue;
+	struct psb_task *current_task[PSB_SCENE_NUM_ENGINES];
+	struct psb_task *feedback_task;
+	int ta_state;
+	struct psb_hw_scene *pending_hw_scene;
+	uint32_t pending_hw_scene_seq;
+	struct delayed_work wq*/;
+	struct delayed_work msvdx_suspend_wq;
+	/*struct psb_scene_pool *pool;
+	uint32_t idle_count;
+	int idle;
+	wait_queue_head_t idle_queue;
+	unsigned long ta_end_jiffies;
+	unsigned long total_ta_jiffies;
+	unsigned long raster_end_jiffies;
+	unsigned long total_raster_jiffies;*/
+};
+
+/*#define PSB_RF_FIRE_TA       (1 << 0)
+#define PSB_RF_OOM           (1 << 1)
+#define PSB_RF_OOM_REPLY     (1 << 2)
+#define PSB_RF_TERMINATE     (1 << 3)
+#define PSB_RF_TA_DONE       (1 << 4)
+#define PSB_RF_FIRE_RASTER   (1 << 5)
+#define PSB_RF_RASTER_DONE   (1 << 6)
+#define PSB_RF_DEALLOC       (1 << 7)
+*/
+
+extern int psb_scheduler_init(struct drm_device *dev,
+			      struct psb_scheduler *scheduler);
+
+#endif
diff --git a/drivers/staging/cdv/drv/psb_sgx.c b/drivers/staging/cdv/drv/psb_sgx.c
new file mode 100644
index 0000000..104fe4b
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_sgx.c
@@ -0,0 +1,943 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * All Rights Reserved.
+ * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX. USA.
+ * 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 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.
+ *
+ **************************************************************************/
+
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_drm.h"
+#include "psb_reg.h"
+#include "psb_msvdx.h"
+#include "ttm/ttm_bo_api.h"
+#include "ttm/ttm_execbuf_util.h"
+#include "psb_ttm_userobj_api.h"
+#include "ttm/ttm_placement.h"
+#include "psb_sgx.h"
+#include "psb_intel_reg.h"
+#include "psb_powermgmt.h"
+
+
+static inline int psb_same_page(unsigned long offset,
+				unsigned long offset2)
+{
+	return (offset & PAGE_MASK) == (offset2 & PAGE_MASK);
+}
+
+static inline unsigned long psb_offset_end(unsigned long offset,
+					      unsigned long end)
+{
+	offset = (offset + PAGE_SIZE) & PAGE_MASK;
+	return (end < offset) ? end : offset;
+}
+
+static void psb_idle_engine(struct drm_device *dev, int engine);
+
+struct psb_dstbuf_cache {
+	unsigned int dst;
+	struct ttm_buffer_object *dst_buf;
+	unsigned long dst_offset;
+	uint32_t *dst_page;
+	unsigned int dst_page_offset;
+	struct ttm_bo_kmap_obj dst_kmap;
+	bool dst_is_iomem;
+};
+
+struct psb_validate_buffer {
+	struct ttm_validate_buffer base;
+	struct psb_validate_req req;
+	int ret;
+	struct psb_validate_arg __user *user_val_arg;
+	uint32_t flags;
+	uint32_t offset;
+	int po_correct;
+};
+
+static int psb_check_presumed(struct psb_validate_req *req,
+			      struct ttm_buffer_object *bo,
+			      struct psb_validate_arg __user *data,
+			      int *presumed_ok)
+{
+	struct psb_validate_req __user *user_req = &(data->d.req);
+
+	*presumed_ok = 0;
+
+	if (bo->mem.mem_type == TTM_PL_SYSTEM) {
+		*presumed_ok = 1;
+		return 0;
+	}
+
+	if (unlikely(!(req->presumed_flags & PSB_USE_PRESUMED)))
+		return 0;
+
+	if (bo->offset == req->presumed_gpu_offset) {
+		*presumed_ok = 1;
+		return 0;
+	}
+
+	return __put_user(req->presumed_flags & ~PSB_USE_PRESUMED,
+			  &user_req->presumed_flags);
+}
+
+
+static void psb_unreference_buffers(struct psb_context *context)
+{
+	struct ttm_validate_buffer *entry, *next;
+	struct list_head *list = &context->validate_list;
+
+	list_for_each_entry_safe(entry, next, list, head) {
+		list_del(&entry->head);
+		ttm_bo_unref(&entry->bo);
+	}
+
+	list = &context->kern_validate_list;
+
+	list_for_each_entry_safe(entry, next, list, head) {
+		list_del(&entry->head);
+		ttm_bo_unref(&entry->bo);
+	}
+}
+
+
+static int psb_lookup_validate_buffer(struct drm_file *file_priv,
+				      uint64_t data,
+				      struct psb_validate_buffer *item)
+{
+	struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
+
+	item->user_val_arg =
+	    (struct psb_validate_arg __user *) (unsigned long) data;
+
+	if (unlikely(copy_from_user(&item->req, &item->user_val_arg->d.req,
+				    sizeof(item->req)) != 0)) {
+		DRM_ERROR("Lookup copy fault.\n");
+		return -EFAULT;
+	}
+
+	item->base.bo =
+	    ttm_buffer_object_lookup(tfile, item->req.buffer_handle);
+
+	if (unlikely(item->base.bo == NULL)) {
+		DRM_ERROR("Bo lookup fault.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int psb_reference_buffers(struct drm_file *file_priv,
+				 uint64_t data,
+				 struct psb_context *context)
+{
+	struct psb_validate_buffer *item;
+	int ret;
+
+	while (likely(data != 0)) {
+		if (unlikely(context->used_buffers >=
+			     PSB_NUM_VALIDATE_BUFFERS)) {
+			DRM_ERROR("Too many buffers "
+				  "on validate list.\n");
+			ret = -EINVAL;
+			goto out_err0;
+		}
+
+		item = &context->buffers[context->used_buffers];
+
+		ret = psb_lookup_validate_buffer(file_priv, data, item);
+		if (unlikely(ret != 0))
+			goto out_err0;
+
+		item->base.reserved = 0;
+		list_add_tail(&item->base.head, &context->validate_list);
+		context->used_buffers++;
+		data = item->req.next;
+	}
+	return 0;
+
+out_err0:
+	psb_unreference_buffers(context);
+	return ret;
+}
+
+static int
+psb_placement_fence_type(struct ttm_buffer_object *bo,
+			 uint64_t set_val_flags,
+			 uint64_t clr_val_flags,
+			 uint32_t new_fence_class,
+			 uint32_t *new_fence_type)
+{
+	int ret;
+	uint32_t n_fence_type;
+	/*
+	uint32_t set_flags = set_val_flags & 0xFFFFFFFF;
+	uint32_t clr_flags = clr_val_flags & 0xFFFFFFFF;
+	*/
+	struct ttm_fence_object *old_fence;
+	uint32_t old_fence_type;
+	struct ttm_placement placement;
+
+	if (unlikely
+	    (!(set_val_flags &
+	       (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)))) {
+		DRM_ERROR
+		    ("GPU access type (read / write) is not indicated.\n");
+		return -EINVAL;
+	}
+
+	/* User space driver doesn't set any TTM placement flags in set_val_flags or clr_val_flags */
+	placement.num_placement = 0;/* FIXME  */
+	placement.num_busy_placement = 0;
+	placement.fpfn = 0;
+        placement.lpfn = 0;
+	ret = psb_ttm_bo_check_placement(bo, &placement);
+	if (unlikely(ret != 0))
+		return ret;
+
+	switch (new_fence_class) {
+	default:
+		n_fence_type = _PSB_FENCE_TYPE_EXE;
+	}
+
+	*new_fence_type = n_fence_type;
+	old_fence = (struct ttm_fence_object *) bo->sync_obj;
+	old_fence_type = (uint32_t) (unsigned long) bo->sync_obj_arg;
+
+	if (old_fence && ((new_fence_class != old_fence->fence_class) ||
+			  ((n_fence_type ^ old_fence_type) &
+			   old_fence_type))) {
+		ret = ttm_bo_wait(bo, 0, 1, 0);
+		if (unlikely(ret != 0))
+			return ret;
+	}
+	/*
+	bo->proposed_flags = (bo->proposed_flags | set_flags)
+		& ~clr_flags & TTM_PL_MASK_MEMTYPE;
+	*/
+	return 0;
+}
+
+int psb_validate_kernel_buffer(struct psb_context *context,
+			       struct ttm_buffer_object *bo,
+			       uint32_t fence_class,
+			       uint64_t set_flags, uint64_t clr_flags)
+{
+	struct psb_validate_buffer *item;
+	uint32_t cur_fence_type;
+	int ret;
+
+	if (unlikely(context->used_buffers >= PSB_NUM_VALIDATE_BUFFERS)) {
+		DRM_ERROR("Out of free validation buffer entries for "
+			  "kernel buffer validation.\n");
+		return -ENOMEM;
+	}
+
+	item = &context->buffers[context->used_buffers];
+	item->user_val_arg = NULL;
+	item->base.reserved = 0;
+
+	ret = ttm_bo_reserve(bo, 1, 0, 1, context->val_seq);
+	if (unlikely(ret != 0))
+		goto out_unlock;
+
+	spin_lock(&bo->bdev->fence_lock);
+	ret = psb_placement_fence_type(bo, set_flags, clr_flags, fence_class,
+				       &cur_fence_type);
+	if (unlikely(ret != 0)) {
+		ttm_bo_unreserve(bo);
+		goto out_unlock;
+	}
+
+	item->base.bo = ttm_bo_reference(bo);
+	item->base.new_sync_obj_arg = (void *) (unsigned long) cur_fence_type;
+	item->base.reserved = 1;
+
+	list_add_tail(&item->base.head, &context->kern_validate_list);
+	context->used_buffers++;
+	/*
+	ret = ttm_bo_validate(bo, 1, 0, 0);
+	if (unlikely(ret != 0))
+		goto out_unlock;
+	*/
+	item->offset = bo->offset;
+	item->flags = bo->mem.placement;
+	context->fence_types |= cur_fence_type;
+
+out_unlock:
+	spin_unlock(&bo->bdev->fence_lock);
+	return ret;
+}
+
+
+static int psb_validate_buffer_list(struct drm_file *file_priv,
+				    uint32_t fence_class,
+				    struct psb_context *context,
+				    int *po_correct)
+{
+	struct psb_validate_buffer *item;
+	struct ttm_buffer_object *bo;
+	int ret;
+	struct psb_validate_req *req;
+	uint32_t fence_types = 0;
+	uint32_t cur_fence_type;
+	struct ttm_validate_buffer *entry;
+	struct list_head *list = &context->validate_list;
+	/*
+	struct ttm_placement placement;
+	uint32_t flags;
+	*/
+
+	*po_correct = 1;
+
+	list_for_each_entry(entry, list, head) {
+		item =
+		    container_of(entry, struct psb_validate_buffer, base);
+		bo = entry->bo;
+		item->ret = 0;
+		req = &item->req;
+
+		spin_lock(&bo->bdev->fence_lock);
+		ret = psb_placement_fence_type(bo,
+					       req->set_flags,
+					       req->clear_flags,
+					       fence_class,
+					       &cur_fence_type);
+		if (unlikely(ret != 0))
+			goto out_err;
+
+		/*
+                flags = item->req.pad64 | TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
+                placement.num_placement = 1;
+                placement.placement = &flags;
+                placement.num_busy_placement = 0;
+                placement.fpfn = 0;
+                placement.lpfn = 0;
+                ret = ttm_bo_validate(bo, &placement, 1, 0, 0);
+		if (unlikely(ret != 0))
+			goto out_err;
+		*/
+		fence_types |= cur_fence_type;
+		entry->new_sync_obj_arg = (void *)
+			(unsigned long) cur_fence_type;
+
+		item->offset = bo->offset;
+		item->flags = bo->mem.placement;
+		spin_unlock(&bo->bdev->fence_lock);
+
+		ret =
+		    psb_check_presumed(&item->req, bo, item->user_val_arg,
+				       &item->po_correct);
+		if (unlikely(ret != 0))
+			goto out_err;
+
+		if (unlikely(!item->po_correct))
+			*po_correct = 0;
+
+		item++;
+	}
+
+	context->fence_types |= fence_types;
+
+	return 0;
+out_err:
+	spin_unlock(&bo->bdev->fence_lock);
+	item->ret = ret;
+	return ret;
+}
+
+static void psb_clear_dstbuf_cache(struct psb_dstbuf_cache *dst_cache)
+{
+	if (dst_cache->dst_page) {
+		ttm_bo_kunmap(&dst_cache->dst_kmap);
+		dst_cache->dst_page = NULL;
+	}
+	dst_cache->dst_buf = NULL;
+	dst_cache->dst = ~0;
+}
+
+static int psb_update_dstbuf_cache(struct psb_dstbuf_cache *dst_cache,
+				   struct psb_validate_buffer *buffers,
+				   unsigned int dst,
+				   unsigned long dst_offset)
+{
+	int ret;
+
+	PSB_DEBUG_GENERAL("Destination buffer is %d.\n", dst);
+
+	if (unlikely(dst != dst_cache->dst || NULL == dst_cache->dst_buf)) {
+		psb_clear_dstbuf_cache(dst_cache);
+		dst_cache->dst = dst;
+		dst_cache->dst_buf = buffers[dst].base.bo;
+	}
+
+	if (unlikely
+	    (dst_offset >= dst_cache->dst_buf->num_pages * PAGE_SIZE)) {
+		DRM_ERROR("Relocation destination out of bounds.\n");
+		return -EINVAL;
+	}
+
+	if (!psb_same_page(dst_cache->dst_offset, dst_offset) ||
+	    NULL == dst_cache->dst_page) {
+		if (NULL != dst_cache->dst_page) {
+			ttm_bo_kunmap(&dst_cache->dst_kmap);
+			dst_cache->dst_page = NULL;
+		}
+
+		ret =
+		    ttm_bo_kmap(dst_cache->dst_buf,
+				dst_offset >> PAGE_SHIFT, 1,
+				&dst_cache->dst_kmap);
+		if (ret) {
+			DRM_ERROR("Could not map destination buffer for "
+				  "relocation.\n");
+			return ret;
+		}
+
+		dst_cache->dst_page =
+		    ttm_kmap_obj_virtual(&dst_cache->dst_kmap,
+					 &dst_cache->dst_is_iomem);
+		dst_cache->dst_offset = dst_offset & PAGE_MASK;
+		dst_cache->dst_page_offset = dst_cache->dst_offset >> 2;
+	}
+	return 0;
+}
+
+static int psb_apply_reloc(struct drm_psb_private *dev_priv,
+			   uint32_t fence_class,
+			   const struct drm_psb_reloc *reloc,
+			   struct psb_validate_buffer *buffers,
+			   int num_buffers,
+			   struct psb_dstbuf_cache *dst_cache,
+			   int no_wait, int interruptible)
+{
+	uint32_t val;
+	uint32_t background;
+	unsigned int index;
+	int ret;
+	unsigned int shift;
+	unsigned int align_shift;
+	struct ttm_buffer_object *reloc_bo;
+
+
+	PSB_DEBUG_GENERAL("Reloc type %d\n"
+			  "\t where 0x%04x\n"
+			  "\t buffer 0x%04x\n"
+			  "\t mask 0x%08x\n"
+			  "\t shift 0x%08x\n"
+			  "\t pre_add 0x%08x\n"
+			  "\t background 0x%08x\n"
+			  "\t dst_buffer 0x%08x\n"
+			  "\t arg0 0x%08x\n"
+			  "\t arg1 0x%08x\n",
+			  reloc->reloc_op,
+			  reloc->where,
+			  reloc->buffer,
+			  reloc->mask,
+			  reloc->shift,
+			  reloc->pre_add,
+			  reloc->background,
+			  reloc->dst_buffer, reloc->arg0, reloc->arg1);
+
+	if (unlikely(reloc->buffer >= num_buffers)) {
+		DRM_ERROR("Illegal relocation buffer %d.\n",
+			  reloc->buffer);
+		return -EINVAL;
+	}
+
+	if (buffers[reloc->buffer].po_correct)
+		return 0;
+
+	if (unlikely(reloc->dst_buffer >= num_buffers)) {
+		DRM_ERROR
+		    ("Illegal destination buffer for relocation %d.\n",
+		     reloc->dst_buffer);
+		return -EINVAL;
+	}
+
+	ret =
+	    psb_update_dstbuf_cache(dst_cache, buffers, reloc->dst_buffer,
+				    reloc->where << 2);
+	if (ret)
+		return ret;
+
+	reloc_bo = buffers[reloc->buffer].base.bo;
+
+	if (unlikely(reloc->pre_add >= (reloc_bo->num_pages << PAGE_SHIFT))) {
+		DRM_ERROR("Illegal relocation offset add.\n");
+		return -EINVAL;
+	}
+
+	switch (reloc->reloc_op) {
+	case PSB_RELOC_OP_OFFSET:
+		val = reloc_bo->offset + reloc->pre_add;
+		break;
+	default:
+		DRM_ERROR("Unimplemented relocation.\n");
+		return -EINVAL;
+	}
+
+	shift =
+	    (reloc->shift & PSB_RELOC_SHIFT_MASK) >> PSB_RELOC_SHIFT_SHIFT;
+	align_shift =
+	    (reloc->
+	     shift & PSB_RELOC_ALSHIFT_MASK) >> PSB_RELOC_ALSHIFT_SHIFT;
+
+	val = ((val >> align_shift) << shift);
+	index = reloc->where - dst_cache->dst_page_offset;
+
+	background = reloc->background;
+	val = (background & ~reloc->mask) | (val & reloc->mask);
+	dst_cache->dst_page[index] = val;
+
+	PSB_DEBUG_GENERAL("Reloc buffer %d index 0x%08x, value 0x%08x\n",
+			  reloc->dst_buffer, index,
+			  dst_cache->dst_page[index]);
+
+	return 0;
+}
+
+static int psb_ok_to_map_reloc(struct drm_psb_private *dev_priv,
+			       unsigned int num_pages)
+{
+	int ret = 0;
+
+	spin_lock(&dev_priv->reloc_lock);
+	if (dev_priv->rel_mapped_pages + num_pages <= PSB_MAX_RELOC_PAGES) {
+		dev_priv->rel_mapped_pages += num_pages;
+		ret = 1;
+	}
+	spin_unlock(&dev_priv->reloc_lock);
+	return ret;
+}
+
+static int psb_fixup_relocs(struct drm_file *file_priv,
+			    uint32_t fence_class,
+			    unsigned int num_relocs,
+			    unsigned int reloc_offset,
+			    uint32_t reloc_handle,
+			    struct psb_context *context,
+			    int no_wait, int interruptible)
+{
+	struct drm_device *dev = file_priv->minor->dev;
+	struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) dev->dev_private;
+	struct ttm_buffer_object *reloc_buffer = NULL;
+	unsigned int reloc_num_pages;
+	unsigned int reloc_first_page;
+	unsigned int reloc_last_page;
+	struct psb_dstbuf_cache dst_cache;
+	struct drm_psb_reloc *reloc;
+	struct ttm_bo_kmap_obj reloc_kmap;
+	bool reloc_is_iomem;
+	int count;
+	int ret = 0;
+	int registered = 0;
+	uint32_t num_buffers = context->used_buffers;
+
+	if (num_relocs == 0)
+		return 0;
+
+	memset(&dst_cache, 0, sizeof(dst_cache));
+	memset(&reloc_kmap, 0, sizeof(reloc_kmap));
+
+	reloc_buffer = ttm_buffer_object_lookup(tfile, reloc_handle);
+	if (!reloc_buffer)
+		goto out;
+
+	if (unlikely(atomic_read(&reloc_buffer->reserved) != 1)) {
+		DRM_ERROR("Relocation buffer was not on validate list.\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	reloc_first_page = reloc_offset >> PAGE_SHIFT;
+	reloc_last_page =
+	    (reloc_offset +
+	     num_relocs * sizeof(struct drm_psb_reloc)) >> PAGE_SHIFT;
+	reloc_num_pages = reloc_last_page - reloc_first_page + 1;
+	reloc_offset &= ~PAGE_MASK;
+
+	if (reloc_num_pages > PSB_MAX_RELOC_PAGES) {
+		DRM_ERROR("Relocation buffer is too large\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	DRM_WAIT_ON(ret, dev_priv->rel_mapped_queue, 3 * DRM_HZ,
+		    (registered =
+		     psb_ok_to_map_reloc(dev_priv, reloc_num_pages)));
+
+	if (ret == -EINTR) {
+		ret = -ERESTART;
+		goto out;
+	}
+	if (ret) {
+		DRM_ERROR("Error waiting for space to map "
+			  "relocation buffer.\n");
+		goto out;
+	}
+
+	ret = ttm_bo_kmap(reloc_buffer, reloc_first_page,
+			  reloc_num_pages, &reloc_kmap);
+
+	if (ret) {
+		DRM_ERROR("Could not map relocation buffer.\n"
+			  "\tReloc buffer id 0x%08x.\n"
+			  "\tReloc first page %d.\n"
+			  "\tReloc num pages %d.\n",
+			  reloc_handle, reloc_first_page, reloc_num_pages);
+		goto out;
+	}
+
+	reloc = (struct drm_psb_reloc *)
+	    ((unsigned long)
+	     ttm_kmap_obj_virtual(&reloc_kmap,
+				  &reloc_is_iomem) + reloc_offset);
+
+	for (count = 0; count < num_relocs; ++count) {
+		ret = psb_apply_reloc(dev_priv, fence_class,
+				      reloc, context->buffers,
+				      num_buffers, &dst_cache,
+				      no_wait, interruptible);
+		if (ret)
+			goto out1;
+		reloc++;
+	}
+
+out1:
+	ttm_bo_kunmap(&reloc_kmap);
+out:
+	if (registered) {
+		spin_lock(&dev_priv->reloc_lock);
+		dev_priv->rel_mapped_pages -= reloc_num_pages;
+		spin_unlock(&dev_priv->reloc_lock);
+		DRM_WAKEUP(&dev_priv->rel_mapped_queue);
+	}
+
+	psb_clear_dstbuf_cache(&dst_cache);
+	if (reloc_buffer)
+		ttm_bo_unref(&reloc_buffer);
+	return ret;
+}
+
+void psb_fence_or_sync(struct drm_file *file_priv,
+		       uint32_t engine,
+		       uint32_t fence_types,
+		       uint32_t fence_flags,
+		       struct list_head *list,
+		       struct psb_ttm_fence_rep *fence_arg,
+		       struct ttm_fence_object **fence_p)
+{
+	struct drm_device *dev = file_priv->minor->dev;
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct ttm_fence_device *fdev = &dev_priv->fdev;
+	int ret;
+	struct ttm_fence_object *fence;
+	struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
+	uint32_t handle;
+
+	ret = ttm_fence_user_create(fdev, tfile,
+				    engine, fence_types,
+				    TTM_FENCE_FLAG_EMIT, &fence, &handle);
+	if (ret) {
+
+		/*
+		 * Fence creation failed.
+		 * Fall back to synchronous operation and idle the engine.
+		 */
+
+		psb_idle_engine(dev, engine);
+		if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) {
+
+			/*
+			 * Communicate to user-space that
+			 * fence creation has failed and that
+			 * the engine is idle.
+			 */
+
+			fence_arg->handle = ~0;
+			fence_arg->error = ret;
+		}
+
+		ttm_eu_backoff_reservation(list);
+		if (fence_p)
+			*fence_p = NULL;
+		return;
+	}
+
+	ttm_eu_fence_buffer_objects(list, fence);
+	if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) {
+		struct ttm_fence_info info = ttm_fence_get_info(fence);
+		fence_arg->handle = handle;
+		fence_arg->fence_class = ttm_fence_class(fence);
+		fence_arg->fence_type = ttm_fence_types(fence);
+		fence_arg->signaled_types = info.signaled_types;
+		fence_arg->error = 0;
+	} else {
+		ret =
+		    ttm_ref_object_base_unref(tfile, handle,
+					      ttm_fence_type);
+		BUG_ON(ret);
+	}
+
+	if (fence_p)
+		*fence_p = fence;
+	else if (fence)
+		ttm_fence_object_unref(&fence);
+}
+
+
+#if 0
+static int psb_dump_page(struct ttm_buffer_object *bo,
+			 unsigned int page_offset, unsigned int num)
+{
+	struct ttm_bo_kmap_obj kmobj;
+	int is_iomem;
+	uint32_t *p;
+	int ret;
+	unsigned int i;
+
+	ret = ttm_bo_kmap(bo, page_offset, 1, &kmobj);
+	if (ret)
+		return ret;
+
+	p = ttm_kmap_obj_virtual(&kmobj, &is_iomem);
+	for (i = 0; i < num; ++i)
+		PSB_DEBUG_GENERAL("0x%04x: 0x%08x\n", i, *p++);
+
+	ttm_bo_kunmap(&kmobj);
+	return 0;
+}
+#endif
+
+static void psb_idle_engine(struct drm_device *dev, int engine)
+{
+	/*Fix me add video engile support*/
+	return;
+}
+
+static int psb_handle_copyback(struct drm_device *dev,
+			       struct psb_context *context,
+			       int ret)
+{
+	int err = ret;
+	struct ttm_validate_buffer *entry;
+	struct psb_validate_arg arg;
+	struct list_head *list = &context->validate_list;
+
+	if (ret) {
+		ttm_eu_backoff_reservation(list);
+		ttm_eu_backoff_reservation(&context->kern_validate_list);
+	}
+
+
+	if (ret != -EAGAIN && ret != -EINTR && ret != -ERESTART) {
+		list_for_each_entry(entry, list, head) {
+			struct psb_validate_buffer *vbuf =
+			    container_of(entry, struct psb_validate_buffer,
+					 base);
+			arg.handled = 1;
+			arg.ret = vbuf->ret;
+			if (!arg.ret) {
+				struct ttm_buffer_object *bo = entry->bo;
+				spin_lock(&bo->bdev->fence_lock);
+				arg.d.rep.gpu_offset = bo->offset;
+				arg.d.rep.placement = bo->mem.placement;
+				arg.d.rep.fence_type_mask =
+					(uint32_t) (unsigned long)
+					entry->new_sync_obj_arg;
+				spin_unlock(&bo->bdev->fence_lock);
+			}
+
+			if (__copy_to_user(vbuf->user_val_arg,
+					   &arg, sizeof(arg)))
+				err = -EFAULT;
+
+			if (arg.ret)
+				break;
+		}
+	}
+
+	return err;
+}
+
+int psb_cmdbuf_ioctl(struct drm_device *dev, void *data,
+		     struct drm_file *file_priv)
+{
+	struct drm_psb_cmdbuf_arg *arg = data;
+	int ret = 0;
+	struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
+	struct ttm_buffer_object *cmd_buffer = NULL;
+	struct psb_ttm_fence_rep fence_arg;
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *)file_priv->minor->dev->dev_private;
+	struct psb_video_ctx *pos, *n;
+	int engine;
+	int po_correct;
+	struct psb_context *context;
+
+	((struct msvdx_private*)dev_priv->msvdx_private)->tfile = tfile;
+
+	ret = ttm_read_lock(&dev_priv->ttm_lock, true);
+	if (unlikely(ret != 0))
+		return ret;
+
+	if (arg->engine == PSB_ENGINE_VIDEO) {
+		if (!ospm_power_using_hw_begin(OSPM_VIDEO_DEC_ISLAND,
+						OSPM_UHB_FORCE_POWER_ON))
+			return -EBUSY;
+	} 
+
+	ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
+	if (unlikely(ret != 0))
+		goto out_err0;
+
+
+	context = &dev_priv->context;
+	context->used_buffers = 0;
+	context->fence_types = 0;
+	BUG_ON(!list_empty(&context->validate_list));
+	BUG_ON(!list_empty(&context->kern_validate_list));
+
+	if (unlikely(context->buffers == NULL)) {
+		context->buffers = vmalloc(PSB_NUM_VALIDATE_BUFFERS *
+					   sizeof(*context->buffers));
+		if (unlikely(context->buffers == NULL)) {
+			ret = -ENOMEM;
+			goto out_err1;
+		}
+	}
+
+	ret = psb_reference_buffers(file_priv,
+				    arg->buffer_list,
+				    context);
+
+	if (unlikely(ret != 0))
+		goto out_err1;
+
+	context->val_seq = atomic_add_return(1, &dev_priv->val_seq);
+
+/*
+	ret = ttm_eu_reserve_buffers(&context->validate_list,
+				     context->val_seq);
+*/
+	/* XXX new TTM removed driver managed sequence number,
+	 * check if this has other side effects! */
+	ret = ttm_eu_reserve_buffers(&context->validate_list);
+
+	if (unlikely(ret != 0))
+		goto out_err2;
+
+	engine = arg->engine;
+	ret = psb_validate_buffer_list(file_priv, engine,
+				       context, &po_correct);
+	if (unlikely(ret != 0))
+		goto out_err3;
+
+	if (!po_correct) {
+		ret = psb_fixup_relocs(file_priv, engine, arg->num_relocs,
+				       arg->reloc_offset,
+				       arg->reloc_handle, context, 0, 1);
+		if (unlikely(ret != 0))
+			goto out_err3;
+
+	}
+
+	cmd_buffer = ttm_buffer_object_lookup(tfile, arg->cmdbuf_handle);
+	if (unlikely(cmd_buffer == NULL)) {
+		ret = -EINVAL;
+		goto out_err4;
+	}
+
+	list_for_each_entry_safe(pos, n, &dev_priv->video_ctx, head) {
+		if (pos->filp == file_priv->filp) {
+			int entrypoint = pos->ctx_type & 0xff;
+
+			PSB_DEBUG_GENERAL("Video:commands for profile %d, entrypoint %d",
+					(pos->ctx_type >> 8), (pos->ctx_type & 0xff));
+
+			if (entrypoint != VAEntrypointEncSlice &&
+			    entrypoint != VAEntrypointEncPicture)
+				dev_priv->msvdx_ctx = pos;
+
+			break;
+		}
+	}
+
+	switch (arg->engine) {
+	case PSB_ENGINE_VIDEO:
+		if (arg->cmdbuf_size == (16 + 32)) {
+			/* Identify deblock msg cmdbuf */
+			/* according to cmdbuf_size */
+			struct ttm_bo_kmap_obj cmd_kmap;
+			struct ttm_buffer_object *deblock;
+			uint32_t *cmd;
+			bool is_iomem;
+
+			/* write regIO BO's address after deblcok msg */
+			ret = ttm_bo_kmap(cmd_buffer, 0, 1, &cmd_kmap);
+			if (unlikely(ret != 0))
+				goto out_err4;
+			cmd = (uint32_t *)(ttm_kmap_obj_virtual(&cmd_kmap,
+							&is_iomem) + 16);
+			deblock = ttm_buffer_object_lookup(tfile,
+							   (uint32_t)(*cmd));
+			*cmd = (uint32_t)deblock;
+			ttm_bo_unref(&deblock); /* FIXME Should move this to interrupt handler? */
+			ttm_bo_kunmap(&cmd_kmap);
+		}
+
+		ret = psb_cmdbuf_video(file_priv, &context->validate_list,
+				       context->fence_types, arg,
+				       cmd_buffer, &fence_arg);
+
+		if (unlikely(ret != 0))
+			goto out_err4;
+		break;
+	default:
+		DRM_ERROR
+		    ("Unimplemented command submission mechanism (%x).\n",
+		     arg->engine);
+		ret = -EINVAL;
+		goto out_err4;
+	}
+
+	if (!(arg->fence_flags & DRM_PSB_FENCE_NO_USER)) {
+		ret = copy_to_user((void __user *)
+				   ((unsigned long) arg->fence_arg),
+				   &fence_arg, sizeof(fence_arg));
+	}
+
+out_err4:
+	if (cmd_buffer)
+		ttm_bo_unref(&cmd_buffer);
+out_err3:
+	ret = psb_handle_copyback(dev, context, ret);
+out_err2:
+	psb_unreference_buffers(context);
+out_err1:
+	mutex_unlock(&dev_priv->cmdbuf_mutex);
+out_err0:
+	ttm_read_unlock(&dev_priv->ttm_lock);
+
+	if (arg->engine == PSB_ENGINE_VIDEO)
+		ospm_power_using_hw_end(OSPM_VIDEO_DEC_ISLAND);
+
+	return ret;
+}
+
diff --git a/drivers/staging/cdv/drv/psb_sgx.h b/drivers/staging/cdv/drv/psb_sgx.h
new file mode 100644
index 0000000..e83ca94
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_sgx.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011, Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ **/
+#ifndef _PSB_SGX_H_
+#define _PSB_SGX_H_
+
+extern int psb_submit_video_cmdbuf(struct drm_device *dev,
+			       struct ttm_buffer_object *cmd_buffer,
+			       unsigned long cmd_offset,
+			       unsigned long cmd_size,
+			       struct ttm_fence_object *fence);
+
+extern int drm_idle_check_interval;
+
+#endif
diff --git a/drivers/staging/cdv/drv/psb_socket.c b/drivers/staging/cdv/drv/psb_socket.c
new file mode 100644
index 0000000..7cc9a7b
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_socket.c
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ * Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004 Novell, Inc.  All rights reserved.
+ * Copyright (C) 2004 IBM, Inc. All rights reserved.
+ * Copyright (C) 2011 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the GNU GPL v2.
+ *
+ * Authors:
+ *	Robert Love		<rml@novell.com>
+ *	Kay Sievers		<kay.sievers@vrfy.org>
+ *	Arjan van de Ven	<arjanv@redhat.com>
+ *	Greg Kroah-Hartman	<greg@kroah.com>
+ *
+ * Notes:
+ *      Adapted from existing kobj event socket code to enable
+ *      mutlicast usermode communication for gfx driver to mutiple
+ *      usermode threads via different socket broadcast groups.
+ *      Original kobject uevent code does not allow for different
+ *      broadcast groups.  Due to the frequency of usermode events
+ *      generated by some gfx subsystems it is necessary to open
+ *      a new dedicated socket with multicast group support.  In
+ *      the future it is hoped that this code can be removed
+ *      and either a new netlink protocol type added for graphics
+ *      or conversely to simply enable group routing to be leveraged
+ *      on the existing kobject uevent infrastructure.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <net/sock.h>
+#include "psb_umevents.h"
+
+#define NETLINK_PSB_KOBJECT_UEVENT	31
+
+u64 psb_uevent_seqnum;
+char psb_uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
+static DEFINE_SPINLOCK(sequence_lock);
+#if defined(CONFIG_NET)
+static struct sock *uevent_sock;
+#endif
+
+/* the strings here must match the enum in include/linux/kobject.h */
+static const char *psb_kobject_actions[] = {
+	[KOBJ_ADD] =		"add",
+	[KOBJ_REMOVE] =		"remove",
+	[KOBJ_CHANGE] =		"change",
+	[KOBJ_MOVE] =		"move",
+	[KOBJ_ONLINE] =		"online",
+	[KOBJ_OFFLINE] =	"offline",
+};
+
+/**
+ * kobject_action_type - translate action string to numeric type
+ *
+ * @buf: buffer containing the action string, newline is ignored
+ * @len: length of buffer
+ * @type: pointer to the location to store the action type
+ *
+ * Returns 0 if the action string was recognized.
+ */
+int psb_kobject_action_type(const char *buf, size_t count,
+			enum kobject_action *type)
+{
+	enum kobject_action action;
+	int ret = -EINVAL;
+
+	if (count && (buf[count-1] == '\n' || buf[count-1] == '\0'))
+		count--;
+
+	if (!count)
+		goto out;
+
+	for (action = 0; action < ARRAY_SIZE(psb_kobject_actions); action++) {
+		if (strncmp(psb_kobject_actions[action], buf, count) != 0)
+			continue;
+		if (psb_kobject_actions[action][count] != '\0')
+			continue;
+		*type = action;
+		ret = 0;
+		break;
+	}
+out:
+	return ret;
+}
+
+/**
+ * psb_kobject_uevent_env - send an uevent with environmental data
+ *
+ * @action: action that is happening
+ * @kobj: struct kobject that the action is happening to
+ * @envp_ext: pointer to environmental data
+ *
+ * Returns 0 if kobject_uevent() is completed with success or the
+ * corresponding error when it fails.
+ */
+int psb_kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
+			   char *envp_ext[], int dst_group_id)
+{
+	struct kobj_uevent_env *env;
+	const char *action_string = psb_kobject_actions[action];
+	const char *devpath = NULL;
+	const char *subsystem;
+	struct kobject *top_kobj;
+	struct kset *kset;
+	struct kset_uevent_ops *uevent_ops;
+	u64 seq;
+	int i = 0;
+	int retval = 0;
+
+	pr_debug("kobject: '%s' (%p): %s\n",
+		 kobject_name(kobj), kobj, __func__);
+
+	/* search the kset we belong to */
+	top_kobj = kobj;
+	while (!top_kobj->kset && top_kobj->parent)
+		top_kobj = top_kobj->parent;
+
+	if (!top_kobj->kset) {
+		pr_debug("kobject: '%s' (%p): %s: attempted to send uevent "
+			 "without kset!\n", kobject_name(kobj), kobj,
+			 __func__);
+		return -EINVAL;
+	}
+
+	kset = top_kobj->kset;
+	uevent_ops = (struct kset_uevent_ops *)kset->uevent_ops;
+
+	/* skip the event, if uevent_suppress is set*/
+	if (kobj->uevent_suppress) {
+		pr_debug("kobject: '%s' (%p): %s: uevent_suppress "
+				 "caused the event to drop!\n",
+				 kobject_name(kobj), kobj, __func__);
+		return 0;
+	}
+	/* skip the event, if the filter returns zero. */
+	if (uevent_ops && uevent_ops->filter)
+		if (!uevent_ops->filter(kset, kobj)) {
+			pr_debug("kobject: '%s' (%p): %s: filter function "
+				 "caused the event to drop!\n",
+				 kobject_name(kobj), kobj, __func__);
+			return 0;
+		}
+
+	/* originating subsystem */
+	if (uevent_ops && uevent_ops->name)
+		subsystem = uevent_ops->name(kset, kobj);
+	else
+		subsystem = kobject_name(&kset->kobj);
+	if (!subsystem) {
+		pr_debug("kobject: '%s' (%p): %s: unset subsystem caused the "
+			 "event to drop!\n", kobject_name(kobj), kobj,
+			 __func__);
+		return 0;
+	}
+
+	/* environment buffer */
+	env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
+	if (!env)
+		return -ENOMEM;
+
+	/* complete object path */
+	devpath = kobject_get_path(kobj, GFP_KERNEL);
+	if (!devpath) {
+		retval = -ENOENT;
+		goto exit;
+	}
+
+	/* default keys */
+	retval = add_uevent_var(env, "ACTION=%s", action_string);
+	if (retval)
+		goto exit;
+	retval = add_uevent_var(env, "DEVPATH=%s", devpath);
+	if (retval)
+		goto exit;
+	retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);
+	if (retval)
+		goto exit;
+
+	/* keys passed in from the caller */
+	if (envp_ext) {
+		for (i = 0; envp_ext[i]; i++) {
+			retval = add_uevent_var(env, "%s", envp_ext[i]);
+			if (retval)
+				goto exit;
+		}
+	}
+
+	/* let the kset specific function add its stuff */
+	if (uevent_ops && uevent_ops->uevent) {
+		retval = uevent_ops->uevent(kset, kobj, env);
+		if (retval) {
+			pr_debug("kobject: '%s' (%p): %s: uevent() returned "
+				 "%d\n", kobject_name(kobj), kobj,
+				 __func__, retval);
+			goto exit;
+		}
+	}
+
+	/*
+	 * Mark "add" and "remove" events in the object to ensure proper
+	 * events to userspace during automatic cleanup. If the object did
+	 * send an "add" event, "remove" will automatically generated by
+	 * the core, if not already done by the caller.
+	 */
+	if (action == KOBJ_ADD)
+		kobj->state_add_uevent_sent = 1;
+	else if (action == KOBJ_REMOVE)
+		kobj->state_remove_uevent_sent = 1;
+
+	/* we will send an event, so request a new sequence number */
+	spin_lock(&sequence_lock);
+	seq = ++psb_uevent_seqnum;
+	spin_unlock(&sequence_lock);
+	retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);
+	if (retval)
+		goto exit;
+
+#if defined(CONFIG_NET)
+	/* send netlink message */
+	if (uevent_sock) {
+		struct sk_buff *skb;
+		size_t len;
+
+		/* allocate message with the maximum possible size */
+		len = strlen(action_string) + strlen(devpath) + 2;
+		skb = alloc_skb(len + env->buflen, GFP_KERNEL);
+		if (skb) {
+			char *scratch;
+
+			/* add header */
+			scratch = skb_put(skb, len);
+			sprintf(scratch, "%s@%s", action_string, devpath);
+
+			/* copy keys to our continuous event payload buffer */
+			for (i = 0; i < env->envp_idx; i++) {
+				len = strlen(env->envp[i]) + 1;
+				scratch = skb_put(skb, len);
+				strcpy(scratch, env->envp[i]);
+			}
+
+			NETLINK_CB(skb).dst_group = dst_group_id;
+			retval = netlink_broadcast(uevent_sock, skb, 0,
+						   dst_group_id,
+						   GFP_KERNEL);
+
+			/* ENOBUFS should be handled in userspace */
+			if (retval == -ENOBUFS)
+				retval = 0;
+		} else
+			retval = -ENOMEM;
+	}
+#endif
+
+	/* call psb_uevent_helper, usually only enabled during early boot */
+	if (psb_uevent_helper[0]) {
+		char *argv[3];
+
+		argv[0] = psb_uevent_helper;
+		argv[1] = (char *)subsystem;
+		argv[2] = NULL;
+		retval = add_uevent_var(env, "HOME=/");
+		if (retval)
+			goto exit;
+		retval = add_uevent_var(env,
+					"PATH=/sbin:/bin:/usr/sbin:/usr/bin");
+		if (retval)
+			goto exit;
+
+		retval = call_usermodehelper(argv[0], argv,
+					     env->envp, UMH_WAIT_EXEC);
+	}
+
+exit:
+	kfree(devpath);
+	kfree(env);
+	return retval;
+}
+/*EXPORT_SYMBOL_GPL(psb_kobject_uevent_env); */
+
+/**
+ * psb_kobject_uevent - notify userspace by ending an uevent
+ *
+ * @action: action that is happening
+ * @kobj: struct kobject that the action is happening to
+ *
+ * Returns 0 if psb_kobject_uevent() is completed with success or the
+ * corresponding error when it fails.
+ */
+int psb_kobject_uevent(struct kobject *kobj, enum kobject_action action,
+		       int dst_group_id)
+{
+	return psb_kobject_uevent_env(kobj, action, NULL, dst_group_id);
+}
+/*EXPORT_SYMBOL_GPL(psb_kobject_uevent); */
+
+/**
+ * psb_add_uevent_var - add key value string to the environment buffer
+ * @env: environment buffer structure
+ * @format: printf format for the key=value pair
+ *
+ * Returns 0 if environment variable was added successfully or -ENOMEM
+ * if no space was available.
+ */
+int psb_add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
+{
+	va_list args;
+	int len;
+
+	if (env->envp_idx >= ARRAY_SIZE(env->envp)) {
+		WARN(1, KERN_ERR "psb_add_uevent_var: too many keys\n");
+		return -ENOMEM;
+	}
+
+	va_start(args, format);
+	len = vsnprintf(&env->buf[env->buflen],
+			sizeof(env->buf) - env->buflen,
+			format, args);
+	va_end(args);
+
+	if (len >= (sizeof(env->buf) - env->buflen)) {
+		WARN(1,
+		     KERN_ERR "psb_add_uevent_var: buffer size too small\n");
+		return -ENOMEM;
+	}
+
+	env->envp[env->envp_idx++] = &env->buf[env->buflen];
+	env->buflen += len + 1;
+	return 0;
+}
+/*EXPORT_SYMBOL_GPL(psb_add_uevent_var);*/ 
+
+#if defined(CONFIG_NET)
+int psb_kobject_uevent_init(void)
+{
+	/* This should be the 15, but 3 seems to work better.  Why? WHY!? */
+	/* uevent_sock = netlink_kernel_create(&init_net,
+					    NETLINK_PSB_KOBJECT_UEVENT,
+					    DRM_GFX_SOCKET_GROUPS,
+					    NULL, NULL, THIS_MODULE); */
+	uevent_sock = netlink_kernel_create(&init_net,
+					    NETLINK_PSB_KOBJECT_UEVENT,
+					    0x3, /* 3 is for hotplug & dpst */
+					    NULL, NULL, THIS_MODULE);
+
+	if (!uevent_sock) {
+		printk(KERN_ERR "psb_kobject_uevent: failed create socket!\n");
+		return -ENODEV;
+	}
+	netlink_set_nonroot(NETLINK_PSB_KOBJECT_UEVENT, NL_NONROOT_RECV);
+
+	return 0;
+}
+#endif
diff --git a/drivers/staging/cdv/drv/psb_umevents.c b/drivers/staging/cdv/drv/psb_umevents.c
new file mode 100644
index 0000000..932d7d3
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_umevents.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 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.
+ *
+ * Authors:
+ *    James C. Gualario <james.c.gualario@intel.com>
+ *
+ */
+#include "psb_umevents.h"
+/**
+ * define sysfs operations supported by umevent objects.
+ *
+ */
+static struct sysfs_ops umevent_obj_sysfs_ops = {
+	.show = psb_umevent_attr_show,
+	.store = psb_umevent_attr_store,
+};
+/**
+ * define the data attributes we will expose through sysfs.
+ *
+ */
+static struct umevent_attribute data_0 =
+	__ATTR(data_0_val, 0666, psb_umevent_attr_show_imp,
+	       psb_umevent_attr_store_imp);
+static struct umevent_attribute data_1 =
+	__ATTR(data_1_val, 0666, psb_umevent_attr_show_imp,
+	       psb_umevent_attr_store_imp);
+static struct umevent_attribute data_2 =
+	__ATTR(data_2_val, 0666, psb_umevent_attr_show_imp,
+	       psb_umevent_attr_store_imp);
+static struct umevent_attribute data_3 =
+	__ATTR(data_3_val, 0666, psb_umevent_attr_show_imp,
+	       psb_umevent_attr_store_imp);
+static struct umevent_attribute data_4 =
+	__ATTR(data_4_val, 0666, psb_umevent_attr_show_imp,
+	       psb_umevent_attr_store_imp);
+static struct umevent_attribute data_5 =
+	__ATTR(data_5_val, 0666, psb_umevent_attr_show_imp,
+	       psb_umevent_attr_store_imp);
+static struct umevent_attribute data_6 =
+	__ATTR(data_6_val, 0666, psb_umevent_attr_show_imp,
+	       psb_umevent_attr_store_imp);
+static struct umevent_attribute data_7 =
+	__ATTR(data_7_val, 0666, psb_umevent_attr_show_imp,
+	       psb_umevent_attr_store_imp);
+/**
+ * define the structure used to seed our ktype.
+ *
+ */
+static struct attribute *umevent_obj_default_attrs[] = {
+	&data_0.attr,
+	&data_1.attr,
+	&data_2.attr,
+	&data_3.attr,
+	&data_4.attr,
+	&data_5.attr,
+	&data_6.attr,
+	&data_7.attr,
+	NULL,	/* need to NULL terminate the list of attributes */
+};
+/**
+ * specify the ktype for our kobjects.
+ *
+ */
+static struct kobj_type umevent_obj_ktype = {
+	.sysfs_ops = &umevent_obj_sysfs_ops,
+	.release = psb_umevent_obj_release,
+	.default_attrs = umevent_obj_default_attrs,
+};
+/**
+ * psb_umevent_attr_show - default kobject show function
+ *
+ * @kobj: kobject associated with the show operation
+ * @attr: attribute being requested
+ * @buf: pointer to the return buffer
+ *
+ */
+ssize_t psb_umevent_attr_show(struct kobject *kobj,
+			     struct attribute *attr,
+			     char *buf)
+{
+	struct umevent_attribute *attribute;
+	struct umevent_obj *any_umevent_obj;
+	attribute = to_umevent_attr(attr);
+	any_umevent_obj = to_umevent_obj(kobj);
+	if (!attribute->show)
+		return -EIO;
+
+	return attribute->show(any_umevent_obj, attribute, buf);
+}
+/**
+ * psb_umevent_attr_store - default kobject store function
+ *
+ * @kobj: kobject associated with the store operation
+ * @attr: attribute being requested
+ * @buf: input data to write to attribute
+ * @len: character count
+ *
+ */
+ssize_t psb_umevent_attr_store(struct kobject *kobj,
+			      struct attribute *attr,
+			      const char *buf, size_t len)
+{
+	struct umevent_attribute *attribute;
+	struct umevent_obj *any_umevent_obj;
+	attribute = to_umevent_attr(attr);
+	any_umevent_obj = to_umevent_obj(kobj);
+	if (!attribute->store)
+		return -EIO;
+
+	return attribute->store(any_umevent_obj, attribute, buf, len);
+}
+/**
+ * psb_umevent_obj_release - kobject release funtion
+ *
+ * @kobj: kobject to be released.
+ */
+void psb_umevent_obj_release(struct kobject *kobj)
+{
+	struct umevent_obj *any_umevent_obj;
+	any_umevent_obj = to_umevent_obj(kobj);
+	kfree(any_umevent_obj);
+}
+/**
+ *  psb_umevent_attr_show_imp - attribute show implementation
+ *
+ * @any_umevent_obj: kobject managed data to read from
+ * @attr: attribute being requested
+ * @buf: pointer to the return buffer
+ *
+ */
+ssize_t psb_umevent_attr_show_imp(struct umevent_obj
+				     *any_umevent_obj,
+				     struct umevent_attribute *attr,
+				     char *buf)
+{
+	int var;
+
+	if (strcmp(attr->attr.name, "data_0_val") == 0)
+		var = any_umevent_obj->data_0_val;
+	else if (strcmp(attr->attr.name, "data_1_val") == 0)
+		var = any_umevent_obj->data_1_val;
+	else if (strcmp(attr->attr.name, "data_2_val") == 0)
+		var = any_umevent_obj->data_2_val;
+	else if (strcmp(attr->attr.name, "data_3_val") == 0)
+		var = any_umevent_obj->data_3_val;
+	else if (strcmp(attr->attr.name, "data_4_val") == 0)
+		var = any_umevent_obj->data_4_val;
+	else if (strcmp(attr->attr.name, "data_5_val") == 0)
+		var = any_umevent_obj->data_5_val;
+	else if (strcmp(attr->attr.name, "data_6_val") == 0)
+		var = any_umevent_obj->data_6_val;
+	else
+		var = any_umevent_obj->data_7_val;
+
+	return sprintf(buf, "%d\n", var);
+}
+/**
+ * psb_umevent_attr_store_imp - attribute store implementation
+ *
+ * @any_umevent_obj: kobject managed data to write to
+ * @attr: attribute being requested
+ * @buf: input data to write to attribute
+ * @count: character count
+ *
+ */
+ssize_t psb_umevent_attr_store_imp(struct umevent_obj
+				      *any_umevent_obj,
+				      struct umevent_attribute *attr,
+				      const char *buf, size_t count)
+{
+	int var;
+
+	sscanf(buf, "%du", &var);
+	if (strcmp(attr->attr.name, "data_0_val") == 0)
+		any_umevent_obj->data_0_val = var;
+	else if (strcmp(attr->attr.name, "data_1_val") == 0)
+		any_umevent_obj->data_1_val = var;
+	else if (strcmp(attr->attr.name, "data_2_val") == 0)
+		any_umevent_obj->data_2_val = var;
+	else if (strcmp(attr->attr.name, "data_3_val") == 0)
+		any_umevent_obj->data_3_val = var;
+	else if (strcmp(attr->attr.name, "data_4_val") == 0)
+		any_umevent_obj->data_4_val = var;
+	else if (strcmp(attr->attr.name, "data_5_val") == 0)
+		any_umevent_obj->data_5_val = var;
+	else if (strcmp(attr->attr.name, "data_6_val") == 0)
+		any_umevent_obj->data_6_val = var;
+	else
+		any_umevent_obj->data_7_val = var;
+	return count;
+}
+/**
+ * psb_create_umevent_obj - create and track new event objects
+ *
+ * @name: name to give to new sysfs / kobject entry
+ * @list: event object list to track the kobject in
+ */
+struct umevent_obj *psb_create_umevent_obj(const char *name,
+						struct umevent_list
+							*list)
+{
+	struct umevent_obj *new_umevent_obj;
+	int retval;
+	new_umevent_obj = kzalloc(sizeof(*new_umevent_obj),
+				       GFP_KERNEL);
+	if (!new_umevent_obj)
+		return NULL;
+
+	new_umevent_obj->kobj.kset = list->umevent_disp_pool;
+	retval = kobject_init_and_add(&new_umevent_obj->kobj,
+				      &umevent_obj_ktype, NULL,
+				      "%s", name);
+	if (retval) {
+		kobject_put(&new_umevent_obj->kobj);
+		kfree(new_umevent_obj);
+		return NULL;
+	}
+	psb_umevent_add_to_list(list, new_umevent_obj);
+	return new_umevent_obj;
+}
+/*EXPORT_SYMBOL(psb_create_umevent_obj); */
+/**
+ * psb_umevent_notify - info user mode of a new device
+ *
+ * @notify_disp_obj: event object to perform notification for
+ *
+ */
+void psb_umevent_notify(struct umevent_obj *notify_disp_obj)
+{
+	kobject_uevent(&notify_disp_obj->kobj, KOBJ_ADD);
+}
+/*EXPORT_SYMBOL(psb_umevent_notify); */
+
+void psb_umevent_notify_gfxsock(struct umevent_obj *notify_disp_obj,
+				int dst_group_id)
+{
+	psb_kobject_uevent(&notify_disp_obj->kobj, KOBJ_ADD, dst_group_id);
+}
+/*EXPORT_SYMBOL(psb_umevent_notify_gfxsock);*/
+/**
+ * psb_umevent_notify_change - notify user mode of a change to a device
+ *
+ * @notify_disp_obj: event object to perform notification for
+ *
+ */
+void psb_umevent_notify_change(struct umevent_obj *notify_disp_obj)
+{
+	kobject_uevent(&notify_disp_obj->kobj, KOBJ_CHANGE);
+}
+/*EXPORT_SYMBOL(psb_umevent_notify_change); */
+/**
+ * psb_umevent_notify_change - notify user mode of a change to a device
+ *
+ * @notify_disp_obj: event object to perform notification for
+ *
+ */
+void psb_umevent_notify_change_gfxsock(struct umevent_obj *notify_disp_obj,
+					int dst_group_id)
+{
+	psb_kobject_uevent(&notify_disp_obj->kobj, KOBJ_CHANGE, dst_group_id);
+}
+/*EXPORT_SYMBOL(psb_umevent_notify_change_gfxsock); */
+/**
+ * psb_destroy_umvent_obj - decrement ref count on event so kernel can kill it
+ *
+ * @any_umevent_obj: event object to destroy
+ *
+ */
+void psb_destroy_umevent_obj(struct umevent_obj
+				     *any_umevent_obj)
+{
+	kobject_put(&any_umevent_obj->kobj);
+}
+/**
+ *
+ * psb_umevent_init - init the event pool
+ *
+ * @parent_kobj: parent kobject to associate new kset with
+ * @new_umevent_list: event list to associate kset with
+ * @name: name to give to new sysfs entry
+ *
+ */
+int psb_umevent_init(struct kobject *parent_kobj,
+		     struct umevent_list *new_umevent_list,
+		     const char *name)
+{
+	psb_umevent_init_list(new_umevent_list);
+	new_umevent_list->umevent_disp_pool = kset_create_and_add(name, NULL,
+						     parent_kobj);
+	if (!new_umevent_list->umevent_disp_pool)
+		return -ENOMEM;
+
+	return 0;
+}
+/*EXPORT_SYMBOL(psb_umevent_init); */
+/**
+ *
+ * psb_umevent_cleanup - cleanup all event objects
+ *
+ * @kill_list: list of events to destroy
+ *
+ */
+void psb_umevent_cleanup(struct umevent_list *kill_list)
+{
+	psb_umevent_destroy_list(kill_list);
+}
+/*EXPORT_SYMBOL(psb_umevent_cleanup); */
+/**
+ * psb_umevent_add_to_list - add an event to the event list
+ *
+ * @list: list to add the event to
+ * @umevent_obj_to_add: event to add
+ *
+ */
+void psb_umevent_add_to_list(struct umevent_list *list,
+			      struct umevent_obj *umevent_obj_to_add)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&list->list_lock, flags);
+	list_add(&umevent_obj_to_add->head, &list->head);
+	spin_unlock_irqrestore(&list->list_lock, flags);
+}
+/**
+ * psb_umevent_init_list - initialize event list
+ *
+ * @list: list to initialize
+ *
+ */
+void psb_umevent_init_list(struct umevent_list *list)
+{
+	spin_lock_init(&list->list_lock);
+	INIT_LIST_HEAD(&list->head);
+}
+/**
+ * psb_umevent_create_list - allocate an event list
+ *
+ */
+struct umevent_list *psb_umevent_create_list()
+{
+	struct umevent_list *new_umevent_list;
+	new_umevent_list = NULL;
+	new_umevent_list =  kmalloc(sizeof(struct umevent_list),
+					 GFP_ATOMIC);
+	return new_umevent_list;
+}
+/*EXPORT_SYMBOL(psb_umevent_create_list); */
+/**
+ * psb_umevent_destroy_list - destroy a list and clean up all mem
+ *
+ * @list: list to destroy and clean up after
+ *
+ */
+void psb_umevent_destroy_list(struct umevent_list *list)
+{
+	struct umevent_obj *umevent_obj_curr;
+	struct list_head *node;
+	struct list_head *node_kill;
+	int i;
+	i = 0;
+	node = NULL;
+	node_kill = NULL;
+	node = list->head.next;
+	while (node != (&list->head)) {
+		umevent_obj_curr = list_entry(node,
+				struct umevent_obj,
+						   head);
+		node_kill = node;
+		node = umevent_obj_curr->head.next;
+		list_del(node_kill);
+		psb_destroy_umevent_obj(umevent_obj_curr);
+		umevent_obj_curr = NULL;
+		i++;
+	}
+	kset_unregister(list->umevent_disp_pool);
+	kfree(list);
+}
+/**
+ * psb_umevent_remove_from_list - remove an event from tracking list
+ *
+ * @list: list to remove the event from
+ * @disp_to_remove: name of event to remove.
+ *
+ */
+void psb_umevent_remove_from_list(struct umevent_list *list,
+				   const char *disp_to_remove)
+{
+	struct umevent_obj *umevent_obj_curr = NULL;
+	struct list_head *node = NULL;
+	struct list_head *node_kill = NULL;
+	int i = 0;
+	int found_match = 0;
+	i = 0;
+	node = NULL;
+	node_kill = NULL;
+	node = list->head.next;
+	while (node != (&list->head)) {
+		umevent_obj_curr = list_entry(node,
+				struct umevent_obj, head);
+		if (strcmp(umevent_obj_curr->kobj.name,
+			  disp_to_remove) == 0) {
+			found_match = 1;
+			break;
+		}
+		node = NULL;
+		node = umevent_obj_curr->head.next;
+		i++;
+	}
+	if (found_match == 1) {
+		node_kill = node;
+		node = umevent_obj_curr->head.next;
+		list_del(node_kill);
+		psb_destroy_umevent_obj(umevent_obj_curr);
+		umevent_obj_curr = NULL;
+	}
+}
+/*EXPORT_SYMBOL(psb_umevent_remove_from_list); */
+/**
+ * psb_umevent_find_obj - find an event in a tracking list
+ *
+ * @name: name of the event to find
+ * @list: list to find the event in
+ *
+ */
+struct umevent_obj *psb_umevent_find_obj(const char *name,
+				  struct umevent_list *list)
+{
+	struct umevent_obj *umevent_obj_curr = NULL;
+	struct list_head *node = NULL;
+	int i = 0;
+	int found_match = 0;
+
+	node = NULL;
+	node = list->head.next;
+	while (node != (&list->head)) {
+		umevent_obj_curr = list_entry(node,
+				struct umevent_obj, head);
+		if (strcmp(umevent_obj_curr->kobj.name,
+			  name) == 0) {
+			found_match = 1;
+			break;
+		}
+		node = NULL;
+		node = umevent_obj_curr->head.next;
+		i++;
+	}
+	if (found_match == 1)
+		return umevent_obj_curr;
+
+	return NULL;
+}
+/*EXPORT_SYMBOL(psb_umevent_find_obj); */
+/**
+ * psb_umevent_debug_dump_list - debug list dump
+ *
+ * @list: list to dump
+ *
+ */
+void psb_umevent_debug_dump_list(struct umevent_list *list)
+{
+	struct umevent_obj *umevent_obj_curr;
+	unsigned long flags;
+	struct list_head *node;
+	int i;
+	spin_lock_irqsave(&list->list_lock, flags);
+	i = 0;
+	node = NULL;
+	node = list->head.next;
+	while (node != (&list->head)) {
+		umevent_obj_curr = list_entry(node,
+						   struct umevent_obj,
+						   head);
+		/*TBD: DUMP ANY REQUIRED VALUES WITH PRINTK*/
+		node = NULL;
+		node = umevent_obj_curr->head.next;
+		i++;
+	}
+	spin_unlock_irqrestore(&list->list_lock, flags);
+}
diff --git a/drivers/staging/cdv/drv/psb_umevents.h b/drivers/staging/cdv/drv/psb_umevents.h
new file mode 100644
index 0000000..0b9b57d
--- /dev/null
+++ b/drivers/staging/cdv/drv/psb_umevents.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ * Authors:
+ *    James C. Gualario <james.c.gualario@intel.com>
+ *
+ */
+#ifndef _PSB_UMEVENT_H_
+#define _PSB_UMEVENT_H_
+/**
+ * required includes
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <drm/drmP.h>
+#include <drm/drm_core.h>
+#include <drm/drm_pciids.h>
+#include <linux/spinlock.h>
+/**
+ * event groups for routing to different user mode threads
+ *
+ */
+#define DRM_DPST_SOCKET_GROUP_ID 1
+#define DRM_HOTPLUG_SOCKET_GROUP_ID 2
+#define DRM_HDMI_AUDIO_SOCKET_GROUP 4
+#define DRM_HDMI_HDCP_SOCKET_GROUP 8
+#define DRM_GFX_SOCKET_GROUPS 15
+/**
+ * event structure managed by kobjects
+ *
+ */
+struct umevent_obj {
+	struct kobject kobj;
+	struct list_head head;
+	int data_0_val;
+	int data_1_val;
+	int data_2_val;
+	int data_3_val;
+	int data_4_val;
+	int data_5_val;
+	int data_6_val;
+	int data_7_val;
+};
+/**
+ * event tracking list element
+ *
+ */
+struct umevent_list{
+	struct list_head head;
+	struct kset *umevent_disp_pool;
+	spinlock_t list_lock;
+};
+/**
+ * to go back and forth between kobjects and their main container
+ *
+ */
+#define to_umevent_obj(x) \
+	container_of(x, struct umevent_obj, kobj)
+
+/**
+ * event attributes exposed via sysfs
+ *
+ */
+struct umevent_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct umevent_obj *any_umevent_obj,
+			struct umevent_attribute *attr, char *buf);
+	ssize_t (*store)(struct umevent_obj *any_umevent_obj,
+			 struct umevent_attribute *attr,
+			 const char *buf, size_t count);
+};
+/**
+ * to go back and forth between the attribute passed to us by the OS
+ * and the umevent_attribute
+ *
+ */
+#define to_umevent_attr(x) \
+	container_of(x, struct umevent_attribute, \
+	attr)
+
+/**
+ * umevent function prototypes
+ *
+ */
+extern struct umevent_obj *psb_create_umevent_obj(const char *name,
+						struct umevent_list
+							*list);
+extern ssize_t psb_umevent_attr_show(struct kobject *kobj,
+				      struct attribute *attr, char *buf);
+extern ssize_t psb_umevent_attr_store(struct kobject *kobj,
+				       struct attribute *attr,
+				       const char *buf, size_t len);
+extern ssize_t psb_umevent_attr_show_imp(struct umevent_obj
+				     *any_umevent_obj,
+				     struct umevent_attribute *attr,
+				     char *buf);
+extern ssize_t psb_umevent_attr_store_imp(struct umevent_obj
+				      *any_umevent_obj,
+				      struct umevent_attribute *attr,
+				      const char *buf, size_t count);
+extern void psb_umevent_cleanup(struct umevent_list *kill_list);
+extern int psb_umevent_init(struct kobject *parent_kobj,
+			    struct umevent_list *new_umevent_list,
+			    const char *name);
+extern void psb_umevent_init_list(struct umevent_list *list);
+extern void psb_umevent_debug_dump_list(struct umevent_list *list);
+extern void psb_umevent_add_to_list(struct umevent_list *list,
+				     struct umevent_obj
+				     *umevent_obj_to_add);
+extern void psb_umevent_destroy_list(struct umevent_list *list);
+extern struct umevent_list *psb_umevent_create_list(void);
+extern void psb_umevent_notify(struct umevent_obj *notify_disp_obj);
+extern void psb_umevent_notify_gfxsock(struct umevent_obj *notify_disp_obj,
+					int dst_group_id);
+extern void psb_umevent_obj_release(struct kobject *kobj);
+extern void psb_umevent_remove_from_list(struct umevent_list *list,
+					  const char *disp_to_remove);
+extern void psb_umevent_workqueue_dispatch(int work_type, const char *name,
+				       struct umevent_list *list);
+extern void psb_umevent_notify_change(struct umevent_obj *notify_disp_obj);
+extern void psb_umevent_notify_change_gfxsock(struct umevent_obj
+					      *notify_disp_obj,
+					      int dst_group_id);
+extern struct umevent_obj *psb_umevent_find_obj(const char *name,
+						struct umevent_list
+							*list);
+/**
+ * socket function prototypes
+ *
+ */
+extern int psb_kobject_uevent(struct kobject *kobj,
+			      enum kobject_action action, int dst_group_id);
+extern int psb_kobject_uevent_env(struct kobject *kobj,
+				  enum kobject_action action,
+				  char *envp[], int dst_group_id);
+int psb_add_uevent_var(struct kobj_uevent_env *env,
+		       const char *format, ...)
+	__attribute__((format (printf, 2, 3)));
+int psb_kobject_action_type(const char *buf,
+			    size_t count, enum kobject_action *type);
+
+#if defined(CONFIG_NET)
+int psb_kobject_uevent_init(void);
+#endif
+
+#endif
diff --git a/drivers/staging/cdv/imgv/msvdx_power.c b/drivers/staging/cdv/imgv/msvdx_power.c
new file mode 100644
index 0000000..7782a51
--- /dev/null
+++ b/drivers/staging/cdv/imgv/msvdx_power.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ * Authors: binglin.chen@intel.com>
+ *
+ */
+
+#include "msvdx_power.h"
+#include "psb_msvdx.h"
+#include "psb_drv.h"
+
+#include "services_headers.h"
+#include "sysconfig.h"
+
+static PVRSRV_ERROR DevInitMSVDXPart1(IMG_VOID *pvDeviceNode)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
+	PVRSRV_ERROR eError;
+	PVRSRV_DEV_POWER_STATE eDefaultPowerState;
+
+	/* register power operation function */
+	/* FIXME: this should be in part2 init function, but
+	 * currently here only OSPM needs IMG device... */
+	eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
+	eError = PVRSRVRegisterPowerDevice(psDeviceNode->sDevId.ui32DeviceIndex,
+					   MSVDXPrePowerState,
+					   MSVDXPostPowerState,
+					   MSVDXPreClockSpeedChange,
+					   MSVDXPostClockSpeedChange,
+					   (IMG_HANDLE)psDeviceNode,
+					   PVRSRV_DEV_POWER_STATE_ON,
+					   eDefaultPowerState);
+	if (eError != PVRSRV_OK) {
+		PVR_DPF((PVR_DBG_ERROR, "DevInitMSVDXPart1: failed to "
+			 "register device with power manager"));
+		return eError;
+	}
+
+	return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR DevDeInitMSVDX(IMG_VOID *pvDeviceNode)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
+	PVRSRV_ERROR eError;
+
+	/* should deinit all resource */
+
+	eError = PVRSRVRemovePowerDevice(psDeviceNode->sDevId.ui32DeviceIndex);
+	if (eError != PVRSRV_OK)
+		return eError;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR MSVDXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	/* version check */
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR MSVDXRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	psDeviceNode->sDevId.eDeviceType	= PVRSRV_DEVICE_TYPE_MSVDX;
+	psDeviceNode->sDevId.eDeviceClass	= PVRSRV_DEVICE_CLASS_VIDEO;
+
+	psDeviceNode->pfnInitDevice		= DevInitMSVDXPart1;
+	psDeviceNode->pfnDeInitDevice		= DevDeInitMSVDX;
+
+	psDeviceNode->pfnInitDeviceCompatCheck	= MSVDXDevInitCompatCheck;
+
+	psDeviceNode->pfnDeviceISR = psb_msvdx_interrupt;
+	psDeviceNode->pvISRData = (IMG_VOID *)gpDrmDevice;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR MSVDXPrePowerState(IMG_HANDLE hDevHandle,
+				 PVRSRV_DEV_POWER_STATE	eNewPowerState,
+				 PVRSRV_DEV_POWER_STATE	eCurrentPowerState)
+{
+#if 1
+	/* ask for a change not power on*/
+	if ((eNewPowerState != eCurrentPowerState) &&
+	    (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON)) {
+		struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
+		struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+		MSVDX_NEW_PMSTATE(gpDrmDevice, msvdx_priv, PSB_PMSTATE_POWERDOWN);
+
+		/* context save */
+		psb_msvdx_save_context(gpDrmDevice);
+
+		/* internally close the device */
+
+		/* ask for power off */
+		if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) {
+			/* here will deinitialize the driver if needed */
+		} else {
+			PVR_DPF((PVR_DBG_MESSAGE,
+				"%s no action for transform from %d to %d",
+				 __func__,
+				eCurrentPowerState,
+				eNewPowerState));
+		}
+	}
+#endif
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR MSVDXPostPowerState(IMG_HANDLE hDevHandle,
+				 PVRSRV_DEV_POWER_STATE	eNewPowerState,
+				 PVRSRV_DEV_POWER_STATE	eCurrentPowerState)
+{
+#if 1
+	/* if ask for change & current status is not on */
+	if ((eNewPowerState != eCurrentPowerState) &&
+	    (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON)) {
+		/* internally open device */
+		struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
+		struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+		MSVDX_NEW_PMSTATE(gpDrmDevice, msvdx_priv, PSB_PMSTATE_POWERUP);
+
+		/* context restore */
+		psb_msvdx_restore_context(gpDrmDevice);
+
+		if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) {
+			/* here will initialize the driver if needed */
+		} else {
+			PVR_DPF((PVR_DBG_MESSAGE,
+				"%s no action for transform from %d to %d",
+				 __func__,
+				eCurrentPowerState,
+				eNewPowerState));
+		}
+	}
+#endif
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR MSVDXPreClockSpeedChange(IMG_HANDLE hDevHandle,
+				      IMG_BOOL bIdleDevice,
+				      PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR MSVDXPostClockSpeedChange(IMG_HANDLE hDevHandle,
+				      IMG_BOOL bIdleDevice,
+				      PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+	return PVRSRV_OK;
+}
diff --git a/drivers/staging/cdv/imgv/msvdx_power.h b/drivers/staging/cdv/imgv/msvdx_power.h
new file mode 100644
index 0000000..580f93f
--- /dev/null
+++ b/drivers/staging/cdv/imgv/msvdx_power.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ * Authors: binglin.chen@intel.com>
+ *
+ */
+
+#ifndef MSVDX_POWER_H_
+#define MSVDX_POWER_H_
+
+#include "services_headers.h"
+#include "sysconfig.h"
+
+extern struct drm_device *gpDrmDevice;
+
+/* function define */
+PVRSRV_ERROR MSVDXRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+PVRSRV_ERROR MSVDXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+/* power function define */
+PVRSRV_ERROR MSVDXPrePowerState(IMG_HANDLE	hDevHandle,
+			PVRSRV_DEV_POWER_STATE	eNewPowerState,
+			PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+PVRSRV_ERROR MSVDXPostPowerState(IMG_HANDLE	hDevHandle,
+			 PVRSRV_DEV_POWER_STATE	eNewPowerState,
+			 PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+PVRSRV_ERROR MSVDXPreClockSpeedChange(IMG_HANDLE	hDevHandle,
+			      IMG_BOOL			bIdleDevice,
+			      PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+PVRSRV_ERROR MSVDXPostClockSpeedChange(IMG_HANDLE	hDevHandle,
+			       IMG_BOOL			bIdleDevice,
+			       PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+PVRSRV_ERROR MSVDXInitOSPM(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+#endif /* !MSVDX_POWER_H_ */
diff --git a/drivers/staging/cdv/imgv/psb_buffer.c b/drivers/staging/cdv/imgv/psb_buffer.c
new file mode 100644
index 0000000..263cd7c
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_buffer.c
@@ -0,0 +1,442 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
+ */
+#include "ttm/ttm_placement.h"
+#include "ttm/ttm_execbuf_util.h"
+#include "psb_ttm_fence_api.h"
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_schedule.h"
+
+#define DRM_MEM_TTM       26
+
+struct drm_psb_ttm_backend {
+	struct ttm_backend base;
+	struct page **pages;
+	unsigned int desired_tile_stride;
+	unsigned int hw_tile_stride;
+	int mem_type;
+	unsigned long offset;
+	unsigned long num_pages;
+};
+
+/*
+ * MSVDX/TOPAZ GPU virtual space looks like this
+ * (We currently use only one MMU context).
+ * PSB_MEM_MMU_START: from 0x00000000~0xe000000, for generic buffers
+ * TTM_PL_CI: from 0xe0000000+half GTT space, for camear/video buffer sharing
+ * TTM_PL_RAR: from TTM_PL_CI+CI size, for RAR/video buffer sharing
+ * TTM_PL_TT: from TTM_PL_RAR+RAR size, for buffers need to mapping into GTT
+ */
+static int psb_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+			     struct ttm_mem_type_manager *man)
+{
+
+	struct drm_psb_private *dev_priv =
+	    container_of(bdev, struct drm_psb_private, bdev);
+	struct psb_gtt *pg = dev_priv->pg;
+
+	switch (type) {
+	case TTM_PL_SYSTEM:
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->available_caching = TTM_PL_FLAG_CACHED |
+		    TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
+		man->default_caching = TTM_PL_FLAG_CACHED;
+		break;
+	case DRM_PSB_MEM_MMU:
+		man->func = &ttm_bo_manager_func;
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
+		    TTM_MEMTYPE_FLAG_CMA;
+		man->gpu_offset = PSB_MEM_MMU_START;
+		man->available_caching = TTM_PL_FLAG_CACHED |
+		    TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
+		man->default_caching = TTM_PL_FLAG_WC;
+		break;
+	case TTM_PL_CI:
+		man->func = &ttm_bo_manager_func;
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
+			TTM_MEMTYPE_FLAG_FIXED;
+		man->gpu_offset = pg->mmu_gatt_start + (pg->ci_start);
+		man->available_caching = TTM_PL_FLAG_UNCACHED;
+		man->default_caching = TTM_PL_FLAG_UNCACHED;
+		break;
+	case TTM_PL_RAR:	/* Unmappable RAR memory */
+		man->func = &ttm_bo_manager_func;
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
+			TTM_MEMTYPE_FLAG_FIXED;
+		man->available_caching = TTM_PL_FLAG_UNCACHED;
+		man->default_caching = TTM_PL_FLAG_UNCACHED;
+		man->gpu_offset = pg->mmu_gatt_start + (pg->rar_start);
+		break;
+	case TTM_PL_TT:	/* Mappable GATT memory */
+		man->func = &ttm_bo_manager_func;
+#ifdef PSB_WORKING_HOST_MMU_ACCESS
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+#else
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
+		    TTM_MEMTYPE_FLAG_CMA;
+#endif
+		man->available_caching = TTM_PL_FLAG_CACHED |
+		    TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
+		man->default_caching = TTM_PL_FLAG_WC;
+		man->gpu_offset = pg->mmu_gatt_start + (pg->rar_start + dev_priv->rar_region_size);
+		break;
+	default:
+		DRM_ERROR("Unsupported memory type %u\n", (unsigned) type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+static void psb_evict_mask(struct ttm_buffer_object *bo, struct ttm_placement* placement)
+{
+	static uint32_t cur_placement;
+
+	cur_placement = bo->mem.placement & ~TTM_PL_MASK_MEM;
+	cur_placement |= TTM_PL_FLAG_SYSTEM;
+
+	placement->fpfn = 0;
+	placement->lpfn = 0;
+	placement->num_placement = 1;
+	placement->placement = &cur_placement;
+	placement->num_busy_placement = 0;
+	placement->busy_placement = NULL;
+	
+	/* all buffers evicted to system memory */
+	/* return cur_placement | TTM_PL_FLAG_SYSTEM; */
+}
+
+static int psb_invalidate_caches(struct ttm_bo_device *bdev,
+				 uint32_t placement)
+{
+	return 0;
+}
+
+static int psb_move_blit(struct ttm_buffer_object *bo,
+			 bool evict, bool no_wait,
+			 struct ttm_mem_reg *new_mem)
+{
+	BUG();
+	return 0;
+}
+
+/*
+ * Flip destination ttm into GATT,
+ * then blit and subsequently move out again.
+ */
+
+static int psb_move_flip(struct ttm_buffer_object *bo,
+			 bool evict, bool interruptible, bool no_wait,
+			 struct ttm_mem_reg *new_mem)
+{
+	/*struct ttm_bo_device *bdev = bo->bdev;*/
+	struct ttm_mem_reg tmp_mem;
+	int ret;
+	struct ttm_placement placement;
+	uint32_t flags = TTM_PL_FLAG_TT;
+
+	tmp_mem = *new_mem;
+	tmp_mem.mm_node = NULL;
+
+	placement.fpfn = 0;
+	placement.lpfn = 0;
+	placement.num_placement = 1;
+	placement.placement = &flags;
+	placement.num_busy_placement = 0; /* FIXME */
+	placement.busy_placement = NULL;
+
+	ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, false, no_wait);
+	if (ret)
+		return ret;
+	ret = ttm_tt_bind(bo->ttm, &tmp_mem);
+	if (ret)
+		goto out_cleanup;
+	ret = psb_move_blit(bo, true, no_wait, &tmp_mem);
+	if (ret)
+		goto out_cleanup;
+
+	ret = ttm_bo_move_ttm(bo, evict, false, no_wait, new_mem);
+out_cleanup:
+	if (tmp_mem.mm_node) {
+		/*spin_lock(&bdev->lru_lock);*/ // lru_lock is removed from upstream TTM
+		drm_mm_put_block(tmp_mem.mm_node);
+		tmp_mem.mm_node = NULL;
+		/*spin_unlock(&bdev->lru_lock);*/
+	}
+	return ret;
+}
+
+static int psb_move(struct ttm_buffer_object *bo,
+		    bool evict, bool interruptible, bool no_wait_reserve,
+		    bool no_wait, struct ttm_mem_reg *new_mem)
+{
+	struct ttm_mem_reg *old_mem = &bo->mem;
+
+	if ((old_mem->mem_type == TTM_PL_RAR) ||
+	    (new_mem->mem_type == TTM_PL_RAR)) {
+		if(old_mem->mm_node) {
+			spin_lock(&bo->glob->lru_lock);
+			drm_mm_put_block(old_mem->mm_node);
+			spin_unlock(&bo->glob->lru_lock);
+		}
+		old_mem->mm_node = NULL;
+		*old_mem = *new_mem;
+	} else if (old_mem->mem_type == TTM_PL_SYSTEM) {
+		return ttm_bo_move_memcpy(bo, evict, false, no_wait, new_mem);
+	} else if (new_mem->mem_type == TTM_PL_SYSTEM) {
+		int ret = psb_move_flip(bo, evict, interruptible,
+					no_wait, new_mem);
+		if (unlikely(ret != 0)) {
+			if (ret == -ERESTART)
+				return ret;
+			else
+				return ttm_bo_move_memcpy(bo, evict, false, no_wait,
+							  new_mem);
+		}
+	} else {
+		if (psb_move_blit(bo, evict, no_wait, new_mem))
+			return ttm_bo_move_memcpy(bo, evict, false, no_wait,
+						  new_mem);
+	}
+	return 0;
+}
+
+static int drm_psb_tbe_populate(struct ttm_backend *backend,
+				unsigned long num_pages,
+				struct page **pages,
+				struct page *dummy_read_page,
+				dma_addr_t *dma_addrs)
+{
+	struct drm_psb_ttm_backend *psb_be =
+	    container_of(backend, struct drm_psb_ttm_backend, base);
+
+	psb_be->pages = pages;
+	return 0;
+}
+
+static int drm_psb_tbe_unbind(struct ttm_backend *backend)
+{
+	struct ttm_bo_device *bdev = backend->bdev;
+	struct drm_psb_private *dev_priv =
+	    container_of(bdev, struct drm_psb_private, bdev);
+	struct drm_psb_ttm_backend *psb_be =
+	    container_of(backend, struct drm_psb_ttm_backend, base);
+	struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
+	/* struct ttm_mem_type_manager *man = &bdev->man[psb_be->mem_type]; */
+
+	if (psb_be->mem_type == TTM_PL_TT) {
+		uint32_t gatt_p_offset =
+		    (psb_be->offset - dev_priv->pg->mmu_gatt_start) >> PAGE_SHIFT;
+
+		(void) psb_gtt_remove_pages(dev_priv->pg, gatt_p_offset,
+					    psb_be->num_pages,
+					    psb_be->desired_tile_stride,
+					    psb_be->hw_tile_stride, 0);
+	}
+
+	psb_mmu_remove_pages(pd, psb_be->offset,
+			     psb_be->num_pages,
+			     psb_be->desired_tile_stride,
+			     psb_be->hw_tile_stride);
+
+	return 0;
+}
+
+static int drm_psb_tbe_bind(struct ttm_backend *backend,
+			    struct ttm_mem_reg *bo_mem)
+{
+	struct ttm_bo_device *bdev = backend->bdev;
+	struct drm_psb_private *dev_priv =
+	    container_of(bdev, struct drm_psb_private, bdev);
+	struct drm_psb_ttm_backend *psb_be =
+	    container_of(backend, struct drm_psb_ttm_backend, base);
+	struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
+	struct ttm_mem_type_manager *man = &bdev->man[bo_mem->mem_type];
+	int type;
+	int ret = 0;
+
+	psb_be->mem_type = bo_mem->mem_type;
+	psb_be->num_pages = bo_mem->num_pages;
+	psb_be->desired_tile_stride = 0;
+	psb_be->hw_tile_stride = 0;
+	psb_be->offset = (bo_mem->start << PAGE_SHIFT) +
+	    man->gpu_offset;
+
+	type =
+	    (bo_mem->
+	     placement & TTM_PL_FLAG_CACHED) ? PSB_MMU_CACHED_MEMORY : 0;
+
+	if (psb_be->mem_type == TTM_PL_TT) {
+		uint32_t gatt_p_offset =
+		    (psb_be->offset - dev_priv->pg->mmu_gatt_start) >> PAGE_SHIFT;
+
+		ret = psb_gtt_insert_pages(dev_priv->pg, psb_be->pages,
+					   gatt_p_offset,
+					   psb_be->num_pages,
+					   psb_be->desired_tile_stride,
+					   psb_be->hw_tile_stride, type);
+	}
+
+	ret = psb_mmu_insert_pages(pd, psb_be->pages,
+				   psb_be->offset, psb_be->num_pages,
+				   psb_be->desired_tile_stride,
+				   psb_be->hw_tile_stride, type);
+	if (ret)
+		goto out_err;
+
+	return 0;
+out_err:
+	drm_psb_tbe_unbind(backend);
+	return ret;
+
+}
+
+static void drm_psb_tbe_clear(struct ttm_backend *backend)
+{
+	struct drm_psb_ttm_backend *psb_be =
+	    container_of(backend, struct drm_psb_ttm_backend, base);
+
+	psb_be->pages = NULL;
+	return;
+}
+
+static void drm_psb_tbe_destroy(struct ttm_backend *backend)
+{
+	struct drm_psb_ttm_backend *psb_be =
+	    container_of(backend, struct drm_psb_ttm_backend, base);
+
+	if (backend)
+		kfree(psb_be);
+}
+
+static struct ttm_backend_func psb_ttm_backend = {
+	.populate = drm_psb_tbe_populate,
+	.clear = drm_psb_tbe_clear,
+	.bind = drm_psb_tbe_bind,
+	.unbind = drm_psb_tbe_unbind,
+	.destroy = drm_psb_tbe_destroy,
+};
+
+static struct ttm_backend *drm_psb_tbe_init(struct ttm_bo_device *bdev)
+{
+	struct drm_psb_ttm_backend *psb_be;
+
+	psb_be = kzalloc(sizeof(*psb_be), GFP_KERNEL);
+	if (!psb_be)
+		return NULL;
+	psb_be->pages = NULL;
+	psb_be->base.func = &psb_ttm_backend;
+	psb_be->base.bdev = bdev;
+	return &psb_be->base;
+}
+
+static int psb_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
+{
+	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+	struct drm_psb_private *dev_priv =
+	    container_of(bdev, struct drm_psb_private, bdev);
+	struct psb_gtt *pg = dev_priv->pg;
+
+	mem->bus.addr = NULL;
+	mem->bus.offset = 0;
+	mem->bus.size = mem->num_pages << PAGE_SHIFT;
+	mem->bus.base = 0;
+	mem->bus.is_iomem = false;
+	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
+		return -EINVAL;
+	switch (mem->mem_type) {
+	case TTM_PL_SYSTEM:
+		/* system memory */
+		return 0;
+	case TTM_PL_TT:
+		mem->bus.offset = mem->start << PAGE_SHIFT;
+		mem->bus.base = pg->gatt_start;
+		mem->bus.is_iomem = false; /* Don't know whether it is IO_MEM, this flag used in vm_fault handle */
+		break;
+	case DRM_PSB_MEM_MMU:
+		mem->bus.offset = mem->start << PAGE_SHIFT;
+		mem->bus.base = 0x00000000;
+		break;
+	case TTM_PL_CI:
+		mem->bus.offset = mem->start << PAGE_SHIFT;
+		mem->bus.base = dev_priv->ci_region_start;;
+		mem->bus.is_iomem = true;
+		break;
+	case TTM_PL_RAR:
+		mem->bus.offset = mem->start << PAGE_SHIFT;
+		mem->bus.base = dev_priv->rar_region_start;;
+		mem->bus.is_iomem = true;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void psb_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
+{
+}
+
+/*
+ * Use this memory type priority if no eviction is needed.
+ */
+/*
+static uint32_t psb_mem_prios[] = {
+	TTM_PL_CI,
+	TTM_PL_RAR,
+	TTM_PL_TT,
+	DRM_PSB_MEM_MMU,
+	TTM_PL_SYSTEM
+};
+*/
+/*
+ * Use this memory type priority if need to evict.
+ */
+/*
+static uint32_t psb_busy_prios[] = {
+	TTM_PL_TT,
+	TTM_PL_CI,
+	TTM_PL_RAR,
+	DRM_PSB_MEM_MMU,
+	TTM_PL_SYSTEM
+};
+*/
+struct ttm_bo_driver psb_ttm_bo_driver = {
+/*
+	.mem_type_prio = psb_mem_prios,
+	.mem_busy_prio = psb_busy_prios,
+	.num_mem_type_prio = ARRAY_SIZE(psb_mem_prios),
+	.num_mem_busy_prio = ARRAY_SIZE(psb_busy_prios),
+*/
+	.create_ttm_backend_entry = &drm_psb_tbe_init,
+	.invalidate_caches = &psb_invalidate_caches,
+	.init_mem_type = &psb_init_mem_type,
+	.evict_flags = &psb_evict_mask,
+	.move = &psb_move,
+	.verify_access = &psb_verify_access,
+	.sync_obj_signaled = &ttm_fence_sync_obj_signaled,
+	.sync_obj_wait = &ttm_fence_sync_obj_wait,
+	.sync_obj_flush = &ttm_fence_sync_obj_flush,
+	.sync_obj_unref = &ttm_fence_sync_obj_unref,
+	.sync_obj_ref = &ttm_fence_sync_obj_ref,
+	.io_mem_reserve = &psb_ttm_io_mem_reserve,
+	.io_mem_free = &psb_ttm_io_mem_free
+};
diff --git a/drivers/staging/cdv/imgv/psb_fence.c b/drivers/staging/cdv/imgv/psb_fence.c
new file mode 100644
index 0000000..79eea76
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_fence.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ * 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 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.
+ *
+ *
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_msvdx.h"
+
+
+static void psb_fence_poll(struct ttm_fence_device *fdev,
+			   uint32_t fence_class, uint32_t waiting_types)
+{
+	struct drm_psb_private *dev_priv =
+	    container_of(fdev, struct drm_psb_private, fdev);
+	uint32_t sequence = 0;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+
+	if (unlikely(!dev_priv))
+		return;
+
+	if (waiting_types == 0)
+		return;
+
+	switch (fence_class) {
+	case PSB_ENGINE_VIDEO:
+		sequence = msvdx_priv->msvdx_current_sequence;
+		break;
+	default:
+		break;
+	}
+
+	/* DRM_ERROR("Polling fence sequence, got 0x%08x\n", sequence); */
+	ttm_fence_handler(fdev, fence_class, sequence,
+			_PSB_FENCE_TYPE_EXE, 0);
+}
+
+void psb_fence_error(struct drm_device *dev,
+		     uint32_t fence_class,
+		     uint32_t sequence, uint32_t type, int error)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct ttm_fence_device *fdev = &dev_priv->fdev;
+	unsigned long irq_flags;
+	struct ttm_fence_class_manager *fc =
+	    &fdev->fence_class[fence_class];
+
+	BUG_ON(fence_class >= PSB_NUM_ENGINES);
+	write_lock_irqsave(&fc->lock, irq_flags);
+	ttm_fence_handler(fdev, fence_class, sequence, type, error);
+	write_unlock_irqrestore(&fc->lock, irq_flags);
+}
+
+int psb_fence_emit_sequence(struct ttm_fence_device *fdev,
+			    uint32_t fence_class,
+			    uint32_t flags, uint32_t *sequence,
+			    unsigned long *timeout_jiffies)
+{
+	struct drm_psb_private *dev_priv =
+	    container_of(fdev, struct drm_psb_private, fdev);
+	uint32_t seq = 0;
+
+	if (!dev_priv)
+		return -EINVAL;
+
+	if (fence_class >= PSB_NUM_ENGINES)
+		return -EINVAL;
+
+	switch (fence_class) {
+	case PSB_ENGINE_VIDEO:
+		spin_lock(&dev_priv->sequence_lock);
+		seq = dev_priv->sequence[fence_class]++;
+		dev_priv->sequence[fence_class] &= fdev->fence_class[fence_class].sequence_mask;
+		if (dev_priv->sequence[fence_class] == 0)
+			dev_priv->sequence[fence_class]++;
+
+		spin_unlock(&dev_priv->sequence_lock);
+		break;
+	default:
+		DRM_ERROR("Unexpected fence class\n");
+		return -EINVAL;
+	}
+
+	*sequence = seq;
+	*timeout_jiffies = jiffies + DRM_HZ * 3;
+
+	return 0;
+}
+
+static void psb_fence_lockup(struct ttm_fence_object *fence,
+			     uint32_t fence_types)
+{
+	struct ttm_fence_device *fdev = fence->fdev;
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+	struct drm_psb_private *dev_priv =
+		container_of(fdev, struct drm_psb_private, fdev);
+	struct drm_device *dev =  (struct drm_device *)dev_priv->dev;
+
+	if (fence->fence_class == PSB_ENGINE_VIDEO) {
+		struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+		DRM_ERROR("MSVDX timeout (probable lockup) detected, flush queued cmdbuf");
+
+		psb_msvdx_flush_cmd_queue(dev);
+
+		write_lock(&fc->lock);
+		ttm_fence_handler(fence->fdev, fence->fence_class,
+				  fence->sequence, fence_types, -EBUSY);
+		write_unlock(&fc->lock);
+		
+		msvdx_priv->msvdx_needs_reset = 1;
+	} else 
+		DRM_ERROR("Unsupported fence class\n");
+}
+
+void psb_fence_handler(struct drm_device *dev, uint32_t fence_class)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct ttm_fence_device *fdev = &dev_priv->fdev;
+	struct ttm_fence_class_manager *fc =
+	    &fdev->fence_class[fence_class];
+	unsigned long irq_flags;
+
+	write_lock_irqsave(&fc->lock, irq_flags);
+	psb_fence_poll(fdev, fence_class, _PSB_FENCE_TYPE_EXE);
+	write_unlock_irqrestore(&fc->lock, irq_flags);
+}
+
+
+static struct ttm_fence_driver psb_ttm_fence_driver = {
+	.has_irq = NULL,
+	.emit = psb_fence_emit_sequence,
+	.flush = NULL,
+	.poll = psb_fence_poll,
+	.needed_flush = NULL,
+	.wait = NULL,
+	.signaled = NULL,
+	.lockup = psb_fence_lockup,
+};
+
+int psb_ttm_fence_device_init(struct ttm_fence_device *fdev)
+{
+	struct drm_psb_private *dev_priv =
+		container_of(fdev, struct drm_psb_private, fdev);
+	struct ttm_fence_class_init fci = {.wrap_diff = (1 << 30),
+		.flush_diff = (1 << 29),
+		.sequence_mask = 0xFFFFFFFF
+	};
+
+	return ttm_fence_device_init(PSB_NUM_ENGINES,
+				     dev_priv->mem_global_ref.object,
+				     fdev, &fci, 1,
+				     &psb_ttm_fence_driver);
+}
diff --git a/drivers/staging/cdv/imgv/psb_mmu.c b/drivers/staging/cdv/imgv/psb_mmu.c
new file mode 100644
index 0000000..aa32627
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_mmu.c
@@ -0,0 +1,1041 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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 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.
+ *
+ **************************************************************************/
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_reg.h"
+
+/*
+ * Code for the SGX MMU:
+ */
+
+/*
+ * clflush on one processor only:
+ * clflush should apparently flush the cache line on all processors in an
+ * SMP system.
+ */
+
+/*
+ * kmap atomic:
+ * The usage of the slots must be completely encapsulated within a spinlock, and
+ * no other functions that may be using the locks for other purposed may be
+ * called from within the locked region.
+ * Since the slots are per processor, this will guarantee that we are the only
+ * user.
+ */
+
+/*
+ * TODO: Inserting ptes from an interrupt handler:
+ * This may be desirable for some SGX functionality where the GPU can fault in
+ * needed pages. For that, we need to make an atomic insert_pages function, that
+ * may fail.
+ * If it fails, the caller need to insert the page using a workqueue function,
+ * but on average it should be fast.
+ */
+
+struct psb_mmu_driver {
+	/* protects driver- and pd structures. Always take in read mode
+	 * before taking the page table spinlock.
+	 */
+	struct rw_semaphore sem;
+
+	/* protects page tables, directory tables and pt tables.
+	 * and pt structures.
+	 */
+	spinlock_t lock;
+
+	atomic_t needs_tlbflush;
+
+	uint8_t __iomem *register_map;
+	struct psb_mmu_pd *default_pd;
+	/*uint32_t bif_ctrl;*/
+	int has_clflush;
+	int clflush_add;
+	unsigned long clflush_mask;
+
+	struct drm_psb_private *dev_priv;
+};
+
+struct psb_mmu_pd;
+
+struct psb_mmu_pt {
+	struct psb_mmu_pd *pd;
+	uint32_t index;
+	uint32_t count;
+	struct page *p;
+	uint32_t *v;
+};
+
+struct psb_mmu_pd {
+	struct psb_mmu_driver *driver;
+	int hw_context;
+	struct psb_mmu_pt **tables;
+	struct page *p;
+	struct page *dummy_pt;
+	struct page *dummy_page;
+	uint32_t pd_mask;
+	uint32_t invalid_pde;
+	uint32_t invalid_pte;
+};
+
+static inline uint32_t psb_mmu_pt_index(uint32_t offset)
+{
+	return (offset >> PSB_PTE_SHIFT) & 0x3FF;
+}
+
+static inline uint32_t psb_mmu_pd_index(uint32_t offset)
+{
+	return offset >> PSB_PDE_SHIFT;
+}
+
+#if defined(CONFIG_X86)
+static inline void psb_clflush(void *addr)
+{
+	__asm__ __volatile__("clflush (%0)\n" : : "r"(addr) : "memory");
+}
+
+static inline void psb_mmu_clflush(struct psb_mmu_driver *driver,
+				   void *addr)
+{
+	if (!driver->has_clflush)
+		return;
+
+	mb();
+	psb_clflush(addr);
+	mb();
+}
+
+static void psb_page_clflush(struct psb_mmu_driver *driver, struct page* page)
+{
+	uint32_t clflush_add = driver->clflush_add >> PAGE_SHIFT;
+	uint32_t clflush_count = PAGE_SIZE / clflush_add;
+	int i;
+	uint8_t *clf;
+
+	clf = kmap_atomic(page, KM_USER0);
+	mb();
+	for (i = 0; i < clflush_count; ++i) {
+		psb_clflush(clf);
+		clf += clflush_add;
+	}
+	mb();
+	kunmap_atomic(clf, KM_USER0);
+}
+
+static void psb_pages_clflush(struct psb_mmu_driver *driver, struct page *page[], unsigned long num_pages)
+{
+	int i;
+
+	if (!driver->has_clflush)
+		return ;
+
+	for(i = 0; i < num_pages; i++ )
+		psb_page_clflush(driver, *page++);
+}
+#else
+
+static inline void psb_mmu_clflush(struct psb_mmu_driver *driver,
+				   void *addr)
+{;
+}
+
+static void psb_pages_clflush(struct psb_mmu_driver *driver, struct page *page[], unsigned long num_pages)
+{
+	printk("Dumy psb_pages_clflush\n");
+}
+
+#endif
+
+static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver,
+				    int force)
+{
+	if (atomic_read(&driver->needs_tlbflush) || force) {
+		if (driver->dev_priv)
+			atomic_set(&driver->dev_priv->msvdx_mmu_invaldc, 1);
+	}
+	atomic_set(&driver->needs_tlbflush, 0);
+}
+
+static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force)
+{
+	down_write(&driver->sem);
+	psb_mmu_flush_pd_locked(driver, force);
+	up_write(&driver->sem);
+}
+
+void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot)
+{
+	if (rc_prot)
+		down_write(&driver->sem);
+
+	if (driver->dev_priv)
+		atomic_set(&driver->dev_priv->msvdx_mmu_invaldc, 1);
+
+	if (rc_prot)
+		up_write(&driver->sem);
+}
+
+void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context)
+{
+	/*ttm_tt_cache_flush(&pd->p, 1);*/
+	psb_pages_clflush(pd->driver, &pd->p, 1);
+	down_write(&pd->driver->sem);
+	wmb();
+	psb_mmu_flush_pd_locked(pd->driver, 1);
+	pd->hw_context = hw_context;
+	up_write(&pd->driver->sem);
+
+}
+
+static inline unsigned long psb_pd_addr_end(unsigned long addr,
+					    unsigned long end)
+{
+
+	addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK;
+	return (addr < end) ? addr : end;
+}
+
+static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type)
+{
+	uint32_t mask = PSB_PTE_VALID;
+
+	if (type & PSB_MMU_CACHED_MEMORY)
+		mask |= PSB_PTE_CACHED;
+	if (type & PSB_MMU_RO_MEMORY)
+		mask |= PSB_PTE_RO;
+	if (type & PSB_MMU_WO_MEMORY)
+		mask |= PSB_PTE_WO;
+
+	return (pfn << PAGE_SHIFT) | mask;
+}
+
+struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
+				    int trap_pagefaults, int invalid_type)
+{
+	struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL);
+	uint32_t *v;
+	int i;
+
+	if (!pd)
+		return NULL;
+
+	pd->p = alloc_page(GFP_DMA32);
+	if (!pd->p)
+		goto out_err1;
+	pd->dummy_pt = alloc_page(GFP_DMA32);
+	if (!pd->dummy_pt)
+		goto out_err2;
+	pd->dummy_page = alloc_page(GFP_DMA32);
+	if (!pd->dummy_page)
+		goto out_err3;
+
+	if (!trap_pagefaults) {
+		pd->invalid_pde =
+		    psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt),
+				     invalid_type);
+		pd->invalid_pte =
+		    psb_mmu_mask_pte(page_to_pfn(pd->dummy_page),
+				     invalid_type);
+	} else {
+		pd->invalid_pde = 0;
+		pd->invalid_pte = 0;
+	}
+
+	v = kmap(pd->dummy_pt);
+	for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
+		v[i] = pd->invalid_pte;
+
+	kunmap(pd->dummy_pt);
+
+	v = kmap(pd->p);
+	for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
+		v[i] = pd->invalid_pde;
+
+	kunmap(pd->p);
+
+	clear_page(kmap(pd->dummy_page));
+	kunmap(pd->dummy_page);
+
+	pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024);
+	if (!pd->tables)
+		goto out_err4;
+
+	pd->hw_context = -1;
+	pd->pd_mask = PSB_PTE_VALID;
+	pd->driver = driver;
+
+	return pd;
+
+out_err4:
+	__free_page(pd->dummy_page);
+out_err3:
+	__free_page(pd->dummy_pt);
+out_err2:
+	__free_page(pd->p);
+out_err1:
+	kfree(pd);
+	return NULL;
+}
+
+void psb_mmu_free_pt(struct psb_mmu_pt *pt)
+{
+	__free_page(pt->p);
+	kfree(pt);
+}
+
+void psb_mmu_free_pagedir(struct psb_mmu_pd *pd)
+{
+	struct psb_mmu_driver *driver = pd->driver;
+	struct psb_mmu_pt *pt;
+	int i;
+
+	down_write(&driver->sem);
+	if (pd->hw_context != -1)
+		psb_mmu_flush_pd_locked(driver, 1);
+
+	/* Should take the spinlock here, but we don't need to do that
+	   since we have the semaphore in write mode. */
+
+	for (i = 0; i < 1024; ++i) {
+		pt = pd->tables[i];
+		if (pt)
+			psb_mmu_free_pt(pt);
+	}
+
+	vfree(pd->tables);
+	__free_page(pd->dummy_page);
+	__free_page(pd->dummy_pt);
+	__free_page(pd->p);
+	kfree(pd);
+	up_write(&driver->sem);
+}
+
+static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd)
+{
+	struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL);
+	void *v;
+	uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT;
+	uint32_t clflush_count = PAGE_SIZE / clflush_add;
+	spinlock_t *lock = &pd->driver->lock;
+	uint8_t *clf;
+	uint32_t *ptes;
+	int i;
+
+	if (!pt)
+		return NULL;
+
+	pt->p = alloc_page(GFP_DMA32);
+	if (!pt->p) {
+		kfree(pt);
+		return NULL;
+	}
+
+	spin_lock(lock);
+
+	v = kmap_atomic(pt->p, KM_USER0);
+	clf = (uint8_t *) v;
+	ptes = (uint32_t *) v;
+	for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
+		*ptes++ = pd->invalid_pte;
+
+
+#if defined(CONFIG_X86)
+	if (pd->driver->has_clflush && pd->hw_context != -1) {
+		mb();
+		for (i = 0; i < clflush_count; ++i) {
+			psb_clflush(clf);
+			clf += clflush_add;
+		}
+		mb();
+	}
+#endif
+	kunmap_atomic(v, KM_USER0);
+	spin_unlock(lock);
+
+	pt->count = 0;
+	pt->pd = pd;
+	pt->index = 0;
+
+	return pt;
+}
+
+struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd,
+					     unsigned long addr)
+{
+	uint32_t index = psb_mmu_pd_index(addr);
+	struct psb_mmu_pt *pt;
+	uint32_t *v;
+	spinlock_t *lock = &pd->driver->lock;
+
+	spin_lock(lock);
+	pt = pd->tables[index];
+	while (!pt) {
+		spin_unlock(lock);
+		pt = psb_mmu_alloc_pt(pd);
+		if (!pt)
+			return NULL;
+		spin_lock(lock);
+
+		if (pd->tables[index]) {
+			spin_unlock(lock);
+			psb_mmu_free_pt(pt);
+			spin_lock(lock);
+			pt = pd->tables[index];
+			continue;
+		}
+
+		v = kmap_atomic(pd->p, KM_USER0);
+		pd->tables[index] = pt;
+		v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask;
+		pt->index = index;
+		kunmap_atomic((void *) v, KM_USER0);
+
+		if (pd->hw_context != -1) {
+			psb_mmu_clflush(pd->driver, (void *) &v[index]);
+			atomic_set(&pd->driver->needs_tlbflush, 1);
+		}
+	}
+	pt->v = kmap_atomic(pt->p, KM_USER0);
+	return pt;
+}
+
+static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd,
+					      unsigned long addr)
+{
+	uint32_t index = psb_mmu_pd_index(addr);
+	struct psb_mmu_pt *pt;
+	spinlock_t *lock = &pd->driver->lock;
+
+	spin_lock(lock);
+	pt = pd->tables[index];
+	if (!pt) {
+		spin_unlock(lock);
+		return NULL;
+	}
+	pt->v = kmap_atomic(pt->p, KM_USER0);
+	return pt;
+}
+
+static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt)
+{
+	struct psb_mmu_pd *pd = pt->pd;
+	uint32_t *v;
+
+	kunmap_atomic(pt->v, KM_USER0);
+	if (pt->count == 0) {
+		v = kmap_atomic(pd->p, KM_USER0);
+		v[pt->index] = pd->invalid_pde;
+		pd->tables[pt->index] = NULL;
+
+		if (pd->hw_context != -1) {
+			psb_mmu_clflush(pd->driver,
+					(void *) &v[pt->index]);
+			atomic_set(&pd->driver->needs_tlbflush, 1);
+		}
+		kunmap_atomic(pt->v, KM_USER0);
+		spin_unlock(&pd->driver->lock);
+		psb_mmu_free_pt(pt);
+		return;
+	}
+	spin_unlock(&pd->driver->lock);
+}
+
+static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt,
+				   unsigned long addr, uint32_t pte)
+{
+	pt->v[psb_mmu_pt_index(addr)] = pte;
+}
+
+static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt,
+					  unsigned long addr)
+{
+	pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte;
+}
+
+#if 0
+static uint32_t psb_mmu_check_pte_locked(struct psb_mmu_pd *pd,
+					 uint32_t mmu_offset)
+{
+	uint32_t *v;
+	uint32_t pfn;
+
+	v = kmap_atomic(pd->p, KM_USER0);
+	if (!v) {
+		printk(KERN_INFO "Could not kmap pde page.\n");
+		return 0;
+	}
+	pfn = v[psb_mmu_pd_index(mmu_offset)];
+	/*      printk(KERN_INFO "pde is 0x%08x\n",pfn); */
+	kunmap_atomic(v, KM_USER0);
+	if (((pfn & 0x0F) != PSB_PTE_VALID)) {
+		printk(KERN_INFO "Strange pde at 0x%08x: 0x%08x.\n",
+		       mmu_offset, pfn);
+	}
+	v = ioremap(pfn & 0xFFFFF000, 4096);
+	if (!v) {
+		printk(KERN_INFO "Could not kmap pte page.\n");
+		return 0;
+	}
+	pfn = v[psb_mmu_pt_index(mmu_offset)];
+	/* printk(KERN_INFO "pte is 0x%08x\n",pfn); */
+	iounmap(v);
+	if (((pfn & 0x0F) != PSB_PTE_VALID)) {
+		printk(KERN_INFO "Strange pte at 0x%08x: 0x%08x.\n",
+		       mmu_offset, pfn);
+	}
+	return pfn >> PAGE_SHIFT;
+}
+
+static void psb_mmu_check_mirrored_gtt(struct psb_mmu_pd *pd,
+				       uint32_t mmu_offset,
+				       uint32_t gtt_pages)
+{
+	uint32_t start;
+	uint32_t next;
+
+	printk(KERN_INFO "Checking mirrored gtt 0x%08x %d\n",
+	       mmu_offset, gtt_pages);
+	down_read(&pd->driver->sem);
+	start = psb_mmu_check_pte_locked(pd, mmu_offset);
+	mmu_offset += PAGE_SIZE;
+	gtt_pages -= 1;
+	while (gtt_pages--) {
+		next = psb_mmu_check_pte_locked(pd, mmu_offset);
+		if (next != start + 1) {
+			printk(KERN_INFO
+			       "Ptes out of order: 0x%08x, 0x%08x.\n",
+			       start, next);
+		}
+		start = next;
+		mmu_offset += PAGE_SIZE;
+	}
+	up_read(&pd->driver->sem);
+}
+
+#endif
+
+void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
+			uint32_t mmu_offset, uint32_t gtt_start,
+			uint32_t gtt_pages)
+{
+	uint32_t *v;
+	uint32_t start = psb_mmu_pd_index(mmu_offset);
+	struct psb_mmu_driver *driver = pd->driver;
+	int num_pages = gtt_pages;
+
+	down_read(&driver->sem);
+	spin_lock(&driver->lock);
+
+	v = kmap_atomic(pd->p, KM_USER0);
+	v += start;
+
+	while (gtt_pages--) {
+		*v++ = gtt_start | pd->pd_mask;
+		gtt_start += PAGE_SIZE;
+	}
+
+	/*ttm_tt_cache_flush(&pd->p, num_pages);*/
+	psb_pages_clflush(pd->driver, &pd->p, num_pages);
+	kunmap_atomic(v, KM_USER0);
+	spin_unlock(&driver->lock);
+
+	if (pd->hw_context != -1)
+		atomic_set(&pd->driver->needs_tlbflush, 1);
+
+	up_read(&pd->driver->sem);
+	psb_mmu_flush_pd(pd->driver, 0);
+}
+
+struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver)
+{
+	struct psb_mmu_pd *pd;
+
+	/* down_read(&driver->sem); */
+	pd = driver->default_pd;
+	/* up_read(&driver->sem); */
+
+	return pd;
+}
+
+/* Returns the physical address of the PD shared by sgx/msvdx */
+uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver)
+{
+	struct psb_mmu_pd *pd;
+
+	pd = psb_mmu_get_default_pd(driver);
+	return page_to_pfn(pd->p) << PAGE_SHIFT;
+}
+
+void psb_mmu_driver_takedown(struct psb_mmu_driver *driver)
+{
+	psb_mmu_free_pagedir(driver->default_pd);
+	kfree(driver);
+}
+
+struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
+					int trap_pagefaults,
+					int invalid_type,
+					struct drm_psb_private *dev_priv)
+{
+	struct psb_mmu_driver *driver;
+
+	driver = kmalloc(sizeof(*driver), GFP_KERNEL);
+
+	if (!driver)
+		return NULL;
+	driver->dev_priv = dev_priv;
+
+	driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults,
+					      invalid_type);
+	if (!driver->default_pd)
+		goto out_err1;
+
+	spin_lock_init(&driver->lock);
+	init_rwsem(&driver->sem);
+	down_write(&driver->sem);
+	driver->register_map = registers;
+	atomic_set(&driver->needs_tlbflush, 1);
+
+	driver->has_clflush = 0;
+
+#if defined(CONFIG_X86)
+	if (boot_cpu_has(X86_FEATURE_CLFLSH)) {
+		uint32_t tfms, misc, cap0, cap4, clflush_size;
+
+		/*
+		 * clflush size is determined at kernel setup for x86_64
+		 *  but not for i386. We have to do it here.
+		 */
+
+		cpuid(0x00000001, &tfms, &misc, &cap0, &cap4);
+		clflush_size = ((misc >> 8) & 0xff) * 8;
+		driver->has_clflush = 1;
+		driver->clflush_add = PAGE_SIZE * clflush_size / sizeof(uint32_t);
+		driver->clflush_mask = driver->clflush_add - 1;
+		driver->clflush_mask = ~driver->clflush_mask;
+	}
+#endif
+
+	up_write(&driver->sem);
+	return driver;
+
+out_err1:
+	kfree(driver);
+	return NULL;
+}
+
+#if defined(CONFIG_X86)
+static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd,
+			       unsigned long address, uint32_t num_pages,
+			       uint32_t desired_tile_stride,
+			       uint32_t hw_tile_stride)
+{
+	struct psb_mmu_pt *pt;
+	uint32_t rows = 1;
+	uint32_t i;
+	unsigned long addr;
+	unsigned long end;
+	unsigned long next;
+	unsigned long add;
+	unsigned long row_add;
+	unsigned long clflush_add = pd->driver->clflush_add;
+	unsigned long clflush_mask = pd->driver->clflush_mask;
+
+	if (!pd->driver->has_clflush) {
+		/*ttm_tt_cache_flush(&pd->p, num_pages);*/
+		psb_pages_clflush(pd->driver, &pd->p, num_pages);
+		return;
+	}
+
+	if (hw_tile_stride)
+		rows = num_pages / desired_tile_stride;
+	else
+		desired_tile_stride = num_pages;
+
+	add = desired_tile_stride << PAGE_SHIFT;
+	row_add = hw_tile_stride << PAGE_SHIFT;
+	mb();
+	for (i = 0; i < rows; ++i) {
+
+		addr = address;
+		end = addr + add;
+
+		do {
+			next = psb_pd_addr_end(addr, end);
+			pt = psb_mmu_pt_map_lock(pd, addr);
+			if (!pt)
+				continue;
+			do {
+				psb_clflush(&pt->v
+					    [psb_mmu_pt_index(addr)]);
+			} while (addr +=
+				 clflush_add,
+				 (addr & clflush_mask) < next);
+
+			psb_mmu_pt_unmap_unlock(pt);
+		} while (addr = next, next != end);
+		address += row_add;
+	}
+	mb();
+}
+#else
+static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd,
+			       unsigned long address, uint32_t num_pages,
+			       uint32_t desired_tile_stride,
+			       uint32_t hw_tile_stride)
+{
+	drm_ttm_cache_flush(&pd->p, num_pages);
+}
+#endif
+
+void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
+				 unsigned long address, uint32_t num_pages)
+{
+	struct psb_mmu_pt *pt;
+	unsigned long addr;
+	unsigned long end;
+	unsigned long next;
+	unsigned long f_address = address;
+
+	down_read(&pd->driver->sem);
+
+	addr = address;
+	end = addr + (num_pages << PAGE_SHIFT);
+
+	do {
+		next = psb_pd_addr_end(addr, end);
+		pt = psb_mmu_pt_alloc_map_lock(pd, addr);
+		if (!pt)
+			goto out;
+		do {
+			psb_mmu_invalidate_pte(pt, addr);
+			--pt->count;
+		} while (addr += PAGE_SIZE, addr < next);
+		psb_mmu_pt_unmap_unlock(pt);
+
+	} while (addr = next, next != end);
+
+out:
+	if (pd->hw_context != -1)
+		psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
+
+	up_read(&pd->driver->sem);
+
+	if (pd->hw_context != -1)
+		psb_mmu_flush(pd->driver, 0);
+
+	return;
+}
+
+void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address,
+			  uint32_t num_pages, uint32_t desired_tile_stride,
+			  uint32_t hw_tile_stride)
+{
+	struct psb_mmu_pt *pt;
+	uint32_t rows = 1;
+	uint32_t i;
+	unsigned long addr;
+	unsigned long end;
+	unsigned long next;
+	unsigned long add;
+	unsigned long row_add;
+	unsigned long f_address = address;
+
+	if (hw_tile_stride)
+		rows = num_pages / desired_tile_stride;
+	else
+		desired_tile_stride = num_pages;
+
+	add = desired_tile_stride << PAGE_SHIFT;
+	row_add = hw_tile_stride << PAGE_SHIFT;
+
+	/* down_read(&pd->driver->sem); */
+
+	/* Make sure we only need to flush this processor's cache */
+
+	for (i = 0; i < rows; ++i) {
+
+		addr = address;
+		end = addr + add;
+
+		do {
+			next = psb_pd_addr_end(addr, end);
+			pt = psb_mmu_pt_map_lock(pd, addr);
+			if (!pt)
+				continue;
+			do {
+				psb_mmu_invalidate_pte(pt, addr);
+				--pt->count;
+
+			} while (addr += PAGE_SIZE, addr < next);
+			psb_mmu_pt_unmap_unlock(pt);
+
+		} while (addr = next, next != end);
+		address += row_add;
+	}
+	if (pd->hw_context != -1)
+		psb_mmu_flush_ptes(pd, f_address, num_pages,
+				   desired_tile_stride, hw_tile_stride);
+
+	/* up_read(&pd->driver->sem); */
+
+	if (pd->hw_context != -1)
+		psb_mmu_flush(pd->driver, 0);
+}
+
+int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn,
+				unsigned long address, uint32_t num_pages,
+				int type)
+{
+	struct psb_mmu_pt *pt;
+	uint32_t pte;
+	unsigned long addr;
+	unsigned long end;
+	unsigned long next;
+	unsigned long f_address = address;
+	int ret = 0;
+
+	down_read(&pd->driver->sem);
+
+	addr = address;
+	end = addr + (num_pages << PAGE_SHIFT);
+
+	do {
+		next = psb_pd_addr_end(addr, end);
+		pt = psb_mmu_pt_alloc_map_lock(pd, addr);
+		if (!pt) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		do {
+			pte = psb_mmu_mask_pte(start_pfn++, type);
+			psb_mmu_set_pte(pt, addr, pte);
+			pt->count++;
+		} while (addr += PAGE_SIZE, addr < next);
+		psb_mmu_pt_unmap_unlock(pt);
+
+	} while (addr = next, next != end);
+
+out:
+	if (pd->hw_context != -1)
+		psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
+
+	up_read(&pd->driver->sem);
+
+	if (pd->hw_context != -1)
+		psb_mmu_flush(pd->driver, 1);
+
+	return ret;
+}
+
+int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
+			 unsigned long address, uint32_t num_pages,
+			 uint32_t desired_tile_stride,
+			 uint32_t hw_tile_stride, int type)
+{
+	struct psb_mmu_pt *pt;
+	uint32_t rows = 1;
+	uint32_t i;
+	uint32_t pte;
+	unsigned long addr;
+	unsigned long end;
+	unsigned long next;
+	unsigned long add;
+	unsigned long row_add;
+	unsigned long f_address = address;
+	int ret = 0;
+
+	if (hw_tile_stride) {
+		if (num_pages % desired_tile_stride != 0)
+			return -EINVAL;
+		rows = num_pages / desired_tile_stride;
+	} else {
+		desired_tile_stride = num_pages;
+	}
+
+	add = desired_tile_stride << PAGE_SHIFT;
+	row_add = hw_tile_stride << PAGE_SHIFT;
+
+	down_read(&pd->driver->sem);
+
+	for (i = 0; i < rows; ++i) {
+
+		addr = address;
+		end = addr + add;
+
+		do {
+			next = psb_pd_addr_end(addr, end);
+			pt = psb_mmu_pt_alloc_map_lock(pd, addr);
+			if (!pt) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			do {
+				pte =
+				    psb_mmu_mask_pte(page_to_pfn(*pages++),
+						     type);
+				psb_mmu_set_pte(pt, addr, pte);
+				pt->count++;
+			} while (addr += PAGE_SIZE, addr < next);
+			psb_mmu_pt_unmap_unlock(pt);
+
+		} while (addr = next, next != end);
+
+		address += row_add;
+	}
+out:
+	if (pd->hw_context != -1)
+		psb_mmu_flush_ptes(pd, f_address, num_pages,
+				   desired_tile_stride, hw_tile_stride);
+
+	up_read(&pd->driver->sem);
+
+	if (pd->hw_context != -1)
+		psb_mmu_flush(pd->driver, 1);
+
+	return ret;
+}
+#if 0 /*comented out, only used in mmu test now*/
+void psb_mmu_enable_requestor(struct psb_mmu_driver *driver, uint32_t mask)
+{
+	mask &= _PSB_MMU_ER_MASK;
+	psb_iowrite32(driver,
+		      psb_ioread32(driver, PSB_CR_BIF_CTRL) & ~mask,
+		      PSB_CR_BIF_CTRL);
+	(void) psb_ioread32(driver, PSB_CR_BIF_CTRL);
+}
+
+void psb_mmu_disable_requestor(struct psb_mmu_driver *driver,
+			       uint32_t mask)
+{
+	mask &= _PSB_MMU_ER_MASK;
+	psb_iowrite32(driver, psb_ioread32(driver, PSB_CR_BIF_CTRL) | mask,
+		      PSB_CR_BIF_CTRL);
+	(void) psb_ioread32(driver, PSB_CR_BIF_CTRL);
+}
+#endif
+int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
+			   unsigned long *pfn)
+{
+	int ret;
+	struct psb_mmu_pt *pt;
+	uint32_t tmp;
+	spinlock_t *lock = &pd->driver->lock;
+
+	down_read(&pd->driver->sem);
+	pt = psb_mmu_pt_map_lock(pd, virtual);
+	if (!pt) {
+		uint32_t *v;
+
+		spin_lock(lock);
+		v = kmap_atomic(pd->p, KM_USER0);
+		tmp = v[psb_mmu_pd_index(virtual)];
+		kunmap_atomic(v, KM_USER0);
+		spin_unlock(lock);
+
+		if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) ||
+		    !(pd->invalid_pte & PSB_PTE_VALID)) {
+			ret = -EINVAL;
+			goto out;
+		}
+		ret = 0;
+		*pfn = pd->invalid_pte >> PAGE_SHIFT;
+		goto out;
+	}
+	tmp = pt->v[psb_mmu_pt_index(virtual)];
+	if (!(tmp & PSB_PTE_VALID)) {
+		ret = -EINVAL;
+	} else {
+		ret = 0;
+		*pfn = tmp >> PAGE_SHIFT;
+	}
+	psb_mmu_pt_unmap_unlock(pt);
+out:
+	up_read(&pd->driver->sem);
+	return ret;
+}
+#if 0
+void psb_mmu_test(struct psb_mmu_driver *driver, uint32_t offset)
+{
+	struct page *p;
+	unsigned long pfn;
+	int ret = 0;
+	struct psb_mmu_pd *pd;
+	uint32_t *v;
+	uint32_t *vmmu;
+
+	pd = driver->default_pd;
+	if (!pd)
+		printk(KERN_WARNING "Could not get default pd\n");
+
+
+	p = alloc_page(GFP_DMA32);
+
+	if (!p) {
+		printk(KERN_WARNING "Failed allocating page\n");
+		return;
+	}
+
+	v = kmap(p);
+	memset(v, 0x67, PAGE_SIZE);
+
+	pfn = (offset >> PAGE_SHIFT);
+
+	ret = psb_mmu_insert_pages(pd, &p, pfn << PAGE_SHIFT, 1, 0, 0, 0);
+	if (ret) {
+		printk(KERN_WARNING "Failed inserting mmu page\n");
+		goto out_err1;
+	}
+
+	/* Ioremap the page through the GART aperture */
+
+	vmmu = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+	if (!vmmu) {
+		printk(KERN_WARNING "Failed ioremapping page\n");
+		goto out_err2;
+	}
+
+	/* Read from the page with mmu disabled. */
+	printk(KERN_INFO "Page first dword is 0x%08x\n", ioread32(vmmu));
+
+	/* Enable the mmu for host accesses and read again. */
+	psb_mmu_enable_requestor(driver, _PSB_MMU_ER_HOST);
+
+	printk(KERN_INFO "MMU Page first dword is (0x67676767) 0x%08x\n",
+	       ioread32(vmmu));
+	*v = 0x15243705;
+	printk(KERN_INFO "MMU Page new dword is (0x15243705) 0x%08x\n",
+	       ioread32(vmmu));
+	iowrite32(0x16243355, vmmu);
+	(void) ioread32(vmmu);
+	printk(KERN_INFO "Page new dword is (0x16243355) 0x%08x\n", *v);
+
+	printk(KERN_INFO "Int stat is 0x%08x\n",
+	       psb_ioread32(driver, PSB_CR_BIF_INT_STAT));
+	printk(KERN_INFO "Fault is 0x%08x\n",
+	       psb_ioread32(driver, PSB_CR_BIF_FAULT));
+
+	/* Disable MMU for host accesses and clear page fault register */
+	psb_mmu_disable_requestor(driver, _PSB_MMU_ER_HOST);
+	iounmap(vmmu);
+out_err2:
+	psb_mmu_remove_pages(pd, pfn << PAGE_SHIFT, 1, 0, 0);
+out_err1:
+	kunmap(p);
+	__free_page(p);
+}
+#endif
diff --git a/drivers/staging/cdv/imgv/psb_msvdx.c b/drivers/staging/cdv/imgv/psb_msvdx.c
new file mode 100644
index 0000000..fc8027b
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_msvdx.c
@@ -0,0 +1,1268 @@
+/**************************************************************************
+ * MSVDX I/O operations and IRQ handling
+ * 
+ * Copyright (c) 2011 Intel Corporation, Hillsboro, OR, USA
+ * Copyright (c) Imagination Technologies Limited, UK
+ *
+ * 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 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.
+ *
+ **************************************************************************/
+
+#include <drm/drmP.h>
+#include "psb_drm.h"
+#include "psb_drv.h"
+#include "psb_msvdx.h"
+#include "psb_powermgmt.h"
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#ifndef list_first_entry
+#define list_first_entry(ptr, type, member) \
+	list_entry((ptr)->next, type, member)
+#endif
+
+#define  DRM_MPEG2_DELAY	125
+#define INITIAL_LOOP_COUNTER	50
+#define LOOP_INTERVAL		500
+
+static int psb_msvdx_send(struct drm_device *dev, void *cmd,
+			  unsigned long cmd_size);
+
+static int psb_msvdx_dequeue_send(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct psb_msvdx_cmd_queue *msvdx_cmd = NULL;
+	int ret = 0;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
+	if (list_empty(&msvdx_priv->msvdx_queue)) {
+		msvdx_priv->msvdx_busy = 0;
+		spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+
+		PSB_DEBUG_GENERAL("MSVDXQUE: msvdx list empty.\n");
+		return -EINVAL;
+	}
+	msvdx_cmd = list_first_entry(&msvdx_priv->msvdx_queue,
+				     struct psb_msvdx_cmd_queue, head);
+	list_del_init(&msvdx_cmd->head);
+	spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+	
+	PSB_DEBUG_GENERAL("MSVDXQUE: Queue has id %08x\n", msvdx_cmd->sequence);
+	ret = psb_msvdx_send(dev, msvdx_cmd->cmd, msvdx_cmd->cmd_size);
+	if (ret) {
+		DRM_ERROR("MSVDXQUE: psb_msvdx_send failed\n");
+		ret = -EINVAL;
+	}
+	kfree(msvdx_cmd->cmd);
+	kfree(msvdx_cmd);
+
+	return ret;
+}
+
+static int psb_msvdx_map_command(struct drm_device *dev,
+				 struct ttm_buffer_object *cmd_buffer,
+				 unsigned long cmd_offset, unsigned long cmd_size,
+				 void **msvdx_cmd, uint32_t sequence, int copy_cmd)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	int ret = 0;
+	unsigned long cmd_page_offset = cmd_offset & ~PAGE_MASK;
+	unsigned long cmd_size_remaining;
+	struct ttm_bo_kmap_obj cmd_kmap;
+	void *cmd, *cmd_copy, *cmd_start;
+	bool is_iomem;
+	int i;
+	struct HOST_BE_OPP_PARAMS * oppParam;
+	drm_psb_msvdx_frame_info_t * current_frame = NULL;
+	int first_empty = -1;
+
+
+	/* command buffers may not exceed page boundary */
+	if (cmd_size + cmd_page_offset > PAGE_SIZE)
+		return -EINVAL;
+
+	ret = ttm_bo_kmap(cmd_buffer, cmd_offset >> PAGE_SHIFT, 1, &cmd_kmap);
+	if (ret) {
+		DRM_ERROR("MSVDXQUE:ret:%d\n", ret);
+		return ret;
+	}
+
+	cmd_start = (void *)ttm_kmap_obj_virtual(&cmd_kmap, &is_iomem)
+		+ cmd_page_offset;
+	cmd = cmd_start;
+	cmd_size_remaining = cmd_size;
+
+	while (cmd_size_remaining > 0) {
+		uint32_t cur_cmd_size = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_SIZE);
+		uint32_t cur_cmd_id = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_ID);
+		uint32_t mmu_ptd = 0, msvdx_mmu_invalid = 0;
+
+		PSB_DEBUG_GENERAL("cmd start at %08x cur_cmd_size = %d"
+				  " cur_cmd_id = %02x fence = %08x\n",
+				  (uint32_t) cmd, cur_cmd_size, cur_cmd_id, sequence);
+		if ((cur_cmd_size % sizeof(uint32_t))
+		    || (cur_cmd_size > cmd_size_remaining)) {
+			ret = -EINVAL;
+			DRM_ERROR("MSVDX: ret:%d\n", ret);
+			goto out;
+		}
+
+		switch (cur_cmd_id) {
+		case VA_MSGID_RENDER:
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: send render message. \n");
+            
+			/* Fence ID */
+			if((IS_CDV(dev)) && IS_FW_UPDATED)
+				MEMIO_WRITE_FIELD(cmd, FW_VA_DECODE_MSG_ID, sequence);
+			else
+				MEMIO_WRITE_FIELD(cmd, FW_VA_RENDER_FENCE_VALUE, sequence);
+
+			mmu_ptd = psb_get_default_pd_addr(dev_priv->mmu);
+			msvdx_mmu_invalid = atomic_cmpxchg(&dev_priv->msvdx_mmu_invaldc,
+					     1, 0);
+			if (msvdx_mmu_invalid == 1) {
+				if(!(IS_CDV(dev) && IS_FW_UPDATED))
+					mmu_ptd |= 1;
+				else {
+					uint32_t flags;
+					flags = MEMIO_READ_FIELD(cmd, FW_DEVA_DECODE_FLAGS);
+					flags |= FW_DEVA_INVALIDATE_MMU;
+					MEMIO_WRITE_FIELD(cmd, FW_DEVA_DECODE_FLAGS, flags);
+				}
+
+				PSB_DEBUG_GENERAL("MSVDX:Set MMU invalidate\n");
+			}
+
+			/* PTD */
+			if((IS_CDV(dev) ) && IS_FW_UPDATED) {
+				uint32_t context_id;
+				context_id = MEMIO_READ_FIELD(cmd, FW_VA_DECODE_MMUPTD);
+				mmu_ptd = mmu_ptd | (context_id & 0xff);
+				MEMIO_WRITE_FIELD(cmd, FW_VA_DECODE_MMUPTD, mmu_ptd);
+			}
+			else
+				MEMIO_WRITE_FIELD(cmd, FW_VA_RENDER_MMUPTD, mmu_ptd);
+			break;
+
+		case VA_MSGID_OOLD:
+			MEMIO_WRITE_FIELD(cmd, FW_DXVA_OOLD_FENCE_VALUE,
+					  sequence);
+			mmu_ptd = psb_get_default_pd_addr(dev_priv->mmu);
+			msvdx_mmu_invalid = atomic_cmpxchg(&dev_priv->msvdx_mmu_invaldc,
+					     1, 0);
+			if (msvdx_mmu_invalid == 1) {
+				mmu_ptd |= 1;
+				PSB_DEBUG_GENERAL("MSVDX:Set MMU invalidate\n");
+			}
+
+			/* PTD */
+			MEMIO_WRITE_FIELD(cmd, FW_DXVA_OOLD_MMUPTD, mmu_ptd);
+
+			PSB_DEBUG_GENERAL("MSVDX:Get oold cmd\n");
+
+			break;
+
+		case VA_MSGID_OOLD_MFLD:
+		case VA_MSGID_DEBLOCK_MFLD: {
+			FW_VA_DEBLOCK_MSG * deblock_msg;
+
+			PSB_DEBUG_GENERAL("MSVDX:Get deblock cmd for medfield\n");
+
+			deblock_msg = (FW_VA_DEBLOCK_MSG *)cmd;
+
+			mmu_ptd = psb_get_default_pd_addr(dev_priv->mmu);
+			msvdx_mmu_invalid = atomic_cmpxchg(&dev_priv->msvdx_mmu_invaldc,
+					     1, 0);
+			if (msvdx_mmu_invalid == 1) {
+				uint32_t flags;
+				flags = deblock_msg->flags;
+				flags |= FW_DEVA_INVALIDATE_MMU;
+				deblock_msg->flags = flags;
+
+				PSB_DEBUG_GENERAL("MSVDX:Set MMU invalidate\n");
+			}
+
+
+			deblock_msg->header.bits.msg_type = cur_cmd_id - VA_MSGID_DEBLOCK_MFLD + VA_MSGID_DEBLOCK; /* patch to right cmd type */
+			deblock_msg->header.bits.msg_fence = (uint16_t)(sequence & 0xffff);
+			deblock_msg->mmu_context.bits.mmu_ptd = (mmu_ptd >> 8);
+
+		}
+			break;
+
+		case VA_MSGID_HOST_BE_OPP:
+
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: send host_be_opp message. \n");
+
+			msvdx_priv->host_be_opp_enabled = 1;
+			/* Fence ID */
+			MEMIO_WRITE_FIELD(cmd, FW_VA_HOST_BE_OPP_FENCE_VALUE,
+					  sequence);
+			mmu_ptd = psb_get_default_pd_addr(dev_priv->mmu);
+			msvdx_mmu_invalid = atomic_cmpxchg(&dev_priv->msvdx_mmu_invaldc,
+					     1, 0);
+			if (msvdx_mmu_invalid == 1) {
+				mmu_ptd |= 1;
+				PSB_DEBUG_GENERAL("MSVDX:Set MMU invalidate\n");
+			}
+        
+			/* PTD */
+			MEMIO_WRITE_FIELD(cmd,
+					  FW_VA_HOST_BE_OPP_MMUPTD,
+					  mmu_ptd);
+
+			/* HostBeOpp message is followed by 32 bytes of host_be_opp params */
+			oppParam = kmalloc(
+				sizeof(struct HOST_BE_OPP_PARAMS),
+				GFP_KERNEL);
+
+			if (oppParam == NULL) {
+				DRM_ERROR("DEBLOCK QUE: Out of memory...\n");
+				ret =  -ENOMEM;
+				goto out;
+			}
+ 
+			memcpy(oppParam, cmd + 16, sizeof(struct HOST_BE_OPP_PARAMS));
+			/*get the right frame_info struct for current surface*/
+			for (i = 0; i < MAX_DECODE_BUFFERS; i++) {
+				if (msvdx_priv->frame_info[i].handle == oppParam->handle) {
+					current_frame = &(msvdx_priv->frame_info[i]);
+					break;
+				}
+				if ((first_empty == -1) && (msvdx_priv->frame_info[i].handle  == 0))
+					first_empty = i;
+			}
+            
+			/*if didn't find the struct for current surface, use the earliest empty one*/
+			if (!current_frame) {
+				if (first_empty == -1) {
+					DRM_ERROR("failed find the struct for current surface and also there is no empty one.\n");
+					ret = -EFAULT;
+					goto out;
+				}
+				current_frame = &(msvdx_priv->frame_info[first_empty]);
+			}
+
+			memset(current_frame, 0, sizeof(drm_psb_msvdx_frame_info_t));
+			current_frame->handle = oppParam->handle;
+			current_frame->buffer_stride = oppParam->buffer_stride;
+			current_frame->buffer_size = oppParam->buffer_size;
+			current_frame->picture_width_mb = oppParam->picture_width_mb;
+			current_frame->size_mb = oppParam->size_mb;
+			current_frame->fence = sequence;
+            
+
+			cmd += sizeof(struct HOST_BE_OPP_PARAMS);
+			cmd_size_remaining -= sizeof(struct HOST_BE_OPP_PARAMS);
+
+			break;
+
+		default:
+			/* Msg not supported */
+			ret = -EINVAL;
+			PSB_DEBUG_GENERAL("MSVDX: ret:%d\n", ret);
+			goto out;
+		}
+
+		cmd += cur_cmd_size;
+		cmd_size_remaining -= cur_cmd_size;
+	}
+
+	if (copy_cmd) {
+		PSB_DEBUG_GENERAL("MSVDXQUE:copying command\n");
+
+		cmd_copy = kzalloc(cmd_size, GFP_KERNEL);
+		if (cmd_copy == NULL) {
+			ret = -ENOMEM;
+			DRM_ERROR("MSVDX: fail to callc,ret=:%d\n", ret);
+			goto out;
+		}
+		memcpy(cmd_copy, cmd_start, cmd_size);
+		*msvdx_cmd = cmd_copy;
+	} else {
+		PSB_DEBUG_GENERAL("MSVDXQUE:did NOT copy command\n");
+		ret = psb_msvdx_send(dev, cmd_start, cmd_size);
+		if (ret) {
+			DRM_ERROR("MSVDXQUE: psb_msvdx_send failed\n");
+			ret = -EINVAL;
+		}
+	}
+
+out:
+	ttm_bo_kunmap(&cmd_kmap);
+
+	return ret;
+}
+
+int psb_submit_video_cmdbuf(struct drm_device *dev,
+			    struct ttm_buffer_object *cmd_buffer,
+			    unsigned long cmd_offset, unsigned long cmd_size,
+			    struct ttm_fence_object *fence)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	uint32_t sequence =  dev_priv->sequence[PSB_ENGINE_VIDEO];
+	unsigned long irq_flags;
+	int ret = 0;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	int offset = 0;
+	/* psb_schedule_watchdog(dev_priv); */
+
+	spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
+
+	/* expected msvdx_needs_reset is set after previous session exited
+	 * but msvdx_hw_busy is always 1, and caused powerdown not excuted
+	 * so reload the firmware for every new context
+	 */
+
+	dev_priv->last_msvdx_ctx = dev_priv->msvdx_ctx;
+
+	if (msvdx_priv->msvdx_needs_reset) {
+		spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+		PSB_DEBUG_GENERAL("MSVDX: will reset msvdx\n");
+		if (psb_msvdx_reset(dev_priv)) {
+			ret = -EBUSY;
+			DRM_ERROR("MSVDX: Reset failed\n");
+			return ret;
+		}
+		msvdx_priv->msvdx_needs_reset = 0;
+		msvdx_priv->msvdx_busy = 0;
+
+		if(psb_msvdx_init(dev)) {
+			ret = -EIO;
+			DRM_ERROR("MSVDX: failed in MSVDX Initialization\n");
+			return ret;
+		}
+
+		/* restore vec local mem if needed */
+		if (msvdx_priv->vec_local_mem_saved &&
+				msvdx_priv->vec_local_mem_data) {
+			for (offset = 0; offset < VEC_LOCAL_MEM_BYTE_SIZE / 4; ++offset)
+				PSB_WMSVDX32(msvdx_priv->vec_local_mem_data[offset],
+					     VEC_LOCAL_MEM_OFFSET + offset * 4);
+
+			msvdx_priv->vec_local_mem_saved = 0;
+		}
+
+		spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
+	}
+
+	if (!msvdx_priv->msvdx_fw_loaded) {
+		spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+		PSB_DEBUG_GENERAL("MSVDX:reload FW to MTX\n");
+
+		ret = psb_setup_fw(dev);
+		if (ret) {
+			DRM_ERROR("MSVDX:fail to load FW\n");
+			/* FIXME: find a proper return value */
+			return -EFAULT;
+		}
+		msvdx_priv->msvdx_fw_loaded = 1;
+
+		PSB_DEBUG_GENERAL("MSVDX: load firmware successfully\n");
+		spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
+	}
+
+	if (!msvdx_priv->msvdx_busy) {
+		msvdx_priv->msvdx_busy = 1;
+		spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+		PSB_DEBUG_GENERAL("MSVDX: commit command to HW,seq=0x%08x\n",
+				  sequence);
+		ret = psb_msvdx_map_command(dev, cmd_buffer, cmd_offset,
+					    cmd_size, NULL, sequence, 0);
+		if (ret) {
+			DRM_ERROR("MSVDXQUE: Failed to extract cmd\n");
+			return ret;
+		}
+	} else {
+		struct psb_msvdx_cmd_queue *msvdx_cmd;
+		void *cmd = NULL;
+
+		spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+		/* queue the command to be sent when the h/w is ready */
+		PSB_DEBUG_GENERAL("MSVDXQUE: queueing sequence:%08x..\n",
+				  sequence);
+		msvdx_cmd = kzalloc(sizeof(struct psb_msvdx_cmd_queue),
+				    GFP_KERNEL);
+		if (msvdx_cmd == NULL) {
+			DRM_ERROR("MSVDXQUE: Out of memory...\n");
+			return -ENOMEM;
+		}
+
+		ret = psb_msvdx_map_command(dev, cmd_buffer, cmd_offset,
+					    cmd_size, &cmd, sequence, 1);
+		if (ret) {
+			DRM_ERROR("MSVDXQUE: Failed to extract cmd\n");
+			kfree(msvdx_cmd
+				);
+			return ret;
+		}
+		msvdx_cmd->cmd = cmd;
+		msvdx_cmd->cmd_size = cmd_size;
+		msvdx_cmd->sequence = sequence;
+		spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
+		list_add_tail(&msvdx_cmd->head, &msvdx_priv->msvdx_queue);
+		if (!msvdx_priv->msvdx_busy) {
+			msvdx_priv->msvdx_busy = 1;
+			spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+			PSB_DEBUG_GENERAL("MSVDXQUE: Need immediate dequeue\n");
+			psb_msvdx_dequeue_send(dev);
+		} else
+			spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+	}
+
+	return ret;
+}
+
+int psb_cmdbuf_video(struct drm_file *priv,
+		     struct list_head *validate_list,
+		     uint32_t fence_type,
+		     struct drm_psb_cmdbuf_arg *arg,
+		     struct ttm_buffer_object *cmd_buffer,
+		     struct psb_ttm_fence_rep *fence_arg)
+{
+	struct drm_device *dev = priv->minor->dev;
+	struct ttm_fence_object *fence;
+	int ret;
+
+	/*
+	 * Check this. Doesn't seem right. Have fencing done AFTER command
+	 * submission and make sure drm_psb_idle idles the MSVDX completely.
+	 */
+	ret =
+		psb_submit_video_cmdbuf(dev, cmd_buffer, arg->cmdbuf_offset,
+					arg->cmdbuf_size, NULL);
+	if (ret)
+		return ret;
+
+
+	/* DRM_ERROR("Intel: Fix video fencing!!\n"); */
+	psb_fence_or_sync(priv, PSB_ENGINE_VIDEO, fence_type,
+			  arg->fence_flags, validate_list, fence_arg,
+			  &fence);
+
+	ttm_fence_object_unref(&fence);
+	spin_lock(&cmd_buffer->bdev->fence_lock);
+	if (cmd_buffer->sync_obj != NULL)
+		ttm_fence_sync_obj_unref(&cmd_buffer->sync_obj);
+	spin_unlock(&cmd_buffer->bdev->fence_lock);
+
+	return 0;
+}
+
+
+static int psb_msvdx_send(struct drm_device *dev, void *cmd,
+			  unsigned long cmd_size)
+{
+	int ret = 0;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct psb_video_ctx *msvdx_ctx = NULL;
+	int ctx_type;
+
+	while (cmd_size > 0) {
+		uint32_t cur_cmd_size = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_SIZE);
+		uint32_t cur_cmd_id = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_ID);
+		if (cur_cmd_size > cmd_size) {
+			ret = -EINVAL;
+			DRM_ERROR("MSVDX:cmd_size %lu cur_cmd_size %lu\n",
+				  cmd_size, (unsigned long)cur_cmd_size);
+			goto out;
+		}
+
+		/* Send the message to h/w */
+		ret = psb_mtx_send(dev_priv, cmd);
+		if (ret) {
+			PSB_DEBUG_GENERAL("MSVDX: ret:%d\n", ret);
+			goto out;
+		}
+		cmd += cur_cmd_size;
+		cmd_size -= cur_cmd_size;
+		if (cur_cmd_id == VA_MSGID_DEBLOCK && (!IS_CDV(dev) && IS_FW_UPDATED)) {
+			cmd += sizeof(struct DEBLOCKPARAMS);
+			cmd_size -= sizeof(struct DEBLOCKPARAMS);
+		}
+		if (cur_cmd_id == VA_MSGID_HOST_BE_OPP) {
+			cmd += sizeof(struct HOST_BE_OPP_PARAMS);
+			cmd_size -= sizeof(struct HOST_BE_OPP_PARAMS);
+		}
+		if(cmd_size && IS_CDV(dev)) {
+			msvdx_ctx = dev_priv->msvdx_ctx;
+			/* Get the Profile for the current video context */
+			ctx_type = msvdx_ctx->ctx_type >> 8;
+			if (ctx_type == VAProfileMPEG2Simple || ctx_type == VAProfileMPEG2Main)
+				udelay(DRM_MPEG2_DELAY);
+			else
+				udelay(drm_msvdx_delay);
+		}
+	}
+
+out:
+	PSB_DEBUG_GENERAL("MSVDX: ret:%d\n", ret);
+	return ret;
+}
+
+int psb_mtx_send(struct drm_psb_private *dev_priv, const void *msg)
+{
+	static uint32_t pad_msg[FWRK_PADMSG_SIZE];
+	const uint32_t *p_msg = (uint32_t *) msg;
+	uint32_t msg_num, words_free, ridx, widx, buf_size, buf_offset;
+	int ret = 0;
+	int loop_counter;
+
+	PSB_DEBUG_GENERAL("MSVDX: psb_mtx_send\n");
+
+	/* we need clocks enabled before we touch VEC local ram */
+	PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
+
+	msg_num = (MEMIO_READ_FIELD(msg, FWRK_GENMSG_SIZE) + 3) / 4;
+
+/*
+	{
+		int i;
+		printk("MSVDX: psb_mtx_send is %dDW\n", msg_num);
+
+		for(i = 0; i < msg_num; i++)
+			printk("0x%08x ", p_msg[i]);
+		printk("\n");
+	}
+*/
+	buf_size = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_BUF_SIZE) & ((1 << 16) - 1);
+
+	if (msg_num > buf_size) {
+		ret = -EINVAL;
+		DRM_ERROR("MSVDX: message exceed maximum,ret:%d\n", ret);
+		goto out;
+	}
+
+	ridx = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_RD_INDEX);
+	widx = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_WRT_INDEX);
+
+
+	buf_size = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_BUF_SIZE) & ((1 << 16) - 1);
+	/*0x2000 is VEC Local Ram offset*/
+	buf_offset =
+		(PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_BUF_SIZE) >> 16) + 0x2000;
+
+	/* message would wrap, need to send a pad message */
+	if (widx + msg_num > buf_size) {
+		/* Shouldn't happen for a PAD message itself */
+		BUG_ON(MEMIO_READ_FIELD(msg, FWRK_GENMSG_ID)
+		       == FWRK_MSGID_PADDING);
+
+		/* if the read pointer is at zero then we must wait for it to
+		 * change otherwise the write pointer will equal the read
+		 * pointer,which should only happen when the buffer is empty
+		 *
+		 * This will only happens if we try to overfill the queue,
+		 * queue management should make
+		 * sure this never happens in the first place.
+		 */
+		if (0 == ridx) {
+			ret = -EINVAL;
+			DRM_ERROR("MSVDX: RIndex=0, ret:%d\n", ret);
+			goto out;
+		}
+
+		/* Send a pad message */
+		MEMIO_WRITE_FIELD(pad_msg, FWRK_GENMSG_SIZE,
+				  (buf_size - widx) << 2);
+		MEMIO_WRITE_FIELD(pad_msg, FWRK_GENMSG_ID,
+				  FWRK_MSGID_PADDING);
+		psb_mtx_send(dev_priv, pad_msg);
+		widx = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_WRT_INDEX);
+	}
+
+	loop_counter = INITIAL_LOOP_COUNTER;
+	do {
+		ridx = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_RD_INDEX);
+		widx = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_WRT_INDEX);
+		if (widx >= ridx)
+			words_free = buf_size - (widx - ridx) -1;
+		else
+			words_free = ridx - widx - 1;
+		if (words_free >= msg_num)
+			break;
+		loop_counter--;
+		udelay(LOOP_INTERVAL);
+	} while(loop_counter);
+
+	if (msg_num > words_free) {
+		ret = -EINVAL;
+		DRM_ERROR("MSVDX: msg_num > words_free, ret:%d, Rindex =%d, Windex=%d, Buf size=%d, msg num %d\n", ret,
+				ridx, widx, buf_size, msg_num);
+		goto out;
+	}
+	while (msg_num > 0) {
+		PSB_WMSVDX32(*p_msg++, buf_offset + (widx << 2));
+		msg_num--;
+		widx++;
+		if (buf_size == widx)
+			widx = 0;
+	}
+
+	PSB_WMSVDX32(widx, MSVDX_COMMS_TO_MTX_WRT_INDEX);
+
+	/* Make sure clocks are enabled before we kick */
+	PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
+
+	PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
+
+	/* signal an interrupt to let the mtx know there is a new message */
+	/* PSB_WMSVDX32(1, MSVDX_MTX_KICKI); */
+	PSB_WMSVDX32(1, MSVDX_MTX_KICK);
+
+	/* Read MSVDX Register several times in case Idle signal assert */
+	PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
+	PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
+	PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
+	PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
+
+
+out:
+	return ret;
+}
+
+
+/*
+ * MSVDX MTX interrupt
+ */
+static void psb_msvdx_mtx_interrupt(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *)dev->dev_private;
+	static uint32_t buf[128]; /* message buffer */
+	uint32_t ridx, widx, buf_size, buf_offset;
+	uint32_t num, ofs; /* message num and offset */
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	int i;
+
+	PSB_DEBUG_GENERAL("MSVDX:Got a MSVDX MTX interrupt\n");
+
+	/* Are clocks enabled  - If not enable before
+	 * attempting to read from VLR
+	 */
+	if (PSB_RMSVDX32(MSVDX_MAN_CLK_ENABLE) != (clk_enable_all)) {
+		PSB_DEBUG_GENERAL("MSVDX:Clocks disabled when Interupt set\n");
+		PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
+	}
+
+loop: /* just for coding style check */
+	ridx = PSB_RMSVDX32(MSVDX_COMMS_TO_HOST_RD_INDEX);
+	widx = PSB_RMSVDX32(MSVDX_COMMS_TO_HOST_WRT_INDEX);
+
+	/* Get out of here if nothing */
+	if (ridx == widx)
+		goto done;
+
+	buf_size = PSB_RMSVDX32(MSVDX_COMMS_TO_HOST_BUF_SIZE) & ((1 << 16) - 1);
+	/*0x2000 is VEC Local Ram offset*/
+	buf_offset =
+		(PSB_RMSVDX32(MSVDX_COMMS_TO_HOST_BUF_SIZE) >> 16) + 0x2000;
+
+	ofs = 0;
+	buf[ofs] = PSB_RMSVDX32(buf_offset + (ridx << 2));
+
+	/* round to nearest word */
+	num = (MEMIO_READ_FIELD(buf, FWRK_GENMSG_SIZE) + 3) / 4;
+
+	/* ASSERT(num <= sizeof(buf) / sizeof(uint32_t)); */
+
+	if (++ridx >= buf_size)
+		ridx = 0;
+
+	for (ofs++; ofs < num; ofs++) {
+		buf[ofs] = PSB_RMSVDX32(buf_offset + (ridx << 2));
+
+		if (++ridx >= buf_size)
+			ridx = 0;
+	}
+
+	/* Update the Read index */
+	PSB_WMSVDX32(ridx, MSVDX_COMMS_TO_HOST_RD_INDEX);
+
+	if (msvdx_priv->msvdx_needs_reset)
+		goto loop;
+
+	switch (MEMIO_READ_FIELD(buf, FWRK_GENMSG_ID)) {
+	case VA_MSGID_CMD_HW_PANIC:
+	case VA_MSGID_CMD_FAILED: {
+		/* For VXD385 firmware, fence value is not validate here */
+		uint32_t msg_id = MEMIO_READ_FIELD(buf, FWRK_GENMSG_ID);
+		uint32_t diff = 0;
+		uint32_t fence, fault = 0;
+		drm_psb_msvdx_frame_info_t *failed_frame = NULL;
+        
+		if (msg_id == VA_MSGID_CMD_HW_PANIC)
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: get panic message.\n");
+		else
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: get failed message.\n");
+        
+		if (msg_id == VA_MSGID_CMD_HW_PANIC) {
+			fence = MEMIO_READ_FIELD(buf,
+						 FW_VA_HW_PANIC_FENCE_VALUE);
+			printk("jiangfei debug: fence in panic message is %d.\n", fence);
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: PANIC MESSAGE fence is %d.\n", MEMIO_READ_FIELD(buf, FW_VA_HW_PANIC_FENCE_VALUE));
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: PANIC MESSAGE first mb num is %d.\n", MEMIO_READ_FIELD(buf, FW_VA_HW_PANIC_FIRST_MB_NUM));
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: PANIC MESSAGE fault mb num is %d.\n", MEMIO_READ_FIELD(buf, FW_VA_HW_PANIC_FAULT_MB_NUM));
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: PANIC MESSAGE fe status is 0x%x.\n", MEMIO_READ_FIELD(buf, FW_VA_HW_PANIC_FESTATUS));
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: PANIC MESSAGE be status is 0x%x.\n", MEMIO_READ_FIELD(buf, FW_VA_HW_PANIC_BESTATUS));
+		} else {
+			fence = MEMIO_READ_FIELD(buf,
+						 FW_VA_CMD_FAILED_FENCE_VALUE);
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: FAILED MESSAGE fence is %d.\n", MEMIO_READ_FIELD(buf, FW_VA_HW_PANIC_FIRST_MB_NUM));
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: FAILED MESSAGE flag is %d.\n", MEMIO_READ_FIELD(buf, FW_VA_CMD_FAILED_FLAGS));
+		}
+
+		if(IS_CDV(dev) && IS_FW_UPDATED) {
+			fence = MEMIO_READ_FIELD(buf, FW_DEVA_CMD_FAILED_MSG_ID);
+			fault = MEMIO_READ_FIELD(buf, FW_DEVA_CMD_FAILED_FLAGS);
+		}
+
+		if (msg_id == VA_MSGID_CMD_HW_PANIC)
+			PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_CMD_HW_PANIC:"
+					  "Fault detected"
+					  " - Fence: %08x"
+					  " - Flags: %08x"
+					  " - resetting and ignoring error\n",
+					  fence, fault);
+		else
+			PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_CMD_FAILED:"
+					  "Fault detected"
+					  " - Fence: %08x"
+					  " - Flags: %08x"
+					  " - resetting and ignoring error\n",
+					  fence, fault);
+
+		msvdx_priv->msvdx_needs_reset = 1;
+
+		if (msg_id == VA_MSGID_CMD_HW_PANIC) {
+			diff = msvdx_priv->msvdx_current_sequence
+				- dev_priv->sequence[PSB_ENGINE_VIDEO];
+
+			if (diff > 0x0FFFFFFF)
+				msvdx_priv->msvdx_current_sequence++;
+
+			PSB_DEBUG_GENERAL("MSVDX: Fence ID missing, "
+					  "assuming %08x\n",
+					  msvdx_priv->msvdx_current_sequence);
+		} else {
+			msvdx_priv->msvdx_current_sequence = fence;
+		}
+
+		psb_fence_error(dev, PSB_ENGINE_VIDEO,
+				msvdx_priv->msvdx_current_sequence,
+				_PSB_FENCE_TYPE_EXE, DRM_CMD_FAILED);
+
+		/* Flush the command queue */
+		psb_msvdx_flush_cmd_queue(dev);
+
+		if (msvdx_priv->host_be_opp_enabled) {
+			/*get the frame_info struct for error concealment frame*/
+			for (i = 0; i < MAX_DECODE_BUFFERS; i++) {
+				/*by default the fence is 0, so there is problem here???*/
+				if (msvdx_priv->frame_info[i].fence == fence) {
+					failed_frame = &msvdx_priv->frame_info[i];
+					break;
+				}
+			}
+			if (!failed_frame) {
+				DRM_ERROR("MSVDX: didn't find frame_info which matched the fence %d in failed/panic message\n", fence);
+				goto done;
+			}
+
+			failed_frame->fw_status = 1; /* set ERROR flag */
+		} else
+			msvdx_priv->fw_status = 1; /* set ERROR flag */
+
+		goto done;
+	}
+	case VA_MSGID_CMD_COMPLETED: {
+		uint32_t fence;
+		uint32_t flags = MEMIO_READ_FIELD(buf, FW_VA_CMD_COMPLETED_FLAGS);
+		/* uint32_t last_mb = MEMIO_READ_FIELD(buf,
+		   FW_VA_CMD_COMPLETED_LASTMB);
+		*/
+
+		if(IS_CDV(dev) && IS_FW_UPDATED)
+			fence = MEMIO_READ_FIELD(buf, FW_VA_CMD_COMPLETED_MSG_ID);
+		else
+			fence = MEMIO_READ_FIELD(buf, FW_VA_CMD_COMPLETED_FENCE_VALUE);
+
+		PSB_DEBUG_GENERAL("MSVDX:VA_MSGID_CMD_COMPLETED: "
+				  "FenceID: %08x, flags: 0x%x\n",
+				  fence, flags);
+
+		msvdx_priv->msvdx_current_sequence = fence;
+		msvdx_priv->ref_pic_fence = fence;
+
+		psb_fence_handler(dev, PSB_ENGINE_VIDEO);
+
+		if (flags & FW_VA_RENDER_HOST_INT) {
+			/*Now send the next command from the msvdx cmd queue */
+			psb_msvdx_dequeue_send(dev);
+			goto done;
+		}
+
+		break;
+	}
+	case VA_MSGID_CMD_COMPLETED_BATCH: {
+		uint32_t fence = MEMIO_READ_FIELD(buf,
+						  FW_VA_CMD_COMPLETED_FENCE_VALUE);
+		uint32_t tickcnt = MEMIO_READ_FIELD(buf,
+						    FW_VA_CMD_COMPLETED_NO_TICKS);
+		(void)tickcnt;
+		/* we have the fence value in the message */
+		PSB_DEBUG_GENERAL("MSVDX:VA_MSGID_CMD_COMPLETED_BATCH:"
+				  " FenceID: %08x, TickCount: %08x\n",
+				  fence, tickcnt);
+		msvdx_priv->msvdx_current_sequence = fence;
+
+		break;
+	}
+	case VA_MSGID_ACK:
+		PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_ACK\n");
+		break;
+
+	case VA_MSGID_TEST1:
+		PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_TEST1\n");
+		break;
+
+		/* Penwell deblock is not implemented here */
+	case VA_MSGID_DEBLOCK_REQUIRED:	{
+		uint32_t ctxid = MEMIO_READ_FIELD(buf,
+						  FW_VA_DEBLOCK_REQUIRED_CONTEXT);
+		uint32_t fence = MEMIO_READ_FIELD(buf,
+						  FW_VA_DEBLOCK_REQUIRED_FENCE_VALUE);
+
+		PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_DEBLOCK_REQUIRED"
+				  " Context=%08x\n", ctxid);
+
+
+		/*deblock and on-be-opp use the same message, there is difficulty to distinguish them*/
+		/*now I just let user space use cpu copy error mb*/
+		if ((msvdx_priv->deblock_enabled == 1) && (msvdx_priv->host_be_opp_enabled == 1)) {
+			DRM_ERROR("MSVDX: should not support both deblock and host_be_opp message. \n");
+			goto done;
+		} else if (msvdx_priv->deblock_enabled == 1) {
+			PSB_DEBUG_GENERAL(
+				"Host deblocking is not used on CDV any more. Abort\n");
+				PSB_WMSVDX32(0, MSVDX_CMDS_END_SLICE_PICTURE);
+				PSB_WMSVDX32(1, MSVDX_CMDS_END_SLICE_PICTURE);
+				goto done;
+
+		} else if (msvdx_priv->host_be_opp_enabled == 1) {
+			PSB_DEBUG_MSVDX("MSVDX_DEBUG: get deblock required message for error concealment.\n");
+            
+			/* try to unblock rendec */
+			PSB_WMSVDX32(0, MSVDX_CMDS_END_SLICE_PICTURE);
+			PSB_WMSVDX32(1, MSVDX_CMDS_END_SLICE_PICTURE);
+
+			/*do error concealment with hw*/
+			msvdx_priv->ec_fence = fence;
+			schedule_work(&msvdx_priv->ec_work);
+		}
+
+		break;
+	}
+
+	case VA_MSGID_CMD_CONTIGUITY_WARNING: {
+		drm_psb_msvdx_frame_info_t *ec_frame = NULL;
+		drm_psb_msvdx_decode_status_t *fault_region = NULL;
+	
+		/*get erro info*/
+		uint32_t fence = MEMIO_READ_FIELD(buf,
+						  FW_VA_CONTIGUITY_WARNING_FENCE_VALUE);
+		uint32_t ui32Start = MEMIO_READ_FIELD(buf,
+						      FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM);
+		uint32_t ui32End = MEMIO_READ_FIELD(buf, 
+						    FW_VA_CONTIGUITY_WARNING_END_MB_NUM);
+		PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_CMD_CONTIGUITY_WARNING\n");
+		PSB_DEBUG_MSVDX("MSVDX_DEBUG: get contiguity warning message.\n");
+		PSB_DEBUG_MSVDX("MSVDX_DEBUG: CONTIGUITY_WARNING MESSAGE fence is %d.\n", MEMIO_READ_FIELD(buf, FW_VA_CONTIGUITY_WARNING_FENCE_VALUE));
+		PSB_DEBUG_MSVDX("MSVDX_DEBUG: CONTIGUITY_WARNING MESSAGE end mb num is %d.\n", MEMIO_READ_FIELD(buf, FW_VA_CONTIGUITY_WARNING_END_MB_NUM));
+		PSB_DEBUG_MSVDX("MSVDX_DEBUG: CONTIGUITY_WARNING MESSAGE begin mb num is %d.\n", MEMIO_READ_FIELD(buf, FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM));
+
+		/*get the frame_info struct for error concealment frame*/
+		for (i = 0; i < MAX_DECODE_BUFFERS; i++) {
+			if (msvdx_priv->frame_info[i].fence == fence) {
+				ec_frame = &msvdx_priv->frame_info[i];
+				break;
+			}
+		}
+		if (!ec_frame) {
+			DRM_ERROR("MSVDX: didn't find frame_info which matched the fence %d when get contiguity warning.\n", fence);
+			goto done;
+		}
+		else if (msvdx_priv->host_be_opp_enabled){
+			ec_frame->fw_status = 1;
+			fault_region = &ec_frame->decode_status;
+			if (ui32Start == 0xffff) {
+				if (fault_region->num_error_slice == 0) {
+					fault_region->start_error_mb_list[fault_region->num_error_slice] = 0;
+					fault_region->end_error_mb_list[fault_region->num_error_slice] = ui32End;
+					fault_region->num_error_slice++;
+				}
+				else if (fault_region->end_error_mb_list[fault_region->num_error_slice - 1] == 0xffff) {
+					fault_region->end_error_mb_list[fault_region->num_error_slice - 1] = ui32End;
+				}
+			}
+			else if (ui32Start <  ui32End) {
+				fault_region->start_error_mb_list[fault_region->num_error_slice] = ui32Start;
+				fault_region->end_error_mb_list[fault_region->num_error_slice] = ui32End;
+				fault_region->num_error_slice++;
+			}
+			else {
+				DRM_ERROR("msvdx error: start mb counter should not be larger than end mb counter.\n");
+				goto done;
+			}     
+		}
+
+	        break;
+
+	}
+	default:
+		DRM_ERROR("ERROR: msvdx Unknown message from MTX, ID:0x%08x\n", MEMIO_READ_FIELD(buf, FWRK_GENMSG_ID));
+		goto done;
+	}
+
+done:
+	if (ridx != widx) {
+		PSB_DEBUG_GENERAL("MSVDX Interrupt: there are more message to be read\n");
+		goto loop;
+	}
+	/* we get a frame/slice done, try to save some power*/
+	if (drm_msvdx_pmpolicy != PSB_PMPOLICY_NOPM)
+		schedule_delayed_work(&dev_priv->scheduler.msvdx_suspend_wq, 0);
+
+	DRM_MEMORYBARRIER();	/* TBD check this... */
+}
+
+
+/*
+ * MSVDX interrupt.
+ */
+IMG_BOOL psb_msvdx_interrupt(IMG_VOID *pvData)
+{
+	struct drm_device *dev;
+	struct drm_psb_private *dev_priv;
+	struct msvdx_private *msvdx_priv;
+	uint32_t msvdx_stat;
+
+	if (pvData == IMG_NULL) {
+		DRM_ERROR("ERROR: msvdx %s, Invalid params\n", __func__);
+		return IMG_FALSE;
+	}
+
+	dev = (struct drm_device *)pvData;
+
+
+	dev_priv = (struct drm_psb_private *) dev->dev_private;
+	msvdx_priv = dev_priv->msvdx_private;
+
+	msvdx_priv->msvdx_hw_busy = REG_READ(0x20D0) & (0x1 << 9);
+
+	msvdx_stat = PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
+
+	if (msvdx_stat & MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK) {
+		/*Ideally we should we should never get to this */
+		PSB_DEBUG_IRQ("MSVDX:MMU Fault:0x%x\n", msvdx_stat);
+
+		/* Pause MMU */
+		PSB_WMSVDX32(MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK,
+			     MSVDX_MMU_CONTROL0);
+		DRM_WRITEMEMORYBARRIER();
+
+		/* Clear this interupt bit only */
+		PSB_WMSVDX32(MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK,
+			     MSVDX_INTERRUPT_CLEAR);
+		PSB_RMSVDX32(MSVDX_INTERRUPT_CLEAR);
+		DRM_READMEMORYBARRIER();
+
+		msvdx_priv->msvdx_needs_reset = 1;
+	} else if (msvdx_stat & MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_MASK) {
+		PSB_DEBUG_IRQ
+			("MSVDX: msvdx_stat: 0x%x(MTX)\n", msvdx_stat);
+
+		/* Clear all interupt bits */
+		PSB_WMSVDX32(0xffff, MSVDX_INTERRUPT_CLEAR);
+		PSB_RMSVDX32(MSVDX_INTERRUPT_CLEAR);
+		DRM_READMEMORYBARRIER();
+
+		psb_msvdx_mtx_interrupt(dev);
+	}
+
+	return IMG_TRUE;
+}
+
+
+void psb_msvdx_lockup(struct drm_psb_private *dev_priv,
+		      int *msvdx_lockup, int *msvdx_idle)
+{
+	int diff;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	*msvdx_lockup = 0;
+	*msvdx_idle = 1;
+
+#if 0
+	PSB_DEBUG_GENERAL("MSVDXTimer: current_sequence:%d "
+			  "last_sequence:%d and last_submitted_sequence :%d\n",
+			  msvdx_priv->msvdx_current_sequence,
+			  msvdx_priv->msvdx_last_sequence,
+			  dev_priv->sequence[PSB_ENGINE_VIDEO]);
+#endif
+
+	diff = msvdx_priv->msvdx_current_sequence -
+		dev_priv->sequence[PSB_ENGINE_VIDEO];
+
+	if (diff > 0x0FFFFFFF) {
+		if (msvdx_priv->msvdx_current_sequence ==
+		    msvdx_priv->msvdx_last_sequence) {
+			DRM_ERROR("MSVDXTimer:locked-up for sequence:%d\n",
+				  msvdx_priv->msvdx_current_sequence);
+			*msvdx_lockup = 1;
+		} else {
+			PSB_DEBUG_GENERAL("MSVDXTimer: "
+					  "msvdx responded fine so far\n");
+			msvdx_priv->msvdx_last_sequence =
+				msvdx_priv->msvdx_current_sequence;
+			*msvdx_idle = 0;
+		}
+	}
+}
+
+int psb_check_msvdx_idle(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *)dev->dev_private;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	/* drm_psb_msvdx_frame_info_t *current_frame = NULL; */
+
+	if (msvdx_priv->msvdx_fw_loaded == 0)
+		return 0;
+
+	if (msvdx_priv->msvdx_busy) {
+		PSB_DEBUG_PM("MSVDX: psb_check_msvdx_idle returns busy\n");
+		return -EBUSY;
+	}
+/*
+	if (msvdx_priv->msvdx_hw_busy) {
+		PSB_DEBUG_PM("MSVDX: %s, HW is busy\n", __func__);
+		return -EBUSY;
+	}
+*/
+	return 0;
+}
+
+
+int psb_remove_videoctx(struct drm_psb_private *dev_priv, struct file *filp)
+{
+	struct psb_video_ctx *pos, *n;
+
+	list_for_each_entry_safe(pos, n, &dev_priv->video_ctx, head) {
+		if (pos->filp == filp) {
+			PSB_DEBUG_GENERAL("Video:remove context profile %d,"
+					" entrypoint %d",
+					(pos->ctx_type >> 8),
+					(pos->ctx_type & 0xff));
+
+			if (dev_priv->msvdx_ctx == pos)
+				dev_priv->msvdx_ctx = NULL;
+			if (dev_priv->last_msvdx_ctx == pos)
+				dev_priv->last_msvdx_ctx = NULL;
+
+			list_del(&pos->head);
+			kfree(pos);
+		}
+	}
+	return 0;
+}
+
+
+int lnc_video_getparam(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	struct drm_lnc_video_getparam_arg *arg = data;
+	int ret = 0;
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *)file_priv->minor->dev->dev_private;
+	drm_psb_msvdx_frame_info_t *current_frame = NULL;
+	uint32_t handle, i;
+
+	void *rar_handler;
+	uint32_t offset = 0;
+	uint32_t device_info = 0;
+	uint32_t ctx_type = 0;
+	struct psb_video_ctx *video_ctx = NULL;
+	uint32_t rar_ci_info[2];
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	switch (arg->key) {
+	case LNC_VIDEO_GETPARAM_RAR_INFO:
+		rar_ci_info[0] = dev_priv->rar_region_start;
+		rar_ci_info[1] = dev_priv->rar_region_size;
+		ret = copy_to_user((void __user *) ((unsigned long)arg->value),
+				   &rar_ci_info[0],
+				   sizeof(rar_ci_info));
+		break;
+	case LNC_VIDEO_GETPARAM_CI_INFO:
+		rar_ci_info[0] = dev_priv->ci_region_start;
+		rar_ci_info[1] = dev_priv->ci_region_size;
+		ret = copy_to_user((void __user *) ((unsigned long)arg->value),
+				   &rar_ci_info[0],
+				   sizeof(rar_ci_info));
+		break;
+	case LNC_VIDEO_GETPARAM_RAR_HANDLER_OFFSET:
+		ret = copy_from_user(&rar_handler,
+				     (void __user *)((unsigned long)arg->arg),
+				     sizeof(rar_handler));
+		if (ret)
+			break;
+
+		ret = copy_to_user((void __user *)((unsigned long)arg->value),
+				   &offset,
+				   sizeof(offset));
+		break;
+	case LNC_VIDEO_FRAME_SKIP:
+		if(IS_CDV(dev)) /* CDV should not call it */
+			ret = -EFAULT;
+		break;
+	case LNC_VIDEO_DEVICE_INFO:
+		device_info = 0xffff & dev_priv->video_device_fuse;
+		device_info |= (0xffff & dev->pci_device) << 16;
+
+		ret = copy_to_user((void __user *) ((unsigned long)arg->value),
+				   &device_info, sizeof(device_info));
+		break;
+	case IMG_VIDEO_NEW_CONTEXT:
+		/* add video decode/encode context */
+		ret = copy_from_user(&ctx_type, (void __user *) ((unsigned long)arg->value),
+				     sizeof(ctx_type));
+		/* Failure in copy */
+		if (ret) {
+			DRM_ERROR("lnc_video_nex_context copy_from_user error.\n");
+			break;
+		}
+
+		video_ctx = kmalloc(sizeof(struct psb_video_ctx), GFP_KERNEL);
+		if (video_ctx == NULL) {
+			ret = -ENOMEM;
+			break;
+		}
+		INIT_LIST_HEAD(&video_ctx->head);
+		video_ctx->ctx_type = ctx_type;
+		video_ctx->filp = file_priv->filp;
+		list_add(&video_ctx->head, &dev_priv->video_ctx);
+		PSB_DEBUG_GENERAL("Video:add context profile %d, entrypoint %d",
+				  (ctx_type >> 8), (ctx_type & 0xff));
+		break;
+
+	case IMG_VIDEO_RM_CONTEXT:
+		psb_remove_videoctx(dev_priv, file_priv->filp);
+		break;
+	case IMG_VIDEO_DECODE_STATUS:
+		if (msvdx_priv->host_be_opp_enabled) {
+			/*get the right frame_info struct for current surface*/
+			ret = copy_from_user(&handle,
+					     (void __user *)((unsigned long)arg->arg), 4);
+			if (ret) {
+				DRM_ERROR("MSVDX in lnc_video_getparam, copy_from_user failed.\n");
+				break;
+			}
+            
+			for (i = 0; i < MAX_DECODE_BUFFERS; i++) {
+				if (msvdx_priv->frame_info[i].handle == handle) {
+					current_frame = &msvdx_priv->frame_info[i];
+					break;
+				}
+			}
+			if (!current_frame) {
+				DRM_ERROR("MSVDX: didn't find frame_info which matched the surface_id. \n");
+				return -EFAULT;
+			}
+			ret = copy_to_user((void __user *) ((unsigned long)arg->value),
+					   &current_frame->fw_status, sizeof(current_frame->fw_status));
+		} else
+			ret = copy_to_user((void __user *) ((unsigned long)arg->value),
+					   &msvdx_priv->fw_status, sizeof(msvdx_priv->fw_status));
+		break;
+
+	case IMG_VIDEO_MB_ERROR:
+		/*get the right frame_info struct for current surface*/
+		ret = copy_from_user(&handle,
+				     (void __user *)((unsigned long)arg->arg), 4);
+		if (ret)
+			break;
+        
+		for (i = 0; i < MAX_DECODE_BUFFERS; i++) {
+			if (msvdx_priv->frame_info[i].handle == handle) {
+				current_frame = &msvdx_priv->frame_info[i];
+				break;
+			}
+		}
+		if (!current_frame) {
+			DRM_ERROR("MSVDX: didn't find frame_info which matched the surface_id. \n");
+			return -EFAULT;
+		}
+		ret = copy_to_user((void __user *) ((unsigned long)arg->value),
+				   &(current_frame->decode_status), sizeof(drm_psb_msvdx_decode_status_t));
+		if (ret) {
+			DRM_ERROR("lnc_video_getparam copy_to_user error.\n");
+			return -EFAULT;
+		}
+		break;
+        
+
+	default:
+		ret = -EFAULT;
+		break;
+	}
+
+	if (ret)
+		return -EFAULT;
+
+	return 0;
+}
+
+inline int psb_try_power_down_msvdx(struct drm_device *dev)
+{
+	ospm_apm_power_down_msvdx(dev);
+	return 0;
+}
+
+int psb_msvdx_save_context(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *)dev->dev_private;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	int offset = 0;
+
+	msvdx_priv->msvdx_needs_reset = 1;
+
+	if (msvdx_priv->vec_local_mem_data) {
+		for (offset = 0; offset < VEC_LOCAL_MEM_BYTE_SIZE / 4; ++offset)
+			msvdx_priv->vec_local_mem_data[offset] =
+				PSB_RMSVDX32(VEC_LOCAL_MEM_OFFSET + offset * 4);
+
+		msvdx_priv->vec_local_mem_saved = 1;
+	}
+	return 0;
+}
+
+int psb_msvdx_restore_context(struct drm_device *dev)
+{
+	return 0;
+}
diff --git a/drivers/staging/cdv/imgv/psb_msvdx.h b/drivers/staging/cdv/imgv/psb_msvdx.h
new file mode 100644
index 0000000..7ac373c
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_msvdx.h
@@ -0,0 +1,1393 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2011 Intel Corporation, Hillsboro, OR, USA
+ * Copyright (c) Imagination Technologies Limited, UK
+ *
+ * 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 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.
+ *
+ **************************************************************************/
+
+#ifndef _PSB_MSVDX_H_
+#define _PSB_MSVDX_H_
+
+#include "psb_drv.h"
+#include "img_types.h"
+
+
+extern int drm_msvdx_pmpolicy;
+extern int drm_msvdx_delay;
+
+typedef enum
+{
+	PSB_DMAC_BSWAP_NO_SWAP = 0x0,   //!< No byte swapping will be performed.
+	PSB_DMAC_BSWAP_REVERSE = 0x1,   //!< Byte order will be reversed.
+
+} DMAC_eBSwap;
+
+typedef enum
+{
+	PSB_DMAC_DIR_MEM_TO_PERIPH = 0x0, //!< Data from memory to peripheral.
+	PSB_DMAC_DIR_PERIPH_TO_MEM = 0x1, //!< Data from peripheral to memory.
+
+} DMAC_eDir;
+
+typedef enum
+{
+	PSB_DMAC_ACC_DEL_0              = 0x0,          //!< Access delay zero clock cycles
+	PSB_DMAC_ACC_DEL_256    = 0x1,      //!< Access delay 256 clock cycles
+	PSB_DMAC_ACC_DEL_512    = 0x2,      //!< Access delay 512 clock cycles
+	PSB_DMAC_ACC_DEL_768    = 0x3,      //!< Access delay 768 clock cycles
+	PSB_DMAC_ACC_DEL_1024   = 0x4,      //!< Access delay 1024 clock cycles
+	PSB_DMAC_ACC_DEL_1280   = 0x5,      //!< Access delay 1280 clock cycles
+	PSB_DMAC_ACC_DEL_1536   = 0x6,      //!< Access delay 1536 clock cycles
+	PSB_DMAC_ACC_DEL_1792   = 0x7,      //!< Access delay 1792 clock cycles
+
+} DMAC_eAccDel;
+
+typedef enum
+{
+	PSB_DMAC_INCR_OFF               = 0,            //!< Static peripheral address.
+	PSB_DMAC_INCR_ON                = 1                     //!< Incrementing peripheral address.
+
+} DMAC_eIncr;
+
+typedef enum
+{
+	PSB_DMAC_BURST_0                = 0x0,          //!< burst size of 0
+	PSB_DMAC_BURST_1        = 0x1,      //!< burst size of 1
+	PSB_DMAC_BURST_2        = 0x2,      //!< burst size of 2
+	PSB_DMAC_BURST_3        = 0x3,      //!< burst size of 3
+	PSB_DMAC_BURST_4        = 0x4,      //!< burst size of 4
+	PSB_DMAC_BURST_5        = 0x5,      //!< burst size of 5
+	PSB_DMAC_BURST_6        = 0x6,      //!< burst size of 6
+	PSB_DMAC_BURST_7        = 0x7,      //!< burst size of 7
+
+} DMAC_eBurst;
+
+int psb_wait_for_register(struct drm_psb_private *dev_priv,
+			  uint32_t offset,
+			  uint32_t value,
+			  uint32_t enable,
+				uint32_t loops,
+				uint32_t interval);
+
+IMG_BOOL psb_msvdx_interrupt(IMG_VOID *pvData);
+
+int psb_msvdx_init(struct drm_device *dev);
+int psb_msvdx_uninit(struct drm_device *dev);
+int psb_msvdx_reset(struct drm_psb_private *dev_priv);
+uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver);
+int psb_mtx_send(struct drm_psb_private *dev_priv, const void *pvMsg);
+void psb_msvdx_flush_cmd_queue(struct drm_device *dev);
+void psb_msvdx_lockup(struct drm_psb_private *dev_priv,
+		      int *msvdx_lockup, int *msvdx_idle);
+int psb_setup_fw(struct drm_device *dev);
+int psb_check_msvdx_idle(struct drm_device *dev);
+int psb_wait_msvdx_idle(struct drm_device *dev);
+int psb_cmdbuf_video(struct drm_file *priv,
+		     struct list_head *validate_list,
+		     uint32_t fence_type,
+		     struct drm_psb_cmdbuf_arg *arg,
+		     struct ttm_buffer_object *cmd_buffer,
+		     struct psb_ttm_fence_rep *fence_arg);
+int psb_msvdx_save_context(struct drm_device *dev);
+int psb_msvdx_restore_context(struct drm_device *dev);
+
+bool
+psb_host_second_pass(struct drm_device *dev,
+		     uint32_t ui32OperatingModeCmd,
+		     void	 *pvParamBase,
+		     uint32_t PicWidthInMbs,
+		     uint32_t FrameHeightInMbs,
+		     uint32_t ui32DeblockSourceY,
+		     uint32_t ui32DeblockSourceUV);
+
+/*  Non-Optimal Invalidation is not default */
+#define MSVDX_DEVICE_NODE_FLAGS_MMU_NONOPT_INV	2
+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK	(0x00000100)
+
+#define FW_VA_RENDER_HOST_INT		0x00004000
+#define MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION	0x00000020
+
+/* There is no work currently underway on the hardware */
+#define MSVDX_FW_STATUS_HW_IDLE	0x00000001
+#define MSVDX_DEVICE_NODE_FLAG_BRN23154_BLOCK_ON_FE	0x00000200
+#define MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D0 \
+	(MSVDX_DEVICE_NODE_FLAGS_MMU_NONOPT_INV |			\
+		MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION |		\
+		MSVDX_DEVICE_NODE_FLAG_BRN23154_BLOCK_ON_FE)
+
+#define MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D1 \
+	(MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION |			\
+		MSVDX_DEVICE_NODE_FLAG_BRN23154_BLOCK_ON_FE)
+
+#define POULSBO_D0	0x5
+#define POULSBO_D1	0x6
+#define PSB_REVID_OFFSET 0x8
+
+#define MTX_CODE_BASE		(0x80900000)
+#define MTX_DATA_BASE		(0x82880000)
+#define PC_START_ADDRESS	(0x80900000)
+
+#define MTX_CORE_CODE_MEM	(0x10)
+#define MTX_CORE_DATA_MEM	(0x18)
+
+#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK		(0x00000100)
+#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_SHIFT		(8)
+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_FE_SOFT_RESET_MASK	\
+	(0x00010000)
+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_BE_SOFT_RESET_MASK	\
+	(0x00100000)
+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_MEMIF_SOFT_RESET_MASK	\
+	(0x01000000)
+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_RENDEC_DEC_SOFT_RESET_MASK \
+	(0x10000000)
+
+#define clk_enable_all	\
+(MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK	| \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_MAN_CLK_ENABLE_MASK | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_MAN_CLK_ENABLE_MASK | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_MAN_CLK_ENABLE_MASK	 | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_MAN_CLK_ENABLE_MASK | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_MAN_CLK_ENABLE_MASK | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK)
+
+#define clk_enable_minimal \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK
+
+#define clk_enable_auto	\
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_AUTO_CLK_ENABLE_MASK	| \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_AUTO_CLK_ENABLE_MASK	| \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_AUTO_CLK_ENABLE_MASK		| \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_AUTO_CLK_ENABLE_MASK	| \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_AUTO_CLK_ENABLE_MASK	| \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK		| \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK
+
+#define msvdx_sw_reset_all \
+(MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK |	  \
+MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_FE_SOFT_RESET_MASK |	  \
+MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_BE_SOFT_RESET_MASK	|		\
+MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_MEMIF_SOFT_RESET_MASK |	\
+MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_RENDEC_DEC_SOFT_RESET_MASK)
+
+#define MTX_INTERNAL_REG(R_SPECIFIER , U_SPECIFIER)	\
+	(((R_SPECIFIER)<<4) | (U_SPECIFIER))
+#define MTX_PC		MTX_INTERNAL_REG(0, 5)
+
+#define RENDEC_A_SIZE	(4 * 1024 * 1024)
+#define RENDEC_B_SIZE	(1024 * 1024)
+
+#define MEMIO_READ_FIELD(vpMem, field)	  \
+	((uint32_t)(((*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) \
+			& field##_MASK) >> field##_SHIFT))
+
+#define MEMIO_WRITE_FIELD(vpMem, field, value) 			\
+	(*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) =	\
+		((*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) \
+			& (field##_TYPE)~field##_MASK) |		\
+	(field##_TYPE)(((uint32_t)(value) << field##_SHIFT) & field##_MASK)
+
+#define MEMIO_WRITE_FIELD_LITE(vpMem, field, value)			\
+	 (*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) =	\
+	((*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) |	\
+		(field##_TYPE)(((uint32_t)(value) << field##_SHIFT)));
+
+#define REGIO_READ_FIELD(reg_val, reg, field)				\
+	((reg_val & reg##_##field##_MASK) >> reg##_##field##_SHIFT)
+
+#define REGIO_WRITE_FIELD(reg_val, reg, field, value)			\
+	(reg_val) =							\
+	((reg_val) & ~(reg##_##field##_MASK)) |				\
+		(((value) << (reg##_##field##_SHIFT)) & (reg##_##field##_MASK));
+
+#define REGIO_WRITE_FIELD_LITE(reg_val, reg, field, value)		\
+	(reg_val) =							\
+	((reg_val) | ((value) << (reg##_##field##_SHIFT)));
+
+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK	\
+	(0x00000001)
+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_MAN_CLK_ENABLE_MASK \
+	(0x00000002)
+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_MAN_CLK_ENABLE_MASK \
+	(0x00000004)
+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_MAN_CLK_ENABLE_MASK \
+			(0x00000008)
+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_MAN_CLK_ENABLE_MASK \
+	(0x00000010)
+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_MAN_CLK_ENABLE_MASK \
+	(0x00000020)
+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK	\
+	(0x00000040)
+
+#define clk_enable_all	\
+	(MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK	| \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_MAN_CLK_ENABLE_MASK | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_MAN_CLK_ENABLE_MASK | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_MAN_CLK_ENABLE_MASK	 | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_MAN_CLK_ENABLE_MASK | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_MAN_CLK_ENABLE_MASK | \
+MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK)
+
+#define clk_enable_minimal \
+	MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK | \
+	MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK
+
+/* MTX registers */
+#define MSVDX_MTX_ENABLE		(0x0000)
+#define MSVDX_MTX_KICKI			(0x0088)
+#define MSVDX_MTX_KICK			(0x0080)
+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST	(0x00FC)
+#define MSVDX_MTX_REGISTER_READ_WRITE_DATA	(0x00F8)
+#define MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER	(0x0104)
+#define MSVDX_MTX_RAM_ACCESS_CONTROL	(0x0108)
+#define MSVDX_MTX_RAM_ACCESS_STATUS	(0x010C)
+#define MSVDX_MTX_SOFT_RESET		(0x0200)
+#define MSVDX_MTX_SYSC_TIMERDIV		(0x0208)
+#define MTX_CORE_CR_MTX_SYSC_CDMAS0_OFFSET              (0x0348)
+#define MTX_CORE_CR_MTX_SYSC_CDMAA_OFFSET               (0x0344)
+#define MTX_CORE_CR_MTX_SYSC_CDMAT_OFFSET               (0x0350)
+#define MTX_CORE_CR_MTX_SYSC_CDMAC_OFFSET               (0x0340)
+
+/* MSVDX registers */
+#define MSVDX_CONTROL			(0x0600)
+#define MSVDX_INTERRUPT_CLEAR		(0x060C)
+#define MSVDX_INTERRUPT_STATUS		(0x0608)
+#define MSVDX_HOST_INTERRUPT_ENABLE	(0x0610)
+#define MSVDX_CORE_REV			(0x0640)
+#define MSVDX_MMU_CONTROL0		(0x0680)
+#define MSVDX_MMU_MEM_REQ		(0x06D0)
+#define MSVDX_MTX_RAM_BANK		(0x06F0)
+#define MSVDX_MTX_DEBUG			MSVDX_MTX_RAM_BANK
+#define MSVDX_MAN_CLK_ENABLE		(0x0620)
+#define MSVDX_CORE_CR_MSVDX_CONTROL_OFFSET              (0x0600)
+#define MSVDX_CORE_CR_MMU_BANK_INDEX_OFFSET             (0x0688)
+#define MSVDX_CORE_CR_MMU_DIR_LIST_BASE_OFFSET          (0x0694)
+#define MSVDX_CORE_CR_MMU_CONTROL0_OFFSET               MSVDX_MMU_CONTROL0
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH		(0x66c)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH		(0x678)
+
+/* RENDEC registers */
+#define MSVDX_RENDEC_CONTROL0		(0x0868)
+#define MSVDX_RENDEC_CONTROL1		(0x086C)
+#define MSVDX_RENDEC_BUFFER_SIZE	(0x0870)
+#define MSVDX_RENDEC_BASE_ADDR0		(0x0874)
+#define MSVDX_RENDEC_BASE_ADDR1		(0x0878)
+#define MSVDX_RENDEC_READ_DATA		(0x0898)
+#define MSVDX_RENDEC_CONTEXT0		(0x0950)
+#define MSVDX_RENDEC_CONTEXT1		(0x0954)
+#define MSVDX_RENDEC_CONTEXT2		(0x0958)
+#define MSVDX_RENDEC_CONTEXT3		(0x095C)
+#define MSVDX_RENDEC_CONTEXT4		(0x0960)
+#define MSVDX_RENDEC_CONTEXT5		(0x0964)
+
+/* VEC registers */
+#define MSVDX_VEC_SHIFTREG_CONTROL	(0x0818)
+
+/* DMAC registers */
+#define DMAC_DMAC_SETUP_OFFSET          (0x0500)
+#define DMAC_DMAC_COUNT_OFFSET          (0x0504)
+#define DMAC_DMAC_PERIPH_OFFSET         (0x0508)
+#define DMAC_DMAC_IRQ_STAT_OFFSET       (0x050C)
+#define DMAC_DMAC_PERIPHERAL_ADDR_OFFSET                (0x0514)
+
+/* DMAC control */
+#define PSB_DMAC_VALUE_COUNT(BSWAP,PW,DIR,PERIPH_INCR,COUNT)                                \
+                                                                                                                                                \
+    (((BSWAP)           & DMAC_DMAC_COUNT_BSWAP_LSBMASK)        << DMAC_DMAC_COUNT_BSWAP_SHIFT) | \
+        (((PW)                  & DMAC_DMAC_COUNT_PW_LSBMASK)           << DMAC_DMAC_COUNT_PW_SHIFT)    | \
+        (((DIR)                 & DMAC_DMAC_COUNT_DIR_LSBMASK)          << DMAC_DMAC_COUNT_DIR_SHIFT)   | \
+        (((PERIPH_INCR) & DMAC_DMAC_COUNT_PI_LSBMASK)           << DMAC_DMAC_COUNT_PI_SHIFT)    | \
+        (((COUNT)               & DMAC_DMAC_COUNT_CNT_LSBMASK)          << DMAC_DMAC_COUNT_CNT_SHIFT)
+
+#define PSB_DMAC_VALUE_PERIPH_PARAM(ACC_DEL,INCR,BURST)                                             \
+                                                                                                                                                \
+        (((ACC_DEL)     & DMAC_DMAC_PERIPH_ACC_DEL_LSBMASK)     << DMAC_DMAC_PERIPH_ACC_DEL_SHIFT)      | \
+        (((INCR)        & DMAC_DMAC_PERIPH_INCR_LSBMASK)        << DMAC_DMAC_PERIPH_INCR_SHIFT)         | \
+        (((BURST)       & DMAC_DMAC_PERIPH_BURST_LSBMASK)       << DMAC_DMAC_PERIPH_BURST_SHIFT)
+
+
+/* CMD */
+#define MSVDX_CMDS_END_SLICE_PICTURE	(0x1404)
+
+/*
+ * This defines the MSVDX communication buffer
+ */
+#define MSVDX_COMMS_SIGNATURE_VALUE	(0xA5A5A5A5)	/*!< Signature value */
+/*!< Host buffer size (in 32-bit words) */
+#define NUM_WORDS_HOST_BUF		(100)
+/*!< MTX buffer size (in 32-bit words) */
+#define NUM_WORDS_MTX_BUF		(100)
+
+/* There is no work currently underway on the hardware */
+#define MSVDX_FW_STATUS_HW_IDLE	0x00000001
+
+#define MSVDX_EXT_FW_ERROR_STATE (0x2884)
+#define MSVDX_COMMS_AREA_ADDR (0x02fe0)
+
+#define MSVDX_COMMS_CORE_WTD			(MSVDX_COMMS_AREA_ADDR - 0x08)
+#define MSVDX_COMMS_ERROR_TRIG			(MSVDX_COMMS_AREA_ADDR - 0x08)
+#define MSVDX_COMMS_FIRMWARE_ID			(MSVDX_COMMS_AREA_ADDR - 0x0C)
+#define MSVDX_COMMS_OFFSET_FLAGS		(MSVDX_COMMS_AREA_ADDR + 0x18)
+#define	MSVDX_COMMS_MSG_COUNTER			(MSVDX_COMMS_AREA_ADDR - 0x04)
+#define MSVDX_COMMS_FW_STATUS			(MSVDX_COMMS_AREA_ADDR - 0x10)
+#define	MSVDX_COMMS_SIGNATURE			(MSVDX_COMMS_AREA_ADDR + 0x00)
+#define	MSVDX_COMMS_TO_HOST_BUF_SIZE		(MSVDX_COMMS_AREA_ADDR + 0x04)
+#define MSVDX_COMMS_TO_HOST_RD_INDEX		(MSVDX_COMMS_AREA_ADDR + 0x08)
+#define MSVDX_COMMS_TO_HOST_WRT_INDEX		(MSVDX_COMMS_AREA_ADDR + 0x0C)
+#define MSVDX_COMMS_TO_MTX_BUF_SIZE		(MSVDX_COMMS_AREA_ADDR + 0x10)
+#define MSVDX_COMMS_TO_MTX_RD_INDEX		(MSVDX_COMMS_AREA_ADDR + 0x14)
+#define MSVDX_COMMS_TO_MTX_CB_RD_INDEX		(MSVDX_COMMS_AREA_ADDR + 0x18)
+#define MSVDX_COMMS_TO_MTX_WRT_INDEX		(MSVDX_COMMS_AREA_ADDR + 0x1C)
+#define MSVDX_COMMS_TO_HOST_BUF			(MSVDX_COMMS_AREA_ADDR + 0x20)
+#define MSVDX_COMMS_TO_MTX_BUF	\
+	(MSVDX_COMMS_TO_HOST_BUF + (NUM_WORDS_HOST_BUF << 2))
+
+#define DSIABLE_FW_WDT			        0x0008
+#define ABORT_ON_ERRORS_IMMEDIATE       0x0010
+#define ABORT_FAULTED_SLICE_IMMEDIATE   0x0020
+#define RETURN_VDEB_DATA_IN_COMPLETION  0x0800
+#define DSIABLE_Auto_CLOCK_GATING	    0x1000
+#define DSIABLE_IDLE_GPIO_SIG			0x2000
+/*
+#define MSVDX_COMMS_AREA_END	\
+  (MSVDX_COMMS_TO_MTX_BUF + (NUM_WORDS_HOST_BUF << 2))
+*/
+#define MSVDX_COMMS_AREA_END 0x03000
+
+#if (MSVDX_COMMS_AREA_END != 0x03000)
+#error
+#endif
+
+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK	(0x80000000)
+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_SHIFT	(31)
+
+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_RNW_MASK	(0x00010000)
+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_RNW_SHIFT	(16)
+
+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMID_MASK		(0x0FF00000)
+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMID_SHIFT		(20)
+
+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCM_ADDR_MASK	(0x000FFFFC)
+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCM_ADDR_SHIFT	(2)
+
+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMAI_MASK	(0x00000002)
+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMAI_SHIFT	(1)
+
+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMR_MASK	(0x00000001)
+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMR_SHIFT	(0)
+
+#define MSVDX_MTX_SOFT_RESET_MTX_RESET_MASK		(0x00000001)
+#define MSVDX_MTX_SOFT_RESET_MTX_RESET_SHIFT		(0)
+
+#define MSVDX_MTX_ENABLE_MTX_ENABLE_MASK		(0x00000001)
+#define MSVDX_MTX_ENABLE_MTX_ENABLE_SHIFT		(0)
+
+#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK		(0x00000100)
+#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_SHIFT		(8)
+
+#define MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK	(0x00000F00)
+#define MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_SHIFT	(8)
+
+#define MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_MASK		(0x00004000)
+#define MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_SHIFT		(14)
+
+#define MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK			(0x00000002)
+#define MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_SHIFT			(1)
+
+#define MSVDX_MTX_RAM_BANK_CR_MTX_RAM_BANK_SIZE_MASK		(0x000F0000)
+#define MSVDX_MTX_RAM_BANK_CR_MTX_RAM_BANK_SIZE_SHIFT		(16)
+
+#define MSVDX_MTX_DEBUG_MTX_DBG_IS_SLAVE_MASK                (0x00000004)
+#define MSVDX_MTX_DEBUG_MTX_DBG_IS_SLAVE_LSBMASK             (0x00000001)
+#define MSVDX_MTX_DEBUG_MTX_DBG_IS_SLAVE_SHIFT               (2)
+
+#define MSVDX_MTX_DEBUG_MTX_DBG_GPIO_IN_MASK         (0x00000003)
+#define MSVDX_MTX_DEBUG_MTX_DBG_GPIO_IN_LSBMASK              (0x00000003)
+#define MSVDX_MTX_DEBUG_MTX_DBG_GPIO_IN_SHIFT                (0)
+
+#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE0_MASK	(0x0000FFFF)
+#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE0_SHIFT	(0)
+
+#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE1_MASK	(0xFFFF0000)
+#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE1_SHIFT	(16)
+
+#define MSVDX_RENDEC_CONTROL1_RENDEC_DECODE_START_SIZE_MASK	(0x000000FF)
+#define MSVDX_RENDEC_CONTROL1_RENDEC_DECODE_START_SIZE_SHIFT	(0)
+
+#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_W_MASK		(0x000C0000)
+#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_W_SHIFT		(18)
+
+#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_R_MASK		(0x00030000)
+#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_R_SHIFT		(16)
+
+#define MSVDX_RENDEC_CONTROL1_RENDEC_EXTERNAL_MEMORY_MASK	(0x01000000)
+#define MSVDX_RENDEC_CONTROL1_RENDEC_EXTERNAL_MEMORY_SHIFT	(24)
+
+#define MSVDX_RENDEC_CONTROL1_RENDEC_DEC_DISABLE_MASK		(0x08000000)
+#define MSVDX_RENDEC_CONTROL1_RENDEC_DEC_DISABLE_SHIFT		(27)
+
+#define MSVDX_RENDEC_CONTROL0_RENDEC_INITIALISE_MASK		(0x00000001)
+#define MSVDX_RENDEC_CONTROL0_RENDEC_INITIALISE_SHIFT		(0)
+
+#define VEC_SHIFTREG_CONTROL_SR_MASTER_SELECT_MASK         (0x00000300)
+#define VEC_SHIFTREG_CONTROL_SR_MASTER_SELECT_SHIFT                (8)
+
+#define MTX_CORE_CR_MTX_SYSC_CDMAC_BURSTSIZE_MASK               (0x07000000)
+#define MTX_CORE_CR_MTX_SYSC_CDMAC_BURSTSIZE_SHIFT              (24)
+
+#define MTX_CORE_CR_MTX_SYSC_CDMAC_RNW_MASK             (0x00020000)
+#define MTX_CORE_CR_MTX_SYSC_CDMAC_RNW_SHIFT            (17)
+
+#define MTX_CORE_CR_MTX_SYSC_CDMAC_ENABLE_MASK          (0x00010000)
+#define MTX_CORE_CR_MTX_SYSC_CDMAC_ENABLE_SHIFT         (16)
+
+#define MTX_CORE_CR_MTX_SYSC_CDMAC_LENGTH_MASK          (0x0000FFFF)
+#define MTX_CORE_CR_MTX_SYSC_CDMAC_LENGTH_SHIFT         (0)
+
+#define MSVDX_CORE_CR_MSVDX_CONTROL_DMAC_CH0_SELECT_MASK                (0x00001000)
+#define MSVDX_CORE_CR_MSVDX_CONTROL_DMAC_CH0_SELECT_SHIFT               (12)
+
+#define MSVDX_CORE_CR_MMU_CONTROL0_CR_MMU_INVALDC_MASK          (0x00000008)
+#define MSVDX_CORE_CR_MMU_CONTROL0_CR_MMU_INVALDC_SHIFT         (3)
+
+#define DMAC_DMAC_COUNT_BSWAP_LSBMASK           (0x00000001)
+#define DMAC_DMAC_COUNT_BSWAP_SHIFT             (30)
+
+#define DMAC_DMAC_COUNT_PW_LSBMASK              (0x00000003)
+#define DMAC_DMAC_COUNT_PW_SHIFT                (27)
+
+#define DMAC_DMAC_COUNT_DIR_LSBMASK             (0x00000001)
+#define DMAC_DMAC_COUNT_DIR_SHIFT               (26)
+
+#define DMAC_DMAC_COUNT_PI_LSBMASK              (0x00000003)
+#define DMAC_DMAC_COUNT_PI_SHIFT                (24)
+
+#define DMAC_DMAC_COUNT_CNT_LSBMASK             (0x0000FFFF)
+#define DMAC_DMAC_COUNT_CNT_SHIFT               (0)
+
+#define DMAC_DMAC_PERIPH_ACC_DEL_LSBMASK                (0x00000007)
+#define DMAC_DMAC_PERIPH_ACC_DEL_SHIFT          (29)
+
+#define DMAC_DMAC_PERIPH_INCR_LSBMASK           (0x00000001)
+#define DMAC_DMAC_PERIPH_INCR_SHIFT             (27)
+
+#define DMAC_DMAC_PERIPH_BURST_LSBMASK          (0x00000007)
+#define DMAC_DMAC_PERIPH_BURST_SHIFT            (24)
+
+#define DMAC_DMAC_PERIPHERAL_ADDR_ADDR_MASK             (0x007FFFFF)
+#define DMAC_DMAC_PERIPHERAL_ADDR_ADDR_LSBMASK          (0x007FFFFF)
+#define DMAC_DMAC_PERIPHERAL_ADDR_ADDR_SHIFT            (0)
+
+#define DMAC_DMAC_COUNT_EN_MASK         (0x00010000)
+#define DMAC_DMAC_COUNT_EN_SHIFT                (16)
+
+#define DMAC_DMAC_IRQ_STAT_TRANSFER_FIN_MASK            (0x00020000)
+
+/*watch dog for FE and BE*/
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_OFFSET		(0x0064)
+
+// MSVDX_CORE, CR_FE_MSVDX_WDT_CONTROL, FE_WDT_CNT_CTRL   
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_CNT_CTRL_MASK		(0x00060000)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_CNT_CTRL_LSBMASK		(0x00000003)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_CNT_CTRL_SHIFT		(17)
+
+// MSVDX_CORE, CR_FE_MSVDX_WDT_CONTROL, FE_WDT_ENABLE   
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_ENABLE_MASK		(0x00010000)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_ENABLE_LSBMASK		(0x00000001)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_ENABLE_SHIFT		(16)
+
+// MSVDX_CORE, CR_FE_MSVDX_WDT_CONTROL, FE_WDT_ACTION1   
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_ACTION1_MASK		(0x00003000)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_ACTION1_LSBMASK		(0x00000003)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_ACTION1_SHIFT		(12)
+
+// MSVDX_CORE, CR_FE_MSVDX_WDT_CONTROL, FE_WDT_ACTION0   
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_ACTION0_MASK		(0x00000100)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_ACTION0_LSBMASK		(0x00000001)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_ACTION0_SHIFT		(8)
+
+// MSVDX_CORE, CR_FE_MSVDX_WDT_CONTROL, FE_WDT_CLEAR_SELECT   
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_CLEAR_SELECT_MASK		(0x00000030)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_CLEAR_SELECT_LSBMASK		(0x00000003)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_CLEAR_SELECT_SHIFT		(4)
+
+// MSVDX_CORE, CR_FE_MSVDX_WDT_CONTROL, FE_WDT_CLKDIV_SELECT   
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_CLKDIV_SELECT_MASK		(0x00000007)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_CLKDIV_SELECT_LSBMASK		(0x00000007)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_FE_WDT_CLKDIV_SELECT_SHIFT		(0)
+
+#define MSVDX_CORE_CR_FE_MSVDX_WDTIMER_OFFSET		(0x0068)
+
+// MSVDX_CORE, CR_FE_MSVDX_WDTIMER, FE_WDT_COUNTER   
+#define MSVDX_CORE_CR_FE_MSVDX_WDTIMER_FE_WDT_COUNTER_MASK		(0x0000FFFF)
+#define MSVDX_CORE_CR_FE_MSVDX_WDTIMER_FE_WDT_COUNTER_LSBMASK		(0x0000FFFF)
+#define MSVDX_CORE_CR_FE_MSVDX_WDTIMER_FE_WDT_COUNTER_SHIFT		(0)
+
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH_OFFSET		(0x006C)
+
+// MSVDX_CORE, CR_FE_MSVDX_WDT_COMPAREMATCH, FE_WDT_CM1   
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH_FE_WDT_CM1_MASK		(0xFFFF0000)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH_FE_WDT_CM1_LSBMASK		(0x0000FFFF)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH_FE_WDT_CM1_SHIFT		(16)
+
+// MSVDX_CORE, CR_FE_MSVDX_WDT_COMPAREMATCH, FE_WDT_CM0   
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH_FE_WDT_CM0_MASK		(0x0000FFFF)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH_FE_WDT_CM0_LSBMASK		(0x0000FFFF)
+#define MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH_FE_WDT_CM0_SHIFT		(0)
+
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_OFFSET		(0x0070)
+
+// MSVDX_CORE, CR_BE_MSVDX_WDT_CONTROL, BE_WDT_CNT_CTRL   
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_CNT_CTRL_MASK		(0x001E0000)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_CNT_CTRL_LSBMASK		(0x0000000F)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_CNT_CTRL_SHIFT		(17)
+
+// MSVDX_CORE, CR_BE_MSVDX_WDT_CONTROL, BE_WDT_ENABLE   
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_ENABLE_MASK		(0x00010000)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_ENABLE_LSBMASK		(0x00000001)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_ENABLE_SHIFT		(16)
+
+// MSVDX_CORE, CR_BE_MSVDX_WDT_CONTROL, BE_WDT_ACTION0   
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_ACTION0_MASK		(0x00000100)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_ACTION0_LSBMASK		(0x00000001)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_ACTION0_SHIFT		(8)
+
+// MSVDX_CORE, CR_BE_MSVDX_WDT_CONTROL, BE_WDT_CLEAR_SELECT   
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_CLEAR_SELECT_MASK		(0x000000F0)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_CLEAR_SELECT_LSBMASK		(0x0000000F)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_CLEAR_SELECT_SHIFT		(4)
+
+// MSVDX_CORE, CR_BE_MSVDX_WDT_CONTROL, BE_WDT_CLKDIV_SELECT   
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_CLKDIV_SELECT_MASK		(0x00000007)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_CLKDIV_SELECT_LSBMASK		(0x00000007)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_BE_WDT_CLKDIV_SELECT_SHIFT		(0)
+
+#define MSVDX_CORE_CR_BE_MSVDX_WDTIMER_OFFSET		(0x0074)
+
+// MSVDX_CORE, CR_BE_MSVDX_WDTIMER, BE_WDT_COUNTER   
+#define MSVDX_CORE_CR_BE_MSVDX_WDTIMER_BE_WDT_COUNTER_MASK		(0x0000FFFF)
+#define MSVDX_CORE_CR_BE_MSVDX_WDTIMER_BE_WDT_COUNTER_LSBMASK		(0x0000FFFF)
+#define MSVDX_CORE_CR_BE_MSVDX_WDTIMER_BE_WDT_COUNTER_SHIFT		(0)
+
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH_OFFSET		(0x0078)
+
+// MSVDX_CORE, CR_BE_MSVDX_WDT_COMPAREMATCH, BE_WDT_CM0   
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH_BE_WDT_CM0_MASK		(0x0000FFFF)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH_BE_WDT_CM0_LSBMASK		(0x0000FFFF)
+#define MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH_BE_WDT_CM0_SHIFT		(0)
+/*watch dog end*/
+
+/* Start of parser specific Host->MTX messages. */
+#define	FWRK_MSGID_START_PSR_HOSTMTX_MSG	(0x80)
+
+/* Start of parser specific MTX->Host messages. */
+#define	FWRK_MSGID_START_PSR_MTXHOST_MSG	(0xC0)
+
+/* Host defined msg, just for host use, MTX not recgnize */
+#define	FWRK_MSGID_HOST_EMULATED		(0x40)
+
+#define FWRK_MSGID_PADDING			(0)
+
+#define FWRK_GENMSG_SIZE_TYPE		uint8_t
+#define FWRK_GENMSG_SIZE_MASK		(0xFF)
+#define FWRK_GENMSG_SIZE_SHIFT		(0)
+#define FWRK_GENMSG_SIZE_OFFSET		(0x0000)
+#define FWRK_GENMSG_ID_TYPE		uint8_t
+#define FWRK_GENMSG_ID_MASK		(0xFF)
+#define FWRK_GENMSG_ID_SHIFT		(0)
+#define FWRK_GENMSG_ID_OFFSET		(0x0001)
+#define FWRK_PADMSG_SIZE		(2)
+
+/* Deblock CMD_ID */
+#define MSVDX_DEBLOCK_REG_SET   0x10000000
+#define MSVDX_DEBLOCK_REG_GET   0x20000000
+#define MSVDX_DEBLOCK_REG_POLLn 0x30000000
+#define MSVDX_DEBLOCK_REG_POLLx 0x40000000
+
+/* vec local MEM save/restore */
+#define VEC_LOCAL_MEM_BYTE_SIZE (4 * 1024)
+#define VEC_LOCAL_MEM_OFFSET 0x2000
+
+/* This type defines the framework specified message ids */
+enum {
+	/* ! Sent by the DXVA driver on the host to the mtx firmware.
+	 */
+	VA_MSGID_INIT = FWRK_MSGID_START_PSR_HOSTMTX_MSG,
+	VA_MSGID_RENDER,
+	VA_MSGID_DEBLOCK,
+	VA_MSGID_OOLD,
+
+	/* Test Messages */
+	VA_MSGID_TEST1,
+	VA_MSGID_HOST_BE_OPP,
+
+	/*! Sent by the mtx firmware to itself.
+	 */
+	VA_MSGID_RENDER_MC_INTERRUPT,
+
+	VA_MSGID_DEBLOCK_MFLD = FWRK_MSGID_HOST_EMULATED,
+	VA_MSGID_OOLD_MFLD,
+	/*! Sent by the DXVA firmware on the MTX to the host.
+	 */
+	VA_MSGID_CMD_COMPLETED = FWRK_MSGID_START_PSR_MTXHOST_MSG,
+	VA_MSGID_CMD_COMPLETED_BATCH,
+	VA_MSGID_DEBLOCK_REQUIRED,
+	VA_MSGID_TEST_RESPONCE,
+	VA_MSGID_ACK,
+
+	VA_MSGID_CMD_FAILED,
+	VA_MSGID_CMD_CONTIGUITY_WARNING,
+	VA_MSGID_CMD_HW_PANIC,
+};
+
+/* Deblock parameters */
+struct DEBLOCKPARAMS {
+	uint32_t handle;	/* struct ttm_buffer_object * of REGIO */
+	uint32_t buffer_size;
+	uint32_t ctxid;
+
+	uint32_t *pPicparams;
+	struct ttm_bo_kmap_obj *regio_kmap;	/* virtual of regio */
+	uint32_t pad[3];
+};
+
+/* HOST_BE_OPP parameters */
+struct HOST_BE_OPP_PARAMS {
+	uint32_t handle;	/* struct ttm_buffer_object * of REGIO */
+	uint32_t buffer_stride;
+	uint32_t buffer_size;
+	uint32_t picture_width_mb;
+	uint32_t size_mb;
+};
+struct psb_msvdx_deblock_queue {
+
+	struct list_head head;
+	struct DEBLOCKPARAMS dbParams;
+};
+
+typedef struct {
+        union {
+                struct {
+                        uint32_t msg_size       : 8;
+                        uint32_t msg_type       : 8;
+                        uint32_t msg_fence      : 16;
+                } bits;
+                uint32_t value;
+        } header;
+        uint32_t flags;
+        uint32_t operating_mode;
+        union {
+                struct {
+                        uint32_t context        : 8;
+                        uint32_t mmu_ptd        : 24;
+                } bits;
+                uint32_t value;
+        } mmu_context;
+        union {
+                struct {
+                        uint32_t frame_height_mb        : 16;
+                        uint32_t pic_width_mb   : 16;
+                } bits;
+                uint32_t value;
+        } pic_size;
+        uint32_t address_a0;
+        uint32_t address_a1;
+        uint32_t mb_param_address;
+        uint32_t address_b0;
+        uint32_t address_b1;
+        uint32_t rotation_flags;
+} FW_VA_DEBLOCK_MSG;
+
+typedef struct drm_psb_msvdx_frame_info {
+	uint32_t handle;
+	uint32_t surface_id;
+	uint32_t fence;
+	uint32_t buffer_stride;
+	uint32_t buffer_size;
+	uint32_t picture_width_mb;
+	uint32_t fw_status;
+	uint32_t size_mb;
+	drm_psb_msvdx_decode_status_t decode_status;
+} drm_psb_msvdx_frame_info_t;
+
+#define MAX_DECODE_BUFFERS 24
+/* MSVDX private structure */
+struct msvdx_private {
+	int msvdx_needs_reset;
+
+	unsigned int pmstate;
+
+	struct sysfs_dirent *sysfs_pmstate;
+
+	uint32_t msvdx_current_sequence;
+	uint32_t msvdx_last_sequence;
+
+	/*
+	 *MSVDX Rendec Memory
+	 */
+	struct ttm_buffer_object *ccb0;
+	uint32_t base_addr0;
+	struct ttm_buffer_object *ccb1;
+	uint32_t base_addr1;
+
+	struct ttm_buffer_object *fw;
+	uint32_t is_load;
+	uint32_t mtx_mem_size;
+
+	/*
+	 *msvdx command queue
+	 */
+	spinlock_t msvdx_lock;
+	struct mutex msvdx_mutex;
+	struct list_head msvdx_queue;
+	int msvdx_busy;
+	int msvdx_fw_loaded;
+	void *msvdx_fw;
+	int msvdx_fw_size;
+
+	struct list_head deblock_queue; /* deblock parameter list */
+
+	uint32_t msvdx_hw_busy;
+
+	uint32_t *vec_local_mem_data;
+	uint32_t vec_local_mem_size;
+	uint32_t vec_local_mem_saved;
+	uint32_t psb_dash_access_ctrl;
+	uint32_t fw_status;
+
+	drm_psb_msvdx_frame_info_t frame_info[MAX_DECODE_BUFFERS];
+	drm_psb_msvdx_decode_status_t decode_status;
+	uint32_t deblock_enabled;
+	uint32_t host_be_opp_enabled;
+
+	uint32_t ec_fence;
+	uint32_t ref_pic_fence;
+	/*work for error concealment*/
+	struct work_struct ec_work;
+	struct ttm_object_file *tfile;
+};
+
+#define REGISTER(__group__, __reg__ )  (__group__##_##__reg__##_OFFSET)
+/* MSVDX Firmware interface */
+#define FW_VA_INIT_SIZE	        	(8)
+#define FW_VA_DEBUG_TEST2_SIZE		(4)
+
+/*MESSAGE SENT FROM HOST TO FW*/
+/*FW_VA_RENDER MESSAGE*/
+/* FW_VA_RENDER     BUFFER_SIZE */
+#define FW_VA_RENDER_BUFFER_SIZE_TYPE           uint16_t
+#define FW_VA_RENDER_BUFFER_SIZE_MASK           (0x0FFF)
+#define FW_VA_RENDER_BUFFER_SIZE_OFFSET         (0x0002)
+#define FW_VA_RENDER_BUFFER_SIZE_SHIFT          (0)
+
+/* FW_VA_RENDER     MMUPTD */
+#define FW_VA_RENDER_MMUPTD_TYPE		uint32_t
+#define FW_VA_RENDER_MMUPTD_MASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_MMUPTD_OFFSET		(0x0004)
+#define FW_VA_RENDER_MMUPTD_SHIFT		(0)
+
+/* FW_VA_RENDER     LLDMA_ADDRESS */
+#define FW_VA_RENDER_LLDMA_ADDRESS_START_BIT		0
+#define FW_VA_RENDER_LLDMA_ADDRESS_END_BIT		31
+#define FW_VA_RENDER_LLDMA_ADDRESS_ALIGNMENT		(4)
+#define FW_VA_RENDER_LLDMA_ADDRESS_TYPE		uint32_t
+#define FW_VA_RENDER_LLDMA_ADDRESS_MASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_LLDMA_ADDRESS_LSBMASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_LLDMA_ADDRESS_OFFSET		(0x0008)
+#define FW_VA_RENDER_LLDMA_ADDRESS_SHIFT		(0)
+#define FW_VA_RENDER_LLDMA_ADDRESS_SIGNED_FIELD	(0)
+
+/* FW_VA_RENDER     CONTEXT */
+#define FW_VA_RENDER_CONTEXT_START_BIT		0
+#define FW_VA_RENDER_CONTEXT_END_BIT		31
+#define FW_VA_RENDER_CONTEXT_ALIGNMENT		(4)
+#define FW_VA_RENDER_CONTEXT_TYPE		uint32_t
+#define FW_VA_RENDER_CONTEXT_MASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_CONTEXT_LSBMASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_CONTEXT_OFFSET		(0x000C)
+#define FW_VA_RENDER_CONTEXT_SHIFT		(0)
+#define FW_VA_RENDER_CONTEXT_SIGNED_FIELD	(0)
+
+
+/* FW_VA_RENDER     FENCE_VALUE_NO_EC */
+#define FW_VA_RENDER_FENCE_VALUE_TYPE		uint32_t
+#define FW_VA_RENDER_FENCE_VALUE_MASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_FENCE_VALUE_OFFSET		(0x0010)
+#define FW_VA_RENDER_FENCE_VALUE_SHIFT		(0)
+
+/* FW_VA_RENDER     OPERATING_MODE */
+#define FW_VA_RENDER_OPERATING_MODE_ALIGNMENT		(4)
+#define FW_VA_RENDER_OPERATING_MODE_TYPE		uint32_t
+#define FW_VA_RENDER_OPERATING_MODE_MASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_OPERATING_MODE_LSBMASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_OPERATING_MODE_OFFSET		(0x0014)
+#define FW_VA_RENDER_OPERATING_MODE_SHIFT		(0)
+#define FW_VA_RENDER_OPERATING_MODE_SIGNED_FIELD	(0)
+   
+/* FW_VA_RENDER     FIRST_MB_IN_SLICE */
+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_START_BIT		0
+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_END_BIT		15
+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_ALIGNMENT		(2)
+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_TYPE		uint16_t
+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_MASK		(0xFFFF)
+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_LSBMASK		(0xFFFF)
+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_OFFSET		(0x0018)
+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_SHIFT		(0)
+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_SIGNED_FIELD	(0)
+   
+/* FW_VA_RENDER     LAST_MB_IN_FRAME */
+#define FW_VA_RENDER_LAST_MB_IN_FRAME_START_BIT		16
+#define FW_VA_RENDER_LAST_MB_IN_FRAME_END_BIT		31
+#define FW_VA_RENDER_LAST_MB_IN_FRAME_ALIGNMENT		(2)
+#define FW_VA_RENDER_LAST_MB_IN_FRAME_TYPE		uint16_t
+#define FW_VA_RENDER_LAST_MB_IN_FRAME_MASK		(0xFFFF)
+#define FW_VA_RENDER_LAST_MB_IN_FRAME_LSBMASK		(0xFFFF)
+#define FW_VA_RENDER_LAST_MB_IN_FRAME_OFFSET		(0x001A)
+#define FW_VA_RENDER_LAST_MB_IN_FRAME_SHIFT		(0)
+#define FW_VA_RENDER_LAST_MB_IN_FRAME_SIGNED_FIELD	(0)
+  
+/* FW_VA_RENDER     FLAGS */
+#define FW_VA_RENDER_FLAGS_START_BIT		0
+#define FW_VA_RENDER_FLAGS_END_BIT		31
+#define FW_VA_RENDER_FLAGS_ALIGNMENT		(4)
+#define FW_VA_RENDER_FLAGS_TYPE		uint32_t
+#define FW_VA_RENDER_FLAGS_MASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_FLAGS_LSBMASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_FLAGS_OFFSET		(0x001C)
+#define FW_VA_RENDER_FLAGS_SHIFT		(0)
+#define FW_VA_RENDER_FLAGS_SIGNED_FIELD	(0)
+/* FW_VA_DEBUG_TEST2     MSG_SIZE */
+#define FW_VA_DEBUG_TEST2_MSG_SIZE_TYPE		uint8_t
+#define FW_VA_DEBUG_TEST2_MSG_SIZE_MASK		(0xFF)
+#define FW_VA_DEBUG_TEST2_MSG_SIZE_OFFSET	(0x0000)
+#define FW_VA_DEBUG_TEST2_MSG_SIZE_SHIFT	(0)
+
+/* FW_VA_DEBUG_TEST2     ID */
+#define FW_VA_DEBUG_TEST2_ID_TYPE		uint8_t
+#define FW_VA_DEBUG_TEST2_ID_MASK		(0xFF)
+#define FW_VA_DEBUG_TEST2_ID_OFFSET		(0x0001)
+#define FW_VA_DEBUG_TEST2_ID_SHIFT		(0)
+
+/* FW_VA_CMD_FAILED     FENCE_VALUE */
+#define FW_VA_CMD_FAILED_FENCE_VALUE_TYPE	uint32_t
+#define FW_VA_CMD_FAILED_FENCE_VALUE_MASK	(0xFFFFFFFF)
+#define FW_VA_CMD_FAILED_FENCE_VALUE_OFFSET	(0x0004)
+#define FW_VA_CMD_FAILED_FENCE_VALUE_SHIFT	(0)
+
+/* FW_VA_CMD_FAILED     IRQSTATUS */
+#define FW_VA_CMD_FAILED_IRQSTATUS_TYPE		uint32_t
+#define FW_VA_CMD_FAILED_IRQSTATUS_MASK		(0xFFFFFFFF)
+#define FW_VA_CMD_FAILED_IRQSTATUS_OFFSET	(0x0008)
+#define FW_VA_CMD_FAILED_IRQSTATUS_SHIFT	(0)
+/*FW_DXVA_DEBLOCK MESSAGE*/
+/* FW_DXVA_DEBLOCK     MSG_SIZE */
+#define FW_DXVA_DEBLOCK_MSG_SIZE_ALIGNMENT              (1)
+#define FW_DXVA_DEBLOCK_MSG_SIZE_TYPE           uint8_t
+#define FW_DXVA_DEBLOCK_MSG_SIZE_MASK           (0xFF)
+#define FW_DXVA_DEBLOCK_MSG_SIZE_LSBMASK                (0xFF)
+#define FW_DXVA_DEBLOCK_MSG_SIZE_OFFSET         (0x0000)
+#define FW_DXVA_DEBLOCK_MSG_SIZE_SHIFT          (0)
+
+/* FW_DXVA_DEBLOCK     ID */
+#define FW_DXVA_DEBLOCK_ID_ALIGNMENT            (1)
+#define FW_DXVA_DEBLOCK_ID_TYPE         uint8_t
+#define FW_DXVA_DEBLOCK_ID_MASK         (0xFF)
+#define FW_DXVA_DEBLOCK_ID_LSBMASK              (0xFF)
+#define FW_DXVA_DEBLOCK_ID_OFFSET               (0x0001)
+#define FW_DXVA_DEBLOCK_ID_SHIFT                (0)
+
+// FW_DXVA_DEBLOCK     FLAGS
+#define FW_DXVA_DEBLOCK_FLAGS_START_BIT		16
+#define FW_DXVA_DEBLOCK_FLAGS_END_BIT		31
+#define FW_DXVA_DEBLOCK_FLAGS_ALIGNMENT		(2)
+#define FW_DXVA_DEBLOCK_FLAGS_TYPE		uint16_t
+#define FW_DXVA_DEBLOCK_FLAGS_MASK		(0xFFFF)
+#define FW_DXVA_DEBLOCK_FLAGS_LSBMASK		(0xFFFF)
+#define FW_DXVA_DEBLOCK_FLAGS_OFFSET		(0x0002)
+#define FW_DXVA_DEBLOCK_FLAGS_SHIFT		(0)
+#define FW_DXVA_DEBLOCK_FLAGS_SIGNED_FIELD	(0)
+
+/* FW_DXVA_DEBLOCK     CONTEXT */
+#define FW_DXVA_DEBLOCK_CONTEXT_START_BIT		0
+#define FW_DXVA_DEBLOCK_CONTEXT_END_BIT		11
+#define FW_DXVA_DEBLOCK_CONTEXT_ALIGNMENT		(4)
+#define FW_DXVA_DEBLOCK_CONTEXT_TYPE		uint16_t
+#define FW_DXVA_DEBLOCK_CONTEXT_MASK		(0xFFF)
+#define FW_DXVA_DEBLOCK_CONTEXT_LSBMASK		(0xFFF)
+#define FW_DXVA_DEBLOCK_CONTEXT_OFFSET		(0x0004)
+#define FW_DXVA_DEBLOCK_CONTEXT_SHIFT		(0)
+#define FW_DXVA_DEBLOCK_CONTEXT_SIGNED_FIELD	(0)
+   
+   
+/* FW_DXVA_DEBLOCK     CONTEXT_NO_EC */
+#define FW_DXVA_DEBLOCK_CONTEXT_NO_EC_START_BIT		0
+#define FW_DXVA_DEBLOCK_CONTEXT_NO_EC_END_BIT		31
+#define FW_DXVA_DEBLOCK_CONTEXT_NO_EC_ALIGNMENT		(4)
+#define FW_DXVA_DEBLOCK_CONTEXT_NO_EC_TYPE		uint32_t
+#define FW_DXVA_DEBLOCK_CONTEXT_NO_EC_MASK		(0xFFFFFFFF)
+#define FW_DXVA_DEBLOCK_CONTEXT_NO_EC_LSBMASK		(0xFFFFFFFF)
+#define FW_DXVA_DEBLOCK_CONTEXT_NO_EC_OFFSET		(0x0004)
+#define FW_DXVA_DEBLOCK_CONTEXT_SHIFT		(0)
+#define FW_DXVA_DEBLOCK_CONTEXT_SIGNED_FIELD	(0)
+   
+/* FW_DXVA_DEBLOCK     FENCE_VALUE_NO_EC */
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_NO_EC_START_BIT		0
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_NO_EC_END_BIT		31
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_NO_EC_ALIGNMENT		(4)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_NO_EC_TYPE		uint32_t
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_NO_EC_MASK		(0xFFFFFFFF)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_NO_EC_LSBMASK		(0xFFFFFFFF)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_NO_EC_OFFSET		(0x0008)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_NO_EC_SHIFT		(0)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_NO_EC_SIGNED_FIELD	(0)
+
+
+/* FW_DXVA_DEBLOCK     MMUPTD */
+#define FW_DXVA_DEBLOCK_MMUPTD_START_BIT		0
+#define FW_DXVA_DEBLOCK_MMUPTD_END_BIT		31
+#define FW_DXVA_DEBLOCK_MMUPTD_ALIGNMENT		(4)
+#define FW_DXVA_DEBLOCK_MMUPTD_TYPE		uint32_t
+#define FW_DXVA_DEBLOCK_MMUPTD_MASK		(0xFFFFFFFF)
+#define FW_DXVA_DEBLOCK_MMUPTD_LSBMASK		(0xFFFFFFFF)
+#define FW_DXVA_DEBLOCK_MMUPTD_OFFSET		(0x000C)
+#define FW_DXVA_DEBLOCK_MMUPTD_SHIFT		(0)
+#define FW_DXVA_DEBLOCK_MMUPTD_SIGNED_FIELD	(0)
+
+
+/* FW_VA_HOST_BE_OPP     MMUPTD */
+#define FW_VA_HOST_BE_OPP_MMUPTD_ALIGNMENT                (4)
+#define FW_VA_HOST_BE_OPP_MMUPTD_TYPE             uint32_t
+#define FW_VA_HOST_BE_OPP_MMUPTD_MASK             (0xFFFFFFFF)
+#define FW_VA_HOST_BE_OPP_MMUPTD_LSBMASK          (0xFFFFFFFF)
+#define FW_VA_HOST_BE_OPP_MMUPTD_OFFSET           (0x000C)
+#define FW_VA_HOST_BE_OPP_MMUPTD_SHIFT            (0)
+
+
+/*MESSAGE SENT FROM FW TO HOST*/
+
+/* FW_VA_CMD_COMPLETED MESSAGE*/
+/* FW_VA_CMD_COMPLETED     LASTMB */
+#define FW_VA_CMD_COMPLETED_LASTMB_ALIGNMENT		(2)
+#define FW_VA_CMD_COMPLETED_LASTMB_TYPE		uint16_t
+#define FW_VA_CMD_COMPLETED_LASTMB_MASK		(0xFFFF)
+#define FW_VA_CMD_COMPLETED_LASTMB_LSBMASK		(0xFFFF)
+#define FW_VA_CMD_COMPLETED_LASTMB_OFFSET		(0x0002)
+#define FW_VA_CMD_COMPLETED_LASTMB_SHIFT		(0)
+#define FW_VA_CMD_COMPLETED_LASTMB_SIGNED_FIELD	(0)
+
+/* FW_VA_CMD_COMPLETED     NO_TICKSNO_EC */
+#define FW_VA_CMD_COMPLETED_NO_TICKS_NO_EC_TYPE	uint16_t
+#define FW_VA_CMD_COMPLETED_NO_TICKS_NO_EC_MASK	(0xFFFF)
+#define FW_VA_CMD_COMPLETED_NO_TICKS_NO_EC_OFFSET	(0x0002)
+#define FW_VA_CMD_COMPLETED_NO_TICKS_NO_EC_SHIFT	(0)
+/* FW_VA_CMD_COMPLETED     FENCE_VALUE */
+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_TYPE	uint32_t
+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_MASK	(0xFFFFFFFF)
+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_OFFSET	(0x0004)
+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_SHIFT	(0)
+
+/* FW_VA_CMD_COMPLETED     FENCE_VALUE_NO_EC */
+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_NO_EC_TYPE	uint32_t
+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_NO_EC_MASK	(0xFFFFFFFF)
+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_NO_EC_OFFSET	(0x0004)
+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_NO_EC_SHIFT	(0)
+
+/* FW_VA_CMD_COMPLETED     FLAGS */
+#define FW_VA_CMD_COMPLETED_FLAGS_ALIGNMENT		(4)
+#define FW_VA_CMD_COMPLETED_FLAGS_TYPE		uint32_t
+#define FW_VA_CMD_COMPLETED_FLAGS_MASK		(0xFFFFFFFF)
+#define FW_VA_CMD_COMPLETED_FLAGS_LSBMASK		(0xFFFFFFFF)
+#define FW_VA_CMD_COMPLETED_FLAGS_OFFSET		(0x0008)
+#define FW_VA_CMD_COMPLETED_FLAGS_SHIFT		(0)
+
+/* FW_VA_CMD_COMPLETED     NO_TICKS */
+#define FW_VA_CMD_COMPLETED_NO_TICKS_TYPE	uint16_t
+#define FW_VA_CMD_COMPLETED_NO_TICKS_MASK	(0xFFFF)
+#define FW_VA_CMD_COMPLETED_NO_TICKS_OFFSET	(0x0002)
+#define FW_VA_CMD_COMPLETED_NO_TICKS_SHIFT	(0)
+
+
+/* FW_VA_DEBLOCK_REQUIRED     CONTEXT */
+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_TYPE	uint16_t
+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_MASK	(0xFFF)
+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_OFFSET	(0x0004)
+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_SHIFT	(0)
+
+/* FW_VA_INIT     GLOBAL_PTD */
+#define FW_VA_INIT_GLOBAL_PTD_TYPE		uint32_t
+#define FW_VA_INIT_GLOBAL_PTD_MASK		(0xFFFFFFFF)
+#define FW_VA_INIT_GLOBAL_PTD_OFFSET		(0x0004)
+#define FW_VA_INIT_GLOBAL_PTD_SHIFT		(0)
+
+/* FW_VA_RENDER     FENCE_VALUE */
+#define FW_VA_RENDER_FENCE_VALUE_TYPE		uint32_t
+#define FW_VA_RENDER_FENCE_VALUE_MASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_FENCE_VALUE_OFFSET		(0x0010)
+#define FW_VA_RENDER_FENCE_VALUE_SHIFT		(0)
+
+/* FW_DXVA_OOLD     FENCE_VALUE */
+#define FW_DXVA_OOLD_FENCE_VALUE_ALIGNMENT              (4)
+#define FW_DXVA_OOLD_FENCE_VALUE_TYPE           uint32_t
+#define FW_DXVA_OOLD_FENCE_VALUE_MASK           (0xFFFFFFFF)
+#define FW_DXVA_OOLD_FENCE_VALUE_LSBMASK                (0xFFFFFFFF)
+#define FW_DXVA_OOLD_FENCE_VALUE_OFFSET         (0x0008)
+#define FW_DXVA_OOLD_FENCE_VALUE_SHIFT          (0)
+
+
+/* FW_VA_RENDER     MMUPTD */
+#define FW_VA_RENDER_MMUPTD_TYPE		uint32_t
+#define FW_VA_RENDER_MMUPTD_MASK		(0xFFFFFFFF)
+#define FW_VA_RENDER_MMUPTD_OFFSET		(0x0004)
+#define FW_VA_RENDER_MMUPTD_SHIFT		(0)
+
+/* FW_VA_RENDER     BUFFER_ADDRESS */
+#define FW_VA_RENDER_BUFFER_ADDRESS_TYPE	uint32_t
+#define FW_VA_RENDER_BUFFER_ADDRESS_MASK	(0xFFFFFFFF)
+#define FW_VA_RENDER_BUFFER_ADDRESS_OFFSET	(0x0008)
+#define FW_VA_RENDER_BUFFER_ADDRESS_SHIFT	(0)
+
+/* FW_VA_RENDER     BUFFER_SIZE */
+#define FW_VA_RENDER_BUFFER_SIZE_TYPE           uint16_t
+#define FW_VA_RENDER_BUFFER_SIZE_MASK           (0x0FFF)
+#define FW_VA_RENDER_BUFFER_SIZE_OFFSET         (0x0002)
+#define FW_VA_RENDER_BUFFER_SIZE_SHIFT          (0)
+
+/* FW_VA_RENDER	    FLAGS */
+#define FW_VA_RENDER_FLAGS_TYPE                 uint32_t
+#define FW_VA_RENDER_FLAGS_MASK                 (0xFFFFFFFF)
+#define FW_VA_RENDER_FLAGS_OFFSET               (0x001C)
+#define FW_VA_RENDER_FLAGS_SHIFT                (0)
+
+/* FW_DEVA_DECODE     MMUPTD */
+#define FW_VA_DECODE_MMUPTD_TYPE              uint32_t
+#define FW_VA_DECODE_MMUPTD_MASK              (0xFFFFFF00)
+#define FW_VA_DECODE_MMUPTD_OFFSET            (0x000C)
+#define FW_VA_DECODE_MMUPTD_SHIFT             (0)
+
+/* FW_DEVA_DECODE     MSG_ID */
+#define FW_VA_DECODE_MSG_ID_TYPE              uint16_t
+#define FW_VA_DECODE_MSG_ID_MASK              (0xFFFF)
+#define FW_VA_DECODE_MSG_ID_OFFSET            (0x0002)
+#define FW_VA_DECODE_MSG_ID_SHIFT             (0)
+
+/* FW_DEVA_DECODE     FLAGS */
+#define FW_DEVA_DECODE_FLAGS_TYPE               uint16_t
+#define FW_DEVA_DECODE_FLAGS_MASK               (0xFFFF)
+#define FW_DEVA_DECODE_FLAGS_OFFSET             (0x0004)
+#define FW_DEVA_DECODE_FLAGS_SHIFT              (0)
+
+#define FW_DEVA_INVALIDATE_MMU			(0x00000010)
+
+/* FW_DEVA_CMD_COMPLETED     MSG_ID */
+#define FW_VA_CMD_COMPLETED_MSG_ID_TYPE               uint16_t
+#define FW_VA_CMD_COMPLETED_MSG_ID_MASK               (0xFFFF)
+#define FW_VA_CMD_COMPLETED_MSG_ID_OFFSET             (0x0002)
+#define FW_VA_CMD_COMPLETED_MSG_ID_SHIFT              (0)
+
+/* FW_DEVA_CMD_FAILED     MSG_ID */
+#define FW_DEVA_CMD_FAILED_MSG_ID_TYPE          uint16_t
+#define FW_DEVA_CMD_FAILED_MSG_ID_MASK          (0xFFFF)
+#define FW_DEVA_CMD_FAILED_MSG_ID_OFFSET                (0x0002)
+#define FW_DEVA_CMD_FAILED_MSG_ID_SHIFT         (0)
+
+/* FW_DEVA_CMD_FAILED     FLAGS */
+#define FW_DEVA_CMD_FAILED_FLAGS_TYPE           uint32_t
+#define FW_DEVA_CMD_FAILED_FLAGS_MASK           (0xFFFFFFFF)
+#define FW_DEVA_CMD_FAILED_FLAGS_OFFSET         (0x0004)
+#define FW_DEVA_CMD_FAILED_FLAGS_SHIFT          (0)
+
+/* FW_DXVA_DEBLOCK     MSG_SIZE */
+#define FW_DXVA_DEBLOCK_MSG_SIZE_ALIGNMENT              (1)
+#define FW_DXVA_DEBLOCK_MSG_SIZE_TYPE           uint8_t
+#define FW_DXVA_DEBLOCK_MSG_SIZE_MASK           (0xFF)
+#define FW_DXVA_DEBLOCK_MSG_SIZE_LSBMASK                (0xFF)
+#define FW_DXVA_DEBLOCK_MSG_SIZE_OFFSET         (0x0000)
+#define FW_DXVA_DEBLOCK_MSG_SIZE_SHIFT          (0)
+
+/* FW_DXVA_DEBLOCK     ID */
+#define FW_DXVA_DEBLOCK_ID_ALIGNMENT            (1)
+#define FW_DXVA_DEBLOCK_ID_TYPE         uint8_t
+#define FW_DXVA_DEBLOCK_ID_MASK         (0xFF)
+#define FW_DXVA_DEBLOCK_ID_LSBMASK              (0xFF)
+#define FW_DXVA_DEBLOCK_ID_OFFSET               (0x0001)
+#define FW_DXVA_DEBLOCK_ID_SHIFT                (0)
+
+/* FW_DXVA_DEBLOCK     FENCE_VALUE */
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_START_BIT		0
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_END_BIT		15
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_ALIGNMENT		(4)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_TYPE		uint16_t
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_MASK		(0xFFFF)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_LSBMASK		(0xFFFF)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_OFFSET		(0x0008)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_SHIFT		(0)
+#define FW_DXVA_DEBLOCK_FENCE_VALUE_SIGNED_FIELD	(0)
+
+/* FW_VA_HOST_BE_OPP MESSAGE */
+/* FW_VA_HOST_BE_OPP     FENCE_VALUE */
+#define FW_VA_HOST_BE_OPP_FENCE_VALUE_ALIGNMENT           (4)
+#define FW_VA_HOST_BE_OPP_FENCE_VALUE_TYPE                uint16_t
+#define FW_VA_HOST_BE_OPP_FENCE_VALUE_MASK                (0xFFFF)
+#define FW_VA_HOST_BE_OPP_FENCE_VALUE_LSBMASK             (0xFFFF)
+#define FW_VA_HOST_BE_OPP_FENCE_VALUE_OFFSET              (0x0008)
+#define FW_VA_HOST_BE_OPP_FENCE_VALUE_SHIFT               (0)
+
+
+/* FW_VA_HOST_BE_OPP     MMUPTD */
+#define FW_VA_HOST_BE_OPP_MMUPTD_ALIGNMENT                (4)
+#define FW_VA_HOST_BE_OPP_MMUPTD_TYPE             uint32_t
+#define FW_VA_HOST_BE_OPP_MMUPTD_MASK             (0xFFFFFFFF)
+#define FW_VA_HOST_BE_OPP_MMUPTD_LSBMASK          (0xFFFFFFFF)
+#define FW_VA_HOST_BE_OPP_MMUPTD_OFFSET           (0x000C)
+#define FW_VA_HOST_BE_OPP_MMUPTD_SHIFT            (0)
+
+
+/* FW_DXVA_DEBLOCK     MMUPTD */
+#define FW_DXVA_DEBLOCK_MMUPTD_ALIGNMENT                (4)
+#define FW_DXVA_DEBLOCK_MMUPTD_TYPE             uint32_t
+#define FW_DXVA_DEBLOCK_MMUPTD_MASK             (0xFFFFFFFF)
+#define FW_DXVA_DEBLOCK_MMUPTD_LSBMASK          (0xFFFFFFFF)
+#define FW_DXVA_DEBLOCK_MMUPTD_OFFSET           (0x000C)
+#define FW_DXVA_DEBLOCK_MMUPTD_SHIFT            (0)
+
+#define FW_DXVA_OOLD_SIZE               (40)
+
+
+// FW_VA_CMD_COMPLETED     VDEBCR
+#define FW_VA_CMD_COMPLETED_VDEBCR_START_BIT		0
+#define FW_VA_CMD_COMPLETED_VDEBCR_END_BIT		31
+#define FW_VA_CMD_COMPLETED_VDEBCR_ALIGNMENT		(4)
+#define FW_VA_CMD_COMPLETED_VDEBCR_TYPE		uint32_t
+#define FW_VA_CMD_COMPLETED_VDEBCR_MASK		(0xFFFFFFFF)
+#define FW_VA_CMD_COMPLETED_VDEBCR_LSBMASK		(0xFFFFFFFF)
+#define FW_VA_CMD_COMPLETED_VDEBCR_OFFSET		(0x000C)
+#define FW_VA_CMD_COMPLETED_VDEBCR_SHIFT		(0)
+#define FW_VA_CMD_COMPLETED_VDEBCR_SIGNED_FIELD	(0)
+
+/* FW_VA_CMD_FAILED     FLAGS */
+#define FW_VA_CMD_FAILED_FLAGS_ALIGNMENT		(4)
+#define FW_VA_CMD_FAILED_FLAGS_TYPE		uint32_t
+#define FW_VA_CMD_FAILED_FLAGS_MASK		(0xFFFFFFFF)
+#define FW_VA_CMD_FAILED_FLAGS_LSBMASK		(0xFFFFFFFF)
+#define FW_VA_CMD_FAILED_FLAGS_OFFSET		(0x0004)
+#define FW_VA_CMD_FAILED_FLAGS_SHIFT		(0)
+#define FW_VA_CMD_FAILED_FLAGS_SIGNED_FIELD	(0)
+
+/* FW_VA_CMD_FAILED_NO_EC     FENCE_VALUE */
+#define FW_VA_CMD_FAILED_FENCE_VALUE_NO_EC_TYPE	uint32_t
+#define FW_VA_CMD_FAILED_FENCE_VALUE_NO_EC_MASK	(0xFFFFFFFF)
+#define FW_VA_CMD_FAILED_FENCE_VALUE_NO_EC_OFFSET	(0x0004)
+#define FW_VA_CMD_FAILED_FENCE_VALUE_NO_EC_SHIFT	(0)
+
+/* FW_VA_CMD_FAILED_NO_EC     IRQSTATUS */
+#define FW_VA_CMD_FAILED_IRQSTATUS_NO_EC_TYPE		uint32_t
+#define FW_VA_CMD_FAILED_IRQSTATUS_NO_EC_MASK		(0xFFFFFFFF)
+#define FW_VA_CMD_FAILED_IRQSTATUS_NO_EC_OFFSET	(0x0008)
+#define FW_VA_CMD_FAILED_IRQSTATUS_NO_EC_SHIFT	(0)
+
+/* PANIC MESSAGE */
+// FW_VA_HW_PANIC     FENCE_VALUE
+#define FW_VA_HW_PANIC_FENCE_VALUE_START_BIT		16
+#define FW_VA_HW_PANIC_FENCE_VALUE_END_BIT		31
+#define FW_VA_HW_PANIC_FENCE_VALUE_ALIGNMENT		(2)
+#define FW_VA_HW_PANIC_FENCE_VALUE_TYPE		uint16_t
+#define FW_VA_HW_PANIC_FENCE_VALUE_MASK		(0xFFFF)
+#define FW_VA_HW_PANIC_FENCE_VALUE_LSBMASK		(0xFFFF)
+#define FW_VA_HW_PANIC_FENCE_VALUE_OFFSET		(0x0002)
+#define FW_VA_HW_PANIC_FENCE_VALUE_SHIFT		(0)
+#define FW_VA_HW_PANIC_FENCE_VALUE_SIGNED_FIELD	(0)
+
+/* FW_VA_HW_PANIC     FIRST_MB_NUM */
+#define FW_VA_HW_PANIC_FIRST_MB_NUM_START_BIT		0
+#define FW_VA_HW_PANIC_FIRST_MB_NUM_END_BIT		15
+#define FW_VA_HW_PANIC_FIRST_MB_NUM_ALIGNMENT		(2)
+#define FW_VA_HW_PANIC_FIRST_MB_NUM_TYPE		uint16_t
+#define FW_VA_HW_PANIC_FIRST_MB_NUM_MASK		(0xFFFF)
+#define FW_VA_HW_PANIC_FIRST_MB_NUM_LSBMASK		(0xFFFF)
+#define FW_VA_HW_PANIC_FIRST_MB_NUM_OFFSET		(0x0004)
+#define FW_VA_HW_PANIC_FIRST_MB_NUM_SHIFT		(0)
+#define FW_VA_HW_PANIC_FIRST_MB_NUM_SIGNED_FIELD	(0)
+
+/* FW_VA_HW_PANIC     FAULT_MB_NUM */
+#define FW_VA_HW_PANIC_FAULT_MB_NUM_START_BIT		16
+#define FW_VA_HW_PANIC_FAULT_MB_NUM_END_BIT		31
+#define FW_VA_HW_PANIC_FAULT_MB_NUM_ALIGNMENT		(2)
+#define FW_VA_HW_PANIC_FAULT_MB_NUM_TYPE		uint16_t
+#define FW_VA_HW_PANIC_FAULT_MB_NUM_MASK		(0xFFFF)
+#define FW_VA_HW_PANIC_FAULT_MB_NUM_LSBMASK		(0xFFFF)
+#define FW_VA_HW_PANIC_FAULT_MB_NUM_OFFSET		(0x0006)
+#define FW_VA_HW_PANIC_FAULT_MB_NUM_SHIFT		(0)
+#define FW_VA_HW_PANIC_FAULT_MB_NUM_SIGNED_FIELD	(0)
+
+/* FW_VA_HW_PANIC     FESTATUS */
+#define FW_VA_HW_PANIC_FESTATUS_START_BIT		0
+#define FW_VA_HW_PANIC_FESTATUS_END_BIT		31
+#define FW_VA_HW_PANIC_FESTATUS_ALIGNMENT		(4)
+#define FW_VA_HW_PANIC_FESTATUS_TYPE		uint32_t
+#define FW_VA_HW_PANIC_FESTATUS_MASK		(0xFFFFFFFF)
+#define FW_VA_HW_PANIC_FESTATUS_LSBMASK		(0xFFFFFFFF)
+#define FW_VA_HW_PANIC_FESTATUS_OFFSET		(0x0008)
+#define FW_VA_HW_PANIC_FESTATUS_SHIFT		(0)
+#define FW_VA_HW_PANIC_FESTATUS_SIGNED_FIELD	(0)
+
+/* FW_VA_HW_PANIC     BESTATUS */
+#define FW_VA_HW_PANIC_BESTATUS_START_BIT		0
+#define FW_VA_HW_PANIC_BESTATUS_END_BIT		31
+#define FW_VA_HW_PANIC_BESTATUS_ALIGNMENT		(4)
+#define FW_VA_HW_PANIC_BESTATUS_TYPE		uint32_t
+#define FW_VA_HW_PANIC_BESTATUS_MASK		(0xFFFFFFFF)
+#define FW_VA_HW_PANIC_BESTATUS_LSBMASK		(0xFFFFFFFF)
+#define FW_VA_HW_PANIC_BESTATUS_OFFSET		(0x000C)
+#define FW_VA_HW_PANIC_BESTATUS_SHIFT		(0)
+#define FW_VA_HW_PANIC_BESTATUS_SIGNED_FIELD	(0)
+
+/* FW_VA_DEBLOCK_REQUIRED MESSAGE*/
+/* FW_VA_DEBLOCK_REQUIRED     FENCE_VALUE */
+#define FW_VA_DEBLOCK_REQUIRED_FENCE_VALUE_ALIGNMENT		(2)
+#define FW_VA_DEBLOCK_REQUIRED_FENCE_VALUE_TYPE		uint16_t
+#define FW_VA_DEBLOCK_REQUIRED_FENCE_VALUE_MASK		(0xFFFF)
+#define FW_VA_DEBLOCK_REQUIRED_FENCE_VALUE_LSBMASK		(0xFFFF)
+#define FW_VA_DEBLOCK_REQUIRED_FENCE_VALUE_OFFSET		(0x0002)
+#define FW_VA_DEBLOCK_REQUIRED_FENCE_VALUE_SHIFT		(0)
+#define FW_VA_DEBLOCK_REQUIRED_FENCE_VALUE_SIGNED_FIELD	(0)
+
+
+/* FW_VA_DEBLOCK_REQUIRED     CONTEXTNO_EC */
+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_NO_EC_TYPE	uint32_t
+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_NO_EC_MASK	(0xFFFFFFFF)
+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_NO_EC_OFFSET	(0x0004)
+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_NO_EC_SHIFT	(0)
+
+/* FW_VA_CONTIGUITY_WARNING MESSAGE */
+#define FW_VA_CONTIGUITY_WARNING_SIZE		(8)
+
+/* FW_VA_CONTIGUITY_WARNING     FENCE_VALUE */
+#define FW_VA_CONTIGUITY_WARNING_FENCE_VALUE_START_BIT		16
+#define FW_VA_CONTIGUITY_WARNING_FENCE_VALUE_END_BIT		31
+#define FW_VA_CONTIGUITY_WARNING_FENCE_VALUE_ALIGNMENT		(2)
+#define FW_VA_CONTIGUITY_WARNING_FENCE_VALUE_TYPE		uint16_t
+#define FW_VA_CONTIGUITY_WARNING_FENCE_VALUE_MASK		(0xFFFF)
+#define FW_VA_CONTIGUITY_WARNING_FENCE_VALUE_LSBMASK		(0xFFFF)
+#define FW_VA_CONTIGUITY_WARNING_FENCE_VALUE_OFFSET		(0x0002)
+#define FW_VA_CONTIGUITY_WARNING_FENCE_VALUE_SHIFT		(0)
+#define FW_VA_CONTIGUITY_WARNING_FENCE_VALUE_SIGNED_FIELD	(0)
+
+/* FW_VA_CONTIGUITY_WARNING     ID */
+#define FW_VA_CONTIGUITY_WARNING_ID_START_BIT		8
+#define FW_VA_CONTIGUITY_WARNING_ID_END_BIT		15
+#define FW_VA_CONTIGUITY_WARNING_ID_ALIGNMENT		(1)
+#define FW_VA_CONTIGUITY_WARNING_ID_TYPE		uint8_t
+#define FW_VA_CONTIGUITY_WARNING_ID_MASK		(0xFF)
+#define FW_VA_CONTIGUITY_WARNING_ID_LSBMASK		(0xFF)
+#define FW_VA_CONTIGUITY_WARNING_ID_OFFSET		(0x0001)
+#define FW_VA_CONTIGUITY_WARNING_ID_SHIFT		(0)
+#define FW_VA_CONTIGUITY_WARNING_ID_SIGNED_FIELD	(0)
+
+/* FW_VA_CONTIGUITY_WARNING     MSG_SIZE */
+#define FW_VA_CONTIGUITY_WARNING_MSG_SIZE_START_BIT		0
+#define FW_VA_CONTIGUITY_WARNING_MSG_SIZE_END_BIT		7
+#define FW_VA_CONTIGUITY_WARNING_MSG_SIZE_ALIGNMENT		(1)
+#define FW_VA_CONTIGUITY_WARNING_MSG_SIZE_TYPE		uint8_t
+#define FW_VA_CONTIGUITY_WARNING_MSG_SIZE_MASK		(0xFF)
+#define FW_VA_CONTIGUITY_WARNING_MSG_SIZE_LSBMASK		(0xFF)
+#define FW_VA_CONTIGUITY_WARNING_MSG_SIZE_OFFSET		(0x0000)
+#define FW_VA_CONTIGUITY_WARNING_MSG_SIZE_SHIFT		(0)
+#define FW_VA_CONTIGUITY_WARNING_MSG_SIZE_SIGNED_FIELD	(0)
+
+/* FW_VA_CONTIGUITY_WARNING     END_MB_NUM */
+#define FW_VA_CONTIGUITY_WARNING_END_MB_NUM_START_BIT		0
+#define FW_VA_CONTIGUITY_WARNING_END_MB_NUM_END_BIT		15
+#define FW_VA_CONTIGUITY_WARNING_END_MB_NUM_ALIGNMENT		(2)
+#define FW_VA_CONTIGUITY_WARNING_END_MB_NUM_TYPE		uint16_t
+#define FW_VA_CONTIGUITY_WARNING_END_MB_NUM_MASK		(0xFFFF)
+#define FW_VA_CONTIGUITY_WARNING_END_MB_NUM_LSBMASK		(0xFFFF)
+#define FW_VA_CONTIGUITY_WARNING_END_MB_NUM_OFFSET		(0x0004)
+#define FW_VA_CONTIGUITY_WARNING_END_MB_NUM_SHIFT		(0)
+#define FW_VA_CONTIGUITY_WARNING_END_MB_NUM_SIGNED_FIELD	(0)
+
+/* FW_VA_CONTIGUITY_WARNING     BEGIN_MB_NUM */
+#define FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM_START_BIT		16
+#define FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM_END_BIT		31
+#define FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM_ALIGNMENT		(2)
+#define FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM_TYPE		uint16_t
+#define FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM_MASK		(0xFFFF)
+#define FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM_LSBMASK		(0xFFFF)
+#define FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM_OFFSET		(0x0006)
+#define FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM_SHIFT		(0)
+#define FW_VA_CONTIGUITY_WARNING_BEGIN_MB_NUM_SIGNED_FIELD	(0)
+
+/* FW_DXVA_OOLD     FENCE_VALUE */
+#define FW_DXVA_OOLD_FENCE_VALUE_ALIGNMENT              (4)
+#define FW_DXVA_OOLD_FENCE_VALUE_TYPE           uint32_t
+#define FW_DXVA_OOLD_FENCE_VALUE_MASK           (0xFFFFFFFF)
+#define FW_DXVA_OOLD_FENCE_VALUE_LSBMASK                (0xFFFFFFFF)
+#define FW_DXVA_OOLD_FENCE_VALUE_OFFSET         (0x0008)
+#define FW_DXVA_OOLD_FENCE_VALUE_SHIFT          (0)
+ 
+/* FW_DXVA_OOLD     MMUPTD */
+#define FW_DXVA_OOLD_MMUPTD_ALIGNMENT           (4)
+#define FW_DXVA_OOLD_MMUPTD_TYPE                IMG_UINT32
+#define FW_DXVA_OOLD_MMUPTD_MASK                (0xFFFFFFFF)
+#define FW_DXVA_OOLD_MMUPTD_LSBMASK             (0xFFFFFFFF)
+#define FW_DXVA_OOLD_MMUPTD_OFFSET              (0x0004)
+#define FW_DXVA_OOLD_MMUPTD_SHIFT               (0)
+
+#define FW_VA_LAST_SLICE_OF_EXT_DMA                                         0x00001000
+
+static inline void psb_msvdx_clearirq(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	unsigned long mtx_int = 0;
+
+	PSB_DEBUG_IRQ("MSVDX: clear IRQ\n");
+
+	/* Clear MTX interrupt */
+	REGIO_WRITE_FIELD_LITE(mtx_int, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ,
+			       1);
+	PSB_WMSVDX32(mtx_int, MSVDX_INTERRUPT_CLEAR);
+}
+
+
+static inline void psb_msvdx_disableirq(struct drm_device *dev)
+{
+	/* nothing */
+}
+
+
+static inline void psb_msvdx_enableirq(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	unsigned long enables = 0;
+
+	PSB_DEBUG_IRQ("MSVDX: enable MSVDX MTX IRQ\n");
+	REGIO_WRITE_FIELD_LITE(enables, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ,
+			       1);
+	PSB_WMSVDX32(enables, MSVDX_HOST_INTERRUPT_ENABLE);
+}
+
+#define MSVDX_NEW_PMSTATE(drm_dev, msvdx_priv, new_state)		\
+do {									\
+	msvdx_priv->pmstate = new_state;				\
+	sysfs_notify_dirent(msvdx_priv->sysfs_pmstate);			\
+	PSB_DEBUG_PM("MSVDX: %s\n",					\
+		(new_state == PSB_PMSTATE_POWERUP) ? "powerup"		\
+		: ((new_state == PSB_PMSTATE_POWERDOWN) ? "powerdown"	\
+			: "clockgated"));				\
+} while (0)
+
+#endif
+
+#define IS_FW_UPDATED 1
diff --git a/drivers/staging/cdv/imgv/psb_msvdxinit.c b/drivers/staging/cdv/imgv/psb_msvdxinit.c
new file mode 100644
index 0000000..c3f3571
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_msvdxinit.c
@@ -0,0 +1,1183 @@
+/**************************************************************************
+ * psb_msvdxinit.c
+ * MSVDX initialization and mtx-firmware upload
+ *
+ * Copyright (c) 2011 Intel Corporation, Hillsboro, OR, USA
+ * Copyright (c) Imagination Technologies Limited, UK
+ *
+ * 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 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.
+ *
+ **************************************************************************/
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drv.h"
+#include "psb_msvdx.h"
+#include <linux/firmware.h>
+
+#define MSVDX_REG (dev_priv->msvdx_reg)
+#define UPLOAD_FW_BY_DMA 1
+#define STACKGUARDWORD          ( 0x10101010 )
+#define MSVDX_MTX_DATA_LOCATION ( 0x82880000 )
+#define UNINITILISE_MEM 	( 0xcdcdcdcd )
+#define FIRMWAREID		( 0x014d42ab )
+
+uint8_t psb_rev_id;
+/*MSVDX FW header*/
+struct msvdx_fw {
+	uint32_t ver;
+	uint32_t text_size;
+	uint32_t data_size;
+	uint32_t data_location;
+};
+
+int psb_wait_for_register(struct drm_psb_private *dev_priv,
+			  uint32_t offset, uint32_t value, uint32_t enable,
+				uint32_t loops, uint32_t interval)
+{
+	uint32_t reg_value = 0;
+	uint32_t poll_cnt = loops;
+	while (poll_cnt) {
+		reg_value = PSB_RMSVDX32(offset);
+		if (value == (reg_value & enable))	/* All the bits are reset   */
+			return 0;	/* So exit			*/
+
+		/* Wait a bit */
+		DRM_UDELAY(interval);
+		poll_cnt--;
+	}
+	DRM_ERROR("MSVDX: Timeout while waiting for register %08x:"
+		  " expecting %08x (mask %08x), got %08x\n",
+		  offset, value, enable, reg_value);
+
+	return 1;
+}
+
+int psb_poll_mtx_irq(struct drm_psb_private *dev_priv)
+{
+	int ret = 0;
+	uint32_t mtx_int = 0;
+
+	REGIO_WRITE_FIELD_LITE(mtx_int, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ,
+			       1);
+
+	ret = psb_wait_for_register(dev_priv, MSVDX_INTERRUPT_STATUS,
+				    /* Required value */
+				    mtx_int,
+				    /* Enabled bits */
+				    mtx_int, 10000, 100);
+
+	if (ret) {
+		DRM_ERROR("MSVDX: Error Mtx did not return"
+			  " int within a resonable time\n");
+		return ret;
+	}
+
+	PSB_DEBUG_IRQ("MSVDX: Got MTX Int\n");
+
+	/* Got it so clear the bit */
+	PSB_WMSVDX32(mtx_int, MSVDX_INTERRUPT_CLEAR);
+
+	return ret;
+}
+
+void psb_write_mtx_core_reg(struct drm_psb_private *dev_priv,
+			    const uint32_t core_reg, const uint32_t val)
+{
+	uint32_t reg = 0;
+
+	/* Put data in MTX_RW_DATA */
+	PSB_WMSVDX32(val, MSVDX_MTX_REGISTER_READ_WRITE_DATA);
+
+	/* DREADY is set to 0 and request a write */
+	reg = core_reg;
+	REGIO_WRITE_FIELD_LITE(reg, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST,
+			       MTX_RNW, 0);
+	REGIO_WRITE_FIELD_LITE(reg, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST,
+			       MTX_DREADY, 0);
+	PSB_WMSVDX32(reg, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST);
+
+	psb_wait_for_register(dev_priv,
+			      MSVDX_MTX_REGISTER_READ_WRITE_REQUEST,
+			      MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK,
+			      MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK,
+				100, 100);
+}
+
+#if UPLOAD_FW_BY_DMA
+
+static void psb_get_mtx_control_from_dash(struct drm_psb_private *dev_priv)
+{
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	int count = 0;
+	uint32_t reg_val = 0;
+
+	REGIO_WRITE_FIELD(reg_val, MSVDX_MTX_DEBUG, MTX_DBG_IS_SLAVE, 1);
+	REGIO_WRITE_FIELD(reg_val, MSVDX_MTX_DEBUG, MTX_DBG_GPIO_IN, 0x02);
+	PSB_WMSVDX32(reg_val, MSVDX_MTX_DEBUG);
+
+	do
+	{
+		reg_val = PSB_RMSVDX32(MSVDX_MTX_DEBUG);
+		count++;
+	} while (((reg_val & 0x18) != 0) && count < 50000);
+
+	if(count >= 50000)
+		PSB_DEBUG_GENERAL("TOPAZ: timeout in get_mtx_control_from_dash\n"); 
+
+	/* Save the access control register...*/
+	msvdx_priv->psb_dash_access_ctrl = PSB_RMSVDX32(MSVDX_MTX_RAM_ACCESS_CONTROL);
+		
+}
+
+static void psb_release_mtx_control_from_dash(struct drm_psb_private *dev_priv)
+{
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	/* restore access control */
+	PSB_WMSVDX32(msvdx_priv->psb_dash_access_ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
+	/* release bus */
+	PSB_WMSVDX32(0x4, MSVDX_MTX_DEBUG);
+}
+
+
+
+static void psb_upload_fw(struct drm_psb_private *dev_priv,
+			  uint32_t address, const unsigned int words, int fw_sel)
+{
+	uint32_t reg_val=0;
+	uint32_t cmd;
+	uint32_t uCountReg, offset, mmu_ptd;
+	uint32_t size = (words*4 ); /* byte count */
+	uint32_t dma_channel = 0; /* Setup a Simple DMA for Ch0 */
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	PSB_DEBUG_GENERAL("MSVDX: Upload firmware by DMA\n");
+	psb_get_mtx_control_from_dash(dev_priv);
+
+	// dma transfers to/from the mtx have to be 32-bit aligned and in multiples of 32 bits
+	PSB_WMSVDX32(address, REGISTER(MTX_CORE, CR_MTX_SYSC_CDMAA));
+
+	REGIO_WRITE_FIELD_LITE(reg_val, MTX_CORE_CR_MTX_SYSC_CDMAC, BURSTSIZE,	4 );// burst size in multiples of 64 bits (allowed values are 2 or 4)
+	REGIO_WRITE_FIELD_LITE(reg_val, MTX_CORE_CR_MTX_SYSC_CDMAC, RNW, 0);	// false means write to mtx mem, true means read from mtx mem
+	REGIO_WRITE_FIELD_LITE(reg_val, MTX_CORE_CR_MTX_SYSC_CDMAC, ENABLE,	1);				// begin transfer
+	REGIO_WRITE_FIELD_LITE(reg_val, MTX_CORE_CR_MTX_SYSC_CDMAC, LENGTH,	words  );		// This specifies the transfer size of the DMA operation in terms of 32-bit words
+	PSB_WMSVDX32(reg_val, REGISTER(MTX_CORE, CR_MTX_SYSC_CDMAC));
+
+	// toggle channel 0 usage between mtx and other msvdx peripherals
+	{
+		reg_val = PSB_RMSVDX32(REGISTER(  MSVDX_CORE, CR_MSVDX_CONTROL));
+		REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_MSVDX_CONTROL, DMAC_CH0_SELECT,  0 );
+		PSB_WMSVDX32(reg_val, REGISTER( MSVDX_CORE, CR_MSVDX_CONTROL));
+	}
+
+
+	/* Clear the DMAC Stats */
+	PSB_WMSVDX32(0 , REGISTER(DMAC, DMAC_IRQ_STAT ) + dma_channel);
+
+	offset = msvdx_priv->fw->offset;
+
+	if(fw_sel)
+		offset += ((msvdx_priv->mtx_mem_size + 8192) & ~0xfff);
+
+	/* use bank 0 */
+	cmd = 0;
+	PSB_WMSVDX32(cmd, REGISTER(MSVDX_CORE, CR_MMU_BANK_INDEX));
+
+	/* Write PTD to mmu base 0*/
+	mmu_ptd = psb_get_default_pd_addr(dev_priv->mmu);
+	PSB_WMSVDX32(mmu_ptd, REGISTER( MSVDX_CORE, CR_MMU_DIR_LIST_BASE) + 0);
+
+	/* Invalidate */
+	reg_val = PSB_RMSVDX32(REGISTER(MSVDX_CORE, CR_MMU_CONTROL0));
+	reg_val &= ~0xf;
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_MMU_CONTROL0, CR_MMU_INVALDC, 1 );
+	PSB_WMSVDX32(reg_val, REGISTER(MSVDX_CORE, CR_MMU_CONTROL0 ));
+
+	PSB_WMSVDX32(offset, REGISTER(DMAC, DMAC_SETUP ) + dma_channel);
+
+	/* Only use a single dma - assert that this is valid */
+	if( (size / 4 ) >= (1<<15) ) {
+		DRM_ERROR("psb: DMA size beyond limited, aboart firmware uploading\n");
+		return;
+	}
+		
+
+	uCountReg = PSB_DMAC_VALUE_COUNT(PSB_DMAC_BSWAP_NO_SWAP,
+					 0,  /* 32 bits */
+					 PSB_DMAC_DIR_MEM_TO_PERIPH,
+					 0,
+					 (size / 4 ) );
+	/* Set the number of bytes to dma*/
+	PSB_WMSVDX32(uCountReg, REGISTER(DMAC, 	DMAC_COUNT ) + dma_channel);
+
+	cmd = PSB_DMAC_VALUE_PERIPH_PARAM(PSB_DMAC_ACC_DEL_0, PSB_DMAC_INCR_OFF, PSB_DMAC_BURST_2);
+	PSB_WMSVDX32(cmd, REGISTER(DMAC, DMAC_PERIPH ) + dma_channel);
+
+	/* Set destination port for dma */
+	cmd = 0;
+	REGIO_WRITE_FIELD(cmd, DMAC_DMAC_PERIPHERAL_ADDR, ADDR, MTX_CORE_CR_MTX_SYSC_CDMAT_OFFSET); 
+	PSB_WMSVDX32(cmd, REGISTER(DMAC, DMAC_PERIPHERAL_ADDR ) + dma_channel);
+
+
+	/* Finally, rewrite the count register with the enable bit set*/
+	PSB_WMSVDX32(uCountReg | DMAC_DMAC_COUNT_EN_MASK, REGISTER(DMAC, DMAC_COUNT ) + dma_channel);
+
+	/* Wait for all to be done */
+	if(psb_wait_for_register(dev_priv, 
+				 REGISTER(DMAC, DMAC_IRQ_STAT ) + dma_channel, 
+				 DMAC_DMAC_IRQ_STAT_TRANSFER_FIN_MASK, 
+				 DMAC_DMAC_IRQ_STAT_TRANSFER_FIN_MASK, 10000,100)) {
+		psb_release_mtx_control_from_dash(dev_priv);
+		return;
+	}
+
+	/* Assert that the MTX DMA port is all done aswell */
+	if(psb_wait_for_register(dev_priv, REGISTER(MTX_CORE, CR_MTX_SYSC_CDMAS0), 1, 1, 10, 10)) {
+		psb_release_mtx_control_from_dash(dev_priv);
+		return;
+	}
+
+	psb_release_mtx_control_from_dash(dev_priv);
+	PSB_DEBUG_GENERAL("MSVDX: Upload done\n");
+}
+
+#else
+
+static void psb_upload_fw(struct drm_psb_private *dev_priv,
+			  const uint32_t data_mem, uint32_t ram_bank_size,
+			  uint32_t address, const unsigned int words,
+			  const uint32_t * const data)
+{
+	uint32_t loop, ctrl, ram_id, addr, cur_bank = (uint32_t) ~0;
+	uint32_t access_ctrl;
+
+	PSB_DEBUG_GENERAL("MSVDX: Upload firmware by register interface\n");
+	/* Save the access control register... */
+	access_ctrl = PSB_RMSVDX32(MSVDX_MTX_RAM_ACCESS_CONTROL);
+
+	/* Wait for MCMSTAT to become be idle 1 */
+	psb_wait_for_register(dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS,
+			      1,	/* Required Value */
+			      0xffffffff,/* Enables */
+				1000,100);
+
+	for (loop = 0; loop < words; loop++) {
+		ram_id = data_mem + (address / ram_bank_size);
+		if (ram_id != cur_bank) {
+			addr = address >> 2;
+			ctrl = 0;
+			REGIO_WRITE_FIELD_LITE(ctrl,
+					       MSVDX_MTX_RAM_ACCESS_CONTROL,
+					       MTX_MCMID, ram_id);
+			REGIO_WRITE_FIELD_LITE(ctrl,
+					       MSVDX_MTX_RAM_ACCESS_CONTROL,
+					       MTX_MCM_ADDR, addr);
+			REGIO_WRITE_FIELD_LITE(ctrl,
+					       MSVDX_MTX_RAM_ACCESS_CONTROL,
+					       MTX_MCMAI, 1);
+			PSB_WMSVDX32(ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
+			cur_bank = ram_id;
+		}
+		address += 4;
+
+		PSB_WMSVDX32(data[loop],
+			     MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER);
+
+		/* Wait for MCMSTAT to become be idle 1 */
+		psb_wait_for_register(dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS,
+				      1,	/* Required Value */
+				      0xffffffff, /* Enables */
+					100, 100);
+	}
+	PSB_DEBUG_GENERAL("MSVDX: Upload done\n");
+
+	/* Restore the access control register... */
+	PSB_WMSVDX32(access_ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
+}
+
+#endif
+
+static int psb_verify_fw(struct drm_psb_private *dev_priv,
+			 const uint32_t ram_bank_size,
+			 const uint32_t data_mem, uint32_t address,
+			 const uint32_t words, const uint32_t * const data)
+{
+	uint32_t loop, ctrl, ram_id, addr, cur_bank = (uint32_t) ~0;
+	uint32_t access_ctrl;
+	int ret = 0;
+
+	/* Save the access control register... */
+	access_ctrl = PSB_RMSVDX32(MSVDX_MTX_RAM_ACCESS_CONTROL);
+
+	/* Wait for MCMSTAT to become be idle 1 */
+	psb_wait_for_register(dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS,
+			      1,	/* Required Value */
+			      0xffffffff, /* Enables */
+				100, 100);
+
+	for (loop = 0; loop < words; loop++) {
+		uint32_t reg_value;
+		ram_id = data_mem + (address / ram_bank_size);
+
+		if (ram_id != cur_bank) {
+			addr = address >> 2;
+			ctrl = 0;
+			REGIO_WRITE_FIELD_LITE(ctrl,
+					       MSVDX_MTX_RAM_ACCESS_CONTROL,
+					       MTX_MCMID, ram_id);
+			REGIO_WRITE_FIELD_LITE(ctrl,
+					       MSVDX_MTX_RAM_ACCESS_CONTROL,
+					       MTX_MCM_ADDR, addr);
+			REGIO_WRITE_FIELD_LITE(ctrl,
+					       MSVDX_MTX_RAM_ACCESS_CONTROL,
+					       MTX_MCMAI, 1);
+			REGIO_WRITE_FIELD_LITE(ctrl,
+					       MSVDX_MTX_RAM_ACCESS_CONTROL,
+					       MTX_MCMR, 1);
+
+			PSB_WMSVDX32(ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
+
+			cur_bank = ram_id;
+		}
+		address += 4;
+
+		/* Wait for MCMSTAT to become be idle 1 */
+		psb_wait_for_register(dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS,
+				      1,	/* Required Value */
+				      0xffffffff, /* Enables */
+					100, 100);
+
+		reg_value = PSB_RMSVDX32(MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER);
+		if (data[loop] != reg_value) {
+			DRM_ERROR("psb: Firmware validation fails"
+				  " at index=%08x\n", loop);
+			ret = 1;
+			break;
+		}
+	}
+
+	/* Restore the access control register... */
+	PSB_WMSVDX32(access_ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
+
+	return ret;
+}
+
+static int msvdx_get_fw_bo(struct drm_device *dev,
+			   const struct firmware **raw, uint8_t *name)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	int rc, fw_size;
+	void *ptr = NULL;
+        struct ttm_bo_kmap_obj tmp_kmap;
+        bool is_iomem;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	void *gpu_addr;
+
+	rc = request_firmware(raw, name, &dev->pdev->dev);
+	if (rc < 0) {
+		DRM_ERROR("MSVDX: %s request_firmware failed: Reason %d\n",
+			  name, rc);
+		return 1;
+	}
+
+	if ((*raw)->size < sizeof(struct msvdx_fw)) {
+		DRM_ERROR("MSVDX: %s is is not correct size(%zd)\n",
+			  name, (*raw)->size);
+		return 1;
+	}
+
+	ptr = (void *) ((*raw))->data;
+
+	if (!ptr) {
+		DRM_ERROR("MSVDX: Failed to load %s\n", name);
+		return 1;
+	}
+
+	/* another sanity check... */
+	fw_size = sizeof(struct msvdx_fw) +
+		sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->text_size +
+		sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->data_size;
+	if ((*raw)->size < fw_size) {
+		DRM_ERROR("MSVDX: %s is is not correct size(%zd)\n",
+			  name, (*raw)->size);
+		return 1;
+	}
+
+	rc = ttm_bo_kmap(msvdx_priv->fw, 0, (msvdx_priv->fw)->num_pages, &tmp_kmap);
+	if (rc) {
+		PSB_DEBUG_GENERAL("drm_bo_kmap failed: %d\n", rc);
+		ttm_bo_unref(&msvdx_priv->fw);
+		ttm_bo_kunmap(&tmp_kmap);
+		return 1;
+	}		
+	else {
+		uint32_t *last_word;
+		gpu_addr = ttm_kmap_obj_virtual(&tmp_kmap, &is_iomem);
+
+		memset(gpu_addr, UNINITILISE_MEM, msvdx_priv->mtx_mem_size);
+
+		memcpy(gpu_addr, ptr + sizeof(struct msvdx_fw),
+			sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->text_size);
+
+		memcpy(gpu_addr + (((struct msvdx_fw *) ptr)->data_location - MSVDX_MTX_DATA_LOCATION),
+			(void *)ptr + sizeof(struct msvdx_fw) + sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->text_size, 
+			sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->data_size);
+
+		last_word = (uint32_t *) (gpu_addr + msvdx_priv->mtx_mem_size -4);
+		/* Write a know value to last word in mtx memory*/
+		/* Usefull for detection of stack overrun */
+		*last_word = STACKGUARDWORD;
+	}
+
+	ttm_bo_kunmap(&tmp_kmap);
+	PSB_DEBUG_GENERAL("MSVDX: releasing firmware resouces\n");
+	PSB_DEBUG_GENERAL("MSVDX: Load firmware into BO successfully\n");
+	release_firmware(*raw);
+	return rc;
+}
+
+
+static uint32_t *msvdx_get_fw(struct drm_device *dev,
+			      const struct firmware **raw, uint8_t *name)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	int rc, fw_size;
+	void *ptr = NULL;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	rc = request_firmware(raw, name, &dev->pdev->dev);
+	if (rc < 0) {
+		DRM_ERROR("MSVDX: %s request_firmware failed: Reason %d\n",
+			  name, rc);
+		return NULL;
+	}
+
+	if ((*raw)->size < sizeof(struct msvdx_fw)) {
+		DRM_ERROR("MSVDX: %s is is not correct size(%zd)\n",
+			  name, (*raw)->size);
+		return NULL;
+	}
+
+	ptr = (int *) ((*raw))->data;
+
+	if (!ptr) {
+		DRM_ERROR("MSVDX: Failed to load %s\n", name);
+		return NULL;
+	}
+
+	/* another sanity check... */
+	fw_size = sizeof(struct msvdx_fw) +
+		sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->text_size +
+		sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->data_size;
+	if ((*raw)->size < fw_size) {
+		DRM_ERROR("MSVDX: %s is is not correct size(%zd)\n",
+			  name, (*raw)->size);
+		return NULL;
+	}
+	else if((*raw)->size > fw_size) { /* there is ec firmware */
+		ptr += ((fw_size + 0xfff) & ~0xfff);
+		fw_size += (sizeof(struct msvdx_fw) +
+			    sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->text_size +
+			    sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->data_size);
+
+		ptr = (int *) ((*raw))->data; /* Resotre ptr to start of the firmware file */
+	}
+
+	msvdx_priv->msvdx_fw = kzalloc(fw_size, GFP_KERNEL);
+	if (msvdx_priv->msvdx_fw == NULL)
+		DRM_ERROR("MSVDX: allocate FW buffer failed\n");
+	else {
+		memcpy(msvdx_priv->msvdx_fw, ptr, fw_size);
+		msvdx_priv->msvdx_fw_size = fw_size;
+	}
+
+	PSB_DEBUG_GENERAL("MSVDX: releasing firmware resouces\n");
+	release_firmware(*raw);
+
+	return msvdx_priv->msvdx_fw;
+}
+
+int psb_setup_fw(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	uint32_t ram_bank_size;
+	struct msvdx_fw *fw;
+	uint32_t *fw_ptr = NULL;
+	uint32_t *text_ptr = NULL;
+	uint32_t *data_ptr = NULL;
+	const struct firmware *raw = NULL;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+	int ec_firmware = 0, ret = 0;
+
+	/* todo : Assert the clock is on - if not turn it on to upload code */
+	PSB_DEBUG_GENERAL("MSVDX: psb_setup_fw\n");
+	PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
+
+	/* Reset MTX */
+	PSB_WMSVDX32(MSVDX_MTX_SOFT_RESET_MTX_RESET_MASK,
+		     MSVDX_MTX_SOFT_RESET);
+
+	/* Initialses Communication controll area to 0 */
+/*
+  if (psb_rev_id >= POULSBO_D1) {
+  PSB_DEBUG_GENERAL("MSVDX: Detected Poulsbo D1"
+  " or later revision.\n");
+  PSB_WMSVDX32(MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D1,
+  MSVDX_COMMS_OFFSET_FLAGS);
+  } else {
+  PSB_DEBUG_GENERAL("MSVDX: Detected Poulsbo D0"
+  " or earlier revision.\n");
+  PSB_WMSVDX32(MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D0,
+  MSVDX_COMMS_OFFSET_FLAGS);
+  }
+*/
+
+	if(IS_CDV(dev)) {
+		PSB_WMSVDX32(FIRMWAREID, MSVDX_COMMS_FIRMWARE_ID);
+	}
+
+	PSB_WMSVDX32(0, MSVDX_COMMS_ERROR_TRIG);
+	PSB_WMSVDX32(199, MSVDX_MTX_SYSC_TIMERDIV); /* MTX_SYSC_TIMERDIV */
+	PSB_WMSVDX32(0, MSVDX_EXT_FW_ERROR_STATE); /* EXT_FW_ERROR_STATE */
+
+	PSB_WMSVDX32(0, MSVDX_COMMS_MSG_COUNTER);
+	PSB_WMSVDX32(0, MSVDX_COMMS_SIGNATURE);
+	PSB_WMSVDX32(0, MSVDX_COMMS_TO_HOST_RD_INDEX);
+	PSB_WMSVDX32(0, MSVDX_COMMS_TO_HOST_WRT_INDEX);
+	PSB_WMSVDX32(0, MSVDX_COMMS_TO_MTX_RD_INDEX);
+	PSB_WMSVDX32(0, MSVDX_COMMS_TO_MTX_WRT_INDEX);
+	PSB_WMSVDX32(0, MSVDX_COMMS_FW_STATUS);
+	PSB_WMSVDX32(DSIABLE_IDLE_GPIO_SIG | DSIABLE_Auto_CLOCK_GATING | RETURN_VDEB_DATA_IN_COMPLETION | DSIABLE_FW_WDT,
+		     MSVDX_COMMS_OFFSET_FLAGS);
+	PSB_WMSVDX32(0, MSVDX_COMMS_SIGNATURE);
+	/* read register bank size */
+	{
+		uint32_t bank_size, reg;
+		reg = PSB_RMSVDX32(MSVDX_MTX_RAM_BANK);
+		bank_size =
+			REGIO_READ_FIELD(reg, MSVDX_MTX_RAM_BANK,
+					 CR_MTX_RAM_BANK_SIZE);
+		ram_bank_size = (uint32_t) (1 << (bank_size + 2));
+	}
+
+	PSB_DEBUG_GENERAL("MSVDX: RAM bank size = %d bytes\n",
+			  ram_bank_size);
+
+	/* if FW already loaded from storage */
+	if (msvdx_priv->msvdx_fw)
+		fw_ptr = msvdx_priv->msvdx_fw;
+	else {
+		if (IS_CDV(dev)) {
+			if(IS_FW_UPDATED)
+				fw_ptr = msvdx_get_fw(dev, &raw, "msvdx_fw_mfld_DE2.0.bin");
+			else
+				fw_ptr = msvdx_get_fw(dev, &raw, "msvdx_fw_mfld.bin");
+
+			PSB_DEBUG_GENERAL("MSVDX:load msvdx_fw_mfld_DE2.0.bin by udevd\n");
+		}
+		else
+			DRM_ERROR("MSVDX:HW is neither mrst nor mfld\n");
+	}
+
+	if (!fw_ptr) {
+		DRM_ERROR("MSVDX:load msvdx_fw.bin failed,is udevd running?\n");
+		ret = 1;
+		goto out;
+	}
+
+	if (!msvdx_priv->is_load) {/* Load firmware into BO */
+		PSB_DEBUG_GENERAL("MSVDX:load msvdx_fw.bin by udevd into BO\n");
+		if(IS_CDV(dev)) {
+			if(IS_FW_UPDATED)
+				ret = msvdx_get_fw_bo(dev, &raw, "msvdx_fw_mfld_DE2.0.bin");
+			else
+				ret = msvdx_get_fw_bo(dev, &raw, "msvdx_fw_mfld.bin");
+		}
+		else
+			DRM_ERROR("MSVDX:HW is neither mrst nor mfld\n");
+		msvdx_priv->is_load = 1;
+	}
+
+
+	fw = (struct msvdx_fw *) fw_ptr;
+
+	if(ec_firmware) {
+		fw_ptr += (((sizeof(struct msvdx_fw) + (fw->text_size + fw->data_size)*4 + 0xfff) & ~0xfff)/sizeof(uint32_t));
+		fw = (struct msvdx_fw *) fw_ptr;
+	}
+
+	/*
+	  if (fw->ver != 0x02) {
+	  DRM_ERROR("psb: msvdx_fw.bin firmware version mismatch,"
+	  "got version=%02x expected version=%02x\n",
+	  fw->ver, 0x02);
+	  ret = 1;
+	  goto out;
+	  }
+	*/
+	text_ptr =
+		(uint32_t *) ((uint8_t *) fw_ptr + sizeof(struct msvdx_fw));
+	data_ptr = text_ptr + fw->text_size;
+
+	if (fw->text_size == 2858)
+		PSB_DEBUG_GENERAL(
+			"MSVDX: FW ver 1.00.10.0187 of SliceSwitch variant\n");
+	else if (fw->text_size == 3021)
+		PSB_DEBUG_GENERAL(
+			"MSVDX: FW ver 1.00.10.0187 of FrameSwitch variant\n");
+	else if (fw->text_size == 2841)
+		PSB_DEBUG_GENERAL("MSVDX: FW ver 1.00.10.0788\n");
+	else if (fw->text_size == 3147)
+		PSB_DEBUG_GENERAL("MSVDX: FW ver BUILD_DXVA_FW1.00.10.1042 of SliceSwitch variant\n");
+	else if (fw->text_size == 3097)
+		PSB_DEBUG_GENERAL("MSVDX: FW ver BUILD_DXVA_FW1.00.10.0963.02.0011 of FrameSwitch variant\n");
+	else
+		PSB_DEBUG_GENERAL("MSVDX: FW ver unknown\n");
+
+
+	PSB_DEBUG_GENERAL("MSVDX: Retrieved pointers for firmware\n");
+	PSB_DEBUG_GENERAL("MSVDX: text_size: %d\n", fw->text_size);
+	PSB_DEBUG_GENERAL("MSVDX: data_size: %d\n", fw->data_size);
+	PSB_DEBUG_GENERAL("MSVDX: data_location: 0x%x\n",
+			  fw->data_location);
+	PSB_DEBUG_GENERAL("MSVDX: First 4 bytes of text: 0x%x\n",
+			  *text_ptr);
+	PSB_DEBUG_GENERAL("MSVDX: First 4 bytes of data: 0x%x\n",
+			  *data_ptr);
+
+	PSB_DEBUG_GENERAL("MSVDX: Uploading firmware\n");
+#if UPLOAD_FW_BY_DMA
+	psb_upload_fw(dev_priv, 0, msvdx_priv->mtx_mem_size/4, ec_firmware);
+#else
+	psb_upload_fw(dev_priv, MTX_CORE_CODE_MEM, ram_bank_size,
+		      PC_START_ADDRESS - MTX_CODE_BASE, fw->text_size,
+		      text_ptr);
+	psb_upload_fw(dev_priv, MTX_CORE_DATA_MEM, ram_bank_size,
+		      fw->data_location - MTX_DATA_BASE, fw->data_size,
+		      data_ptr);
+#endif
+#if 0
+	/* todo :  Verify code upload possibly only in debug */
+	ret = psb_verify_fw(dev_priv, ram_bank_size,
+			    MTX_CORE_CODE_MEM,
+			    PC_START_ADDRESS - MTX_CODE_BASE,
+			    fw->text_size, text_ptr);
+	if (ret) {
+		/* Firmware code upload failed */
+		ret = 1;
+		goto out;
+	}
+
+	ret = psb_verify_fw(dev_priv, ram_bank_size, MTX_CORE_DATA_MEM,
+			    fw->data_location - MTX_DATA_BASE,
+			    fw->data_size, data_ptr);
+	if (ret) {
+		/* Firmware data upload failed */
+		ret = 1;
+		goto out;
+	}
+#else
+	(void)psb_verify_fw;
+#endif
+	/*	-- Set starting PC address	*/
+	psb_write_mtx_core_reg(dev_priv, MTX_PC, PC_START_ADDRESS);
+
+	/*	-- Turn on the thread	*/
+	PSB_WMSVDX32(MSVDX_MTX_ENABLE_MTX_ENABLE_MASK, MSVDX_MTX_ENABLE);
+
+	/* Wait for the signature value to be written back */
+	ret = psb_wait_for_register(dev_priv, MSVDX_COMMS_SIGNATURE,
+				    MSVDX_COMMS_SIGNATURE_VALUE, /*Required value*/
+				    0xffffffff, /* Enabled bits */
+					1000, 100);
+	if (ret) {
+		DRM_ERROR("MSVDX: firmware fails to initialize.\n");
+		goto out;
+	}
+
+	PSB_DEBUG_GENERAL("MSVDX: MTX Initial indications OK\n");
+	PSB_DEBUG_GENERAL("MSVDX: MSVDX_COMMS_AREA_ADDR = %08x\n",
+			  MSVDX_COMMS_AREA_ADDR);
+#if 0
+
+	/* Send test message */
+	{
+		uint32_t msg_buf[FW_VA_DEBUG_TEST2_SIZE >> 2];
+
+		MEMIO_WRITE_FIELD(msg_buf, FW_VA_DEBUG_TEST2_MSG_SIZE,
+				  FW_VA_DEBUG_TEST2_SIZE);
+		MEMIO_WRITE_FIELD(msg_buf, FW_VA_DEBUG_TEST2_ID,
+				  VA_MSGID_TEST2);
+
+		ret = psb_mtx_send(dev_priv, msg_buf);
+		if (ret) {
+			DRM_ERROR("psb: MSVDX sending fails.\n");
+			goto out;
+		}
+
+		/* Wait for Mtx to ack this message */
+		psb_poll_mtx_irq(dev_priv);
+
+	}
+#endif
+out:
+
+	return ret;
+}
+
+
+static void psb_free_ccb(struct ttm_buffer_object **ccb)
+{
+	ttm_bo_unref(ccb);
+	*ccb = NULL;
+}
+
+/**
+ * Reset chip and disable interrupts.
+ * Return 0 success, 1 failure
+ */
+int psb_msvdx_reset(struct drm_psb_private *dev_priv)
+{
+	int ret = 0;
+
+	if(IS_CDV(dev_priv->dev)) {
+		int loop;
+		/* Enable Clocks */
+		PSB_DEBUG_GENERAL("Enabling clocks\n");
+		PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
+
+		/* Always pause the MMU as the core may be still active when resetting.  It is very bad to have memory 
+		   activity at the same time as a reset - Very Very bad */
+		PSB_WMSVDX32(2, MSVDX_MMU_CONTROL0);
+
+		for(loop = 0; loop < 50; loop++)
+			ret = psb_wait_for_register(dev_priv, MSVDX_MMU_MEM_REQ, 0,
+						    0xff, 100, 10);
+		if(ret)
+			return ret;
+	}
+	{
+		uint32_t ui32RegValue = 0;
+		ui32RegValue = PSB_RMSVDX32(MSVDX_RENDEC_CONTROL1);
+		REGIO_WRITE_FIELD(ui32RegValue, MSVDX_RENDEC_CONTROL1, RENDEC_DEC_DISABLE, 1);
+		PSB_WMSVDX32(ui32RegValue, MSVDX_RENDEC_CONTROL1);
+	}
+	PSB_WMSVDX32((uint32_t)(~MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK), MSVDX_CONTROL);
+	PSB_RMSVDX32(MSVDX_CONTROL);
+	PSB_WMSVDX32(0, MSVDX_CONTROL);
+	psb_wait_for_register(dev_priv, MSVDX_MMU_MEM_REQ, 0, 0xff, 100, 100);
+		
+		
+	/* Issue software reset */
+	/* PSB_WMSVDX32(msvdx_sw_reset_all, MSVDX_CONTROL); */
+        PSB_WMSVDX32(MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK, MSVDX_CONTROL);
+
+	ret = psb_wait_for_register(dev_priv, MSVDX_CONTROL, 0,
+				    MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK, 1000, 100);
+
+	if (!ret) {
+		/* Clear interrupt enabled flag */
+		PSB_WMSVDX32(0, MSVDX_HOST_INTERRUPT_ENABLE);
+
+		/* Clear any pending interrupt flags */
+		PSB_WMSVDX32(0xFFFFFFFF, MSVDX_INTERRUPT_CLEAR);
+	}
+
+	/* mutex_destroy(&msvdx_priv->msvdx_mutex); */
+
+	return ret;
+}
+
+static int psb_allocate_ccb(struct drm_device *dev,
+			    struct ttm_buffer_object **ccb,
+			    uint32_t *base_addr, unsigned long size)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	struct ttm_bo_device *bdev = &dev_priv->bdev;
+	int ret;
+	struct ttm_bo_kmap_obj tmp_kmap;
+	bool is_iomem;
+
+	PSB_DEBUG_INIT("MSVDX: allocate CCB\n");
+
+	ret = ttm_buffer_object_create(bdev, size,
+				       ttm_bo_type_kernel,
+				       DRM_PSB_FLAG_MEM_MMU |
+				       TTM_PL_FLAG_NO_EVICT, 0, 0, 0,
+				       NULL, ccb);
+	if (ret) {
+		DRM_ERROR("MSVDX:failed to allocate CCB.\n");
+		*ccb = NULL;
+		return 1;
+	}
+
+	ret = ttm_bo_kmap(*ccb, 0, (*ccb)->num_pages, &tmp_kmap);
+	if (ret) {
+		PSB_DEBUG_GENERAL("ttm_bo_kmap failed ret: %d\n", ret);
+		ttm_bo_unref(ccb);
+		*ccb = NULL;
+		return 1;
+	}
+/*
+  memset(ttm_kmap_obj_virtual(&tmp_kmap, &is_iomem), 0,
+  RENDEC_A_SIZE);
+*/
+	memset(ttm_kmap_obj_virtual(&tmp_kmap, &is_iomem), 0,
+	       size);
+	ttm_bo_kunmap(&tmp_kmap);
+
+	*base_addr = (*ccb)->offset;
+	return 0;
+}
+
+static ssize_t psb_msvdx_pmstate_show(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct drm_device *drm_dev = dev_get_drvdata(dev);
+	struct drm_psb_private *dev_priv;
+	struct msvdx_private *msvdx_priv;
+	unsigned int pmstate;
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (drm_dev == NULL)
+		return 0;
+
+	dev_priv = drm_dev->dev_private;
+	msvdx_priv = dev_priv->msvdx_private;
+	pmstate = msvdx_priv->pmstate;
+
+	spin_lock_irqsave(&msvdx_priv->msvdx_lock, flags);
+	ret = snprintf(buf, 64, "%s\n",
+		       (pmstate == PSB_PMSTATE_POWERUP) ? "powerup"
+		       : ((pmstate == PSB_PMSTATE_POWERDOWN) ? "powerdown"
+			  : "clockgated"));
+	spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, flags);
+
+	return ret;
+}
+
+static DEVICE_ATTR(msvdx_pmstate, 0444, psb_msvdx_pmstate_show, NULL);
+
+int psb_msvdx_init(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	/* uint32_t clk_gate_ctrl = clk_enable_all; */
+	uint32_t cmd;
+	int ret;
+	struct msvdx_private *msvdx_priv;
+/*
+	uint32_t reg_value;
+	uint32_t reg_val;
+*/
+	if (!dev_priv->msvdx_private) {
+		msvdx_priv = kmalloc(sizeof(struct msvdx_private), GFP_KERNEL);
+		if (msvdx_priv == NULL)
+			goto err_exit;
+
+		dev_priv->msvdx_private = msvdx_priv;
+		memset(msvdx_priv, 0, sizeof(struct msvdx_private));
+
+		/* get device --> drm_device --> drm_psb_private --> msvdx_priv
+		 * for psb_msvdx_pmstate_show: msvdx_pmpolicy
+		 * if not pci_set_drvdata, can't get drm_device from device
+		 */
+		/* pci_set_drvdata(dev->pdev, dev); */
+		if (device_create_file(&dev->pdev->dev,
+				       &dev_attr_msvdx_pmstate))
+			DRM_ERROR("MSVDX: could not create sysfs file\n");
+		msvdx_priv->sysfs_pmstate = sysfs_get_dirent(
+			dev->pdev->dev.kobj.sd, 
+			NULL,
+			"msvdx_pmstate");
+	}
+
+	msvdx_priv = dev_priv->msvdx_private;
+	if (!msvdx_priv->ccb0) { /* one for the first time */
+		/* Initialize comand msvdx queueing */
+		INIT_LIST_HEAD(&msvdx_priv->msvdx_queue);
+		INIT_LIST_HEAD(&msvdx_priv->deblock_queue);
+		mutex_init(&msvdx_priv->msvdx_mutex);
+		spin_lock_init(&msvdx_priv->msvdx_lock);
+		/*figure out the stepping */
+		pci_read_config_byte(dev->pdev, PSB_REVID_OFFSET, &psb_rev_id);
+	}
+
+	msvdx_priv->vec_local_mem_size = VEC_LOCAL_MEM_BYTE_SIZE;
+	if (!msvdx_priv->vec_local_mem_data) {
+		msvdx_priv->vec_local_mem_data = 
+			kzalloc(msvdx_priv->vec_local_mem_size, GFP_KERNEL);
+		if (msvdx_priv->vec_local_mem_data == NULL) {
+			PSB_DEBUG_GENERAL("Vec local memory fail\n");
+			goto err_exit;
+		}
+	}
+
+	msvdx_priv->msvdx_busy = 0;
+	msvdx_priv->msvdx_hw_busy = 1;
+
+	/* Enable Clocks */
+	PSB_DEBUG_GENERAL("Enabling clocks\n");
+	PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
+
+	/* Issue software reset for all but core*/
+/*
+	PSB_WMSVDX32((uint32_t) ~MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK, REGISTER(MSVDX_CORE, CR_MSVDX_CONTROL));
+	reg_value = PSB_RMSVDX32(REGISTER(MSVDX_CORE, CR_MSVDX_CONTROL));
+	PSB_WMSVDX32(0, REGISTER(MSVDX_CORE, CR_MSVDX_CONTROL));
+	PSB_WMSVDX32(MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK, REGISTER(MSVDX_CORE, CR_MSVDX_CONTROL));
+
+	reg_val = 0;
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL, FE_WDT_CNT_CTRL, 0x3);
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL, FE_WDT_ENABLE, 0);
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL, FE_WDT_ACTION0, 1);
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL, FE_WDT_CLEAR_SELECT, 1);
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL, FE_WDT_CLKDIV_SELECT, 7);
+	PSB_WMSVDX32(820, REGISTER( MSVDX_CORE, CR_FE_MSVDX_WDT_COMPAREMATCH ));
+	PSB_WMSVDX32(reg_val, REGISTER( MSVDX_CORE, CR_FE_MSVDX_WDT_CONTROL ));
+
+	reg_val = 0;
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL, BE_WDT_CNT_CTRL, 0x7);
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL, BE_WDT_ENABLE, 0);
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL, BE_WDT_ACTION0, 1);
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL, BE_WDT_CLEAR_SELECT, 0xd);
+	REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL, BE_WDT_CLKDIV_SELECT, 7);
+	PSB_WMSVDX32(8200, REGISTER(MSVDX_CORE, CR_BE_MSVDX_WDT_COMPAREMATCH));
+	PSB_WMSVDX32(reg_val, REGISTER(MSVDX_CORE, CR_BE_MSVDX_WDT_CONTROL)); 
+*/
+	/* Enable MMU by removing all bypass bits */
+	PSB_WMSVDX32(0, MSVDX_MMU_CONTROL0);
+
+	/* move firmware loading to the place receiving first command buffer */
+
+	PSB_DEBUG_GENERAL("MSVDX: Setting up RENDEC,allocate CCB 0/1\n");
+	/* Allocate device virtual memory as required by rendec.... */
+	if (!msvdx_priv->ccb0) {
+		ret = psb_allocate_ccb(dev, &msvdx_priv->ccb0,
+				       &msvdx_priv->base_addr0,
+				       RENDEC_A_SIZE);
+		if (ret) {
+			PSB_DEBUG_GENERAL("Allocate Rendec A fail\n");
+			goto err_exit;
+		}
+	}
+
+	if (!msvdx_priv->ccb1) {
+		ret = psb_allocate_ccb(dev, &msvdx_priv->ccb1,
+				       &msvdx_priv->base_addr1,
+				       RENDEC_B_SIZE);
+		if (ret)
+			goto err_exit;
+	}
+
+	if(!msvdx_priv->fw) {
+		uint32_t core_rev;
+		uint32_t fw_bo_size;
+
+		core_rev = PSB_RMSVDX32(MSVDX_CORE_REV);
+
+		if( (core_rev&0xffffff ) < 0x020000 )
+			msvdx_priv->mtx_mem_size = 16*1024;
+		else
+			msvdx_priv->mtx_mem_size = 40*1024;
+
+		if(IS_CDV(dev))
+			fw_bo_size =  msvdx_priv->mtx_mem_size + 4096;
+		else
+			fw_bo_size =  ((msvdx_priv->mtx_mem_size + 8192) & ~0xfff)*2; /* fw + ec_fw */
+
+		PSB_DEBUG_INIT("MSVDX: MTX mem size is 0x%08xbytes  allocate firmware BO size 0x%08x\n", msvdx_priv->mtx_mem_size, 
+			       fw_bo_size);
+
+                ret = ttm_buffer_object_create(&dev_priv->bdev, fw_bo_size, /* DMA may run over a page */
+                                               ttm_bo_type_kernel,
+                                               DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT,
+                                               0, 0, 0, NULL, &msvdx_priv->fw);
+ 
+		if (ret) {
+			PSB_DEBUG_GENERAL("Allocate firmware BO fail\n");
+			goto err_exit;
+		}
+	}
+
+	PSB_DEBUG_GENERAL("MSVDX: RENDEC A: %08x RENDEC B: %08x\n",
+			  msvdx_priv->base_addr0, msvdx_priv->base_addr1);
+
+	PSB_WMSVDX32(msvdx_priv->base_addr0, MSVDX_RENDEC_BASE_ADDR0);
+	PSB_WMSVDX32(msvdx_priv->base_addr1, MSVDX_RENDEC_BASE_ADDR1);
+
+	cmd = 0;
+	REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_BUFFER_SIZE,
+			  RENDEC_BUFFER_SIZE0, RENDEC_A_SIZE / 4096);
+	REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_BUFFER_SIZE,
+			  RENDEC_BUFFER_SIZE1, RENDEC_B_SIZE / 4096);
+	PSB_WMSVDX32(cmd, MSVDX_RENDEC_BUFFER_SIZE);
+
+	if(!msvdx_priv->fw) {
+		uint32_t core_rev;
+
+		core_rev = PSB_RMSVDX32(MSVDX_CORE_REV);
+
+		if( (core_rev&0xffffff ) < 0x020000 )
+			msvdx_priv->mtx_mem_size = 16*1024;
+		else
+			msvdx_priv->mtx_mem_size = 40*1024;
+
+		PSB_DEBUG_INIT("MSVDX: MTX mem size is 0x%08xbytes  allocate firmware BO size 0x%08x\n", msvdx_priv->mtx_mem_size, 
+			       msvdx_priv->mtx_mem_size + 4096);
+
+                ret = ttm_buffer_object_create(&dev_priv->bdev, msvdx_priv->mtx_mem_size + 4096, /* DMA may run over a page */
+                                               ttm_bo_type_kernel,
+                                               DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT,
+                                               0, 0, 0, NULL, &msvdx_priv->fw);
+ 
+		if (ret) {
+			PSB_DEBUG_GENERAL("Allocate firmware BO fail\n");
+			goto err_exit;
+		}
+	}
+
+	cmd = 0;
+	REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1,
+			  RENDEC_DECODE_START_SIZE, 0);
+	REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1,
+			  RENDEC_BURST_SIZE_W, 1);
+	REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1,
+			  RENDEC_BURST_SIZE_R, 1);
+	REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1,
+			  RENDEC_EXTERNAL_MEMORY, 1);
+	PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTROL1);
+
+	cmd = 0x00101010;
+	PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT0);
+	PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT1);
+	PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT2);
+	PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT3);
+	PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT4);
+	PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT5);
+
+	cmd = 0;
+	REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL0, RENDEC_INITIALISE,
+			  1);
+	PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTROL0);
+
+	/* PSB_WMSVDX32(clk_enable_minimal, MSVDX_MAN_CLK_ENABLE); */
+	PSB_DEBUG_INIT("MSVDX:defer firmware loading to the"
+		       " place when receiving user space commands\n");
+
+	msvdx_priv->msvdx_fw_loaded = 0; /* need to load firware */
+
+	PSB_WMSVDX32(820, MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH);
+	PSB_WMSVDX32(8200, MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH);
+
+	PSB_WMSVDX32(820, MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH);
+	PSB_WMSVDX32(8200, MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH);
+
+	psb_msvdx_clearirq(dev);
+	psb_msvdx_enableirq(dev);
+
+	if (IS_MSVDX(dev)) {
+		PSB_DEBUG_INIT("MSDVX:old clock gating disable = 0x%08x\n",
+			       PSB_RVDC32(PSB_MSVDX_CLOCKGATING));
+	}
+
+	{
+		cmd = 0;
+		cmd = PSB_RMSVDX32(MSVDX_VEC_SHIFTREG_CONTROL); /* VEC_SHIFTREG_CONTROL */
+		REGIO_WRITE_FIELD(cmd,
+				  VEC_SHIFTREG_CONTROL,
+				  SR_MASTER_SELECT,
+				  1);  /* Host */
+		PSB_WMSVDX32(cmd, MSVDX_VEC_SHIFTREG_CONTROL);
+	}
+
+#if 0
+	ret = psb_setup_fw(dev);
+	if (ret)
+		goto err_exit;
+	/* Send Initialisation message to firmware */
+	if (0) {
+		uint32_t msg_init[FW_VA_INIT_SIZE >> 2];
+		MEMIO_WRITE_FIELD(msg_init, FWRK_GENMSG_SIZE,
+				  FW_VA_INIT_SIZE);
+		MEMIO_WRITE_FIELD(msg_init, FWRK_GENMSG_ID, VA_MSGID_INIT);
+
+		/* Need to set this for all but A0 */
+		MEMIO_WRITE_FIELD(msg_init, FW_VA_INIT_GLOBAL_PTD,
+				  psb_get_default_pd_addr(dev_priv->mmu));
+
+		ret = psb_mtx_send(dev_priv, msg_init);
+		if (ret)
+			goto err_exit;
+
+		psb_poll_mtx_irq(dev_priv);
+	}
+#endif
+
+	return 0;
+
+err_exit:
+	DRM_ERROR("MSVDX: initialization failed\n");
+	if (msvdx_priv && msvdx_priv->ccb0)
+		psb_free_ccb(&msvdx_priv->ccb0);
+	if (msvdx_priv && msvdx_priv->ccb1)
+		psb_free_ccb(&msvdx_priv->ccb1);
+	if (dev_priv->msvdx_private) {
+		kfree(dev_priv->msvdx_private);
+		dev_priv->msvdx_private = NULL;
+	}
+	return 1;
+}
+
+int psb_msvdx_uninit(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+
+	/* Reset MSVDX chip */
+	psb_msvdx_reset(dev_priv);
+
+	/* PSB_WMSVDX32 (clk_enable_minimal, MSVDX_MAN_CLK_ENABLE); */
+	PSB_DEBUG_INIT("MSVDX:set the msvdx clock to 0\n");
+	PSB_WMSVDX32(0, MSVDX_MAN_CLK_ENABLE);
+
+	if (NULL == msvdx_priv)
+	{
+		DRM_ERROR("MSVDX: psb_msvdx_uninit: msvdx_priv is NULL!\n");
+		return -1;
+	}
+
+	if (msvdx_priv->ccb0)
+		psb_free_ccb(&msvdx_priv->ccb0);
+	if (msvdx_priv->ccb1)
+		psb_free_ccb(&msvdx_priv->ccb1);
+	if (msvdx_priv->msvdx_fw)
+		kfree(msvdx_priv->msvdx_fw
+			);
+	if (msvdx_priv->vec_local_mem_data)
+		kfree(msvdx_priv->vec_local_mem_data);
+
+	if (msvdx_priv) {
+		/* pci_set_drvdata(dev->pdev, NULL); */
+		device_remove_file(&dev->pdev->dev, &dev_attr_msvdx_pmstate);
+		sysfs_put(msvdx_priv->sysfs_pmstate);
+		msvdx_priv->sysfs_pmstate = NULL;
+
+		kfree(msvdx_priv);
+		dev_priv->msvdx_private = NULL;
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/cdv/imgv/psb_ttm_fence.c b/drivers/staging/cdv/imgv/psb_ttm_fence.c
new file mode 100644
index 0000000..50ed848
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_ttm_fence.c
@@ -0,0 +1,547 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
+ * 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 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.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include "psb_ttm_fence_api.h"
+#include "psb_ttm_fence_driver.h"
+#include <linux/wait.h>
+#include <linux/sched.h>
+
+#include <drm/drmP.h>
+
+/*
+ * Simple implementation for now.
+ */
+
+static void ttm_fence_lockup(struct ttm_fence_object *fence, uint32_t mask)
+{
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+
+	printk(KERN_ERR "GPU lockup dectected on engine %u "
+	       "fence type 0x%08x\n",
+	       (unsigned int)fence->fence_class, (unsigned int)mask);
+	/*
+	 * Give engines some time to idle?
+	 */
+
+	write_lock(&fc->lock);
+	ttm_fence_handler(fence->fdev, fence->fence_class,
+			  fence->sequence, mask, -EBUSY);
+	write_unlock(&fc->lock);
+}
+
+/*
+ * Convenience function to be called by fence::wait methods that
+ * need polling.
+ */
+
+int ttm_fence_wait_polling(struct ttm_fence_object *fence, bool lazy,
+			   bool interruptible, uint32_t mask)
+{
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
+	uint32_t count = 0;
+	int ret;
+	unsigned long end_jiffies = fence->timeout_jiffies;
+
+	DECLARE_WAITQUEUE(entry, current);
+	add_wait_queue(&fc->fence_queue, &entry);
+
+	ret = 0;
+
+	for (;;) {
+		__set_current_state((interruptible) ?
+				    TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+		if (ttm_fence_object_signaled(fence, mask))
+			break;
+		if (time_after_eq(jiffies, end_jiffies)) {
+			if (driver->lockup)
+				driver->lockup(fence, mask);
+			else
+				ttm_fence_lockup(fence, mask);
+			continue;
+		}
+		if (lazy)
+			schedule_timeout(1);
+		else if ((++count & 0x0F) == 0) {
+			__set_current_state(TASK_RUNNING);
+			schedule();
+			__set_current_state((interruptible) ?
+					    TASK_INTERRUPTIBLE :
+					    TASK_UNINTERRUPTIBLE);
+		}
+		if (interruptible && signal_pending(current)) {
+			ret = -ERESTART;
+			break;
+		}
+	}
+	__set_current_state(TASK_RUNNING);
+	remove_wait_queue(&fc->fence_queue, &entry);
+	return ret;
+}
+
+/*
+ * Typically called by the IRQ handler.
+ */
+
+void ttm_fence_handler(struct ttm_fence_device *fdev, uint32_t fence_class,
+		       uint32_t sequence, uint32_t type, uint32_t error)
+{
+	int wake = 0;
+	struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class];
+	struct ttm_fence_object *fence, *next, *temp_fence;
+
+	if (list_empty(&fc->ring))
+		return;
+	temp_fence = NULL;
+	list_for_each_entry(fence, &fc->ring, ring) {
+		if (fence->sequence == sequence) {
+			temp_fence = fence;
+			break;
+		}
+	}
+	if (temp_fence == NULL)
+		return;
+
+	list_for_each_entry_safe(fence, next, &fc->ring, ring) {
+		DRM_DEBUG_KMS("Fence 0x%08lx, sequence 0x%08x, type 0x%08x\n",
+			  (unsigned long)fence, fence->sequence,
+			  fence->fence_type);
+
+		if (error) {
+			fence->info.error = error;
+			fence->info.signaled_types = fence->fence_type;
+		} else {
+			fence->info.signaled_types |= fence->fence_type;
+		}
+		list_del_init(&fence->ring);
+		wake = 1;
+		if (fence == temp_fence) {
+			break;
+		}
+		//kref_put(&fence->kref, &ttm_fence_object_destroy);
+	}
+
+	if (wake)
+		wake_up_all(&fc->fence_queue);
+}
+
+static void ttm_fence_unring(struct ttm_fence_object *fence)
+{
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+	unsigned long irq_flags;
+
+	write_lock_irqsave(&fc->lock, irq_flags);
+	list_del_init(&fence->ring);
+	write_unlock_irqrestore(&fc->lock, irq_flags);
+}
+
+bool ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask)
+{
+	unsigned long flags;
+	bool signaled;
+	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+
+	mask &= fence->fence_type;
+	read_lock_irqsave(&fc->lock, flags);
+	signaled = (mask & fence->info.signaled_types) == mask;
+	read_unlock_irqrestore(&fc->lock, flags);
+	if (!signaled && driver->poll) {
+		write_lock_irqsave(&fc->lock, flags);
+		driver->poll(fence->fdev, fence->fence_class, mask);
+		signaled = (mask & fence->info.signaled_types) == mask;
+		write_unlock_irqrestore(&fc->lock, flags);
+	}
+	return signaled;
+}
+
+int ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t type)
+{
+	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+	unsigned long irq_flags;
+	uint32_t diff;
+	bool call_flush;
+
+	if (type & ~fence->fence_type) {
+		DRM_ERROR("Flush trying to extend fence type, "
+			  "0x%x, 0x%x\n", type, fence->fence_type);
+		return -EINVAL;
+	}
+
+	write_lock_irqsave(&fc->lock, irq_flags);
+	fence->waiting_types |= type;
+	fc->waiting_types |= fence->waiting_types;
+	diff = (fence->sequence - fc->highest_waiting_sequence) &
+	    fc->sequence_mask;
+
+	if (diff < fc->wrap_diff)
+		fc->highest_waiting_sequence = fence->sequence;
+
+	/*
+	 * fence->waiting_types has changed. Determine whether
+	 * we need to initiate some kind of flush as a result of this.
+	 */
+
+	if (driver->needed_flush)
+		fc->pending_flush |= driver->needed_flush(fence);
+
+	if (driver->poll)
+		driver->poll(fence->fdev, fence->fence_class,
+			     fence->waiting_types);
+
+	call_flush = (fc->pending_flush != 0);
+	write_unlock_irqrestore(&fc->lock, irq_flags);
+
+	if (call_flush && driver->flush)
+		driver->flush(fence->fdev, fence->fence_class);
+
+	return 0;
+}
+
+/*
+ * Make sure old fence objects are signaled before their fence sequences are
+ * wrapped around and reused.
+ */
+
+void ttm_fence_flush_old(struct ttm_fence_device *fdev,
+			 uint32_t fence_class, uint32_t sequence)
+{
+	struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class];
+	struct ttm_fence_object *fence;
+	unsigned long irq_flags;
+	const struct ttm_fence_driver *driver = fdev->driver;
+	bool call_flush;
+
+	uint32_t diff;
+
+	write_lock_irqsave(&fc->lock, irq_flags);
+
+	list_for_each_entry_reverse(fence, &fc->ring, ring) {
+		diff = (sequence - fence->sequence) & fc->sequence_mask;
+		if (diff <= fc->flush_diff)
+			break;
+
+		fence->waiting_types = fence->fence_type;
+		fc->waiting_types |= fence->fence_type;
+
+		if (driver->needed_flush)
+			fc->pending_flush |= driver->needed_flush(fence);
+	}
+
+	if (driver->poll)
+		driver->poll(fdev, fence_class, fc->waiting_types);
+
+	call_flush = (fc->pending_flush != 0);
+	write_unlock_irqrestore(&fc->lock, irq_flags);
+
+	if (call_flush && driver->flush)
+		driver->flush(fdev, fence->fence_class);
+
+	/*
+	 * FIXME: Shold we implement a wait here for really old fences?
+	 */
+
+}
+
+int ttm_fence_object_wait(struct ttm_fence_object *fence,
+			  bool lazy, bool interruptible, uint32_t mask)
+{
+	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+	int ret = 0;
+	unsigned long timeout;
+	unsigned long cur_jiffies;
+	unsigned long to_jiffies;
+
+	if (mask & ~fence->fence_type) {
+		DRM_ERROR("Wait trying to extend fence type"
+			  " 0x%08x 0x%08x\n", mask, fence->fence_type);
+		BUG();
+		return -EINVAL;
+	}
+
+	if (driver->wait)
+		return driver->wait(fence, lazy, interruptible, mask);
+
+	ttm_fence_object_flush(fence, mask);
+retry:
+	if (!driver->has_irq ||
+	    driver->has_irq(fence->fdev, fence->fence_class, mask)) {
+
+		cur_jiffies = jiffies;
+		to_jiffies = fence->timeout_jiffies;
+
+		timeout = (time_after(to_jiffies, cur_jiffies)) ?
+		    to_jiffies - cur_jiffies : 1;
+
+		if (interruptible)
+			ret = wait_event_interruptible_timeout
+			    (fc->fence_queue,
+			     ttm_fence_object_signaled(fence, mask), timeout);
+		else
+			ret = wait_event_timeout
+			    (fc->fence_queue,
+			     ttm_fence_object_signaled(fence, mask), timeout);
+
+		if (unlikely(ret == -ERESTARTSYS))
+			return -ERESTART;
+
+		if (unlikely(ret == 0)) {
+			if (driver->lockup)
+				driver->lockup(fence, mask);
+			else
+				ttm_fence_lockup(fence, mask);
+			goto retry;
+		}
+
+		return 0;
+	}
+
+	return ttm_fence_wait_polling(fence, lazy, interruptible, mask);
+}
+
+int ttm_fence_object_emit(struct ttm_fence_object *fence, uint32_t fence_flags,
+			  uint32_t fence_class, uint32_t type)
+{
+	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+	unsigned long flags;
+	uint32_t sequence;
+	unsigned long timeout;
+	int ret;
+
+	ttm_fence_unring(fence);
+	ret = driver->emit(fence->fdev,
+			   fence_class, fence_flags, &sequence, &timeout);
+	if (ret)
+		return ret;
+
+	write_lock_irqsave(&fc->lock, flags);
+	fence->fence_class = fence_class;
+	fence->fence_type = type;
+	fence->waiting_types = 0;
+	fence->info.signaled_types = 0;
+	fence->info.error = 0;
+	fence->sequence = sequence;
+	fence->timeout_jiffies = timeout;
+	if (list_empty(&fc->ring))
+		fc->highest_waiting_sequence = sequence - 1;
+	list_add_tail(&fence->ring, &fc->ring);
+	fc->latest_queued_sequence = sequence;
+	write_unlock_irqrestore(&fc->lock, flags);
+	return 0;
+}
+
+int ttm_fence_object_init(struct ttm_fence_device *fdev,
+			  uint32_t fence_class,
+			  uint32_t type,
+			  uint32_t create_flags,
+			  void (*destroy) (struct ttm_fence_object *),
+			  struct ttm_fence_object *fence)
+{
+	int ret = 0;
+
+	kref_init(&fence->kref);
+	fence->fence_class = fence_class;
+	fence->fence_type = type;
+	fence->info.signaled_types = 0;
+	fence->waiting_types = 0;
+	fence->sequence = 0;
+	fence->info.error = 0;
+	fence->fdev = fdev;
+	fence->destroy = destroy;
+	INIT_LIST_HEAD(&fence->ring);
+	atomic_inc(&fdev->count);
+
+	if (create_flags & TTM_FENCE_FLAG_EMIT) {
+		ret = ttm_fence_object_emit(fence, create_flags,
+					    fence->fence_class, type);
+	}
+
+	return ret;
+}
+
+int ttm_fence_object_create(struct ttm_fence_device *fdev,
+			    uint32_t fence_class,
+			    uint32_t type,
+			    uint32_t create_flags,
+			    struct ttm_fence_object **c_fence)
+{
+	struct ttm_fence_object *fence;
+	int ret;
+
+	ret = ttm_mem_global_alloc(fdev->mem_glob,
+				   sizeof(*fence),
+				   false,
+				   false);
+	if (unlikely(ret != 0)) {
+		printk(KERN_ERR "Out of memory creating fence object\n");
+		return ret;
+	}
+
+	fence = kmalloc(sizeof(*fence), GFP_KERNEL);
+	if (!fence) {
+		printk(KERN_ERR "Out of memory creating fence object\n");
+		ttm_mem_global_free(fdev->mem_glob, sizeof(*fence));
+		return -ENOMEM;
+	}
+
+	ret = ttm_fence_object_init(fdev, fence_class, type,
+				    create_flags, NULL, fence);
+	if (ret) {
+		ttm_fence_object_unref(&fence);
+		return ret;
+	}
+	*c_fence = fence;
+
+	return 0;
+}
+
+static void ttm_fence_object_destroy(struct kref *kref)
+{
+	struct ttm_fence_object *fence =
+	    container_of(kref, struct ttm_fence_object, kref);
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+	unsigned long irq_flags;
+
+	write_lock_irqsave(&fc->lock, irq_flags);
+	list_del_init(&fence->ring);
+	write_unlock_irqrestore(&fc->lock, irq_flags);
+
+	atomic_dec(&fence->fdev->count);
+	if (fence->destroy)
+		fence->destroy(fence);
+	else {
+		ttm_mem_global_free(fence->fdev->mem_glob,
+				    sizeof(*fence));
+		kfree(fence);
+	}
+}
+
+void ttm_fence_device_release(struct ttm_fence_device *fdev)
+{
+	kfree(fdev->fence_class);
+}
+
+int
+ttm_fence_device_init(int num_classes,
+		      struct ttm_mem_global *mem_glob,
+		      struct ttm_fence_device *fdev,
+		      const struct ttm_fence_class_init *init,
+		      bool replicate_init,
+		      const struct ttm_fence_driver *driver)
+{
+	struct ttm_fence_class_manager *fc;
+	const struct ttm_fence_class_init *fci;
+	int i;
+
+	fdev->mem_glob = mem_glob;
+	fdev->fence_class = kzalloc(num_classes *
+				    sizeof(*fdev->fence_class), GFP_KERNEL);
+
+	if (unlikely(!fdev->fence_class))
+		return -ENOMEM;
+
+	fdev->num_classes = num_classes;
+	atomic_set(&fdev->count, 0);
+	fdev->driver = driver;
+
+	for (i = 0; i < fdev->num_classes; ++i) {
+		fc = &fdev->fence_class[i];
+		fci = &init[(replicate_init) ? 0 : i];
+
+		fc->wrap_diff = fci->wrap_diff;
+		fc->flush_diff = fci->flush_diff;
+		fc->sequence_mask = fci->sequence_mask;
+
+		rwlock_init(&fc->lock);
+		INIT_LIST_HEAD(&fc->ring);
+		init_waitqueue_head(&fc->fence_queue);
+	}
+
+	return 0;
+}
+
+struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence)
+{
+	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
+	struct ttm_fence_info tmp;
+	unsigned long irq_flags;
+
+	read_lock_irqsave(&fc->lock, irq_flags);
+	tmp = fence->info;
+	read_unlock_irqrestore(&fc->lock, irq_flags);
+
+	return tmp;
+}
+
+void ttm_fence_object_unref(struct ttm_fence_object **p_fence)
+{
+	struct ttm_fence_object *fence = *p_fence;
+
+	*p_fence = NULL;
+	(void)kref_put(&fence->kref, &ttm_fence_object_destroy);
+}
+
+/*
+ * Placement / BO sync object glue.
+ */
+
+bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg)
+{
+	struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
+	uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
+
+	return ttm_fence_object_signaled(fence, fence_types);
+}
+
+int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg,
+			    bool lazy, bool interruptible)
+{
+	struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
+	uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
+
+	return ttm_fence_object_wait(fence, lazy, interruptible, fence_types);
+}
+
+int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg)
+{
+	struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
+	uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
+
+	return ttm_fence_object_flush(fence, fence_types);
+}
+
+void ttm_fence_sync_obj_unref(void **sync_obj)
+{
+	ttm_fence_object_unref((struct ttm_fence_object **)sync_obj);
+}
+
+void *ttm_fence_sync_obj_ref(void *sync_obj)
+{
+	return (void *)
+	    ttm_fence_object_ref((struct ttm_fence_object *)sync_obj);
+}
diff --git a/drivers/staging/cdv/imgv/psb_ttm_fence_api.h b/drivers/staging/cdv/imgv/psb_ttm_fence_api.h
new file mode 100644
index 0000000..d42904c
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_ttm_fence_api.h
@@ -0,0 +1,272 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
+ * 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 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.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+#ifndef _TTM_FENCE_API_H_
+#define _TTM_FENCE_API_H_
+
+#include <linux/list.h>
+#include <linux/kref.h>
+
+#define TTM_FENCE_FLAG_EMIT (1 << 0)
+#define TTM_FENCE_TYPE_EXE  (1 << 0)
+
+struct ttm_fence_device;
+
+/**
+ * struct ttm_fence_info
+ *
+ * @fence_class:    The fence class.
+ * @fence_type:     Bitfield indicating types for this fence.
+ * @signaled_types: Bitfield indicating which types are signaled.
+ * @error:          Last error reported from the device.
+ *
+ * Used as output from the ttm_fence_get_info
+ */
+
+struct ttm_fence_info {
+	uint32_t signaled_types;
+	uint32_t error;
+};
+
+/**
+ * struct ttm_fence_object
+ *
+ * @fdev:            Pointer to the fence device struct.
+ * @kref:            Holds the reference count of this fence object.
+ * @ring:            List head used for the circular list of not-completely
+ *                   signaled fences.
+ * @info:            Data for fast retrieval using the ttm_fence_get_info()
+ * function.
+ * @timeout_jiffies: Absolute jiffies value indicating when this fence
+ *                   object times out and, if waited on, calls ttm_fence_lockup
+ *                   to check for and resolve a GPU lockup.
+ * @sequence:        Fence sequence number.
+ * @waiting_types:   Types currently waited on.
+ * @destroy:         Called to free the fence object, when its refcount has
+ *                   reached zero. If NULL, kfree is used.
+ *
+ * This struct is provided in the driver interface so that drivers can
+ * derive from it and create their own fence implementation. All members
+ * are private to the fence implementation and the fence driver callbacks.
+ * Otherwise a driver may access the derived object using container_of().
+ */
+
+struct ttm_fence_object {
+	struct ttm_fence_device *fdev;
+	struct kref kref;
+	uint32_t fence_class;
+	uint32_t fence_type;
+
+	/*
+	 * The below fields are protected by the fence class
+	 * manager spinlock.
+	 */
+
+	struct list_head ring;
+	struct ttm_fence_info info;
+	unsigned long timeout_jiffies;
+	uint32_t sequence;
+	uint32_t waiting_types;
+	void (*destroy) (struct ttm_fence_object *);
+};
+
+/**
+ * ttm_fence_object_init
+ *
+ * @fdev: Pointer to a struct ttm_fence_device.
+ * @fence_class: Fence class for this fence.
+ * @type: Fence type for this fence.
+ * @create_flags: Flags indicating varios actions at init time. At this point
+ * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to
+ * the command stream.
+ * @destroy: Destroy function. If NULL, kfree() is used.
+ * @fence: The struct ttm_fence_object to initialize.
+ *
+ * Initialize a pre-allocated fence object. This function, together with the
+ * destroy function makes it possible to derive driver-specific fence objects.
+ */
+
+extern int
+ttm_fence_object_init(struct ttm_fence_device *fdev,
+		      uint32_t fence_class,
+		      uint32_t type,
+		      uint32_t create_flags,
+		      void (*destroy) (struct ttm_fence_object *fence),
+		      struct ttm_fence_object *fence);
+
+/**
+ * ttm_fence_object_create
+ *
+ * @fdev: Pointer to a struct ttm_fence_device.
+ * @fence_class: Fence class for this fence.
+ * @type: Fence type for this fence.
+ * @create_flags: Flags indicating varios actions at init time. At this point
+ * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to
+ * the command stream.
+ * @c_fence: On successful termination, *(@c_fence) will point to the created
+ * fence object.
+ *
+ * Create and initialize a struct ttm_fence_object. The destroy function will
+ * be set to kfree().
+ */
+
+extern int
+ttm_fence_object_create(struct ttm_fence_device *fdev,
+			uint32_t fence_class,
+			uint32_t type,
+			uint32_t create_flags,
+			struct ttm_fence_object **c_fence);
+
+/**
+ * ttm_fence_object_wait
+ *
+ * @fence: The fence object to wait on.
+ * @lazy: Allow sleeps to reduce the cpu-usage if polling.
+ * @interruptible: Sleep interruptible when waiting.
+ * @type_mask: Wait for the given type_mask to signal.
+ *
+ * Wait for a fence to signal the given type_mask. The function will
+ * perform a fence_flush using type_mask. (See ttm_fence_object_flush).
+ *
+ * Returns
+ * -ERESTART if interrupted by a signal.
+ * May return driver-specific error codes if timed-out.
+ */
+
+extern int
+ttm_fence_object_wait(struct ttm_fence_object *fence,
+		      bool lazy, bool interruptible, uint32_t type_mask);
+
+/**
+ * ttm_fence_object_flush
+ *
+ * @fence: The fence object to flush.
+ * @flush_mask: Fence types to flush.
+ *
+ * Make sure that the given fence eventually signals the
+ * types indicated by @flush_mask. Note that this may or may not
+ * map to a CPU or GPU flush.
+ */
+
+extern int
+ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t flush_mask);
+
+/**
+ * ttm_fence_get_info
+ *
+ * @fence: The fence object.
+ *
+ * Copy the info block from the fence while holding relevant locks.
+ */
+
+struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence);
+
+/**
+ * ttm_fence_object_ref
+ *
+ * @fence: The fence object.
+ *
+ * Return a ref-counted pointer to the fence object indicated by @fence.
+ */
+
+static inline struct ttm_fence_object *ttm_fence_object_ref(struct
+							    ttm_fence_object
+							    *fence)
+{
+	kref_get(&fence->kref);
+	return fence;
+}
+
+/**
+ * ttm_fence_object_unref
+ *
+ * @p_fence: Pointer to a ref-counted pinter to a struct ttm_fence_object.
+ *
+ * Unreference the fence object pointed to by *(@p_fence), clearing
+ * *(p_fence).
+ */
+
+extern void ttm_fence_object_unref(struct ttm_fence_object **p_fence);
+
+/**
+ * ttm_fence_object_signaled
+ *
+ * @fence: Pointer to the struct ttm_fence_object.
+ * @mask: Type mask to check whether signaled.
+ *
+ * This function checks (without waiting) whether the fence object
+ * pointed to by @fence has signaled the types indicated by @mask,
+ * and returns 1 if true, 0 if false. This function does NOT perform
+ * an implicit fence flush.
+ */
+
+extern bool
+ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask);
+
+/**
+ * ttm_fence_class
+ *
+ * @fence: Pointer to the struct ttm_fence_object.
+ *
+ * Convenience function that returns the fence class of a
+ * struct ttm_fence_object.
+ */
+
+static inline uint32_t ttm_fence_class(const struct ttm_fence_object *fence)
+{
+	return fence->fence_class;
+}
+
+/**
+ * ttm_fence_types
+ *
+ * @fence: Pointer to the struct ttm_fence_object.
+ *
+ * Convenience function that returns the fence types of a
+ * struct ttm_fence_object.
+ */
+
+static inline uint32_t ttm_fence_types(const struct ttm_fence_object *fence)
+{
+	return fence->fence_type;
+}
+
+/*
+ * The functions below are wrappers to the above functions, with
+ * similar names but with sync_obj omitted. These wrappers are intended
+ * to be plugged directly into the buffer object driver's sync object
+ * API, if the driver chooses to use ttm_fence_objects as buffer object
+ * sync objects. In the prototypes below, a sync_obj is cast to a
+ * struct ttm_fence_object, whereas a sync_arg is cast to an
+ * uint32_t representing a fence_type argument.
+ */
+
+extern bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg);
+extern int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg,
+				   bool lazy, bool interruptible);
+extern int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg);
+extern void ttm_fence_sync_obj_unref(void **sync_obj);
+extern void *ttm_fence_sync_obj_ref(void *sync_obj);
+
+#endif
diff --git a/drivers/staging/cdv/imgv/psb_ttm_fence_driver.h b/drivers/staging/cdv/imgv/psb_ttm_fence_driver.h
new file mode 100644
index 0000000..233c6ba
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_ttm_fence_driver.h
@@ -0,0 +1,302 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
+ * 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 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.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+#ifndef _TTM_FENCE_DRIVER_H_
+#define _TTM_FENCE_DRIVER_H_
+
+#include <linux/kref.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include "psb_ttm_fence_api.h"
+#include "ttm/ttm_memory.h"
+
+/** @file ttm_fence_driver.h
+ *
+ * Definitions needed for a driver implementing the
+ * ttm_fence subsystem.
+ */
+
+/**
+ * struct ttm_fence_class_manager:
+ *
+ * @wrap_diff: Sequence difference to catch 32-bit wrapping.
+ * if (seqa - seqb) > @wrap_diff, then seqa < seqb.
+ * @flush_diff: Sequence difference to trigger fence flush.
+ * if (cur_seq - seqa) > @flush_diff, then consider fence object with
+ * seqa as old an needing a flush.
+ * @sequence_mask: Mask of valid bits in a fence sequence.
+ * @lock: Lock protecting this struct as well as fence objects
+ * associated with this struct.
+ * @ring: Circular sequence-ordered list of fence objects.
+ * @pending_flush: Fence types currently needing a flush.
+ * @waiting_types: Fence types that are currently waited for.
+ * @fence_queue: Queue of waiters on fences belonging to this fence class.
+ * @highest_waiting_sequence: Sequence number of the fence with highest
+ * sequence number and that is waited for.
+ * @latest_queued_sequence: Sequence number of the fence latest queued
+ * on the ring.
+ */
+
+struct ttm_fence_class_manager {
+
+	/*
+	 * Unprotected constant members.
+	 */
+
+	uint32_t wrap_diff;
+	uint32_t flush_diff;
+	uint32_t sequence_mask;
+
+	/*
+	 * The rwlock protects this structure as well as
+	 * the data in all fence objects belonging to this
+	 * class. This should be OK as most fence objects are
+	 * only read from once they're created.
+	 */
+
+	rwlock_t lock;
+	struct list_head ring;
+	uint32_t pending_flush;
+	uint32_t waiting_types;
+	wait_queue_head_t fence_queue;
+	uint32_t highest_waiting_sequence;
+	uint32_t latest_queued_sequence;
+};
+
+/**
+ * struct ttm_fence_device
+ *
+ * @fence_class:  Array of fence class managers.
+ * @num_classes:  Array dimension of @fence_class.
+ * @count:        Current number of fence objects for statistics.
+ * @driver:       Driver struct.
+ *
+ * Provided in the driver interface so that the driver can derive
+ * from this struct for its driver_private, and accordingly
+ * access the driver_private from the fence driver callbacks.
+ *
+ * All members except "count" are initialized at creation and
+ * never touched after that. No protection needed.
+ *
+ * This struct is private to the fence implementation and to the fence
+ * driver callbacks, and may otherwise be used by drivers only to
+ * obtain the derived device_private object using container_of().
+ */
+
+struct ttm_fence_device {
+	struct ttm_mem_global *mem_glob;
+	struct ttm_fence_class_manager *fence_class;
+	uint32_t num_classes;
+	atomic_t count;
+	const struct ttm_fence_driver *driver;
+};
+
+/**
+ * struct ttm_fence_class_init
+ *
+ * @wrap_diff:    Fence sequence number wrap indicator. If
+ * (sequence1 - sequence2) > @wrap_diff, then sequence1 is
+ * considered to be older than sequence2.
+ * @flush_diff:   Fence sequence number flush indicator.
+ * If a non-completely-signaled fence has a fence sequence number
+ * sequence1 and (sequence1 - current_emit_sequence) > @flush_diff,
+ * the fence is considered too old and it will be flushed upon the
+ * next call of ttm_fence_flush_old(), to make sure no fences with
+ * stale sequence numbers remains unsignaled. @flush_diff should
+ * be sufficiently less than @wrap_diff.
+ * @sequence_mask: Mask with valid bits of the fence sequence
+ * number set to 1.
+ *
+ * This struct is used as input to ttm_fence_device_init.
+ */
+
+struct ttm_fence_class_init {
+	uint32_t wrap_diff;
+	uint32_t flush_diff;
+	uint32_t sequence_mask;
+};
+
+/**
+ * struct ttm_fence_driver
+ *
+ * @has_irq: Called by a potential waiter. Should return 1 if a
+ * fence object with indicated parameters is expected to signal
+ * automatically, and 0 if the fence implementation needs to
+ * repeatedly call @poll to make it signal.
+ * @emit:    Make sure a fence with the given parameters is
+ * present in the indicated command stream. Return its sequence number
+ * in "breadcrumb".
+ * @poll:    Check and report sequences of the given "fence_class"
+ *           that have signaled "types"
+ * @flush:   Make sure that the types indicated by the bitfield
+ *           ttm_fence_class_manager::pending_flush will eventually
+ *           signal. These bits have been put together using the
+ *           result from the needed_flush function described below.
+ * @needed_flush: Given the fence_class and fence_types indicated by
+ *           "fence", and the last received fence sequence of this
+ *           fence class, indicate what types need a fence flush to
+ *           signal. Return as a bitfield.
+ * @wait:    Set to non-NULL if the driver wants to override the fence
+ *           wait implementation. Return 0 on success, -EBUSY on failure,
+ *           and -ERESTART if interruptible and a signal is pending.
+ * @signaled:  Driver callback that is called whenever a
+ *           ttm_fence_object::signaled_types has changed status.
+ *           This function is called from atomic context,
+ *           with the ttm_fence_class_manager::lock held in write mode.
+ * @lockup:  Driver callback that is called whenever a wait has exceeded
+ *           the lifetime of a fence object.
+ *           If there is a GPU lockup,
+ *           this function should, if possible, reset the GPU,
+ *           call the ttm_fence_handler with an error status, and
+ *           return. If no lockup was detected, simply extend the
+ *           fence timeout_jiffies and return. The driver might
+ *           want to protect the lockup check with a mutex and cache a
+ *           non-locked-up status for a while to avoid an excessive
+ *           amount of lockup checks from every waiting thread.
+ */
+
+struct ttm_fence_driver {
+	bool (*has_irq) (struct ttm_fence_device *fdev,
+			uint32_t fence_class, uint32_t flags);
+	int (*emit) (struct ttm_fence_device *fdev,
+		     uint32_t fence_class,
+		     uint32_t flags,
+		     uint32_t *breadcrumb, unsigned long *timeout_jiffies);
+	void (*flush) (struct ttm_fence_device *fdev, uint32_t fence_class);
+	void (*poll) (struct ttm_fence_device *fdev,
+		      uint32_t fence_class, uint32_t types);
+	 uint32_t(*needed_flush)
+	 (struct ttm_fence_object *fence);
+	int (*wait) (struct ttm_fence_object *fence, bool lazy,
+		     bool interruptible, uint32_t mask);
+	void (*signaled) (struct ttm_fence_object *fence);
+	void (*lockup) (struct ttm_fence_object *fence, uint32_t fence_types);
+};
+
+/**
+ * function ttm_fence_device_init
+ *
+ * @num_classes:      Number of fence classes for this fence implementation.
+ * @mem_global:       Pointer to the global memory accounting info.
+ * @fdev:             Pointer to an uninitialised struct ttm_fence_device.
+ * @init:             Array of initialization info for each fence class.
+ * @replicate_init:   Use the first @init initialization info for all classes.
+ * @driver:           Driver callbacks.
+ *
+ * Initialize a struct ttm_fence_driver structure. Returns -ENOMEM if
+ * out-of-memory. Otherwise returns 0.
+ */
+extern int
+ttm_fence_device_init(int num_classes,
+		      struct ttm_mem_global *mem_glob,
+		      struct ttm_fence_device *fdev,
+		      const struct ttm_fence_class_init *init,
+		      bool replicate_init,
+		      const struct ttm_fence_driver *driver);
+
+/**
+ * function ttm_fence_device_release
+ *
+ * @fdev:             Pointer to the fence device.
+ *
+ * Release all resources held by a fence device. Note that before
+ * this function is called, the caller must have made sure all fence
+ * objects belonging to this fence device are completely signaled.
+ */
+
+extern void ttm_fence_device_release(struct ttm_fence_device *fdev);
+
+/**
+ * ttm_fence_handler - the fence handler.
+ *
+ * @fdev:        Pointer to the fence device.
+ * @fence_class: Fence class that signals.
+ * @sequence:    Signaled sequence.
+ * @type:        Types that signal.
+ * @error:       Error from the engine.
+ *
+ * This function signals all fences with a sequence previous to the
+ * @sequence argument, and belonging to @fence_class. The signaled fence
+ * types are provided in @type. If error is non-zero, the error member
+ * of the fence with sequence = @sequence is set to @error. This value
+ * may be reported back to user-space, indicating, for example an illegal
+ * 3D command or illegal mpeg data.
+ *
+ * This function is typically called from the driver::poll method when the
+ * command sequence preceding the fence marker has executed. It should be
+ * called with the ttm_fence_class_manager::lock held in write mode and
+ * may be called from interrupt context.
+ */
+
+extern void
+ttm_fence_handler(struct ttm_fence_device *fdev,
+		  uint32_t fence_class,
+		  uint32_t sequence, uint32_t type, uint32_t error);
+
+/**
+ * ttm_fence_driver_from_dev
+ *
+ * @fdev:        The ttm fence device.
+ *
+ * Returns a pointer to the fence driver struct.
+ */
+
+static inline const struct ttm_fence_driver *ttm_fence_driver_from_dev(
+						struct ttm_fence_device *fdev)
+{
+	return fdev->driver;
+}
+
+/**
+ * ttm_fence_driver
+ *
+ * @fence:        Pointer to a ttm fence object.
+ *
+ * Returns a pointer to the fence driver struct.
+ */
+
+static inline const struct ttm_fence_driver *ttm_fence_driver(struct
+							      ttm_fence_object
+							      *fence)
+{
+	return ttm_fence_driver_from_dev(fence->fdev);
+}
+
+/**
+ * ttm_fence_fc
+ *
+ * @fence:        Pointer to a ttm fence object.
+ *
+ * Returns a pointer to the struct ttm_fence_class_manager for the
+ * fence class of @fence.
+ */
+
+static inline struct ttm_fence_class_manager *ttm_fence_fc(struct
+							   ttm_fence_object
+							   *fence)
+{
+	return &fence->fdev->fence_class[fence->fence_class];
+}
+
+#endif
diff --git a/drivers/staging/cdv/imgv/psb_ttm_fence_user.c b/drivers/staging/cdv/imgv/psb_ttm_fence_user.c
new file mode 100644
index 0000000..7ada0dd
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_ttm_fence_user.c
@@ -0,0 +1,237 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
+ * 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 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.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include <drm/drmP.h>
+#include "psb_ttm_fence_user.h"
+#include "ttm/ttm_object.h"
+#include "psb_ttm_fence_driver.h"
+#include "psb_ttm_userobj_api.h"
+
+/**
+ * struct ttm_fence_user_object
+ *
+ * @base:    The base object used for user-space visibility and refcounting.
+ *
+ * @fence:   The fence object itself.
+ *
+ */
+
+struct ttm_fence_user_object {
+	struct ttm_base_object base;
+	struct ttm_fence_object fence;
+};
+
+static struct ttm_fence_user_object *ttm_fence_user_object_lookup(
+					struct ttm_object_file *tfile,
+					uint32_t handle)
+{
+	struct ttm_base_object *base;
+
+	base = ttm_base_object_lookup(tfile, handle);
+	if (unlikely(base == NULL)) {
+		printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
+		       (unsigned long)handle);
+		return NULL;
+	}
+
+	if (unlikely(base->object_type != ttm_fence_type)) {
+		ttm_base_object_unref(&base);
+		printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
+		       (unsigned long)handle);
+		return NULL;
+	}
+
+	return container_of(base, struct ttm_fence_user_object, base);
+}
+
+/*
+ * The fence object destructor.
+ */
+
+static void ttm_fence_user_destroy(struct ttm_fence_object *fence)
+{
+	struct ttm_fence_user_object *ufence =
+	    container_of(fence, struct ttm_fence_user_object, fence);
+
+	ttm_mem_global_free(fence->fdev->mem_glob, sizeof(*ufence));
+	kfree(ufence);
+}
+
+/*
+ * The base object destructor. We basically unly unreference the
+ * attached fence object.
+ */
+
+static void ttm_fence_user_release(struct ttm_base_object **p_base)
+{
+	struct ttm_fence_user_object *ufence;
+	struct ttm_base_object *base = *p_base;
+	struct ttm_fence_object *fence;
+
+	*p_base = NULL;
+
+	if (unlikely(base == NULL))
+		return;
+
+	ufence = container_of(base, struct ttm_fence_user_object, base);
+	fence = &ufence->fence;
+	ttm_fence_object_unref(&fence);
+}
+
+int
+ttm_fence_user_create(struct ttm_fence_device *fdev,
+		      struct ttm_object_file *tfile,
+		      uint32_t fence_class,
+		      uint32_t fence_types,
+		      uint32_t create_flags,
+		      struct ttm_fence_object **fence,
+		      uint32_t *user_handle)
+{
+	int ret;
+	struct ttm_fence_object *tmp;
+	struct ttm_fence_user_object *ufence;
+
+	ret = ttm_mem_global_alloc(fdev->mem_glob,
+				   sizeof(*ufence),
+				   false,
+				   false);
+	if (unlikely(ret != 0))
+		return -ENOMEM;
+
+	ufence = kmalloc(sizeof(*ufence), GFP_KERNEL);
+	if (unlikely(ufence == NULL)) {
+		ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence));
+		return -ENOMEM;
+	}
+
+	ret = ttm_fence_object_init(fdev,
+				    fence_class,
+				    fence_types, create_flags,
+				    &ttm_fence_user_destroy, &ufence->fence);
+
+	if (unlikely(ret != 0))
+		goto out_err0;
+
+	/*
+	 * One fence ref is held by the fence ptr we return.
+	 * The other one by the base object. Need to up the
+	 * fence refcount before we publish this object to
+	 * user-space.
+	 */
+
+	tmp = ttm_fence_object_ref(&ufence->fence);
+	ret = ttm_base_object_init(tfile, &ufence->base,
+				   false, ttm_fence_type,
+				   &ttm_fence_user_release, NULL);
+
+	if (unlikely(ret != 0))
+		goto out_err1;
+
+	*fence = &ufence->fence;
+	*user_handle = ufence->base.hash.key;
+
+	return 0;
+out_err1:
+	ttm_fence_object_unref(&tmp);
+	tmp = &ufence->fence;
+	ttm_fence_object_unref(&tmp);
+	return ret;
+out_err0:
+	ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence));
+	kfree(ufence);
+	return ret;
+}
+
+int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data)
+{
+	int ret;
+	union ttm_fence_signaled_arg *arg = data;
+	struct ttm_fence_object *fence;
+	struct ttm_fence_info info;
+	struct ttm_fence_user_object *ufence;
+	struct ttm_base_object *base;
+	ret = 0;
+
+	ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
+	if (unlikely(ufence == NULL))
+		return -EINVAL;
+
+	fence = &ufence->fence;
+
+	if (arg->req.flush) {
+		ret = ttm_fence_object_flush(fence, arg->req.fence_type);
+		if (unlikely(ret != 0))
+			goto out;
+	}
+
+	info = ttm_fence_get_info(fence);
+	arg->rep.signaled_types = info.signaled_types;
+	arg->rep.fence_error = info.error;
+
+out:
+	base = &ufence->base;
+	ttm_base_object_unref(&base);
+	return ret;
+}
+
+int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data)
+{
+	int ret;
+	union ttm_fence_finish_arg *arg = data;
+	struct ttm_fence_user_object *ufence;
+	struct ttm_base_object *base;
+	struct ttm_fence_object *fence;
+	ret = 0;
+
+	ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
+	if (unlikely(ufence == NULL))
+		return -EINVAL;
+
+	fence = &ufence->fence;
+
+	ret = ttm_fence_object_wait(fence,
+				    arg->req.mode & TTM_FENCE_FINISH_MODE_LAZY,
+				    true, arg->req.fence_type);
+	if (likely(ret == 0)) {
+		struct ttm_fence_info info = ttm_fence_get_info(fence);
+
+		arg->rep.signaled_types = info.signaled_types;
+		arg->rep.fence_error = info.error;
+	}
+
+	base = &ufence->base;
+	ttm_base_object_unref(&base);
+
+	return ret;
+}
+
+int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data)
+{
+	struct ttm_fence_unref_arg *arg = data;
+	int ret = 0;
+
+	ret = ttm_ref_object_base_unref(tfile, arg->handle, ttm_fence_type);
+	return ret;
+}
diff --git a/drivers/staging/cdv/imgv/psb_ttm_fence_user.h b/drivers/staging/cdv/imgv/psb_ttm_fence_user.h
new file mode 100644
index 0000000..ee95e6a
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_ttm_fence_user.h
@@ -0,0 +1,140 @@
+/**************************************************************************
+ *
+ * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
+ * 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 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.
+ *
+ **************************************************************************/
+/*
+ * Authors
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef TTM_FENCE_USER_H
+#define TTM_FENCE_USER_H
+
+#if !defined(__KERNEL__) && !defined(_KERNEL)
+#include <stdint.h>
+#endif
+
+#define TTM_FENCE_MAJOR 0
+#define TTM_FENCE_MINOR 1
+#define TTM_FENCE_PL    0
+#define TTM_FENCE_DATE  "080819"
+
+/**
+ * struct ttm_fence_signaled_req
+ *
+ * @handle: Handle to the fence object. Input.
+ *
+ * @fence_type: Fence types we want to flush. Input.
+ *
+ * @flush: Boolean. Flush the indicated fence_types. Input.
+ *
+ * Argument to the TTM_FENCE_SIGNALED ioctl.
+ */
+
+struct ttm_fence_signaled_req {
+	uint32_t handle;
+	uint32_t fence_type;
+	int32_t flush;
+	uint32_t pad64;
+};
+
+/**
+ * struct ttm_fence_rep
+ *
+ * @signaled_types: Fence type that has signaled.
+ *
+ * @fence_error: Command execution error.
+ * Hardware errors that are consequences of the execution
+ * of the command stream preceding the fence are reported
+ * here.
+ *
+ * Output argument to the TTM_FENCE_SIGNALED and
+ * TTM_FENCE_FINISH ioctls.
+ */
+
+struct ttm_fence_rep {
+	uint32_t signaled_types;
+	uint32_t fence_error;
+};
+
+union ttm_fence_signaled_arg {
+	struct ttm_fence_signaled_req req;
+	struct ttm_fence_rep rep;
+};
+
+/*
+ * Waiting mode flags for the TTM_FENCE_FINISH ioctl.
+ *
+ * TTM_FENCE_FINISH_MODE_LAZY: Allow for sleeps during polling
+ * wait.
+ *
+ * TTM_FENCE_FINISH_MODE_NO_BLOCK: Don't block waiting for GPU,
+ * but return -EBUSY if the buffer is busy.
+ */
+
+#define TTM_FENCE_FINISH_MODE_LAZY     (1 << 0)
+#define TTM_FENCE_FINISH_MODE_NO_BLOCK (1 << 1)
+
+/**
+ * struct ttm_fence_finish_req
+ *
+ * @handle: Handle to the fence object. Input.
+ *
+ * @fence_type: Fence types we want to finish.
+ *
+ * @mode: Wait mode.
+ *
+ * Input to the TTM_FENCE_FINISH ioctl.
+ */
+
+struct ttm_fence_finish_req {
+	uint32_t handle;
+	uint32_t fence_type;
+	uint32_t mode;
+	uint32_t pad64;
+};
+
+union ttm_fence_finish_arg {
+	struct ttm_fence_finish_req req;
+	struct ttm_fence_rep rep;
+};
+
+/**
+ * struct ttm_fence_unref_arg
+ *
+ * @handle: Handle to the fence object.
+ *
+ * Argument to the TTM_FENCE_UNREF ioctl.
+ */
+
+struct ttm_fence_unref_arg {
+	uint32_t handle;
+	uint32_t pad64;
+};
+
+/*
+ * Ioctl offsets frome extenstion start.
+ */
+
+#define TTM_FENCE_SIGNALED 0x01
+#define TTM_FENCE_FINISH   0x02
+#define TTM_FENCE_UNREF    0x03
+
+#endif
diff --git a/drivers/staging/cdv/imgv/psb_ttm_glue.c b/drivers/staging/cdv/imgv/psb_ttm_glue.c
new file mode 100644
index 0000000..57cb6ec
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_ttm_glue.c
@@ -0,0 +1,376 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * All Rights Reserved.
+ * Copyright (c) 2008, Tungsten Graphics Inc.  Cedar Park, TX., USA.
+ * 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 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.
+ *
+ **************************************************************************/
+
+
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_ttm_userobj_api.h"
+#include <linux/io.h>
+#include "psb_msvdx.h"
+#include "bufferclass_video.h"
+
+/*IMG Headers*/
+#include "private_data.h"
+
+extern int PVRMMap(struct file *pFile, struct vm_area_struct *ps_vma);
+extern unsigned int bc_video_id_usage[BC_VIDEO_DEVICE_MAX_ID];
+int BC_DestroyBuffers (int id);
+
+static struct vm_operations_struct psb_ttm_vm_ops;
+
+/**
+ * NOTE: driver_private of drm_file is now a PVRSRV_FILE_PRIVATE_DATA struct
+ * pPriv in PVRSRV_FILE_PRIVATE_DATA contains the original psb_fpriv;
+ */
+int psb_open(struct inode *inode, struct file *filp)
+{
+	struct drm_file *file_priv;
+	struct drm_psb_private *dev_priv;
+	struct psb_fpriv *psb_fp;
+	PVRSRV_FILE_PRIVATE_DATA *pvr_file_priv;
+	int ret;
+
+	DRM_DEBUG("\n");
+
+	ret = drm_open(inode, filp);
+	if (unlikely(ret))
+		return ret;
+
+	psb_fp = kzalloc(sizeof(*psb_fp), GFP_KERNEL);
+
+	if (unlikely(psb_fp == NULL))
+		goto out_err0;
+
+	file_priv = (struct drm_file *) filp->private_data;
+	dev_priv = psb_priv(file_priv->minor->dev);
+
+	DRM_DEBUG("is_master %d\n", file_priv->is_master ? 1 : 0);
+
+	psb_fp->tfile = ttm_object_file_init(dev_priv->tdev,
+					     PSB_FILE_OBJECT_HASH_ORDER);
+	if (unlikely(psb_fp->tfile == NULL))
+		goto out_err1;
+
+	pvr_file_priv = (PVRSRV_FILE_PRIVATE_DATA *)file_priv->driver_priv;
+	if (!pvr_file_priv) {
+		DRM_ERROR("drm file private is NULL\n");
+		goto out_err1;
+	}
+
+	pvr_file_priv->pPriv = psb_fp;
+	if (unlikely(dev_priv->bdev.dev_mapping == NULL))
+		dev_priv->bdev.dev_mapping = dev_priv->dev->dev_mapping;
+
+	return 0;
+
+out_err1:
+	kfree(psb_fp);
+out_err0:
+	(void) drm_release(inode, filp);
+	return ret;
+}
+
+int psb_release(struct inode *inode, struct file *filp)
+{
+	struct drm_file *file_priv;
+	struct psb_fpriv *psb_fp;
+	struct drm_psb_private *dev_priv;
+	struct msvdx_private *msvdx_priv;
+	int ret;
+	file_priv = (struct drm_file *) filp->private_data;
+	psb_fp = psb_fpriv(file_priv);
+	dev_priv = psb_priv(file_priv->minor->dev);
+	msvdx_priv = (struct msvdx_private *)dev_priv->msvdx_private;
+
+	/*cleanup for msvdx*/
+	if (msvdx_priv->tfile == psb_fpriv(file_priv)->tfile) {
+		msvdx_priv->fw_status = 0;
+		msvdx_priv->host_be_opp_enabled = 0;
+		msvdx_priv->deblock_enabled = 0;
+		memset(&msvdx_priv->frame_info, 0, sizeof(struct drm_psb_msvdx_frame_info) * MAX_DECODE_BUFFERS);
+	}
+
+        if (psb_fp->bcd_index >= 0 &&
+                psb_fp->bcd_index < BC_VIDEO_DEVICE_MAX_ID &&
+                bc_video_id_usage[psb_fp->bcd_index] == 1) {
+            bc_video_id_usage[psb_fp->bcd_index] = 0;
+            BC_DestroyBuffers(psb_fp->bcd_index);
+        }
+
+	ttm_object_file_release(&psb_fp->tfile);
+	kfree(psb_fp);
+
+	/* remove video context */
+	psb_remove_videoctx(dev_priv, filp);
+
+	ret = drm_release(inode, filp);
+
+	return ret;
+}
+
+int psb_fence_signaled_ioctl(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv)
+{
+
+	return ttm_fence_signaled_ioctl(psb_fpriv(file_priv)->tfile, data);
+}
+
+int psb_fence_finish_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	return ttm_fence_finish_ioctl(psb_fpriv(file_priv)->tfile, data);
+}
+
+int psb_fence_unref_ioctl(struct drm_device *dev, void *data,
+			  struct drm_file *file_priv)
+{
+	return ttm_fence_unref_ioctl(psb_fpriv(file_priv)->tfile, data);
+}
+
+int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data,
+			  struct drm_file *file_priv)
+{
+	return ttm_pl_waitidle_ioctl(psb_fpriv(file_priv)->tfile, data);
+}
+
+int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	return ttm_pl_setstatus_ioctl(psb_fpriv(file_priv)->tfile,
+				      &psb_priv(dev)->ttm_lock, data);
+
+}
+
+int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv)
+{
+	return ttm_pl_synccpu_ioctl(psb_fpriv(file_priv)->tfile, data);
+}
+
+int psb_pl_unref_ioctl(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	return ttm_pl_unref_ioctl(psb_fpriv(file_priv)->tfile, data);
+
+}
+
+int psb_pl_reference_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	return  ttm_pl_reference_ioctl(psb_fpriv(file_priv)->tfile, data);
+
+}
+
+int psb_pl_create_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+
+	return ttm_pl_create_ioctl(psb_fpriv(file_priv)->tfile,
+				   &dev_priv->bdev, &dev_priv->ttm_lock, data);
+
+}
+
+int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+
+	return ttm_pl_ub_create_ioctl(psb_fpriv(file_priv)->tfile,
+				   &dev_priv->bdev, &dev_priv->ttm_lock, data);
+
+}
+/**
+ * psb_ttm_fault - Wrapper around the ttm fault method.
+ *
+ * @vma: The struct vm_area_struct as in the vm fault() method.
+ * @vmf: The struct vm_fault as in the vm fault() method.
+ *
+ * Since ttm_fault() will reserve buffers while faulting,
+ * we need to take the ttm read lock around it, as this driver
+ * relies on the ttm_lock in write mode to exclude all threads from
+ * reserving and thus validating buffers in aperture- and memory shortage
+ * situations.
+ */
+
+static int psb_ttm_fault(struct vm_area_struct *vma,
+			 struct vm_fault *vmf)
+{
+	struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
+		vma->vm_private_data;
+	struct drm_psb_private *dev_priv =
+		container_of(bo->bdev, struct drm_psb_private, bdev);
+	int ret;
+
+	ret = ttm_read_lock(&dev_priv->ttm_lock, true);
+	if (unlikely(ret != 0))
+		return VM_FAULT_NOPAGE;
+
+	ret = dev_priv->ttm_vm_ops->fault(vma, vmf);
+
+	ttm_read_unlock(&dev_priv->ttm_lock);
+	return ret;
+}
+
+/**
+ * if vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET call directly to
+ * PVRMMap
+ */
+int psb_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct drm_file *file_priv;
+	struct drm_psb_private *dev_priv;
+	int ret;
+
+	if (vma->vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET ||
+	    vma->vm_pgoff > 2 * DRM_PSB_FILE_PAGE_OFFSET)
+		return PVRMMap(filp, vma);
+
+	file_priv = (struct drm_file *) filp->private_data;
+	dev_priv = psb_priv(file_priv->minor->dev);
+
+	ret = ttm_bo_mmap(filp, vma, &dev_priv->bdev);
+	if (unlikely(ret != 0))
+		return ret;
+
+	if (unlikely(dev_priv->ttm_vm_ops == NULL)) {
+		dev_priv->ttm_vm_ops = (struct vm_operations_struct *)vma->vm_ops;
+		psb_ttm_vm_ops = *vma->vm_ops;
+		psb_ttm_vm_ops.fault = &psb_ttm_fault;
+	}
+
+	vma->vm_ops = &psb_ttm_vm_ops;
+
+	return 0;
+}
+/*
+ssize_t psb_ttm_write(struct file *filp, const char __user *buf,
+		      size_t count, loff_t *f_pos)
+{
+	struct drm_file *file_priv = (struct drm_file *)filp->private_data;
+	struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev);
+
+	return ttm_bo_io(&dev_priv->bdev, filp, buf, NULL, count, f_pos, 1);
+}
+
+ssize_t psb_ttm_read(struct file *filp, char __user *buf,
+		     size_t count, loff_t *f_pos)
+{
+	struct drm_file *file_priv = (struct drm_file *)filp->private_data;
+	struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev);
+
+	return ttm_bo_io(&dev_priv->bdev, filp, NULL, buf, count, f_pos, 1);
+}
+*/
+int psb_verify_access(struct ttm_buffer_object *bo,
+		      struct file *filp)
+{
+	struct drm_file *file_priv = (struct drm_file *)filp->private_data;
+
+	if (capable(CAP_SYS_ADMIN))
+		return 0;
+
+	if (unlikely(!file_priv->authenticated))
+		return -EPERM;
+
+	return ttm_pl_verify_access(bo, psb_fpriv(file_priv)->tfile);
+}
+
+static int psb_ttm_mem_global_init(struct drm_global_reference *ref)
+{
+	return ttm_mem_global_init(ref->object);
+}
+
+static void psb_ttm_mem_global_release(struct drm_global_reference *ref)
+{
+	ttm_mem_global_release(ref->object);
+}
+
+int psb_ttm_global_init(struct drm_psb_private *dev_priv)
+{
+	struct drm_global_reference *global_ref;
+	int ret;
+
+	global_ref = &dev_priv->mem_global_ref;
+	global_ref->global_type = DRM_GLOBAL_TTM_MEM;
+	global_ref->size = sizeof(struct ttm_mem_global);
+	global_ref->init = &psb_ttm_mem_global_init;
+	global_ref->release = &psb_ttm_mem_global_release;
+
+	ret = drm_global_item_ref(global_ref);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed referencing a global TTM memory object.\n");
+		return ret;
+	}
+
+	dev_priv->bo_global_ref.mem_glob = dev_priv->mem_global_ref.object;
+        global_ref = &dev_priv->bo_global_ref.ref;
+        global_ref->global_type = DRM_GLOBAL_TTM_BO;
+        global_ref->size = sizeof(struct ttm_bo_global);
+        global_ref->init = &ttm_bo_global_init;
+        global_ref->release = &ttm_bo_global_release;
+        ret = drm_global_item_ref(global_ref);
+        if (ret != 0) {
+                DRM_ERROR("Failed setting up TTM BO subsystem.\n");
+                drm_global_item_unref(&dev_priv->mem_global_ref);
+                return ret;
+        }
+
+	return 0;
+}
+
+void psb_ttm_global_release(struct drm_psb_private *dev_priv)
+{
+	drm_global_item_unref(&dev_priv->mem_global_ref);
+}
+
+int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data,
+		struct drm_file *file_priv)
+{
+	struct drm_psb_getpageaddrs_arg *arg = data;
+	struct ttm_buffer_object *bo;
+	struct ttm_tt *ttm;
+	struct page **tt_pages;
+	unsigned long i, num_pages;
+	unsigned long *p = arg->page_addrs;
+	int ret = 0;
+
+	bo = ttm_buffer_object_lookup(psb_fpriv(file_priv)->tfile,
+					arg->handle);
+	if (unlikely(bo == NULL)) {
+		printk(KERN_ERR
+			"Could not find buffer object for getpageaddrs.\n");
+		return -EINVAL;
+	}
+
+	arg->gtt_offset = bo->offset;
+	ttm = bo->ttm;
+	num_pages = ttm->num_pages;
+	tt_pages = ttm->pages;
+
+	for (i = 0; i < num_pages; i++)
+		p[i] = (unsigned long)page_to_phys(tt_pages[i]);
+
+	if (bo)
+		ttm_bo_unref(&bo);
+
+	return ret;
+}
diff --git a/drivers/staging/cdv/imgv/psb_ttm_placement_user.c b/drivers/staging/cdv/imgv/psb_ttm_placement_user.c
new file mode 100644
index 0000000..7395901
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_ttm_placement_user.c
@@ -0,0 +1,631 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * 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 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.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include "psb_ttm_placement_user.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_object.h"
+#include "psb_ttm_userobj_api.h"
+#include "ttm/ttm_lock.h"
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+struct ttm_bo_user_object {
+	struct ttm_base_object base;
+	struct ttm_buffer_object bo;
+};
+
+static size_t pl_bo_size;
+
+static uint32_t psb_busy_prios[] = {
+	TTM_PL_TT,
+	TTM_PL_PRIV0, /* CI */
+	TTM_PL_PRIV2, /* RAR */
+	TTM_PL_PRIV1, /* DRM_PSB_MEM_MMU */
+	TTM_PL_SYSTEM
+};
+
+const struct ttm_placement default_placement = {0, 0, 0, NULL, 5, psb_busy_prios};
+
+static size_t ttm_pl_size(struct ttm_bo_device *bdev, unsigned long num_pages)
+{
+	size_t page_array_size =
+	    (num_pages * sizeof(void *) + PAGE_SIZE - 1) & PAGE_MASK;
+
+	if (unlikely(pl_bo_size == 0)) {
+		pl_bo_size = bdev->glob->ttm_bo_extra_size +
+		    ttm_round_pot(sizeof(struct ttm_bo_user_object));
+	}
+
+	return bdev->glob->ttm_bo_size + 2 * page_array_size;
+}
+
+static struct ttm_bo_user_object *ttm_bo_user_lookup(struct ttm_object_file
+						     *tfile, uint32_t handle)
+{
+	struct ttm_base_object *base;
+
+	base = ttm_base_object_lookup(tfile, handle);
+	if (unlikely(base == NULL)) {
+		printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
+		       (unsigned long)handle);
+		return NULL;
+	}
+
+	if (unlikely(base->object_type != ttm_buffer_type)) {
+		ttm_base_object_unref(&base);
+		printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
+		       (unsigned long)handle);
+		return NULL;
+	}
+
+	return container_of(base, struct ttm_bo_user_object, base);
+}
+
+struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file
+						   *tfile, uint32_t handle)
+{
+	struct ttm_bo_user_object *user_bo;
+	struct ttm_base_object *base;
+
+	user_bo = ttm_bo_user_lookup(tfile, handle);
+	if (unlikely(user_bo == NULL))
+		return NULL;
+
+	(void)ttm_bo_reference(&user_bo->bo);
+	base = &user_bo->base;
+	ttm_base_object_unref(&base);
+	return &user_bo->bo;
+}
+
+static void ttm_bo_user_destroy(struct ttm_buffer_object *bo)
+{
+	struct ttm_bo_user_object *user_bo =
+	    container_of(bo, struct ttm_bo_user_object, bo);
+
+	ttm_mem_global_free(bo->glob->mem_glob, bo->acc_size);
+	kfree(user_bo);
+}
+
+static void ttm_bo_user_release(struct ttm_base_object **p_base)
+{
+	struct ttm_bo_user_object *user_bo;
+	struct ttm_base_object *base = *p_base;
+	struct ttm_buffer_object *bo;
+
+	*p_base = NULL;
+
+	if (unlikely(base == NULL))
+		return;
+
+	user_bo = container_of(base, struct ttm_bo_user_object, base);
+	bo = &user_bo->bo;
+	ttm_bo_unref(&bo);
+}
+
+static void ttm_bo_user_ref_release(struct ttm_base_object *base,
+				    enum ttm_ref_type ref_type)
+{
+	struct ttm_bo_user_object *user_bo =
+	    container_of(base, struct ttm_bo_user_object, base);
+	struct ttm_buffer_object *bo = &user_bo->bo;
+
+	switch (ref_type) {
+	case TTM_REF_SYNCCPU_WRITE:
+		ttm_bo_synccpu_write_release(bo);
+		break;
+	default:
+		BUG();
+	}
+}
+
+static void ttm_pl_fill_rep(struct ttm_buffer_object *bo,
+			    struct ttm_pl_rep *rep)
+{
+	struct ttm_bo_user_object *user_bo =
+	    container_of(bo, struct ttm_bo_user_object, bo);
+
+	rep->gpu_offset = bo->offset;
+	rep->bo_size = bo->num_pages << PAGE_SHIFT;
+	rep->map_handle = bo->addr_space_offset;
+	rep->placement = bo->mem.placement;
+	rep->handle = user_bo->base.hash.key;
+	rep->sync_object_arg = (uint32_t) (unsigned long)bo->sync_obj_arg;
+}
+
+/* FIXME Copy from upstream TTM */
+static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
+				 unsigned long num_pages)
+{
+	size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) &
+	    PAGE_MASK;
+
+	return glob->ttm_bo_size + 2 * page_array_size;
+}
+
+/* FIXME Copy from upstream TTM "ttm_bo_create", upstream TTM does not export this, so copy it here */
+static int ttm_bo_create_private(struct ttm_bo_device *bdev,
+			unsigned long size,
+			enum ttm_bo_type type,
+			struct ttm_placement *placement,
+			uint32_t page_alignment,
+			unsigned long buffer_start,
+			bool interruptible,
+			struct file *persistant_swap_storage,
+			struct ttm_buffer_object **p_bo)
+{
+	struct ttm_buffer_object *bo;
+	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
+	int ret;
+
+	size_t acc_size =
+	    ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
+	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
+	if (unlikely(ret != 0))
+		return ret;
+
+	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
+
+	if (unlikely(bo == NULL)) {
+		ttm_mem_global_free(mem_glob, acc_size);
+		return -ENOMEM;
+	}
+
+	ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
+				buffer_start, interruptible,
+				persistant_swap_storage, acc_size, NULL);
+	if (likely(ret == 0))
+		*p_bo = bo;
+
+	return ret;
+}
+
+int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo,
+				struct ttm_placement *placement)
+{
+	int i;
+
+	for (i = 0; i < placement->num_placement; i++) {
+		if (!capable(CAP_SYS_ADMIN)) {
+			if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) {
+				printk(KERN_ERR TTM_PFX "Need to be root to "
+					"modify NO_EVICT status.\n");
+				return -EINVAL;
+			}
+		}
+	}
+	for (i = 0; i < placement->num_busy_placement; i++) {
+		if (!capable(CAP_SYS_ADMIN)) {
+			if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) {
+				printk(KERN_ERR TTM_PFX "Need to be root to "
+					"modify NO_EVICT status.\n");
+				return -EINVAL;
+			}
+		}
+	}
+	return 0;
+}
+
+int ttm_buffer_object_create(struct ttm_bo_device *bdev,
+			unsigned long size,
+			enum ttm_bo_type type,
+			uint32_t flags,
+			uint32_t page_alignment,
+			unsigned long buffer_start,
+			bool interruptible,
+			struct file *persistant_swap_storage,
+			struct ttm_buffer_object **p_bo)
+{
+	struct ttm_placement placement = default_placement;
+	int ret;
+
+	if ((flags & TTM_PL_MASK_CACHING) == 0)
+		flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
+
+	placement.num_placement = 1;
+	placement.placement = &flags;
+
+        ret = ttm_bo_create_private(bdev,
+	   		size,
+			type,
+			&placement,
+			page_alignment,
+			buffer_start,
+			interruptible,
+			persistant_swap_storage,
+			p_bo);
+
+	return ret;
+}
+
+
+int ttm_pl_create_ioctl(struct ttm_object_file *tfile,
+			struct ttm_bo_device *bdev,
+			struct ttm_lock *lock, void *data)
+{
+	union ttm_pl_create_arg *arg = data;
+	struct ttm_pl_create_req *req = &arg->req;
+	struct ttm_pl_rep *rep = &arg->rep;
+	struct ttm_buffer_object *bo;
+	struct ttm_buffer_object *tmp;
+	struct ttm_bo_user_object *user_bo;
+	uint32_t flags;
+	int ret = 0;
+	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
+	struct ttm_placement placement = default_placement;
+	size_t acc_size =
+	    ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT);
+	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
+	if (unlikely(ret != 0))
+		return ret;
+
+	flags = req->placement;
+	user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL);
+	if (unlikely(user_bo == NULL)) {
+		ttm_mem_global_free(mem_glob, acc_size);
+		return -ENOMEM;
+	}
+
+	bo = &user_bo->bo;
+	ret = ttm_read_lock(lock, true);
+	if (unlikely(ret != 0)) {
+		ttm_mem_global_free(mem_glob, acc_size);
+		kfree(user_bo);
+		return ret;
+	}
+
+	placement.num_placement = 1;
+	placement.placement = &flags;
+
+	if ((flags & TTM_PL_MASK_CACHING) == 0)
+		flags |=  TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
+
+	ret = ttm_bo_init(bdev, bo, req->size,
+				     ttm_bo_type_device, &placement,
+				     req->page_alignment, 0, true,
+				     NULL, acc_size, &ttm_bo_user_destroy);
+	ttm_read_unlock(lock);
+
+	/*
+	 * Note that the ttm_buffer_object_init function
+	 * would've called the destroy function on failure!!
+	 */
+
+	if (unlikely(ret != 0))
+		goto out;
+
+	tmp = ttm_bo_reference(bo);
+	ret = ttm_base_object_init(tfile, &user_bo->base,
+				   flags & TTM_PL_FLAG_SHARED,
+				   ttm_buffer_type,
+				   &ttm_bo_user_release,
+				   &ttm_bo_user_ref_release);
+	if (unlikely(ret != 0))
+		goto out_err;
+
+	spin_lock(&bo->bdev->fence_lock);
+	ttm_pl_fill_rep(bo, rep);
+	spin_unlock(&bo->bdev->fence_lock);
+	ttm_bo_unref(&bo);
+out:
+	return 0;
+out_err:
+	ttm_bo_unref(&tmp);
+	ttm_bo_unref(&bo);
+	return ret;
+}
+
+int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile,
+			   struct ttm_bo_device *bdev,
+			   struct ttm_lock *lock, void *data)
+{
+	union ttm_pl_create_ub_arg *arg = data;
+	struct ttm_pl_create_ub_req *req = &arg->req;
+	struct ttm_pl_rep *rep = &arg->rep;
+	struct ttm_buffer_object *bo;
+	struct ttm_buffer_object *tmp;
+	struct ttm_bo_user_object *user_bo;
+	uint32_t flags;
+	int ret = 0;
+	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
+	struct ttm_placement placement = default_placement;
+	size_t acc_size =
+	    ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT);
+	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
+	if (unlikely(ret != 0))
+		return ret;
+
+	flags = req->placement;
+	user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL);
+	if (unlikely(user_bo == NULL)) {
+		ttm_mem_global_free(mem_glob, acc_size);
+		return -ENOMEM;
+	}
+	ret = ttm_read_lock(lock, true);
+	if (unlikely(ret != 0)) {
+		ttm_mem_global_free(mem_glob, acc_size);
+		kfree(user_bo);
+		return ret;
+	}
+	bo = &user_bo->bo;
+
+	placement.num_placement = 1;
+	placement.placement = &flags;
+
+	ret = ttm_bo_init(bdev,
+					bo,
+					req->size,
+					ttm_bo_type_user,
+					&placement,
+					req->page_alignment,
+					req->user_address,
+					true,
+					NULL,
+					acc_size,
+					&ttm_bo_user_destroy);
+
+	/*
+	 * Note that the ttm_buffer_object_init function
+	 * would've called the destroy function on failure!!
+	 */
+	ttm_read_unlock(lock);
+	if (unlikely(ret != 0))
+		goto out;
+
+	tmp = ttm_bo_reference(bo);
+	ret = ttm_base_object_init(tfile, &user_bo->base,
+				   flags & TTM_PL_FLAG_SHARED,
+				   ttm_buffer_type,
+				   &ttm_bo_user_release,
+				   &ttm_bo_user_ref_release);
+	if (unlikely(ret != 0))
+		goto out_err;
+
+	spin_lock(&bo->bdev->fence_lock);
+	ttm_pl_fill_rep(bo, rep);
+	spin_unlock(&bo->bdev->fence_lock);
+	ttm_bo_unref(&bo);
+out:
+	return 0;
+out_err:
+	ttm_bo_unref(&tmp);
+	ttm_bo_unref(&bo);
+	return ret;
+}
+
+int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data)
+{
+	union ttm_pl_reference_arg *arg = data;
+	struct ttm_pl_rep *rep = &arg->rep;
+	struct ttm_bo_user_object *user_bo;
+	struct ttm_buffer_object *bo;
+	struct ttm_base_object *base;
+	int ret;
+
+	user_bo = ttm_bo_user_lookup(tfile, arg->req.handle);
+	if (unlikely(user_bo == NULL)) {
+		printk(KERN_ERR "Could not reference buffer object.\n");
+		return -EINVAL;
+	}
+
+	bo = &user_bo->bo;
+	ret = ttm_ref_object_add(tfile, &user_bo->base, TTM_REF_USAGE, NULL);
+	if (unlikely(ret != 0)) {
+		printk(KERN_ERR
+		       "Could not add a reference to buffer object.\n");
+		goto out;
+	}
+
+	spin_lock(&bo->bdev->fence_lock);
+	ttm_pl_fill_rep(bo, rep);
+	spin_unlock(&bo->bdev->fence_lock);
+
+out:
+	base = &user_bo->base;
+	ttm_base_object_unref(&base);
+	return ret;
+}
+
+int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data)
+{
+	struct ttm_pl_reference_req *arg = data;
+
+	return ttm_ref_object_base_unref(tfile, arg->handle, TTM_REF_USAGE);
+}
+
+int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data)
+{
+	struct ttm_pl_synccpu_arg *arg = data;
+	struct ttm_bo_user_object *user_bo;
+	struct ttm_buffer_object *bo;
+	struct ttm_base_object *base;
+	bool existed;
+	int ret;
+
+	switch (arg->op) {
+	case TTM_PL_SYNCCPU_OP_GRAB:
+		user_bo = ttm_bo_user_lookup(tfile, arg->handle);
+		if (unlikely(user_bo == NULL)) {
+			printk(KERN_ERR
+			       "Could not find buffer object for synccpu.\n");
+			return -EINVAL;
+		}
+		bo = &user_bo->bo;
+		base = &user_bo->base;
+		ret = ttm_bo_synccpu_write_grab(bo,
+						arg->access_mode &
+						TTM_PL_SYNCCPU_MODE_NO_BLOCK);
+		if (unlikely(ret != 0)) {
+			ttm_base_object_unref(&base);
+			goto out;
+		}
+		ret = ttm_ref_object_add(tfile, &user_bo->base,
+					 TTM_REF_SYNCCPU_WRITE, &existed);
+		if (existed || ret != 0)
+			ttm_bo_synccpu_write_release(bo);
+		ttm_base_object_unref(&base);
+		break;
+	case TTM_PL_SYNCCPU_OP_RELEASE:
+		ret = ttm_ref_object_base_unref(tfile, arg->handle,
+						TTM_REF_SYNCCPU_WRITE);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+out:
+	return ret;
+}
+
+int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile,
+			   struct ttm_lock *lock, void *data)
+{
+	union ttm_pl_setstatus_arg *arg = data;
+	struct ttm_pl_setstatus_req *req = &arg->req;
+	struct ttm_pl_rep *rep = &arg->rep; 
+	struct ttm_buffer_object *bo;
+	struct ttm_placement placement = default_placement;
+	uint32_t flags[2];
+	int ret;
+
+	bo = ttm_buffer_object_lookup(tfile, req->handle);
+	if (unlikely(bo == NULL)) {
+		printk(KERN_ERR
+		       "Could not find buffer object for setstatus.\n");
+		return -EINVAL;
+	}
+
+	ret = ttm_read_lock(lock, true);
+	if (unlikely(ret != 0))
+		goto out_err0;
+
+	ret = ttm_bo_reserve(bo, true, false, false, 0);
+	if (unlikely(ret != 0))
+		goto out_err1;
+
+	ret = ttm_bo_wait_cpu(bo, false);
+	if (unlikely(ret != 0))
+		goto out_err2;
+
+	flags[0] = req->set_placement;
+	flags[1] = req->clr_placement;
+
+	placement.num_placement = 2;
+	placement.placement = flags;
+
+	spin_lock(&bo->bdev->fence_lock);
+
+	ret = psb_ttm_bo_check_placement(bo, &placement);
+	if (unlikely(ret != 0))
+		goto out_err2;
+
+	placement.num_placement = 1;
+	flags[0] = (req->set_placement | bo->mem.placement) & ~req->clr_placement;
+
+	ret = ttm_bo_validate(bo, &placement, true, false, false);
+	if (unlikely(ret != 0))
+		goto out_err2;
+
+	ttm_pl_fill_rep(bo, rep);
+out_err2:
+	spin_unlock(&bo->bdev->fence_lock);
+	ttm_bo_unreserve(bo);
+out_err1:
+	ttm_read_unlock(lock);
+out_err0:
+	ttm_bo_unref(&bo);
+	return ret;
+}
+
+static int psb_ttm_bo_block_reservation(struct ttm_buffer_object *bo, bool interruptible,
+                             bool no_wait)
+{
+        int ret;
+
+        while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
+                if (no_wait)
+                        return -EBUSY;
+                else if (interruptible) {
+                        ret = wait_event_interruptible
+                            (bo->event_queue, atomic_read(&bo->reserved) == 0);
+                        if (unlikely(ret != 0))
+                                return -ERESTART;
+                } else {
+                        wait_event(bo->event_queue,
+                                   atomic_read(&bo->reserved) == 0);
+                }
+        }
+        return 0;
+}
+
+static void psb_ttm_bo_unblock_reservation(struct ttm_buffer_object *bo)
+{
+        atomic_set(&bo->reserved, 0);
+        wake_up_all(&bo->event_queue);
+}
+
+int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data)
+{
+	struct ttm_pl_waitidle_arg *arg = data;
+	struct ttm_buffer_object *bo;
+	int ret;
+
+	bo = ttm_buffer_object_lookup(tfile, arg->handle);
+	if (unlikely(bo == NULL)) {
+		printk(KERN_ERR "Could not find buffer object for waitidle.\n");
+		return -EINVAL;
+	}
+
+	ret =
+	    psb_ttm_bo_block_reservation(bo, true,
+				     arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK);
+	if (unlikely(ret != 0))
+		goto out;
+	spin_lock(&bo->bdev->fence_lock);
+	ret = ttm_bo_wait(bo,
+			  arg->mode & TTM_PL_WAITIDLE_MODE_LAZY,
+			  true, arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK);
+	spin_unlock(&bo->bdev->fence_lock);
+	psb_ttm_bo_unblock_reservation(bo);
+out:
+	ttm_bo_unref(&bo);
+	return ret;
+}
+
+int ttm_pl_verify_access(struct ttm_buffer_object *bo,
+			 struct ttm_object_file *tfile)
+{
+	struct ttm_bo_user_object *ubo;
+
+	/*
+	 * Check bo subclass.
+	 */
+
+	if (unlikely(bo->destroy != &ttm_bo_user_destroy))
+		return -EPERM;
+
+	ubo = container_of(bo, struct ttm_bo_user_object, bo);
+	if (likely(ubo->base.shareable || ubo->base.tfile == tfile))
+		return 0;
+
+	return -EPERM;
+}
diff --git a/drivers/staging/cdv/imgv/psb_ttm_placement_user.h b/drivers/staging/cdv/imgv/psb_ttm_placement_user.h
new file mode 100644
index 0000000..f17bf48
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_ttm_placement_user.h
@@ -0,0 +1,252 @@
+/**************************************************************************
+ *
+ * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
+ * 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 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.
+ *
+ **************************************************************************/
+/*
+ * Authors
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _TTM_PLACEMENT_USER_H_
+#define _TTM_PLACEMENT_USER_H_
+
+#if !defined(__KERNEL__) && !defined(_KERNEL)
+#include <stdint.h>
+#else
+#include <linux/kernel.h>
+#endif
+
+#include "ttm/ttm_placement.h"
+
+#define TTM_PLACEMENT_MAJOR 0
+#define TTM_PLACEMENT_MINOR 1
+#define TTM_PLACEMENT_PL    0
+#define TTM_PLACEMENT_DATE  "080819"
+
+/**
+ * struct ttm_pl_create_req
+ *
+ * @size: The buffer object size.
+ * @placement: Flags that indicate initial acceptable
+ *  placement.
+ * @page_alignment: Required alignment in pages.
+ *
+ * Input to the TTM_BO_CREATE ioctl.
+ */
+
+struct ttm_pl_create_req {
+	uint64_t size;
+	uint32_t placement;
+	uint32_t page_alignment;
+};
+
+/**
+ * struct ttm_pl_create_ub_req
+ *
+ * @size: The buffer object size.
+ * @user_address: User-space address of the memory area that
+ * should be used to back the buffer object cast to 64-bit.
+ * @placement: Flags that indicate initial acceptable
+ *  placement.
+ * @page_alignment: Required alignment in pages.
+ *
+ * Input to the TTM_BO_CREATE_UB ioctl.
+ */
+
+struct ttm_pl_create_ub_req {
+	uint64_t size;
+	uint64_t user_address;
+	uint32_t placement;
+	uint32_t page_alignment;
+};
+
+/**
+ * struct ttm_pl_rep
+ *
+ * @gpu_offset: The current offset into the memory region used.
+ * This can be used directly by the GPU if there are no
+ * additional GPU mapping procedures used by the driver.
+ *
+ * @bo_size: Actual buffer object size.
+ *
+ * @map_handle: Offset into the device address space.
+ * Used for map, seek, read, write. This will never change
+ * during the lifetime of an object.
+ *
+ * @placement: Flag indicating the placement status of
+ * the buffer object using the TTM_PL flags above.
+ *
+ * @sync_object_arg: Used for user-space synchronization and
+ * depends on the synchronization model used. If fences are
+ * used, this is the buffer_object::fence_type_mask
+ *
+ * Output from the TTM_PL_CREATE and TTM_PL_REFERENCE, and
+ * TTM_PL_SETSTATUS ioctls.
+ */
+
+struct ttm_pl_rep {
+	uint64_t gpu_offset;
+	uint64_t bo_size;
+	uint64_t map_handle;
+	uint32_t placement;
+	uint32_t handle;
+	uint32_t sync_object_arg;
+	uint32_t pad64;
+};
+
+/**
+ * struct ttm_pl_setstatus_req
+ *
+ * @set_placement: Placement flags to set.
+ *
+ * @clr_placement: Placement flags to clear.
+ *
+ * @handle: The object handle
+ *
+ * Input to the TTM_PL_SETSTATUS ioctl.
+ */
+
+struct ttm_pl_setstatus_req {
+	uint32_t set_placement;
+	uint32_t clr_placement;
+	uint32_t handle;
+	uint32_t pad64;
+};
+
+/**
+ * struct ttm_pl_reference_req
+ *
+ * @handle: The object to put a reference on.
+ *
+ * Input to the TTM_PL_REFERENCE and the TTM_PL_UNREFERENCE ioctls.
+ */
+
+struct ttm_pl_reference_req {
+	uint32_t handle;
+	uint32_t pad64;
+};
+
+/*
+ * ACCESS mode flags for SYNCCPU.
+ *
+ * TTM_SYNCCPU_MODE_READ will guarantee that the GPU is not
+ * writing to the buffer.
+ *
+ * TTM_SYNCCPU_MODE_WRITE will guarantee that the GPU is not
+ * accessing the buffer.
+ *
+ * TTM_SYNCCPU_MODE_NO_BLOCK makes sure the call does not wait
+ * for GPU accesses to finish but return -EBUSY.
+ *
+ * TTM_SYNCCPU_MODE_TRYCACHED Try to place the buffer in cacheable
+ * memory while synchronized for CPU.
+ */
+
+#define TTM_PL_SYNCCPU_MODE_READ      TTM_ACCESS_READ
+#define TTM_PL_SYNCCPU_MODE_WRITE     TTM_ACCESS_WRITE
+#define TTM_PL_SYNCCPU_MODE_NO_BLOCK  (1 << 2)
+#define TTM_PL_SYNCCPU_MODE_TRYCACHED (1 << 3)
+
+/**
+ * struct ttm_pl_synccpu_arg
+ *
+ * @handle: The object to synchronize.
+ *
+ * @access_mode: access mode indicated by the
+ * TTM_SYNCCPU_MODE flags.
+ *
+ * @op: indicates whether to grab or release the
+ * buffer for cpu usage.
+ *
+ * Input to the TTM_PL_SYNCCPU ioctl.
+ */
+
+struct ttm_pl_synccpu_arg {
+	uint32_t handle;
+	uint32_t access_mode;
+	enum {
+		TTM_PL_SYNCCPU_OP_GRAB,
+		TTM_PL_SYNCCPU_OP_RELEASE
+	} op;
+	uint32_t pad64;
+};
+
+/*
+ * Waiting mode flags for the TTM_BO_WAITIDLE ioctl.
+ *
+ * TTM_WAITIDLE_MODE_LAZY: Allow for sleeps during polling
+ * wait.
+ *
+ * TTM_WAITIDLE_MODE_NO_BLOCK: Don't block waiting for GPU,
+ * but return -EBUSY if the buffer is busy.
+ */
+
+#define TTM_PL_WAITIDLE_MODE_LAZY     (1 << 0)
+#define TTM_PL_WAITIDLE_MODE_NO_BLOCK (1 << 1)
+
+/**
+ * struct ttm_waitidle_arg
+ *
+ * @handle: The object to synchronize.
+ *
+ * @mode: wait mode indicated by the
+ * TTM_SYNCCPU_MODE flags.
+ *
+ * Argument to the TTM_BO_WAITIDLE ioctl.
+ */
+
+struct ttm_pl_waitidle_arg {
+	uint32_t handle;
+	uint32_t mode;
+};
+
+union ttm_pl_create_arg {
+	struct ttm_pl_create_req req;
+	struct ttm_pl_rep rep;
+};
+
+union ttm_pl_reference_arg {
+	struct ttm_pl_reference_req req;
+	struct ttm_pl_rep rep;
+};
+
+union ttm_pl_setstatus_arg {
+	struct ttm_pl_setstatus_req req;
+	struct ttm_pl_rep rep;
+};
+
+union ttm_pl_create_ub_arg {
+	struct ttm_pl_create_ub_req req;
+	struct ttm_pl_rep rep;
+};
+
+/*
+ * Ioctl offsets.
+ */
+
+#define TTM_PL_CREATE      0x00
+#define TTM_PL_REFERENCE   0x01
+#define TTM_PL_UNREF       0x02
+#define TTM_PL_SYNCCPU     0x03
+#define TTM_PL_WAITIDLE    0x04
+#define TTM_PL_SETSTATUS   0x05
+#define TTM_PL_CREATE_UB   0x06
+
+#endif
diff --git a/drivers/staging/cdv/imgv/psb_ttm_userobj_api.h b/drivers/staging/cdv/imgv/psb_ttm_userobj_api.h
new file mode 100644
index 0000000..c69fa88
--- /dev/null
+++ b/drivers/staging/cdv/imgv/psb_ttm_userobj_api.h
@@ -0,0 +1,85 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
+ * 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 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.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _TTM_USEROBJ_API_H_
+#define _TTM_USEROBJ_API_H_
+
+#include "psb_ttm_placement_user.h"
+#include "psb_ttm_fence_user.h"
+#include "ttm/ttm_object.h"
+#include "psb_ttm_fence_api.h"
+#include "ttm/ttm_bo_api.h"
+
+struct ttm_lock;
+
+/*
+ * User ioctls.
+ */
+
+extern int ttm_pl_create_ioctl(struct ttm_object_file *tfile,
+			       struct ttm_bo_device *bdev,
+			       struct ttm_lock *lock, void *data);
+extern int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile,
+				  struct ttm_bo_device *bdev,
+				  struct ttm_lock *lock, void *data);
+extern int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data);
+extern int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data);
+extern int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data);
+extern int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile,
+				  struct ttm_lock *lock, void *data);
+extern int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data);
+extern int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data);
+extern int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data);
+extern int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data);
+
+extern int
+ttm_fence_user_create(struct ttm_fence_device *fdev,
+		      struct ttm_object_file *tfile,
+		      uint32_t fence_class,
+		      uint32_t fence_types,
+		      uint32_t create_flags,
+		      struct ttm_fence_object **fence, uint32_t * user_handle);
+
+extern struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file
+							  *tfile,
+							  uint32_t handle);
+
+extern int
+ttm_pl_verify_access(struct ttm_buffer_object *bo,
+		     struct ttm_object_file *tfile);
+
+extern int ttm_buffer_object_create(struct ttm_bo_device *bdev,
+			unsigned long size,
+			enum ttm_bo_type type,
+			uint32_t flags,
+			uint32_t page_alignment,
+			unsigned long buffer_start,
+			bool interruptible,
+			struct file *persistant_swap_storage,
+			struct ttm_buffer_object **p_bo);
+
+extern int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo,
+				struct ttm_placement *placement);
+#endif
diff --git a/drivers/staging/cdv/pvr/COPYING b/drivers/staging/cdv/pvr/COPYING
new file mode 100644
index 0000000..80dd76b
--- /dev/null
+++ b/drivers/staging/cdv/pvr/COPYING
@@ -0,0 +1,351 @@
+
+This software is Copyright (C) 2008 Imagination Technologies Ltd.
+			All rights reserved.
+
+You may use, distribute and copy this software under the terms of
+GNU General Public License version 2, which is displayed below.
+
+-------------------------------------------------------------------------
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+-------------------------------------------------------------------------
+
diff --git a/drivers/staging/cdv/pvr/INSTALL b/drivers/staging/cdv/pvr/INSTALL
new file mode 100644
index 0000000..e4c1069
--- /dev/null
+++ b/drivers/staging/cdv/pvr/INSTALL
@@ -0,0 +1,76 @@
+
+SGX Embedded Systems DDK for the Linux kernel.
+Copyright (C) 2008 Imagination Technologies Ltd. All rights reserved.
+======================================================================
+
+This file covers how to build and install the Imagination Technologies
+SGX DDK for the Linux kernel.
+
+
+Build System Environment Variables
+-------------------------------------------
+
+The SGX DDK Build scripts depend on a number of environment variables
+being setup before compilation or installation of DDK software can
+commence:
+
+$DISCIMAGE
+The DDK Build scripts install files to the location specified by the
+DISCIMAGE environment variable, when the make install target is used.
+This should point to the target filesystem.
+$ export DISCIMAGE=/path/to/filesystem
+
+$KERNELDIR
+When building the SGX DDK kernel module, the build needs access
+to the headers of the Linux kernel
+$ export KERNELDIR=/path/to/kernel
+
+$PATH
+If a cross compiler is being used make sure the PATH environment variable
+includes the path to the toolchain
+$ export PATH=$PATH:/path/to/toolchain
+
+$CROSS_COMPILE
+Since the SGX DDK Build scripts are geared toward a cross-compilation
+workflow, the CROSS_COMPILE environment variable needs to be set
+$ export CROSS_COMPILE=toolchain-prefix-
+
+
+Build and Install Instructions
+-------------------------------------------
+
+The SGX DDK configures different target builds within directories under
+eurasiacon/build/linux/.
+
+The supported build targets are:
+
+	all		Makes everything
+	clean	Removes all intermediate files created by a build.
+	clobber	Removes all binaries for all builds as well.
+	install	Runs the install script generated by the build.
+
+The following variables may be set on the command line to influence a build.
+
+	BUILD	The type of build being performed.
+			Alternatives are release, timing or debug.
+	CFLAGS	Build dependent	optimisations and debug information flags.
+	SILENT	Determines whether text of commands is produced during build.
+
+To build for, change to the appropriate target directory, e.g.:
+$ cd eurasiacon/build/linux/platform/kbuild
+
+Issue the make command:
+$ make BUILD=debug all
+
+The DDK software must be installed by the root user.  Become the root user:
+$ su
+
+Install the DDK software:
+$ make install
+
+Become an ordinary user again:
+$ exit
+
+
+
+
diff --git a/drivers/staging/cdv/pvr/README b/drivers/staging/cdv/pvr/README
new file mode 100644
index 0000000..8039c39
--- /dev/null
+++ b/drivers/staging/cdv/pvr/README
@@ -0,0 +1,48 @@
+
+SGX Embedded Systems DDK for Linux kernel.
+Copyright (C) 2008 Imagination Technologies Ltd. All rights reserved.
+======================================================================
+
+
+About
+-------------------------------------------
+
+This is the Imagination Technologies SGX DDK for the Linux kernel.
+
+
+License
+-------------------------------------------
+
+You may use, distribute and copy this software under the terms of
+GNU General Public License version 2.
+
+The full GNU General Public License version 2 is included in this
+distribution in the file called "COPYING".
+
+
+Build and Install Instructions
+-------------------------------------------
+
+For details see the "INSTALL" file.
+
+To build for, change to the appropriate target directory, e.g.:
+$ cd eurasiacon/build/linux/platform/kbuild
+
+Issue the make command:
+$ make BUILD=debug all
+
+The DDK software must be installed by the root user.  Become the root user:
+$ su
+
+Install the DDK software:
+$ make install
+
+Become an ordinary user again:
+$ exit
+
+
+Contact information:
+-------------------------------------------
+
+Imagination Technologies Ltd. <gpl-support@imgtec.com>
+Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
diff --git a/drivers/staging/cdv/pvr/eurasiacon/.gitignore b/drivers/staging/cdv/pvr/eurasiacon/.gitignore
new file mode 100644
index 0000000..f558f8b
--- /dev/null
+++ b/drivers/staging/cdv/pvr/eurasiacon/.gitignore
@@ -0,0 +1,6 @@
+bin_pc_i686*
+tmp_pc_i686*
+host_pc_i686*
+binary_pc_i686*
+*.o
+*.o.cmd
diff --git a/drivers/staging/cdv/pvr/include4/dbgdrvif.h b/drivers/staging/cdv/pvr/include4/dbgdrvif.h
new file mode 100644
index 0000000..b7614ac
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/dbgdrvif.h
@@ -0,0 +1,328 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _DBGDRVIF_
+#define _DBGDRVIF_
+
+
+#if defined(__linux__)
+
+#define FILE_DEVICE_UNKNOWN             0
+#define METHOD_BUFFERED                 0
+#define FILE_ANY_ACCESS                 0
+
+#define CTL_CODE( DeviceType, Function, Method, Access ) (Function) 
+#define MAKEIOCTLINDEX(i)	((i) & 0xFFF)
+
+#else
+
+#include "ioctldef.h"
+
+#endif
+
+#define DEBUG_CAPMODE_FRAMED			0x00000001UL
+#define DEBUG_CAPMODE_CONTINUOUS		0x00000002UL
+#define DEBUG_CAPMODE_HOTKEY			0x00000004UL
+
+#define DEBUG_OUTMODE_STANDARDDBG		0x00000001UL
+#define DEBUG_OUTMODE_MONO				0x00000002UL
+#define DEBUG_OUTMODE_STREAMENABLE		0x00000004UL
+#define DEBUG_OUTMODE_ASYNC				0x00000008UL
+#define DEBUG_OUTMODE_SGXVGA            0x00000010UL
+
+#define DEBUG_FLAGS_USE_NONPAGED_MEM	0x00000001UL
+#define DEBUG_FLAGS_NO_BUF_EXPANDSION	0x00000002UL
+#define DEBUG_FLAGS_ENABLESAMPLE		0x00000004UL
+#define DEBUG_FLAGS_READONLY			0x00000008UL
+#define DEBUG_FLAGS_WRITEONLY			0x00000010UL
+
+#define DEBUG_FLAGS_TEXTSTREAM			0x80000000UL
+
+#define DEBUG_LEVEL_0					0x00000001UL
+#define DEBUG_LEVEL_1					0x00000003UL
+#define DEBUG_LEVEL_2					0x00000007UL
+#define DEBUG_LEVEL_3					0x0000000FUL
+#define DEBUG_LEVEL_4					0x0000001FUL
+#define DEBUG_LEVEL_5					0x0000003FUL
+#define DEBUG_LEVEL_6					0x0000007FUL
+#define DEBUG_LEVEL_7					0x000000FFUL
+#define DEBUG_LEVEL_8					0x000001FFUL
+#define DEBUG_LEVEL_9					0x000003FFUL
+#define DEBUG_LEVEL_10					0x000007FFUL
+#define DEBUG_LEVEL_11					0x00000FFFUL
+
+#define DEBUG_LEVEL_SEL0				0x00000001UL
+#define DEBUG_LEVEL_SEL1				0x00000002UL
+#define DEBUG_LEVEL_SEL2				0x00000004UL
+#define DEBUG_LEVEL_SEL3				0x00000008UL
+#define DEBUG_LEVEL_SEL4				0x00000010UL
+#define DEBUG_LEVEL_SEL5				0x00000020UL
+#define DEBUG_LEVEL_SEL6				0x00000040UL
+#define DEBUG_LEVEL_SEL7				0x00000080UL
+#define DEBUG_LEVEL_SEL8				0x00000100UL
+#define DEBUG_LEVEL_SEL9				0x00000200UL
+#define DEBUG_LEVEL_SEL10				0x00000400UL
+#define DEBUG_LEVEL_SEL11				0x00000800UL
+
+#define DEBUG_SERVICE_IOCTL_BASE		0x800UL
+#define DEBUG_SERVICE_CREATESTREAM		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_DESTROYSTREAM		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETSTREAM			CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITESTRING		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_READSTRING		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITE				CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_READ				CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETDEBUGMODE		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETDEBUGOUTMODE	CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETDEBUGLEVEL		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0A, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETFRAME			CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0B, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETFRAME			CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0C, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_OVERRIDEMODE		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0D, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_DEFAULTMODE		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0E, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETSERVICETABLE	CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0F, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITE2			CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITESTRINGCM		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x11, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITECM			CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETMARKER			CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x13, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETMARKER			CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_ISCAPTUREFRAME	CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x15, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITELF			CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x16, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_READLF			CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x17, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WAITFOREVENT		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETCONNNOTIFY		CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x19, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+
+typedef enum _DBG_EVENT_
+{
+	DBG_EVENT_STREAM_DATA = 1
+} DBG_EVENT;
+
+
+typedef struct _DBG_IN_CREATESTREAM_
+{
+	union
+	{
+		IMG_CHAR *pszName;
+		IMG_UINT64 ui64Name;
+	} u;
+	IMG_UINT32 ui32Pages;
+	IMG_UINT32 ui32CapMode;
+	IMG_UINT32 ui32OutMode;
+}DBG_IN_CREATESTREAM, *PDBG_IN_CREATESTREAM;
+
+typedef struct _DBG_IN_FINDSTREAM_
+{
+	union
+	{
+		IMG_CHAR *pszName;
+		IMG_UINT64 ui64Name;
+	}u;
+	IMG_BOOL bResetStream;
+}DBG_IN_FINDSTREAM, *PDBG_IN_FINDSTREAM;
+
+typedef struct _DBG_IN_WRITESTRING_
+{
+	union
+	{
+		IMG_CHAR *pszString;
+		IMG_UINT64 ui64String;
+	} u;
+	IMG_SID hStream;
+	IMG_UINT32 ui32Level;
+}DBG_IN_WRITESTRING, *PDBG_IN_WRITESTRING;
+
+typedef struct _DBG_IN_READSTRING_
+{
+	union
+	{
+		IMG_CHAR *pszString;
+		IMG_UINT64 ui64String;
+	} u;
+	IMG_SID hStream;
+	IMG_UINT32 ui32StringLen;
+} DBG_IN_READSTRING, *PDBG_IN_READSTRING;
+
+typedef struct _DBG_IN_SETDEBUGMODE_
+{
+	IMG_SID hStream;
+	IMG_UINT32 ui32Mode;
+	IMG_UINT32 ui32Start;
+	IMG_UINT32 ui32End;
+	IMG_UINT32 ui32SampleRate;
+} DBG_IN_SETDEBUGMODE, *PDBG_IN_SETDEBUGMODE;
+
+typedef struct _DBG_IN_SETDEBUGOUTMODE_
+{
+	IMG_SID hStream;
+	IMG_UINT32 ui32Mode;
+} DBG_IN_SETDEBUGOUTMODE, *PDBG_IN_SETDEBUGOUTMODE;
+
+typedef struct _DBG_IN_SETDEBUGLEVEL_
+{
+	IMG_SID hStream;
+	IMG_UINT32 ui32Level;
+} DBG_IN_SETDEBUGLEVEL, *PDBG_IN_SETDEBUGLEVEL;
+
+typedef struct _DBG_IN_SETFRAME_
+{
+	IMG_SID hStream;
+	IMG_UINT32 ui32Frame;
+} DBG_IN_SETFRAME, *PDBG_IN_SETFRAME;
+
+typedef struct _DBG_IN_WRITE_
+{
+	union
+	{
+		IMG_UINT8 *pui8InBuffer;
+		IMG_UINT64 ui64InBuffer;
+	} u;
+	IMG_SID hStream;
+	IMG_UINT32 ui32Level;
+	IMG_UINT32 ui32TransferSize;
+} DBG_IN_WRITE, *PDBG_IN_WRITE;
+
+typedef struct _DBG_IN_READ_
+{
+	union
+	{
+		IMG_UINT8 *pui8OutBuffer;
+		IMG_UINT64 ui64OutBuffer;
+	} u;
+	IMG_SID hStream;
+	IMG_BOOL bReadInitBuffer;
+	IMG_UINT32 ui32OutBufferSize;
+} DBG_IN_READ, *PDBG_IN_READ;
+
+typedef struct _DBG_IN_OVERRIDEMODE_
+{
+	IMG_SID hStream;
+	IMG_UINT32 ui32Mode;
+} DBG_IN_OVERRIDEMODE, *PDBG_IN_OVERRIDEMODE;
+
+typedef struct _DBG_IN_ISCAPTUREFRAME_
+{
+	IMG_SID hStream;
+	IMG_BOOL bCheckPreviousFrame;
+} DBG_IN_ISCAPTUREFRAME, *PDBG_IN_ISCAPTUREFRAME;
+
+typedef struct _DBG_IN_SETMARKER_
+{
+	IMG_SID hStream;
+	IMG_UINT32 ui32Marker;
+} DBG_IN_SETMARKER, *PDBG_IN_SETMARKER;
+
+typedef struct _DBG_IN_WRITE_LF_
+{
+	union
+	{
+		IMG_UINT8 *pui8InBuffer;
+		IMG_UINT64 ui64InBuffer;
+	} u;
+	IMG_UINT32 ui32Flags;
+	IMG_SID    hStream;
+	IMG_UINT32 ui32Level;
+	IMG_UINT32 ui32BufferSize;
+} DBG_IN_WRITE_LF, *PDBG_IN_WRITE_LF;
+
+#define WRITELF_FLAGS_RESETBUF		0x00000001UL
+
+typedef struct _DBG_STREAM_CONTROL_
+{
+	IMG_BOOL   bInitPhaseComplete;	
+	IMG_UINT32 ui32Flags;			
+
+	IMG_UINT32 ui32CapMode;			
+	IMG_UINT32 ui32OutMode;			
+	IMG_UINT32 ui32DebugLevel;
+	IMG_UINT32 ui32DefaultMode;
+	IMG_UINT32 ui32Start;			
+	IMG_UINT32 ui32End;				
+	IMG_UINT32 ui32Current;			
+	IMG_UINT32 ui32SampleRate;		
+	IMG_UINT32 ui32Reserved;
+} DBG_STREAM_CONTROL, *PDBG_STREAM_CONTROL;
+typedef struct _DBG_STREAM_
+{
+	struct _DBG_STREAM_ *psNext;
+	struct _DBG_STREAM_ *psInitStream;
+	DBG_STREAM_CONTROL *psCtrl;
+	IMG_BOOL   bCircularAllowed;
+	IMG_PVOID  pvBase;
+	IMG_UINT32 ui32Size;
+	IMG_UINT32 ui32RPtr;
+	IMG_UINT32 ui32WPtr;
+	IMG_UINT32 ui32DataWritten;
+	IMG_UINT32 ui32Marker;			
+	IMG_UINT32 ui32InitPhaseWOff;	
+	
+	
+	
+	
+	IMG_CHAR szName[30];		
+} DBG_STREAM,*PDBG_STREAM;
+
+typedef struct _DBGKM_CONNECT_NOTIFIER_
+{
+	IMG_VOID (IMG_CALLCONV *pfnConnectNotifier)		(IMG_VOID);
+} DBGKM_CONNECT_NOTIFIER, *PDBGKM_CONNECT_NOTIFIER;
+
+typedef struct _DBGKM_SERVICE_TABLE_
+{
+	IMG_UINT32 ui32Size;
+	IMG_VOID * 	(IMG_CALLCONV *pfnCreateStream)			(IMG_CHAR * pszName,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32OutMode,IMG_UINT32 ui32Flags,IMG_UINT32 ui32Pages);
+	IMG_VOID 	(IMG_CALLCONV *pfnDestroyStream)		(PDBG_STREAM psStream);
+	IMG_VOID * 	(IMG_CALLCONV *pfnFindStream) 			(IMG_CHAR * pszName, IMG_BOOL bResetInitBuffer);
+	IMG_UINT32 	(IMG_CALLCONV *pfnWriteString) 			(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+	IMG_UINT32 	(IMG_CALLCONV *pfnReadString)			(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit);
+	IMG_UINT32 	(IMG_CALLCONV *pfnWriteBIN)				(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+	IMG_UINT32 	(IMG_CALLCONV *pfnReadBIN)				(PDBG_STREAM psStream,IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBufferSize,IMG_UINT8 *pui8OutBuf);
+	IMG_VOID 	(IMG_CALLCONV *pfnSetCaptureMode)		(PDBG_STREAM psStream,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32Start,IMG_UINT32 ui32Stop,IMG_UINT32 ui32SampleRate);
+	IMG_VOID 	(IMG_CALLCONV *pfnSetOutputMode)		(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode);
+	IMG_VOID 	(IMG_CALLCONV *pfnSetDebugLevel)		(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel);
+	IMG_VOID 	(IMG_CALLCONV *pfnSetFrame)				(PDBG_STREAM psStream,IMG_UINT32 ui32Frame);
+	IMG_UINT32 	(IMG_CALLCONV *pfnGetFrame)				(PDBG_STREAM psStream);
+	IMG_VOID 	(IMG_CALLCONV *pfnOverrideMode)			(PDBG_STREAM psStream,IMG_UINT32 ui32Mode);
+	IMG_VOID 	(IMG_CALLCONV *pfnDefaultMode)			(PDBG_STREAM psStream);
+	IMG_UINT32	(IMG_CALLCONV *pfnDBGDrivWrite2)		(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+	IMG_UINT32 	(IMG_CALLCONV *pfnWriteStringCM)		(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+	IMG_UINT32	(IMG_CALLCONV *pfnWriteBINCM)			(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+	IMG_VOID 	(IMG_CALLCONV *pfnSetMarker)			(PDBG_STREAM psStream,IMG_UINT32 ui32Marker);
+	IMG_UINT32 	(IMG_CALLCONV *pfnGetMarker)			(PDBG_STREAM psStream);
+	IMG_VOID 	(IMG_CALLCONV *pfnStartInitPhase)		(PDBG_STREAM psStream);
+	IMG_VOID 	(IMG_CALLCONV *pfnStopInitPhase)		(PDBG_STREAM psStream);
+	IMG_BOOL 	(IMG_CALLCONV *pfnIsCaptureFrame)		(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame);
+	IMG_UINT32 	(IMG_CALLCONV *pfnWriteLF)				(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags);
+	IMG_UINT32 	(IMG_CALLCONV *pfnReadLF)				(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf);
+	IMG_UINT32 	(IMG_CALLCONV *pfnGetStreamOffset)		(PDBG_STREAM psStream);
+	IMG_VOID	(IMG_CALLCONV *pfnSetStreamOffset)		(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset);
+	IMG_BOOL 	(IMG_CALLCONV *pfnIsLastCaptureFrame)	(PDBG_STREAM psStream);
+	IMG_VOID 	(IMG_CALLCONV *pfnWaitForEvent)			(DBG_EVENT eEvent);
+	IMG_VOID 	(IMG_CALLCONV *pfnSetConnectNotifier)	(DBGKM_CONNECT_NOTIFIER fn_notifier);
+	IMG_UINT32 	(IMG_CALLCONV *pfnWritePersist)			(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+} DBGKM_SERVICE_TABLE, *PDBGKM_SERVICE_TABLE;
+
+
+#endif
diff --git a/drivers/staging/cdv/pvr/include4/img_defs.h b/drivers/staging/cdv/pvr/include4/img_defs.h
new file mode 100644
index 0000000..79a730f
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/img_defs.h
@@ -0,0 +1,121 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined (__IMG_DEFS_H__)
+#define __IMG_DEFS_H__
+
+#include "img_types.h"
+
+typedef		enum	img_tag_TriStateSwitch
+{
+	IMG_ON		=	0x00,
+	IMG_OFF,
+	IMG_IGNORE
+
+} img_TriStateSwitch, * img_pTriStateSwitch;
+
+#define		IMG_SUCCESS				0
+
+#define		IMG_NO_REG				1
+
+#if defined (NO_INLINE_FUNCS)
+	#define	INLINE
+	#define	FORCE_INLINE
+#else
+#if defined (__cplusplus)
+	#define INLINE					inline
+	#define	FORCE_INLINE			inline
+#else
+#if	!defined(INLINE)
+	#define	INLINE					__inline
+#endif
+	#define	FORCE_INLINE			static __inline
+#endif
+#endif
+
+
+#ifndef PVR_UNREFERENCED_PARAMETER
+#define	PVR_UNREFERENCED_PARAMETER(param) (param) = (param)
+#endif
+
+#ifdef __GNUC__
+#define unref__ __attribute__ ((unused))
+#else
+#define unref__
+#endif
+
+#ifndef _TCHAR_DEFINED
+#if defined(UNICODE)
+typedef unsigned short		TCHAR, *PTCHAR, *PTSTR;
+#else	
+typedef char				TCHAR, *PTCHAR, *PTSTR;
+#endif	
+#define _TCHAR_DEFINED
+#endif 
+
+
+			#if defined(__linux__) || defined(__QNXNTO__) || defined(__METAG)
+
+				#define IMG_CALLCONV
+				#define IMG_INTERNAL	__attribute__((visibility("hidden")))
+				#define IMG_EXPORT		__attribute__((visibility("default")))
+				#define IMG_IMPORT
+				#define IMG_RESTRICT	__restrict__
+
+			#else
+					#error("define an OS")
+			#endif
+
+#ifndef IMG_ABORT
+	#define IMG_ABORT()	abort()
+#endif
+
+#ifndef IMG_MALLOC
+	#define IMG_MALLOC(A)		malloc	(A)
+#endif
+
+#ifndef IMG_FREE
+	#define IMG_FREE(A)			free	(A)
+#endif
+
+#define IMG_CONST const
+
+#if defined(__GNUC__)
+#define IMG_FORMAT_PRINTF(x,y)		__attribute__((format(printf,x,y)))
+#else
+#define IMG_FORMAT_PRINTF(x,y)
+#endif
+
+#define  CLEANUP_WITH_POLL		IMG_FALSE
+#define  FORCE_CLEANUP			IMG_TRUE
+
+#if defined (_WIN64)
+#define IMG_UNDEF	(~0ULL)
+#else
+#define IMG_UNDEF	(~0UL)
+#endif
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/include4/img_types.h b/drivers/staging/cdv/pvr/include4/img_types.h
new file mode 100644
index 0000000..2431786
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/img_types.h
@@ -0,0 +1,151 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __IMG_TYPES_H__
+#define __IMG_TYPES_H__
+
+#if !defined(IMG_ADDRSPACE_CPUVADDR_BITS)
+#define IMG_ADDRSPACE_CPUVADDR_BITS		32
+#endif
+
+#if !defined(IMG_ADDRSPACE_PHYSADDR_BITS)
+#define IMG_ADDRSPACE_PHYSADDR_BITS		32
+#endif
+
+typedef unsigned int	IMG_UINT,	*IMG_PUINT;
+typedef signed int		IMG_INT,	*IMG_PINT;
+
+typedef unsigned char	IMG_UINT8,	*IMG_PUINT8;
+typedef unsigned char	IMG_BYTE,	*IMG_PBYTE;
+typedef signed char		IMG_INT8,	*IMG_PINT8;
+typedef char			IMG_CHAR,	*IMG_PCHAR;
+
+typedef unsigned short	IMG_UINT16,	*IMG_PUINT16;
+typedef signed short	IMG_INT16,	*IMG_PINT16;
+#if !defined(IMG_UINT32_IS_ULONG)
+typedef unsigned int	IMG_UINT32,	*IMG_PUINT32;
+typedef signed int		IMG_INT32,	*IMG_PINT32;
+#else
+typedef unsigned long	IMG_UINT32,	*IMG_PUINT32;
+typedef signed long		IMG_INT32,	*IMG_PINT32;
+#endif
+#if !defined(IMG_UINT32_MAX)
+	#define IMG_UINT32_MAX 0xFFFFFFFFUL
+#endif
+
+#if defined(USE_CODE)
+
+typedef unsigned __int64	IMG_UINT64, *IMG_PUINT64;
+typedef __int64				IMG_INT64,  *IMG_PINT64;
+
+#else
+	#if ((defined(LINUX) || defined(__METAG)) || defined(__QNXNTO__))
+		typedef unsigned long long		IMG_UINT64,	*IMG_PUINT64;
+		typedef long long 				IMG_INT64,	*IMG_PINT64;
+	#else
+		#error("define an OS")
+	#endif
+#endif
+
+#if !(defined(LINUX) && defined (__KERNEL__))
+typedef float			IMG_FLOAT,	*IMG_PFLOAT;
+typedef double			IMG_DOUBLE, *IMG_PDOUBLE;
+#endif
+
+typedef	enum tag_img_bool
+{
+	IMG_FALSE		= 0,
+	IMG_TRUE		= 1,
+	IMG_FORCE_ALIGN = 0x7FFFFFFF
+} IMG_BOOL, *IMG_PBOOL;
+
+typedef void            IMG_VOID, *IMG_PVOID;
+
+typedef IMG_INT32       IMG_RESULT;
+
+#if defined(_WIN64)
+	typedef unsigned __int64	IMG_UINTPTR_T;
+	typedef signed __int64		IMG_PTRDIFF_T;
+	typedef IMG_UINT64			IMG_SIZE_T;
+#else
+	typedef unsigned int	IMG_UINTPTR_T;
+	typedef IMG_UINT32		IMG_SIZE_T;
+#endif
+
+typedef IMG_PVOID       IMG_HANDLE;
+
+typedef void**          IMG_HVOID,	* IMG_PHVOID;
+
+#define IMG_NULL        0 
+
+typedef IMG_UINT32      IMG_SID;
+
+typedef IMG_UINT32      IMG_EVENTSID;
+
+#if defined(SUPPORT_SID_INTERFACE)
+	typedef IMG_SID IMG_S_HANDLE;
+#else
+	typedef IMG_HANDLE IMG_S_HANDLE;
+#endif
+
+typedef IMG_PVOID IMG_CPU_VIRTADDR;
+
+typedef struct _IMG_DEV_VIRTADDR
+{
+	
+	IMG_UINT32  uiAddr;
+#define IMG_CAST_TO_DEVVADDR_UINT(var)		(IMG_UINT32)(var)
+	
+} IMG_DEV_VIRTADDR;
+
+typedef IMG_UINT32 IMG_DEVMEM_SIZE_T;
+
+typedef struct _IMG_CPU_PHYADDR
+{
+	
+	IMG_UINTPTR_T uiAddr;
+} IMG_CPU_PHYADDR;
+
+typedef struct _IMG_DEV_PHYADDR
+{
+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
+	
+	IMG_UINTPTR_T uiAddr;
+#else
+	IMG_UINT32 uiAddr;
+	IMG_UINT32 uiHighAddr;
+#endif
+} IMG_DEV_PHYADDR;
+
+typedef struct _IMG_SYS_PHYADDR
+{
+	
+	IMG_UINTPTR_T uiAddr;
+} IMG_SYS_PHYADDR;
+
+#include "img_defs.h"
+
+#endif	
diff --git a/drivers/staging/cdv/pvr/include4/pdumpdefs.h b/drivers/staging/cdv/pvr/include4/pdumpdefs.h
new file mode 100644
index 0000000..193b464
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/pdumpdefs.h
@@ -0,0 +1,108 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined (__PDUMPDEFS_H__)
+#define __PDUMPDEFS_H__
+
+typedef enum _PDUMP_PIXEL_FORMAT_
+{
+	PVRSRV_PDUMP_PIXEL_FORMAT_UNSUPPORTED = 0,
+	PVRSRV_PDUMP_PIXEL_FORMAT_RGB8 = 1,
+	PVRSRV_PDUMP_PIXEL_FORMAT_RGB332 = 2,
+	PVRSRV_PDUMP_PIXEL_FORMAT_KRGB555 = 3,
+	PVRSRV_PDUMP_PIXEL_FORMAT_RGB565 = 4,
+	PVRSRV_PDUMP_PIXEL_FORMAT_ARGB4444 = 5,
+	PVRSRV_PDUMP_PIXEL_FORMAT_ARGB1555 = 6,
+	PVRSRV_PDUMP_PIXEL_FORMAT_RGB888 = 7,
+	PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8888 = 8,
+	PVRSRV_PDUMP_PIXEL_FORMAT_YUV8 = 9,
+	PVRSRV_PDUMP_PIXEL_FORMAT_AYUV4444 = 10,
+	PVRSRV_PDUMP_PIXEL_FORMAT_VY0UY1_8888 = 11,
+	PVRSRV_PDUMP_PIXEL_FORMAT_UY0VY1_8888 = 12,
+	PVRSRV_PDUMP_PIXEL_FORMAT_Y0UY1V_8888 = 13,
+	PVRSRV_PDUMP_PIXEL_FORMAT_Y0VY1U_8888 = 14,
+	PVRSRV_PDUMP_PIXEL_FORMAT_YUV888 = 15,
+	PVRSRV_PDUMP_PIXEL_FORMAT_UYVY10101010 = 16,
+	PVRSRV_PDUMP_PIXEL_FORMAT_VYAUYA8888 = 17,
+	PVRSRV_PDUMP_PIXEL_FORMAT_AYUV8888 = 18,
+	PVRSRV_PDUMP_PIXEL_FORMAT_AYUV2101010 = 19,
+	PVRSRV_PDUMP_PIXEL_FORMAT_YUV101010 = 20,
+	PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y8 = 21,
+	PVRSRV_PDUMP_PIXEL_FORMAT_YUV_IMC2 = 22,
+	PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12 = 23,
+	PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL8 = 24,
+	PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL12 = 25,
+	PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV8 = 26,
+	PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8 = 27,
+	PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y10 = 28,
+	PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV10 = 29,
+	PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV10 = 30,
+	PVRSRV_PDUMP_PIXEL_FORMAT_ABGR8888 = 31,
+	PVRSRV_PDUMP_PIXEL_FORMAT_BGRA8888 = 32,
+	PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8332 = 33,
+	PVRSRV_PDUMP_PIXEL_FORMAT_RGB555 = 34,
+	PVRSRV_PDUMP_PIXEL_FORMAT_F16 = 35,
+	PVRSRV_PDUMP_PIXEL_FORMAT_F32 = 36,
+	PVRSRV_PDUMP_PIXEL_FORMAT_L16 = 37,
+	PVRSRV_PDUMP_PIXEL_FORMAT_L32 = 38,
+	PVRSRV_PDUMP_PIXEL_FORMAT_RGBA8888 = 39,
+	PVRSRV_PDUMP_PIXEL_FORMAT_ABGR4444 = 40,
+	PVRSRV_PDUMP_PIXEL_FORMAT_RGBA4444 = 41,
+	PVRSRV_PDUMP_PIXEL_FORMAT_BGRA4444 = 42,
+	PVRSRV_PDUMP_PIXEL_FORMAT_ABGR1555 = 43,
+	PVRSRV_PDUMP_PIXEL_FORMAT_RGBA5551 = 44,
+	PVRSRV_PDUMP_PIXEL_FORMAT_BGRA5551 = 45,
+	PVRSRV_PDUMP_PIXEL_FORMAT_BGR565 = 46,
+	PVRSRV_PDUMP_PIXEL_FORMAT_A8 = 47,
+	
+	PVRSRV_PDUMP_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff
+
+} PDUMP_PIXEL_FORMAT;
+
+typedef enum _PDUMP_MEM_FORMAT_
+{
+	PVRSRV_PDUMP_MEM_FORMAT_STRIDE = 0,
+	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;
+
+typedef enum _PDUMP_POLL_OPERATOR
+{
+	PDUMP_POLL_OPERATOR_EQUAL = 0,
+	PDUMP_POLL_OPERATOR_LESS = 1,
+	PDUMP_POLL_OPERATOR_LESSEQUAL = 2,
+	PDUMP_POLL_OPERATOR_GREATER = 3,
+	PDUMP_POLL_OPERATOR_GREATEREQUAL = 4,
+	PDUMP_POLL_OPERATOR_NOTEQUAL = 5,
+} PDUMP_POLL_OPERATOR;
+
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/include4/pvr_debug.h b/drivers/staging/cdv/pvr/include4/pvr_debug.h
new file mode 100644
index 0000000..a9d082e
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/pvr_debug.h
@@ -0,0 +1,148 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+******************************************************************************/
+
+#ifndef __PVR_DEBUG_H__
+#define __PVR_DEBUG_H__
+
+
+#include "img_types.h"
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define PVR_MAX_DEBUG_MESSAGE_LEN	(512)
+
+/* These are privately used by pvr_debug, use the PVR_DBG_ defines instead */
+#define DBGPRIV_FATAL		0x01UL
+#define DBGPRIV_ERROR		0x02UL
+#define DBGPRIV_WARNING		0x04UL
+#define DBGPRIV_MESSAGE		0x08UL
+#define DBGPRIV_VERBOSE		0x10UL
+#define DBGPRIV_CALLTRACE	0x20UL
+#define DBGPRIV_ALLOC		0x40UL
+
+#define DBGPRIV_DBGDRV_MESSAGE	0x1000UL
+
+#define DBGPRIV_ALLLEVELS	(DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING | DBGPRIV_MESSAGE | DBGPRIV_VERBOSE)
+
+
+
+#define PVR_DBG_FATAL		DBGPRIV_FATAL,__FILE__, __LINE__
+#define PVR_DBG_ERROR		DBGPRIV_ERROR,__FILE__, __LINE__
+#define PVR_DBG_WARNING		DBGPRIV_WARNING,__FILE__, __LINE__
+#define PVR_DBG_MESSAGE		DBGPRIV_MESSAGE,__FILE__, __LINE__
+#define PVR_DBG_VERBOSE		DBGPRIV_VERBOSE,__FILE__, __LINE__
+#define PVR_DBG_CALLTRACE	DBGPRIV_CALLTRACE,__FILE__, __LINE__
+#define PVR_DBG_ALLOC		DBGPRIV_ALLOC,__FILE__, __LINE__
+
+/*
+ *	Debug driver debugging
+ */
+#define PVR_DBGDRIV_MESSAGE		DBGPRIV_DBGDRV_MESSAGE, "", 0
+
+#if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG)
+#define PVRSRV_NEED_PVR_ASSERT
+#endif
+
+#if defined(PVRSRV_NEED_PVR_ASSERT) && !defined(PVRSRV_NEED_PVR_DPF)
+#define PVRSRV_NEED_PVR_DPF
+#endif
+
+#if !defined(PVRSRV_NEED_PVR_TRACE) && (defined(DEBUG) || defined(TIMING))
+#define PVRSRV_NEED_PVR_TRACE
+#endif
+
+
+/* PVR_ASSERT() and PVR_DBG_BREAK handling */
+
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+
+	#define PVR_ASSERT(EXPR) if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__);
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugAssertFail(const IMG_CHAR *pszFile,
+													   IMG_UINT32 ui32Line);
+
+			#if defined(PVR_DBG_BREAK_ASSERT_FAIL)
+				#define PVR_DBG_BREAK	PVRSRVDebugAssertFail("PVR_DBG_BREAK", 0)
+			#else
+				#define PVR_DBG_BREAK
+			#endif
+
+#else  /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+	#define PVR_ASSERT(EXPR)
+	#define PVR_DBG_BREAK
+
+#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+
+/* PVR_DPF() handling */
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+	#define PVR_DPF(X)		PVRSRVDebugPrintf X
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel,
+												   const IMG_CHAR *pszFileName,
+												   IMG_UINT32 ui32Line,
+												   const IMG_CHAR *pszFormat,
+												   ...) IMG_FORMAT_PRINTF(4, 5);
+
+#else  /* defined(PVRSRV_NEED_PVR_DPF) */
+
+	#define PVR_DPF(X)
+
+#endif /* defined(PVRSRV_NEED_PVR_DPF) */
+
+
+/* PVR_TRACE() handling */
+
+#if defined(PVRSRV_NEED_PVR_TRACE)
+
+	#define PVR_TRACE(X)	PVRSRVTrace X
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... )
+	IMG_FORMAT_PRINTF(1, 2);
+
+#else /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+	#define PVR_TRACE(X)
+
+#endif /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif	/* __PVR_DEBUG_H__ */
+
+/******************************************************************************
+ End of file (pvr_debug.h)
+******************************************************************************/
+
diff --git a/drivers/staging/cdv/pvr/include4/pvrmodule.h b/drivers/staging/cdv/pvr/include4/pvrmodule.h
new file mode 100644
index 0000000..4e36557
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/pvrmodule.h
@@ -0,0 +1,34 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef	_PVRMODULE_H_
+#define	_PVRMODULE_H_
+
+#include <linux/module.h>
+
+MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>");
+MODULE_LICENSE("GPL");
+#endif	
diff --git a/drivers/staging/cdv/pvr/include4/pvrversion.h b/drivers/staging/cdv/pvr/include4/pvrversion.h
new file mode 100644
index 0000000..d0288e3
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/pvrversion.h
@@ -0,0 +1,61 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+ 
+
+
+
+
+
+
+
+ 
+
+#ifndef _PVRVERSION_H_
+#define _PVRVERSION_H_
+
+#define PVR_STR(X) #X
+#define PVR_STR2(X) PVR_STR(X)
+
+#define PVRVERSION_MAJ               1
+#define PVRVERSION_MIN               7
+#define PVRVERSION_BRANCH            17
+
+#define PVRVERSION_FAMILY           "sgxddk"
+#define PVRVERSION_BRANCHNAME       "1.7"
+#define PVRVERSION_BUILD             862890
+#define PVRVERSION_BSCONTROL        "pc_i686_linux_XOrg_family"
+
+#define PVRVERSION_STRING           "pc_i686_linux_XOrg_family sgxddk 17 1.7@" PVR_STR2(PVRVERSION_BUILD)
+#define PVRVERSION_STRING_SHORT     "1.7@" PVR_STR2(PVRVERSION_BUILD)
+
+#define COPYRIGHT_TXT               "Copyright (c) Imagination Technologies Ltd. All Rights Reserved."
+
+#define PVRVERSION_BUILD_HI          86
+#define PVRVERSION_BUILD_LO          2890
+#define PVRVERSION_STRING_NUMERIC    PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO)
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/include4/services.h b/drivers/staging/cdv/pvr/include4/services.h
new file mode 100644
index 0000000..1d786bf
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/services.h
@@ -0,0 +1,1235 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __SERVICES_H__
+#define __SERVICES_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "pdumpdefs.h"
+
+
+#define PVRSRV_4K_PAGE_SIZE		4096UL
+
+#define PVRSRV_MAX_CMD_SIZE		1024
+
+#define PVRSRV_MAX_DEVICES		16	
+
+#define EVENTOBJNAME_MAXLENGTH (50)
+
+#define PVRSRV_MEM_READ						(1U<<0)
+#define PVRSRV_MEM_WRITE					(1U<<1)
+#define PVRSRV_MEM_CACHE_CONSISTENT			(1U<<2)
+#define PVRSRV_MEM_NO_SYNCOBJ				(1U<<3)
+#define PVRSRV_MEM_INTERLEAVED				(1U<<4)
+#define PVRSRV_MEM_DUMMY					(1U<<5)
+#define PVRSRV_MEM_EDM_PROTECT				(1U<<6)
+#define PVRSRV_MEM_ZERO						(1U<<7)
+#define PVRSRV_MEM_USER_SUPPLIED_DEVVADDR	(1U<<8)
+#define PVRSRV_MEM_RAM_BACKED_ALLOCATION	(1U<<9)
+#define PVRSRV_MEM_NO_RESMAN				(1U<<10)
+#define PVRSRV_MEM_EXPORTED					(1U<<11)
+
+
+#define PVRSRV_HAP_CACHED					(1U<<12)
+#define PVRSRV_HAP_UNCACHED					(1U<<13)
+#define PVRSRV_HAP_WRITECOMBINE				(1U<<14)
+#define PVRSRV_HAP_CACHETYPE_MASK			(PVRSRV_HAP_CACHED|PVRSRV_HAP_UNCACHED|PVRSRV_HAP_WRITECOMBINE)
+#define PVRSRV_HAP_KERNEL_ONLY				(1U<<15)
+#define PVRSRV_HAP_SINGLE_PROCESS			(1U<<16)
+#define PVRSRV_HAP_MULTI_PROCESS			(1U<<17)
+#define PVRSRV_HAP_FROM_EXISTING_PROCESS	(1U<<18)
+#define PVRSRV_HAP_NO_CPU_VIRTUAL			(1U<<19)
+#define PVRSRV_HAP_MAPTYPE_MASK				(PVRSRV_HAP_KERNEL_ONLY \
+                                            |PVRSRV_HAP_SINGLE_PROCESS \
+                                            |PVRSRV_HAP_MULTI_PROCESS \
+                                            |PVRSRV_HAP_FROM_EXISTING_PROCESS \
+                                            |PVRSRV_HAP_NO_CPU_VIRTUAL)
+
+#define PVRSRV_MEM_CACHED					PVRSRV_HAP_CACHED
+#define PVRSRV_MEM_UNCACHED					PVRSRV_HAP_UNCACHED
+#define PVRSRV_MEM_WRITECOMBINE				PVRSRV_HAP_WRITECOMBINE
+
+#define PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT	(24)
+
+#define PVRSRV_MAP_NOUSERVIRTUAL            (1UL<<27)
+#define PVRSRV_MEM_XPROC  					(1U<<28)
+
+#define PVRSRV_NO_CONTEXT_LOSS					0		
+#define PVRSRV_SEVERE_LOSS_OF_CONTEXT			1		
+#define PVRSRV_PRE_STATE_CHANGE_MASK			0x80	
+
+
+#define PVRSRV_DEFAULT_DEV_COOKIE			(1)	 
+
+
+#define PVRSRV_MISC_INFO_TIMER_PRESENT				(1U<<0)
+#define PVRSRV_MISC_INFO_CLOCKGATE_PRESENT			(1U<<1)
+#define PVRSRV_MISC_INFO_MEMSTATS_PRESENT			(1U<<2)
+#define PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT	(1U<<3)
+#define PVRSRV_MISC_INFO_DDKVERSION_PRESENT			(1U<<4)
+#define PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT			(1U<<5)
+#define PVRSRV_MISC_INFO_FREEMEM_PRESENT			(1U<<6)
+
+#define PVRSRV_MISC_INFO_RESET_PRESENT				(1U<<31)
+
+#define PVRSRV_PDUMP_MAX_FILENAME_SIZE			20
+#define PVRSRV_PDUMP_MAX_COMMENT_SIZE			200
+
+
+#define PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT		0x00000001
+
+#define PVRSRV_MAPEXTMEMORY_FLAGS_ALTERNATEVA			0x00000001
+#define PVRSRV_MAPEXTMEMORY_FLAGS_PHYSCONTIG			0x00000002
+
+#define PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC			0x00000001
+#define PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC			0x00000002
+
+#define SRV_FLAGS_PERSIST		0x1
+#define SRV_FLAGS_PDUMP_ACTIVE	0x2
+
+#define PVRSRV_PDUMP_FLAGS_CONTINUOUS		0x1
+
+
+typedef enum _PVRSRV_DEVICE_TYPE_
+{
+	PVRSRV_DEVICE_TYPE_UNKNOWN			= 0 ,
+	PVRSRV_DEVICE_TYPE_MBX1				= 1 ,
+	PVRSRV_DEVICE_TYPE_MBX1_LITE		= 2 ,
+
+	PVRSRV_DEVICE_TYPE_M24VA			= 3,
+	PVRSRV_DEVICE_TYPE_MVDA2			= 4,
+	PVRSRV_DEVICE_TYPE_MVED1			= 5,
+	PVRSRV_DEVICE_TYPE_MSVDX			= 6,
+
+	PVRSRV_DEVICE_TYPE_SGX				= 7,
+
+	PVRSRV_DEVICE_TYPE_VGX				= 8,
+
+	PVRSRV_DEVICE_TYPE_TOPAZ			= 9,
+	
+	PVRSRV_DEVICE_TYPE_EXT				= 10,
+
+	PVRSRV_DEVICE_TYPE_LAST             = 10,
+
+	PVRSRV_DEVICE_TYPE_FORCE_I32		= 0x7fffffff
+
+} PVRSRV_DEVICE_TYPE;
+
+#define HEAP_ID( _dev_ , _dev_heap_idx_ )	(  ((_dev_)<<24) | ((_dev_heap_idx_)&((1<<24)-1))  )
+#define HEAP_IDX( _heap_id_ )				( (_heap_id_)&((1<<24) - 1 ) )
+#define HEAP_DEV( _heap_id_ )				( (_heap_id_)>>24 )
+
+#define PVRSRV_UNDEFINED_HEAP_ID			(~0LU)
+
+typedef enum
+{
+	IMG_EGL				= 0x00000001,
+	IMG_OPENGLES1		= 0x00000002,
+	IMG_OPENGLES2		= 0x00000003,
+	IMG_D3DM			= 0x00000004,
+	IMG_SRV_UM			= 0x00000005,
+	IMG_OPENVG			= 0x00000006,
+	IMG_SRVCLIENT		= 0x00000007,
+	IMG_VISTAKMD		= 0x00000008,
+	IMG_VISTA3DNODE		= 0x00000009,
+	IMG_VISTAMVIDEONODE	= 0x0000000A,
+	IMG_VISTAVPBNODE	= 0x0000000B,
+	IMG_OPENGL			= 0x0000000C,
+	IMG_D3D				= 0x0000000D,
+#if defined(SUPPORT_GRAPHICS_HAL) || defined(SUPPORT_COMPOSER_HAL)
+	IMG_ANDROID_HAL		= 0x0000000E,
+#endif
+#if defined(SUPPORT_OPENCL)
+	IMG_OPENCL			= 0x0000000F,
+#endif
+
+} IMG_MODULE_ID;
+
+
+#define APPHINT_MAX_STRING_SIZE	256
+
+typedef enum
+{
+	IMG_STRING_TYPE		= 1,
+	IMG_FLOAT_TYPE		,
+	IMG_UINT_TYPE		,
+	IMG_INT_TYPE		,
+	IMG_FLAG_TYPE
+}IMG_DATA_TYPE;
+
+
+typedef struct _PVRSRV_DEV_DATA_ *PPVRSRV_DEV_DATA;
+
+typedef struct _PVRSRV_DEVICE_IDENTIFIER_
+{
+	PVRSRV_DEVICE_TYPE		eDeviceType;		
+	PVRSRV_DEVICE_CLASS		eDeviceClass;		
+	IMG_UINT32				ui32DeviceIndex;	
+	IMG_CHAR				*pszPDumpDevName;	
+	IMG_CHAR				*pszPDumpRegName;	
+
+} PVRSRV_DEVICE_IDENTIFIER;
+
+
+typedef struct _PVRSRV_CLIENT_DEV_DATA_
+{
+	IMG_UINT32		ui32NumDevices;				
+	PVRSRV_DEVICE_IDENTIFIER asDevID[PVRSRV_MAX_DEVICES];		
+	PVRSRV_ERROR	(*apfnDevConnect[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA);	
+	PVRSRV_ERROR	(*apfnDumpTrace[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA);		
+
+} PVRSRV_CLIENT_DEV_DATA;
+
+
+typedef struct _PVRSRV_CONNECTION_
+{
+	IMG_HANDLE hServices;					
+	IMG_UINT32 ui32ProcessID;				
+	PVRSRV_CLIENT_DEV_DATA	sClientDevData;	
+	IMG_UINT32 ui32SrvFlags;				
+}PVRSRV_CONNECTION;
+
+
+typedef struct _PVRSRV_DEV_DATA_
+{
+	IMG_CONST PVRSRV_CONNECTION	 *psConnection;	
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hDevCookie;				
+#else
+	IMG_HANDLE			hDevCookie;				
+#endif
+
+} PVRSRV_DEV_DATA;
+
+typedef struct _PVRSRV_MEMUPDATE_
+{
+	IMG_UINT32			ui32UpdateAddr;		
+	IMG_UINT32			ui32UpdateVal;		
+} PVRSRV_MEMUPDATE;
+
+typedef struct _PVRSRV_HWREG_
+{
+	IMG_UINT32			ui32RegAddr;	
+	IMG_UINT32			ui32RegVal;		
+} PVRSRV_HWREG;
+
+typedef struct _PVRSRV_MEMBLK_
+{
+	IMG_DEV_VIRTADDR	sDevVirtAddr;			
+	IMG_HANDLE			hOSMemHandle;			
+	IMG_HANDLE			hOSWrapMem;				
+	IMG_HANDLE			hBuffer;				
+	IMG_HANDLE			hResItem;				
+	IMG_SYS_PHYADDR	 	*psIntSysPAddr;
+
+} PVRSRV_MEMBLK;
+
+typedef struct _PVRSRV_KERNEL_MEM_INFO_ *PPVRSRV_KERNEL_MEM_INFO;
+
+typedef struct _PVRSRV_CLIENT_MEM_INFO_
+{
+	
+	IMG_PVOID				pvLinAddr;
+
+	
+	IMG_PVOID				pvLinAddrKM;
+
+	
+	IMG_DEV_VIRTADDR		sDevVAddr;
+
+	
+
+
+
+
+	IMG_CPU_PHYADDR			sCpuPAddr;
+
+	
+	IMG_UINT32				ui32Flags;
+
+	
+
+
+	IMG_UINT32				ui32ClientFlags;
+
+	
+	IMG_SIZE_T				uAllocSize;
+
+
+	
+	struct _PVRSRV_CLIENT_SYNC_INFO_	*psClientSyncInfo;
+
+#if defined (SUPPORT_SID_INTERFACE)
+	
+	IMG_SID								hMappingInfo;
+
+	
+	IMG_SID								hKernelMemInfo;
+
+	
+	IMG_SID								hResItem;
+#else
+	
+	IMG_HANDLE							hMappingInfo;
+
+	
+	IMG_HANDLE							hKernelMemInfo;
+
+	
+	IMG_HANDLE							hResItem;
+#endif
+
+#if defined(SUPPORT_MEMINFO_IDS)
+	#if !defined(USE_CODE)
+	
+	IMG_UINT64							ui64Stamp;
+	#else 
+	IMG_UINT32							dummy1;
+	IMG_UINT32							dummy2;
+	#endif 
+#endif 
+
+	
+
+
+	struct _PVRSRV_CLIENT_MEM_INFO_		*psNext;
+
+} PVRSRV_CLIENT_MEM_INFO, *PPVRSRV_CLIENT_MEM_INFO;
+
+
+#define PVRSRV_MAX_CLIENT_HEAPS (32)
+typedef struct _PVRSRV_HEAP_INFO_
+{
+	IMG_UINT32			ui32HeapID;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID 			hDevMemHeap;
+#else
+	IMG_HANDLE 			hDevMemHeap;
+#endif
+	IMG_DEV_VIRTADDR	sDevVAddrBase;
+	IMG_UINT32			ui32HeapByteSize;
+	IMG_UINT32			ui32Attribs;
+	IMG_UINT32			ui32XTileStride;
+}PVRSRV_HEAP_INFO;
+
+
+
+
+typedef struct _PVRSRV_EVENTOBJECT_
+{
+	
+	IMG_CHAR	szName[EVENTOBJNAME_MAXLENGTH];
+	
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID     hOSEventKM;
+#else
+	IMG_HANDLE	hOSEventKM;
+#endif
+
+} PVRSRV_EVENTOBJECT;
+
+typedef enum
+{
+	PVRSRV_MISC_INFO_CPUCACHEOP_NONE = 0,
+	PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN,
+	PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH
+} PVRSRV_MISC_INFO_CPUCACHEOP_TYPE;
+
+typedef struct _PVRSRV_MISC_INFO_
+{
+	IMG_UINT32	ui32StateRequest;		
+	IMG_UINT32	ui32StatePresent;		
+
+	
+	IMG_VOID	*pvSOCTimerRegisterKM;
+	IMG_VOID	*pvSOCTimerRegisterUM;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hSOCTimerRegisterOSMemHandle;
+	IMG_SID		hSOCTimerRegisterMappingInfo;
+#else
+	IMG_HANDLE	hSOCTimerRegisterOSMemHandle;
+	IMG_HANDLE	hSOCTimerRegisterMappingInfo;
+#endif
+
+	
+	IMG_VOID	*pvSOCClockGateRegs;
+	IMG_UINT32	ui32SOCClockGateRegsSize;
+
+	
+	IMG_CHAR	*pszMemoryStr;
+	IMG_UINT32	ui32MemoryStrLen;
+
+	
+	PVRSRV_EVENTOBJECT	sGlobalEventObject;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_EVENTSID		hOSGlobalEvent;
+#else
+	IMG_HANDLE			hOSGlobalEvent;
+#endif
+
+	
+	IMG_UINT32	aui32DDKVersion[4];
+
+	
+	struct
+	{
+		
+		IMG_BOOL bDeferOp;
+
+		
+		PVRSRV_MISC_INFO_CPUCACHEOP_TYPE eCacheOpType;
+
+		
+#if !defined (SUPPORT_SID_INTERFACE)
+		union
+		{
+			
+			PVRSRV_CLIENT_MEM_INFO *psClientMemInfo;
+
+			
+			struct _PVRSRV_KERNEL_MEM_INFO_ *psKernelMemInfo;
+		} u;
+#endif
+
+		
+		IMG_VOID *pvBaseVAddr;
+
+		
+		IMG_UINT32	ui32Length;
+	} sCacheOpCtl;
+} PVRSRV_MISC_INFO;
+
+typedef struct _PVRSRV_SYNC_TOKEN_
+{
+	
+
+	struct
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		IMG_SID    hKernelSyncInfo;
+#else
+		IMG_HANDLE hKernelSyncInfo;
+#endif
+		IMG_UINT32 ui32ReadOpsPendingSnapshot;
+		IMG_UINT32 ui32WriteOpsPendingSnapshot;
+	} sPrivate;
+} PVRSRV_SYNC_TOKEN;
+
+
+typedef enum _PVRSRV_CLIENT_EVENT_
+{
+	PVRSRV_CLIENT_EVENT_HWTIMEOUT = 0,
+} PVRSRV_CLIENT_EVENT;
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVClientEvent(IMG_CONST PVRSRV_CLIENT_EVENT eEvent,
+											PVRSRV_DEV_DATA *psDevData,
+											IMG_PVOID pvData);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVConnect(PVRSRV_CONNECTION **ppsConnection, IMG_UINT32 ui32SrvFlags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDisconnect(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevices(IMG_CONST PVRSRV_CONNECTION 			*psConnection,
+													IMG_UINT32 					*puiNumDevices,
+													PVRSRV_DEVICE_IDENTIFIER 	*puiDevIDs);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceData(IMG_CONST PVRSRV_CONNECTION 	*psConnection,
+													IMG_UINT32			uiDevIndex,
+													PVRSRV_DEV_DATA		*psDevData,
+													PVRSRV_DEVICE_TYPE	eDeviceType);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo);
+
+#if 1
+IMG_IMPORT
+IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+
+IMG_IMPORT
+IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
+
+IMG_IMPORT IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVPollForValue ( const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+							IMG_SID    hOSEvent,
+#else
+							IMG_HANDLE hOSEvent,
+#endif
+							volatile IMG_UINT32 *pui32LinMemAddr,
+							IMG_UINT32 ui32Value,
+							IMG_UINT32 ui32Mask,
+							IMG_UINT32 ui32Waitus,
+							IMG_UINT32 ui32Tries);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+											IMG_SID    *phDevMemContext,
+#else
+											IMG_HANDLE *phDevMemContext,
+#endif
+											IMG_UINT32 *pui32SharedHeapCount,
+											PVRSRV_HEAP_INFO *psHeapInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+											IMG_SID 			hDevMemContext);
+#else
+											IMG_HANDLE 			hDevMemContext);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+											IMG_SID     hDevMemContext,
+#else
+											IMG_HANDLE hDevMemContext,
+#endif
+											IMG_UINT32 *pui32SharedHeapCount,
+											PVRSRV_HEAP_INFO *psHeapInfo);
+
+#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
+	#define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
+		(PVR_TRACE(("PVRSRVAllocDeviceMem(" #psDevData "," #hDevMemHeap "," #ui32Attribs "," #ui32Size "," #ui32Alignment "," #ppsMemInfo ")" \
+			": " logStr " (size = 0x%lx)", ui32Size)), \
+		PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo))
+#else
+	#define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
+		PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo)
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem(IMG_CONST PVRSRV_DEV_DATA	*psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+									IMG_SID			hDevMemHeap,
+#else
+									IMG_HANDLE		hDevMemHeap,
+#endif
+									IMG_UINT32		ui32Attribs,
+									IMG_SIZE_T		ui32Size,
+									IMG_SIZE_T		ui32Alignment,
+									PVRSRV_CLIENT_MEM_INFO	**ppsMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMem(IMG_CONST PVRSRV_DEV_DATA	*psDevData,
+								PVRSRV_CLIENT_MEM_INFO		*psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem(IMG_CONST PVRSRV_DEV_DATA	*psDevData,
+												PVRSRV_CLIENT_MEM_INFO		*psMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+												IMG_SID						*phMemInfo);
+#else
+												IMG_HANDLE					*phMemInfo);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+											IMG_SID				hDevMemHeap,
+#else
+											IMG_HANDLE			hDevMemHeap,
+#endif
+											IMG_DEV_VIRTADDR	*psDevVAddr,
+											IMG_SIZE_T			ui32Size,
+											IMG_SIZE_T			ui32Alignment,
+											PVRSRV_CLIENT_MEM_INFO		**ppsMemInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+													PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+									IMG_SID hKernelMemInfo,
+									IMG_SID hDstDevMemHeap,
+#else
+									IMG_HANDLE hKernelMemInfo,
+									IMG_HANDLE hDstDevMemHeap,
+#endif
+									PVRSRV_CLIENT_MEM_INFO **ppsDstMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+										PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapExtMemory (IMG_CONST PVRSRV_DEV_DATA	*psDevData,
+									PVRSRV_CLIENT_MEM_INFO		*psMemInfo,
+									IMG_SYS_PHYADDR				*psSysPAddr,
+									IMG_UINT32					ui32Flags);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+									PVRSRV_CLIENT_MEM_INFO		*psMemInfo,
+									IMG_UINT32					ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemory(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+												IMG_SID					hDevMemContext,
+#else
+												IMG_HANDLE				hDevMemContext,
+#endif
+												IMG_SIZE_T 				ui32ByteSize,
+												IMG_SIZE_T				ui32PageOffset,
+												IMG_BOOL				bPhysContig,
+												IMG_SYS_PHYADDR	 		*psSysPAddr,
+												IMG_VOID 				*pvLinAddr,
+												IMG_UINT32				ui32Flags,
+												PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+												PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+
+PVRSRV_ERROR PVRSRVChangeDeviceMemoryAttributes(IMG_CONST PVRSRV_DEV_DATA			*psDevData,
+												PVRSRV_CLIENT_MEM_INFO	*psClientMemInfo,
+												IMG_UINT32				ui32Attribs);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+										IMG_SID hDevMemContext,
+										IMG_SID hDeviceClassBuffer,
+#else
+										IMG_HANDLE hDevMemContext,
+										IMG_HANDLE hDeviceClassBuffer,
+#endif
+										PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+										PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+									  IMG_SYS_PHYADDR sSysPhysAddr,
+									  IMG_UINT32 uiSizeInBytes,
+									  IMG_PVOID *ppvUserAddr,
+									  IMG_UINT32 *puiActualSize,
+									  IMG_PVOID *ppvProcess);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+										IMG_PVOID pvUserAddr,
+										IMG_PVOID pvProcess);
+
+#if defined(LINUX)
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem2(IMG_CONST PVRSRV_DEV_DATA	*psDevData,
+												 PVRSRV_CLIENT_MEM_INFO		*psMemInfo,
+												 IMG_INT					*iFd);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory2(IMG_CONST PVRSRV_DEV_DATA	*psDevData,
+												 IMG_INT					iFd,
+#if defined (SUPPORT_SID_INTERFACE)
+												 IMG_SID					hDstDevMemHeap,
+#else
+												 IMG_HANDLE					hDstDevMemHeap,
+#endif
+												 PVRSRV_CLIENT_MEM_INFO		**ppsDstMemInfo);
+#endif 
+
+typedef enum _PVRSRV_SYNCVAL_MODE_
+{
+	PVRSRV_SYNCVAL_READ				= IMG_TRUE,
+	PVRSRV_SYNCVAL_WRITE			= IMG_FALSE,
+
+} PVRSRV_SYNCVAL_MODE, *PPVRSRV_SYNCVAL_MODE;
+
+typedef IMG_UINT32 PVRSRV_SYNCVAL;
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+	PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+	PVRSRV_SYNCVAL_MODE eMode);
+
+IMG_IMPORT IMG_BOOL PVRSRVTestOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+	PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
+
+IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+	PVRSRV_SYNCVAL_MODE eMode);
+
+IMG_IMPORT IMG_BOOL PVRSRVTestOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+	PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
+
+IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+	PVRSRV_SYNCVAL_MODE eMode);
+
+IMG_IMPORT PVRSRV_SYNCVAL PVRSRVGetPendingOpSyncVal(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+	PVRSRV_SYNCVAL_MODE eMode);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDeviceClass(IMG_CONST PVRSRV_CONNECTION *psConnection,
+													PVRSRV_DEVICE_CLASS DeviceClass,
+													IMG_UINT32 *pui32DevCount,
+													IMG_UINT32 *pui32DevID);
+
+IMG_IMPORT
+IMG_HANDLE IMG_CALLCONV PVRSRVOpenDCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+											IMG_UINT32 ui32DeviceID);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseDCDevice(IMG_CONST PVRSRV_CONNECTION	*psConnection, IMG_HANDLE hDevice);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCFormats (IMG_HANDLE hDevice,
+											IMG_UINT32		*pui32Count,
+											DISPLAY_FORMAT	*psFormat);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCDims (IMG_HANDLE hDevice,
+										IMG_UINT32 		*pui32Count,
+										DISPLAY_FORMAT	*psFormat,
+										DISPLAY_DIMS	*psDims);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCSystemBuffer(IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+										IMG_SID *phBuffer);
+#else
+										IMG_HANDLE *phBuffer);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCInfo(IMG_HANDLE hDevice,
+										DISPLAY_INFO* psDisplayInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDCSwapChain (IMG_HANDLE				hDevice,
+													IMG_UINT32				ui32Flags,
+													DISPLAY_SURF_ATTRIBUTES	*psDstSurfAttrib,
+													DISPLAY_SURF_ATTRIBUTES	*psSrcSurfAttrib,
+													IMG_UINT32				ui32BufferCount,
+													IMG_UINT32				ui32OEMFlags,
+													IMG_UINT32				*pui32SwapChainID,
+#if defined (SUPPORT_SID_INTERFACE)
+													IMG_SID					*phSwapChain);
+#else
+													IMG_HANDLE				*phSwapChain);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDCSwapChain (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+											IMG_SID hSwapChain);
+#else
+											IMG_HANDLE		hSwapChain);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstRect (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+										IMG_SID		hSwapChain,
+#else
+										IMG_HANDLE	hSwapChain,
+#endif
+										IMG_RECT	*psDstRect);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcRect (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+										IMG_SID		hSwapChain,
+#else
+										IMG_HANDLE	hSwapChain,
+#endif
+										IMG_RECT	*psSrcRect);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstColourKey (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+											IMG_SID		hSwapChain,
+#else
+											IMG_HANDLE	hSwapChain,
+#endif
+											IMG_UINT32	ui32CKColour);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcColourKey (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+											IMG_SID		hSwapChain,
+#else
+											IMG_HANDLE	hSwapChain,
+#endif
+											IMG_UINT32	ui32CKColour);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers(IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+									IMG_SID     hSwapChain,
+									IMG_SID    *phBuffer);
+#else
+									IMG_HANDLE hSwapChain,
+									IMG_HANDLE *phBuffer);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+										IMG_SID    hBuffer,
+#else
+										IMG_HANDLE hBuffer,
+#endif
+										IMG_UINT32 ui32ClipRectCount,
+										IMG_RECT  *psClipRect,
+										IMG_UINT32 ui32SwapInterval,
+#if defined (SUPPORT_SID_INTERFACE)
+										IMG_SID hPrivateTag);
+#else
+										IMG_HANDLE hPrivateTag);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCSystem (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+										IMG_SID hSwapChain);
+#else
+										IMG_HANDLE hSwapChain);
+#endif
+
+
+IMG_IMPORT
+IMG_HANDLE IMG_CALLCONV PVRSRVOpenBCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+											IMG_UINT32 ui32DeviceID);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseBCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection,
+												IMG_HANDLE hDevice);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBufferInfo(IMG_HANDLE hDevice,
+												BUFFER_INFO	*psBuffer);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBuffer(IMG_HANDLE hDevice,
+												IMG_UINT32 ui32BufferIndex,
+#if defined (SUPPORT_SID_INTERFACE)
+												IMG_SID   *phBuffer);
+#else
+												IMG_HANDLE *phBuffer);
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpInit(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStartInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStopInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+										  IMG_SID    hKernelMemInfo,
+#else
+										  PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+#endif										  
+										  IMG_UINT32 ui32Offset,
+										  IMG_UINT32 ui32Value,
+										  IMG_UINT32 ui32Mask,
+										  PDUMP_POLL_OPERATOR eOperator,
+										  IMG_UINT32 ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+											 IMG_SID    hKernelSyncInfo,
+#else
+											 PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+#endif
+											 IMG_BOOL   bIsRead,
+											 IMG_UINT32 ui32Value,
+											 IMG_UINT32 ui32Mask);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol2(IMG_CONST PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+											 IMG_SID  hKernelSyncInfo,
+#else
+											 PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+#endif
+											 IMG_BOOL bIsRead);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMem(IMG_CONST PVRSRV_CONNECTION *psConnection,
+									IMG_PVOID pvAltLinAddr,
+									PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+									IMG_UINT32 ui32Offset,
+									IMG_UINT32 ui32Bytes,
+									IMG_UINT32 ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSync(IMG_CONST PVRSRV_CONNECTION *psConnection,
+										IMG_PVOID pvAltLinAddr,
+										PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+										IMG_UINT32 ui32Offset,
+										IMG_UINT32 ui32Bytes);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpReg(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+										 IMG_CHAR *pszRegRegion,
+											IMG_UINT32 ui32RegAddr,
+											IMG_UINT32 ui32RegValue,
+											IMG_UINT32 ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPolWithFlags(const PVRSRV_DEV_DATA *psDevData,
+													 IMG_CHAR *pszRegRegion,
+													 IMG_UINT32 ui32RegAddr,
+													 IMG_UINT32 ui32RegValue,
+													 IMG_UINT32 ui32Mask,
+													 IMG_UINT32 ui32Flags);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPol(const PVRSRV_DEV_DATA *psDevData,
+											IMG_CHAR *pszRegRegion,
+											IMG_UINT32 ui32RegAddr,
+											IMG_UINT32 ui32RegValue,
+											IMG_UINT32 ui32Mask);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDReg(IMG_CONST PVRSRV_CONNECTION *psConnection,
+											IMG_UINT32 ui32RegAddr,
+											IMG_UINT32 ui32RegValue);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDDevPAddr(IMG_CONST PVRSRV_CONNECTION *psConnection,
+												PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+												IMG_UINT32 ui32Offset,
+												IMG_DEV_PHYADDR sPDDevPAddr);
+
+#if !defined(USE_CODE)
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPages(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+														   IMG_SID				hKernelMemInfo,
+#else
+														   IMG_HANDLE			hKernelMemInfo,
+#endif
+														   IMG_DEV_PHYADDR		*pPages,
+														   IMG_UINT32			ui32NumPages,
+												   		   IMG_DEV_VIRTADDR		sDevVAddr,
+														   IMG_UINT32			ui32Start,
+														   IMG_UINT32			ui32Length,
+														   IMG_UINT32			ui32Flags);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSetFrame(IMG_CONST PVRSRV_CONNECTION *psConnection,
+											  IMG_UINT32 ui32Frame);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpComment(IMG_CONST PVRSRV_CONNECTION *psConnection,
+											 IMG_CONST IMG_CHAR *pszComment,
+											 IMG_BOOL bContinuous);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentf(IMG_CONST PVRSRV_CONNECTION *psConnection,
+											  IMG_BOOL bContinuous,
+											  IMG_CONST IMG_CHAR *pszFormat, ...)
+#if !defined(USE_CODE)
+											  IMG_FORMAT_PRINTF(3, 4)
+#endif
+;
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentWithFlagsf(IMG_CONST PVRSRV_CONNECTION *psConnection,
+													   IMG_UINT32 ui32Flags,
+													   IMG_CONST IMG_CHAR *pszFormat, ...)
+#if !defined(USE_CODE)
+													   IMG_FORMAT_PRINTF(3, 4)
+#endif
+;
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpDriverInfo(IMG_CONST PVRSRV_CONNECTION *psConnection,
+								 				IMG_CHAR *pszString,
+												IMG_BOOL bContinuous);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpIsCapturing(IMG_CONST PVRSRV_CONNECTION *psConnection,
+								 				IMG_BOOL *pbIsCapturing);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpBitmap(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+								 			IMG_CHAR *pszFileName,
+											IMG_UINT32 ui32FileOffset,
+											IMG_UINT32 ui32Width,
+											IMG_UINT32 ui32Height,
+											IMG_UINT32 ui32StrideInBytes,
+											IMG_DEV_VIRTADDR sDevBaseAddr,
+#if defined (SUPPORT_SID_INTERFACE)
+											IMG_SID    hDevMemContext,
+#else
+											IMG_HANDLE hDevMemContext,
+#endif
+											IMG_UINT32 ui32Size,
+											PDUMP_PIXEL_FORMAT ePixelFormat,
+											PDUMP_MEM_FORMAT eMemFormat,
+											IMG_UINT32 ui32PDumpFlags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegRead(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+											IMG_CONST IMG_CHAR *pszRegRegion,
+								 			IMG_CONST IMG_CHAR *pszFileName,
+											IMG_UINT32 ui32FileOffset,
+											IMG_UINT32 ui32Address,
+											IMG_UINT32 ui32Size,
+											IMG_UINT32 ui32PDumpFlags);
+
+
+IMG_IMPORT
+IMG_BOOL IMG_CALLCONV PVRSRVPDumpIsCapturingTest(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCycleCountRegRead(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+														IMG_UINT32 ui32RegOffset,
+														IMG_BOOL bLastFrame);
+
+IMG_IMPORT IMG_HANDLE	PVRSRVLoadLibrary(const IMG_CHAR *pszLibraryName);
+IMG_IMPORT PVRSRV_ERROR	PVRSRVUnloadLibrary(IMG_HANDLE hExtDrv);
+IMG_IMPORT PVRSRV_ERROR	PVRSRVGetLibFuncAddr(IMG_HANDLE hExtDrv, const IMG_CHAR *pszFunctionName, IMG_VOID **ppvFuncAddr);
+
+IMG_IMPORT IMG_UINT32 PVRSRVClockus (void);
+IMG_IMPORT IMG_VOID PVRSRVWaitus (IMG_UINT32 ui32Timeus);
+IMG_IMPORT IMG_VOID PVRSRVReleaseThreadQuanta (void);
+IMG_IMPORT IMG_UINT32 IMG_CALLCONV PVRSRVGetCurrentProcessID(void);
+IMG_IMPORT IMG_CHAR * IMG_CALLCONV PVRSRVSetLocale(const IMG_CHAR *pszLocale);
+
+
+
+
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVCreateAppHintState(IMG_MODULE_ID eModuleID,
+														const IMG_CHAR *pszAppName,
+														IMG_VOID **ppvState);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeAppHintState(IMG_MODULE_ID eModuleID,
+										 IMG_VOID *pvHintState);
+
+IMG_IMPORT IMG_BOOL IMG_CALLCONV PVRSRVGetAppHint(IMG_VOID			*pvHintState,
+												  const IMG_CHAR	*pszHintName,
+												  IMG_DATA_TYPE		eDataType,
+												  const IMG_VOID	*pvDefault,
+												  IMG_VOID			*pvReturn);
+
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMem (IMG_SIZE_T ui32Size);
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMem (IMG_SIZE_T ui32Size);
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMem (IMG_PVOID pvBase, IMG_SIZE_T uNewSize);
+IMG_IMPORT IMG_VOID  IMG_CALLCONV PVRSRVFreeUserModeMem (IMG_PVOID pvMem);
+IMG_IMPORT IMG_VOID PVRSRVMemCopy(IMG_VOID *pvDst, const IMG_VOID *pvSrc, IMG_SIZE_T ui32Size);
+IMG_IMPORT IMG_VOID PVRSRVMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
+
+struct _PVRSRV_MUTEX_OPAQUE_STRUCT_;
+typedef	struct  _PVRSRV_MUTEX_OPAQUE_STRUCT_ *PVRSRV_MUTEX_HANDLE;
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex);
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex);
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockProcessGlobalMutex(void);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockProcessGlobalMutex(void);
+
+
+struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_;
+typedef	struct  _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_ *PVRSRV_SEMAPHORE_HANDLE;
+
+
+  	#define IMG_SEMAPHORE_WAIT_INFINITE       ((IMG_UINT64)0xFFFFFFFFFFFFFFFFull)
+
+
+#if !defined(USE_CODE)
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVCreateSemaphore)
+#endif
+static INLINE PVRSRV_ERROR PVRSRVCreateSemaphore(PVRSRV_SEMAPHORE_HANDLE *phSemaphore, IMG_INT iInitialCount)
+{
+	PVR_UNREFERENCED_PARAMETER(iInitialCount);
+	*phSemaphore = 0;
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVDestroySemaphore)
+#endif
+static INLINE PVRSRV_ERROR PVRSRVDestroySemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore)
+{
+	PVR_UNREFERENCED_PARAMETER(hSemaphore);
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVWaitSemaphore)
+#endif
+static INLINE PVRSRV_ERROR PVRSRVWaitSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_UINT64 ui64TimeoutMicroSeconds)
+{
+	PVR_UNREFERENCED_PARAMETER(hSemaphore);
+	PVR_UNREFERENCED_PARAMETER(ui64TimeoutMicroSeconds);
+	return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPostSemaphore)
+#endif
+static INLINE IMG_VOID PVRSRVPostSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_INT iPostCount)
+{
+	PVR_UNREFERENCED_PARAMETER(hSemaphore);
+	PVR_UNREFERENCED_PARAMETER(iPostCount);
+}
+
+#endif 
+
+
+#if (defined(DEBUG) && (defined(__linux__) || defined(__QNXNTO__)))
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
+
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
+
+IMG_IMPORT IMG_VOID  IMG_CALLCONV PVRSRVFreeUserModeMemTracking(IMG_VOID *pvMem);
+
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_SIZE_T ui32NewSize, 
+													  IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
+#endif 
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVEventObjectWait(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+									IMG_EVENTSID hOSEvent);
+#else
+									IMG_HANDLE hOSEvent);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateSyncInfoModObj(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+													 IMG_SID *phKernelSyncInfoModObj);
+#else
+													 IMG_HANDLE *phKernelSyncInfoModObj);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroySyncInfoModObj(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+													  IMG_SID hKernelSyncInfoModObj);
+#else
+													  IMG_HANDLE hKernelSyncInfoModObj);
+#endif
+
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyPendingSyncOps(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+													  IMG_SID    hKernelSyncInfoModObj,
+#else
+													  IMG_HANDLE hKernelSyncInfoModObj,
+#endif
+													  PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
+													  IMG_UINT32 ui32ModifyFlags,
+													  IMG_UINT32 *pui32ReadOpsPending,
+													  IMG_UINT32 *pui32WriteOpsPending);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyCompleteSyncOps(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+													  IMG_SID hKernelSyncInfoModObj);
+#else
+													  IMG_HANDLE hKernelSyncInfoModObj);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsTakeToken(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+												 const IMG_SID      hKernelSyncInfo,
+#else
+												 const PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
+#endif
+												 PVRSRV_SYNC_TOKEN *psSyncToken);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToToken(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+													const IMG_SID            hKernelSyncInfo,
+#else
+													const PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
+#endif
+													const PVRSRV_SYNC_TOKEN *psSyncToken,
+													IMG_BOOL bWait);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToModObj(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+													 IMG_SID  hKernelSyncInfoModObj,
+#else
+													 IMG_HANDLE hKernelSyncInfoModObj,
+#endif
+													 IMG_BOOL bWait);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToDelta(const PVRSRV_CONNECTION *psConnection,
+													PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+													IMG_UINT32 ui32Delta,
+													IMG_BOOL bWait);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfo(IMG_CONST PVRSRV_DEV_DATA	*psDevData,
+											  PVRSRV_CLIENT_SYNC_INFO **ppsSyncInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+											 PVRSRV_CLIENT_SYNC_INFO *psSyncInfo);
+
+IMG_IMPORT
+const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCacheInvalidate(const PVRSRV_CONNECTION *psConnection,
+                                                IMG_PVOID pvLinearAddress,
+	                                            IMG_UINT32 ui32Size);
+
+#define TIME_NOT_PASSED_UINT32(a,b,c)		(((a) - (b)) < (c))
+
+#if defined (__cplusplus)
+}
+#endif
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/include4/servicesext.h b/drivers/staging/cdv/pvr/include4/servicesext.h
new file mode 100644
index 0000000..54dd4d9
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/servicesext.h
@@ -0,0 +1,846 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined (__SERVICESEXT_H__)
+#define __SERVICESEXT_H__
+
+#define PVRSRV_LOCKFLG_READONLY     	(1)		
+
+typedef enum _PVRSRV_ERROR_
+{
+	PVRSRV_OK = 0,
+	PVRSRV_ERROR_OUT_OF_MEMORY,
+	PVRSRV_ERROR_TOO_FEW_BUFFERS,
+	PVRSRV_ERROR_INVALID_PARAMS,
+	PVRSRV_ERROR_INIT_FAILURE,
+	PVRSRV_ERROR_CANT_REGISTER_CALLBACK,
+	PVRSRV_ERROR_INVALID_DEVICE,
+	PVRSRV_ERROR_NOT_OWNER,
+	PVRSRV_ERROR_BAD_MAPPING,
+	PVRSRV_ERROR_TIMEOUT,
+	PVRSRV_ERROR_FLIP_CHAIN_EXISTS,
+	PVRSRV_ERROR_INVALID_SWAPINTERVAL,
+	PVRSRV_ERROR_SCENE_INVALID,
+	PVRSRV_ERROR_STREAM_ERROR,
+	PVRSRV_ERROR_FAILED_DEPENDENCIES,
+	PVRSRV_ERROR_CMD_NOT_PROCESSED,
+	PVRSRV_ERROR_CMD_TOO_BIG,
+	PVRSRV_ERROR_DEVICE_REGISTER_FAILED,
+	PVRSRV_ERROR_TOOMANYBUFFERS,
+	PVRSRV_ERROR_NOT_SUPPORTED,
+	PVRSRV_ERROR_PROCESSING_BLOCKED,
+
+	PVRSRV_ERROR_CANNOT_FLUSH_QUEUE,
+	PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE,
+	PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS,
+	PVRSRV_ERROR_RETRY,
+
+	PVRSRV_ERROR_DDK_VERSION_MISMATCH,
+	PVRSRV_ERROR_BUILD_MISMATCH,
+	PVRSRV_ERROR_CORE_REVISION_MISMATCH,
+
+	PVRSRV_ERROR_UPLOAD_TOO_BIG,
+
+	PVRSRV_ERROR_INVALID_FLAGS,
+	PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS,
+
+	PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY,
+	PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR,
+	PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED,
+
+	PVRSRV_ERROR_BRIDGE_CALL_FAILED,
+	PVRSRV_ERROR_IOCTL_CALL_FAILED,
+
+    PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND,
+	PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND,
+	PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT,
+
+	PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND,
+	PVRSRV_ERROR_PCI_CALL_FAILED,
+	PVRSRV_ERROR_PCI_REGION_TOO_SMALL,
+	PVRSRV_ERROR_PCI_REGION_UNAVAILABLE,
+	PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH,
+
+	PVRSRV_ERROR_REGISTER_BASE_NOT_SET,
+
+    PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE,
+
+	PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM,
+	PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY,
+	PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC,
+	PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR,
+
+	PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY,
+	PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY,
+
+	PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES,
+	PVRSRV_ERROR_FAILED_TO_FREE_PAGES,
+	PVRSRV_ERROR_FAILED_TO_COPY_PAGES,
+	PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES,
+	PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES,
+	PVRSRV_ERROR_STILL_MAPPED,
+	PVRSRV_ERROR_MAPPING_NOT_FOUND,
+	PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT,
+	PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE,
+
+	PVRSRV_ERROR_INVALID_SEGMENT_BLOCK,
+	PVRSRV_ERROR_INVALID_SGXDEVDATA,
+	PVRSRV_ERROR_INVALID_DEVINFO,
+	PVRSRV_ERROR_INVALID_MEMINFO,
+	PVRSRV_ERROR_INVALID_MISCINFO,
+	PVRSRV_ERROR_UNKNOWN_IOCTL,
+	PVRSRV_ERROR_INVALID_CONTEXT,
+	PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT,
+	PVRSRV_ERROR_INVALID_HEAP,
+	PVRSRV_ERROR_INVALID_KERNELINFO,
+	PVRSRV_ERROR_UNKNOWN_POWER_STATE,
+	PVRSRV_ERROR_INVALID_HANDLE_TYPE,
+	PVRSRV_ERROR_INVALID_WRAP_TYPE,
+	PVRSRV_ERROR_INVALID_PHYS_ADDR,
+	PVRSRV_ERROR_INVALID_CPU_ADDR,
+	PVRSRV_ERROR_INVALID_HEAPINFO,
+	PVRSRV_ERROR_INVALID_PERPROC,
+	PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO,
+	PVRSRV_ERROR_INVALID_MAP_REQUEST,
+	PVRSRV_ERROR_INVALID_UNMAP_REQUEST,
+	PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP,
+	PVRSRV_ERROR_MAPPING_STILL_IN_USE,
+
+	PVRSRV_ERROR_EXCEEDED_HW_LIMITS,
+	PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED,
+
+	PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA,
+	PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT,
+	PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT,
+	PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT,
+	PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT,
+	PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD,
+	PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD,
+	PVRSRV_ERROR_THREAD_READ_ERROR,
+	PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER,
+	PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR,
+	PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR,
+	PVRSRV_ERROR_ISR_ALREADY_INSTALLED,
+	PVRSRV_ERROR_ISR_NOT_INSTALLED,
+	PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT,
+	PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO,
+	PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT,
+	PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES,
+	PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT,
+	PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE,
+	PVRSRV_ERROR_UNABLE_TO_CLOSE_HANDLE,
+
+	PVRSRV_ERROR_INVALID_CCB_COMMAND,
+
+	PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE,
+	PVRSRV_ERROR_INVALID_LOCK_ID,
+	PVRSRV_ERROR_RESOURCE_NOT_LOCKED,
+
+	PVRSRV_ERROR_FLIP_FAILED,
+	PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED,
+
+	PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE,
+
+	PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED,
+	PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG,
+	PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG,
+	PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG,
+
+	PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID,
+
+	PVRSRV_ERROR_BLIT_SETUP_FAILED,
+
+	PVRSRV_ERROR_PDUMP_NOT_AVAILABLE,
+	PVRSRV_ERROR_PDUMP_BUFFER_FULL,
+	PVRSRV_ERROR_PDUMP_BUF_OVERFLOW,
+	PVRSRV_ERROR_PDUMP_NOT_ACTIVE,
+	PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES,
+
+	PVRSRV_ERROR_MUTEX_DESTROY_FAILED,
+	PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR,
+
+	PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE,
+	PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND,
+
+	PVRSRV_ERROR_PROCESS_NOT_INITIALISED,
+	PVRSRV_ERROR_PROCESS_NOT_FOUND,
+	PVRSRV_ERROR_SRV_CONNECT_FAILED,
+	PVRSRV_ERROR_SRV_DISCONNECT_FAILED,
+	PVRSRV_ERROR_DEINT_PHASE_FAILED,
+	PVRSRV_ERROR_INIT2_PHASE_FAILED,
+
+	PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE,
+
+	PVRSRV_ERROR_NO_DC_DEVICES_FOUND,
+	PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE,
+	PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE,
+	PVRSRV_ERROR_NO_DEVICEDATA_FOUND,
+	PVRSRV_ERROR_NO_DEVICENODE_FOUND,
+	PVRSRV_ERROR_NO_CLIENTNODE_FOUND,
+	PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE,
+
+	PVRSRV_ERROR_UNABLE_TO_INIT_TASK,
+	PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK,
+	PVRSRV_ERROR_UNABLE_TO_KILL_TASK,
+
+	PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER,
+	PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER,
+	PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER,
+
+	PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT,
+	PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION,
+
+	PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE,
+	PVRSRV_ERROR_HANDLE_NOT_ALLOCATED,
+	PVRSRV_ERROR_HANDLE_TYPE_MISMATCH,
+	PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE,
+	PVRSRV_ERROR_HANDLE_NOT_SHAREABLE,
+	PVRSRV_ERROR_HANDLE_NOT_FOUND,
+	PVRSRV_ERROR_INVALID_SUBHANDLE,
+	PVRSRV_ERROR_HANDLE_BATCH_IN_USE,
+	PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE,
+
+	PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE,
+	PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED,
+
+	PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE,
+	PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP,
+
+	PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE,
+
+	PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE,
+	PVRSRV_ERROR_INVALID_DEVICEID,
+	PVRSRV_ERROR_DEVICEID_NOT_FOUND,
+
+	PVRSRV_ERROR_MEMORY_TEST_FAILED,
+	PVRSRV_ERROR_CPUPADDR_TEST_FAILED,
+	PVRSRV_ERROR_COPY_TEST_FAILED,
+
+	PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED,
+
+	PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK,
+	PVRSRV_ERROR_CLOCK_REQUEST_FAILED,
+	PVRSRV_ERROR_DISABLE_CLOCK_FAILURE,
+	PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE,
+	PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE,
+	PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK,
+	PVRSRV_ERROR_UNABLE_TO_GET_CLOCK,
+	PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK,
+	PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK,
+
+	PVRSRV_ERROR_UNKNOWN_SGL_ERROR,
+
+	PVRSRV_ERROR_SYSTEM_POWER_CHANGE_FAILURE,
+	PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE,
+
+	PVRSRV_ERROR_BAD_SYNC_STATE,
+
+	PVRSRV_ERROR_CACHEOP_FAILED,
+
+	PVRSRV_ERROR_CACHE_INVALIDATE_FAILED,
+
+	PVRSRV_ERROR_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_ERROR;
+
+
+typedef enum _PVRSRV_DEVICE_CLASS_
+{
+	PVRSRV_DEVICE_CLASS_3D				= 0 ,
+	PVRSRV_DEVICE_CLASS_DISPLAY			= 1 ,
+	PVRSRV_DEVICE_CLASS_BUFFER			= 2 ,
+	PVRSRV_DEVICE_CLASS_VIDEO			= 3 ,
+
+	PVRSRV_DEVICE_CLASS_FORCE_I32 		= 0x7fffffff
+
+} PVRSRV_DEVICE_CLASS;
+
+
+typedef enum _PVRSRV_SYS_POWER_STATE_
+{
+	PVRSRV_SYS_POWER_STATE_Unspecified		= -1,	
+	PVRSRV_SYS_POWER_STATE_D0				= 0,	
+	PVRSRV_SYS_POWER_STATE_D1				= 1,	
+	PVRSRV_SYS_POWER_STATE_D2				= 2,	
+	PVRSRV_SYS_POWER_STATE_D3				= 3,	
+	PVRSRV_SYS_POWER_STATE_D4				= 4,	
+
+	PVRSRV_SYS_POWER_STATE_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_SYS_POWER_STATE, *PPVRSRV_SYS_POWER_STATE;
+
+
+typedef enum _PVRSRV_DEV_POWER_STATE_
+{
+	PVRSRV_DEV_POWER_STATE_DEFAULT	= -1,	
+	PVRSRV_DEV_POWER_STATE_ON		= 0,	
+	PVRSRV_DEV_POWER_STATE_IDLE		= 1,	
+	PVRSRV_DEV_POWER_STATE_OFF		= 2,	
+
+	PVRSRV_DEV_POWER_STATE_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_DEV_POWER_STATE, *PPVRSRV_DEV_POWER_STATE;	
+
+
+typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE				hDevHandle,
+									   PVRSRV_DEV_POWER_STATE	eNewPowerState,
+									   PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE				hDevHandle,
+										PVRSRV_DEV_POWER_STATE	eNewPowerState,
+										PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+
+typedef PVRSRV_ERROR (*PFN_PRE_CLOCKSPEED_CHANGE) (IMG_HANDLE				hDevHandle,
+												   IMG_BOOL					bIdleDevice,
+												   PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+typedef PVRSRV_ERROR (*PFN_POST_CLOCKSPEED_CHANGE) (IMG_HANDLE				hDevHandle,
+													IMG_BOOL				bIdleDevice,
+													PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+
+
+typedef enum _PVRSRV_PIXEL_FORMAT_ {
+	
+	PVRSRV_PIXEL_FORMAT_UNKNOWN				=  0,
+	PVRSRV_PIXEL_FORMAT_RGB565				=  1,
+	PVRSRV_PIXEL_FORMAT_RGB555				=  2,
+	PVRSRV_PIXEL_FORMAT_RGB888				=  3,	
+	PVRSRV_PIXEL_FORMAT_BGR888				=  4,	
+	PVRSRV_PIXEL_FORMAT_GREY_SCALE			=  8,
+	PVRSRV_PIXEL_FORMAT_PAL12				= 13,
+	PVRSRV_PIXEL_FORMAT_PAL8				= 14,
+	PVRSRV_PIXEL_FORMAT_PAL4				= 15,
+	PVRSRV_PIXEL_FORMAT_PAL2				= 16,
+	PVRSRV_PIXEL_FORMAT_PAL1				= 17,
+	PVRSRV_PIXEL_FORMAT_ARGB1555			= 18,
+	PVRSRV_PIXEL_FORMAT_ARGB4444			= 19,
+	PVRSRV_PIXEL_FORMAT_ARGB8888			= 20,
+	PVRSRV_PIXEL_FORMAT_ABGR8888			= 21,
+	PVRSRV_PIXEL_FORMAT_YV12				= 22,
+	PVRSRV_PIXEL_FORMAT_I420				= 23,
+    PVRSRV_PIXEL_FORMAT_IMC2				= 25,
+	PVRSRV_PIXEL_FORMAT_XRGB8888			= 26,
+	PVRSRV_PIXEL_FORMAT_XBGR8888			= 27,
+	PVRSRV_PIXEL_FORMAT_BGRA8888			= 28,
+	PVRSRV_PIXEL_FORMAT_XRGB4444			= 29,
+	PVRSRV_PIXEL_FORMAT_ARGB8332			= 30,
+	PVRSRV_PIXEL_FORMAT_A2RGB10				= 31,	
+	PVRSRV_PIXEL_FORMAT_A2BGR10				= 32,	
+	PVRSRV_PIXEL_FORMAT_P8					= 33,
+	PVRSRV_PIXEL_FORMAT_L8					= 34,
+	PVRSRV_PIXEL_FORMAT_A8L8				= 35,
+	PVRSRV_PIXEL_FORMAT_A4L4				= 36,
+	PVRSRV_PIXEL_FORMAT_L16					= 37,
+	PVRSRV_PIXEL_FORMAT_L6V5U5				= 38,
+	PVRSRV_PIXEL_FORMAT_V8U8				= 39,
+	PVRSRV_PIXEL_FORMAT_V16U16				= 40,
+	PVRSRV_PIXEL_FORMAT_QWVU8888			= 41,
+	PVRSRV_PIXEL_FORMAT_XLVU8888			= 42,
+	PVRSRV_PIXEL_FORMAT_QWVU16				= 43,
+	PVRSRV_PIXEL_FORMAT_D16					= 44,
+	PVRSRV_PIXEL_FORMAT_D24S8				= 45,
+	PVRSRV_PIXEL_FORMAT_D24X8				= 46,
+
+	
+	PVRSRV_PIXEL_FORMAT_ABGR16				= 47,
+	PVRSRV_PIXEL_FORMAT_ABGR16F				= 48,
+	PVRSRV_PIXEL_FORMAT_ABGR32				= 49,
+	PVRSRV_PIXEL_FORMAT_ABGR32F				= 50,
+	PVRSRV_PIXEL_FORMAT_B10GR11				= 51,
+	PVRSRV_PIXEL_FORMAT_GR88				= 52,
+	PVRSRV_PIXEL_FORMAT_BGR32				= 53,
+	PVRSRV_PIXEL_FORMAT_GR32				= 54,
+	PVRSRV_PIXEL_FORMAT_E5BGR9				= 55,
+
+	
+	PVRSRV_PIXEL_FORMAT_RESERVED1			= 56,
+	PVRSRV_PIXEL_FORMAT_RESERVED2			= 57,
+	PVRSRV_PIXEL_FORMAT_RESERVED3			= 58,
+	PVRSRV_PIXEL_FORMAT_RESERVED4			= 59,
+	PVRSRV_PIXEL_FORMAT_RESERVED5			= 60,
+
+	
+	PVRSRV_PIXEL_FORMAT_R8G8_B8G8			= 61,
+	PVRSRV_PIXEL_FORMAT_G8R8_G8B8			= 62,
+
+	
+	PVRSRV_PIXEL_FORMAT_NV11				= 63,
+	PVRSRV_PIXEL_FORMAT_NV12				= 64,
+
+	
+	PVRSRV_PIXEL_FORMAT_YUY2				= 65,
+	PVRSRV_PIXEL_FORMAT_YUV420				= 66,
+	PVRSRV_PIXEL_FORMAT_YUV444				= 67,
+	PVRSRV_PIXEL_FORMAT_VUY444				= 68,
+	PVRSRV_PIXEL_FORMAT_YUYV				= 69,
+	PVRSRV_PIXEL_FORMAT_YVYU				= 70,
+	PVRSRV_PIXEL_FORMAT_UYVY				= 71,
+	PVRSRV_PIXEL_FORMAT_VYUY				= 72,
+
+	PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY		= 73,	
+	PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV		= 74,	
+	PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU		= 75,	
+	PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY		= 76,	
+	PVRSRV_PIXEL_FORMAT_FOURCC_ORG_AYUV		= 77,	
+
+	
+	PVRSRV_PIXEL_FORMAT_A32B32G32R32		= 78,	
+	PVRSRV_PIXEL_FORMAT_A32B32G32R32F		= 79,	
+	PVRSRV_PIXEL_FORMAT_A32B32G32R32_UINT	= 80,	
+	PVRSRV_PIXEL_FORMAT_A32B32G32R32_SINT	= 81,	
+
+	
+	PVRSRV_PIXEL_FORMAT_B32G32R32			= 82,	
+	PVRSRV_PIXEL_FORMAT_B32G32R32F			= 83,	
+	PVRSRV_PIXEL_FORMAT_B32G32R32_UINT		= 84,	
+	PVRSRV_PIXEL_FORMAT_B32G32R32_SINT		= 85,	
+
+	
+	PVRSRV_PIXEL_FORMAT_G32R32				= 86,	
+	PVRSRV_PIXEL_FORMAT_G32R32F				= 87,	
+	PVRSRV_PIXEL_FORMAT_G32R32_UINT			= 88,	
+	PVRSRV_PIXEL_FORMAT_G32R32_SINT			= 89,	
+
+	
+	PVRSRV_PIXEL_FORMAT_D32F				= 90,	
+	PVRSRV_PIXEL_FORMAT_R32					= 91,	
+	PVRSRV_PIXEL_FORMAT_R32F				= 92,	
+	PVRSRV_PIXEL_FORMAT_R32_UINT			= 93,	
+	PVRSRV_PIXEL_FORMAT_R32_SINT			= 94,	
+
+	
+	PVRSRV_PIXEL_FORMAT_A16B16G16R16		= 95,	
+	PVRSRV_PIXEL_FORMAT_A16B16G16R16F		= 96,	
+	PVRSRV_PIXEL_FORMAT_A16B16G16R16_SINT	= 97,	
+	PVRSRV_PIXEL_FORMAT_A16B16G16R16_SNORM	= 98,	
+	PVRSRV_PIXEL_FORMAT_A16B16G16R16_UINT	= 99,	
+	PVRSRV_PIXEL_FORMAT_A16B16G16R16_UNORM	= 100,	
+
+	
+	PVRSRV_PIXEL_FORMAT_G16R16				= 101,	
+	PVRSRV_PIXEL_FORMAT_G16R16F				= 102,	
+	PVRSRV_PIXEL_FORMAT_G16R16_UINT			= 103,	
+	PVRSRV_PIXEL_FORMAT_G16R16_UNORM		= 104,	
+	PVRSRV_PIXEL_FORMAT_G16R16_SINT			= 105,	
+	PVRSRV_PIXEL_FORMAT_G16R16_SNORM		= 106,	
+
+	
+	PVRSRV_PIXEL_FORMAT_R16					= 107,	
+	PVRSRV_PIXEL_FORMAT_R16F				= 108,	
+	PVRSRV_PIXEL_FORMAT_R16_UINT			= 109,	
+	PVRSRV_PIXEL_FORMAT_R16_UNORM			= 110,	
+	PVRSRV_PIXEL_FORMAT_R16_SINT			= 111,	
+	PVRSRV_PIXEL_FORMAT_R16_SNORM			= 112,	
+
+	
+	PVRSRV_PIXEL_FORMAT_X8R8G8B8			= 113,	
+	PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM		= 114,	
+	PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM_SRGB	= 115,	
+
+	PVRSRV_PIXEL_FORMAT_A8R8G8B8			= 116,	
+	PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM		= 117,	
+	PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM_SRGB	= 118,	
+
+	PVRSRV_PIXEL_FORMAT_A8B8G8R8			= 119,	
+	PVRSRV_PIXEL_FORMAT_A8B8G8R8_UINT		= 120,	
+	PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM		= 121,	
+	PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM_SRGB	= 122,	
+	PVRSRV_PIXEL_FORMAT_A8B8G8R8_SINT		= 123,	
+	PVRSRV_PIXEL_FORMAT_A8B8G8R8_SNORM		= 124,	
+
+	
+	PVRSRV_PIXEL_FORMAT_G8R8				= 125,	
+	PVRSRV_PIXEL_FORMAT_G8R8_UINT			= 126,	
+	PVRSRV_PIXEL_FORMAT_G8R8_UNORM			= 127,	
+	PVRSRV_PIXEL_FORMAT_G8R8_SINT			= 128,	
+	PVRSRV_PIXEL_FORMAT_G8R8_SNORM			= 129,	
+
+	
+	PVRSRV_PIXEL_FORMAT_A8					= 130,	
+	PVRSRV_PIXEL_FORMAT_R8					= 131,	
+	PVRSRV_PIXEL_FORMAT_R8_UINT				= 132,	
+	PVRSRV_PIXEL_FORMAT_R8_UNORM			= 133,	
+	PVRSRV_PIXEL_FORMAT_R8_SINT				= 134,	
+	PVRSRV_PIXEL_FORMAT_R8_SNORM			= 135,	
+
+	
+	PVRSRV_PIXEL_FORMAT_A2B10G10R10			= 136,	
+	PVRSRV_PIXEL_FORMAT_A2B10G10R10_UNORM	= 137,	
+	PVRSRV_PIXEL_FORMAT_A2B10G10R10_UINT	= 138,	
+
+	
+	PVRSRV_PIXEL_FORMAT_B10G11R11			= 139,	
+	PVRSRV_PIXEL_FORMAT_B10G11R11F			= 140,	
+
+	
+	PVRSRV_PIXEL_FORMAT_X24G8R32			= 141,	
+	PVRSRV_PIXEL_FORMAT_G8R24				= 142,	
+	PVRSRV_PIXEL_FORMAT_X8R24				= 143,
+	PVRSRV_PIXEL_FORMAT_E5B9G9R9			= 144,	
+	PVRSRV_PIXEL_FORMAT_R1					= 145,	
+
+	PVRSRV_PIXEL_FORMAT_RESERVED6			= 146,
+	PVRSRV_PIXEL_FORMAT_RESERVED7			= 147,
+	PVRSRV_PIXEL_FORMAT_RESERVED8			= 148,
+	PVRSRV_PIXEL_FORMAT_RESERVED9			= 149,
+	PVRSRV_PIXEL_FORMAT_RESERVED10			= 150,
+	PVRSRV_PIXEL_FORMAT_RESERVED11			= 151,
+	PVRSRV_PIXEL_FORMAT_RESERVED12			= 152,
+	PVRSRV_PIXEL_FORMAT_RESERVED13			= 153,
+	PVRSRV_PIXEL_FORMAT_RESERVED14			= 154,
+	PVRSRV_PIXEL_FORMAT_RESERVED15			= 155,
+	PVRSRV_PIXEL_FORMAT_RESERVED16			= 156,
+	PVRSRV_PIXEL_FORMAT_RESERVED17			= 157,
+	PVRSRV_PIXEL_FORMAT_RESERVED18			= 158,
+	PVRSRV_PIXEL_FORMAT_RESERVED19			= 159,
+	PVRSRV_PIXEL_FORMAT_RESERVED20			= 160,
+
+	
+	PVRSRV_PIXEL_FORMAT_UBYTE4				= 161,	
+	PVRSRV_PIXEL_FORMAT_SHORT4				= 162,	
+	PVRSRV_PIXEL_FORMAT_SHORT4N				= 163,	
+	PVRSRV_PIXEL_FORMAT_USHORT4N			= 164,	
+	PVRSRV_PIXEL_FORMAT_SHORT2N				= 165,	
+	PVRSRV_PIXEL_FORMAT_SHORT2				= 166,	
+	PVRSRV_PIXEL_FORMAT_USHORT2N			= 167,	
+	PVRSRV_PIXEL_FORMAT_UDEC3				= 168,	
+	PVRSRV_PIXEL_FORMAT_DEC3N				= 169,	
+	PVRSRV_PIXEL_FORMAT_F16_2				= 170,	
+	PVRSRV_PIXEL_FORMAT_F16_4				= 171,	
+
+	
+	PVRSRV_PIXEL_FORMAT_L_F16				= 172,
+	PVRSRV_PIXEL_FORMAT_L_F16_REP			= 173,
+	PVRSRV_PIXEL_FORMAT_L_F16_A_F16			= 174,
+	PVRSRV_PIXEL_FORMAT_A_F16				= 175,
+	PVRSRV_PIXEL_FORMAT_B16G16R16F			= 176,
+
+	PVRSRV_PIXEL_FORMAT_L_F32				= 177,
+	PVRSRV_PIXEL_FORMAT_A_F32				= 178,
+	PVRSRV_PIXEL_FORMAT_L_F32_A_F32			= 179,
+
+	
+	PVRSRV_PIXEL_FORMAT_PVRTC2				= 180,
+	PVRSRV_PIXEL_FORMAT_PVRTC4				= 181,
+	PVRSRV_PIXEL_FORMAT_PVRTCII2			= 182,
+	PVRSRV_PIXEL_FORMAT_PVRTCII4			= 183,
+	PVRSRV_PIXEL_FORMAT_PVRTCIII			= 184,
+	PVRSRV_PIXEL_FORMAT_PVRO8				= 185,
+	PVRSRV_PIXEL_FORMAT_PVRO88				= 186,
+	PVRSRV_PIXEL_FORMAT_PT1					= 187,
+	PVRSRV_PIXEL_FORMAT_PT2					= 188,
+	PVRSRV_PIXEL_FORMAT_PT4					= 189,
+	PVRSRV_PIXEL_FORMAT_PT8					= 190,
+	PVRSRV_PIXEL_FORMAT_PTW					= 191,
+	PVRSRV_PIXEL_FORMAT_PTB					= 192,
+	PVRSRV_PIXEL_FORMAT_MONO8				= 193,
+	PVRSRV_PIXEL_FORMAT_MONO16				= 194,
+
+	
+	PVRSRV_PIXEL_FORMAT_C0_YUYV				= 195,
+	PVRSRV_PIXEL_FORMAT_C0_UYVY				= 196,
+	PVRSRV_PIXEL_FORMAT_C0_YVYU				= 197,
+	PVRSRV_PIXEL_FORMAT_C0_VYUY				= 198,
+	PVRSRV_PIXEL_FORMAT_C1_YUYV				= 199,
+	PVRSRV_PIXEL_FORMAT_C1_UYVY				= 200,
+	PVRSRV_PIXEL_FORMAT_C1_YVYU				= 201,
+	PVRSRV_PIXEL_FORMAT_C1_VYUY				= 202,
+
+	
+	PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_UV		= 203,
+	PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_VU		= 204,
+	PVRSRV_PIXEL_FORMAT_C0_YUV420_3P		= 205,
+	PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_UV		= 206,
+	PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_VU		= 207,
+	PVRSRV_PIXEL_FORMAT_C1_YUV420_3P		= 208,
+
+	PVRSRV_PIXEL_FORMAT_A2B10G10R10F		= 209,
+	PVRSRV_PIXEL_FORMAT_B8G8R8_SINT			= 210,
+	PVRSRV_PIXEL_FORMAT_PVRF32SIGNMASK		= 211,
+	
+	PVRSRV_PIXEL_FORMAT_ABGR4444			= 212,	
+	PVRSRV_PIXEL_FORMAT_ABGR1555			= 213,
+	PVRSRV_PIXEL_FORMAT_BGR565				= 214,			
+
+	
+	PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_UV	= 215,
+	PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_VU	= 216,
+	PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_UV	= 217,
+	PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_VU	= 218,
+	PVRSRV_PIXEL_FORMAT_P208				= 219,			
+	PVRSRV_PIXEL_FORMAT_A8P8				= 220,			
+
+	PVRSRV_PIXEL_FORMAT_A4					= 221,
+	PVRSRV_PIXEL_FORMAT_AYUV8888			= 222,
+	PVRSRV_PIXEL_FORMAT_RAW256				= 223,
+	PVRSRV_PIXEL_FORMAT_RAW512				= 224,
+	PVRSRV_PIXEL_FORMAT_RAW1024				= 225,
+
+	PVRSRV_PIXEL_FORMAT_FORCE_I32			= 0x7fffffff
+
+} PVRSRV_PIXEL_FORMAT;
+
+typedef enum _PVRSRV_ALPHA_FORMAT_ {
+	PVRSRV_ALPHA_FORMAT_UNKNOWN		=  0x00000000,
+	PVRSRV_ALPHA_FORMAT_PRE			=  0x00000001,
+	PVRSRV_ALPHA_FORMAT_NONPRE		=  0x00000002,
+	PVRSRV_ALPHA_FORMAT_MASK		=  0x0000000F,
+} PVRSRV_ALPHA_FORMAT;
+
+typedef enum _PVRSRV_COLOURSPACE_FORMAT_ {
+	PVRSRV_COLOURSPACE_FORMAT_UNKNOWN		=  0x00000000,
+	PVRSRV_COLOURSPACE_FORMAT_LINEAR		=  0x00010000,
+	PVRSRV_COLOURSPACE_FORMAT_NONLINEAR		=  0x00020000,
+	PVRSRV_COLOURSPACE_FORMAT_MASK			=  0x000F0000,
+} PVRSRV_COLOURSPACE_FORMAT;
+
+
+typedef enum _PVRSRV_ROTATION_ {
+	PVRSRV_ROTATE_0		=	0,
+	PVRSRV_ROTATE_90	=	1,
+	PVRSRV_ROTATE_180	=	2,
+	PVRSRV_ROTATE_270	=	3,
+	PVRSRV_FLIP_Y
+
+} PVRSRV_ROTATION;
+
+#define PVRSRV_CREATE_SWAPCHAIN_SHARED		(1<<0)
+#define PVRSRV_CREATE_SWAPCHAIN_QUERY		(1<<1)
+#define PVRSRV_CREATE_SWAPCHAIN_OEMOVERLAY	(1<<2)
+
+typedef struct _PVRSRV_SYNC_DATA_
+{
+	
+	IMG_UINT32					ui32WriteOpsPending;
+	volatile IMG_UINT32			ui32WriteOpsComplete;
+
+	
+	IMG_UINT32					ui32ReadOpsPending;
+	volatile IMG_UINT32			ui32ReadOpsComplete;
+
+	
+	IMG_UINT32					ui32LastOpDumpVal;
+	IMG_UINT32					ui32LastReadOpDumpVal;
+
+} PVRSRV_SYNC_DATA;
+
+typedef struct _PVRSRV_CLIENT_SYNC_INFO_
+{
+	
+	PVRSRV_SYNC_DATA		*psSyncData;
+
+	
+
+
+	
+	IMG_DEV_VIRTADDR		sWriteOpsCompleteDevVAddr;
+
+	
+	IMG_DEV_VIRTADDR		sReadOpsCompleteDevVAddr;
+
+	
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hMappingInfo;
+
+	
+	IMG_SID					hKernelSyncInfo;
+#else
+	IMG_HANDLE					hMappingInfo;
+
+	
+	IMG_HANDLE					hKernelSyncInfo;
+#endif
+
+} PVRSRV_CLIENT_SYNC_INFO, *PPVRSRV_CLIENT_SYNC_INFO;
+
+typedef struct PVRSRV_RESOURCE_TAG
+{
+	volatile IMG_UINT32 ui32Lock;
+	IMG_UINT32 			ui32ID;
+}PVRSRV_RESOURCE;
+typedef PVRSRV_RESOURCE PVRSRV_RES_HANDLE;
+
+
+typedef IMG_VOID (*PFN_CMD_COMPLETE) (IMG_HANDLE);
+typedef IMG_VOID (**PPFN_CMD_COMPLETE) (IMG_HANDLE);
+
+typedef IMG_BOOL (*PFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
+typedef IMG_BOOL (**PPFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
+
+
+typedef struct _IMG_RECT_
+{
+	IMG_INT32	x0;
+	IMG_INT32	y0;
+	IMG_INT32	x1;
+	IMG_INT32	y1;
+}IMG_RECT;
+
+typedef struct _IMG_RECT_16_
+{
+	IMG_INT16	x0;
+	IMG_INT16	y0;
+	IMG_INT16	x1;
+	IMG_INT16	y1;
+}IMG_RECT_16;
+
+
+typedef PVRSRV_ERROR (*PFN_GET_BUFFER_ADDR)(IMG_HANDLE,
+											IMG_HANDLE,
+											IMG_SYS_PHYADDR**,
+											IMG_SIZE_T*,
+											IMG_VOID**,
+											IMG_HANDLE*,
+											IMG_BOOL*,
+											IMG_UINT32*);
+
+
+typedef struct DISPLAY_DIMS_TAG
+{
+	IMG_UINT32	ui32ByteStride;
+	IMG_UINT32	ui32Width;
+	IMG_UINT32	ui32Height;
+} DISPLAY_DIMS;
+
+
+typedef struct DISPLAY_FORMAT_TAG
+{
+	
+	PVRSRV_PIXEL_FORMAT		pixelformat;
+} DISPLAY_FORMAT;
+
+typedef struct DISPLAY_SURF_ATTRIBUTES_TAG
+{
+	
+	PVRSRV_PIXEL_FORMAT		pixelformat;
+	
+	DISPLAY_DIMS			sDims;
+} DISPLAY_SURF_ATTRIBUTES;
+
+
+typedef struct DISPLAY_MODE_INFO_TAG
+{
+	
+	PVRSRV_PIXEL_FORMAT		pixelformat;
+	
+	DISPLAY_DIMS			sDims;
+	
+	IMG_UINT32				ui32RefreshHZ;
+	
+	IMG_UINT32				ui32OEMFlags;
+} DISPLAY_MODE_INFO;
+
+
+
+#define MAX_DISPLAY_NAME_SIZE	(50) 
+
+typedef struct DISPLAY_INFO_TAG
+{
+	
+	IMG_UINT32 ui32MaxSwapChains;
+	
+	IMG_UINT32 ui32MaxSwapChainBuffers;
+	
+	IMG_UINT32 ui32MinSwapInterval;
+	
+	IMG_UINT32 ui32MaxSwapInterval;
+	
+	IMG_UINT32 ui32PhysicalWidthmm;
+	IMG_UINT32 ui32PhysicalHeightmm;
+	
+	IMG_CHAR	szDisplayName[MAX_DISPLAY_NAME_SIZE];
+#if defined(SUPPORT_HW_CURSOR)
+	
+	IMG_UINT16	ui32CursorWidth;
+	IMG_UINT16	ui32CursorHeight;
+#endif
+} DISPLAY_INFO;
+
+typedef struct ACCESS_INFO_TAG
+{
+	IMG_UINT32		ui32Size;
+	IMG_UINT32  	ui32FBPhysBaseAddress;
+	IMG_UINT32		ui32FBMemAvailable;			
+	IMG_UINT32  	ui32SysPhysBaseAddress;
+	IMG_UINT32		ui32SysSize;
+	IMG_UINT32		ui32DevIRQ;
+}ACCESS_INFO;
+
+
+
+#if defined(PDUMP_SUSPEND_IS_PER_THREAD)
+typedef struct {
+	IMG_UINT32 threadId;
+	IMG_INT    suspendCount;
+} PVRSRV_THREAD_SUSPEND_COUNT;
+
+#define PVRSRV_PDUMP_SUSPEND_Q_NAME "PVRSRVPDumpSuspendMsgQ"
+#define PVRSRV_PDUMP_SUSPEND_Q_LENGTH 8
+
+#endif 
+
+
+typedef struct _PVRSRV_REGISTRY_INFO_
+{
+    IMG_UINT32		ui32DevCookie;
+    IMG_PCHAR		pszKey;
+    IMG_PCHAR		pszValue;
+    IMG_PCHAR		pszBuf;
+    IMG_UINT32		ui32BufSize;
+} PVRSRV_REGISTRY_INFO, *PPVRSRV_REGISTRY_INFO;
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReadRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo);
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWriteRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo);
+
+
+#define PVRSRV_BC_FLAGS_YUVCSC_CONFORMANT_RANGE	(0 << 0)
+#define PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE		(1 << 0)
+
+#define PVRSRV_BC_FLAGS_YUVCSC_BT601			(0 << 1)
+#define PVRSRV_BC_FLAGS_YUVCSC_BT709			(1 << 1)
+
+#define MAX_BUFFER_DEVICE_NAME_SIZE	(50) 
+
+typedef struct BUFFER_INFO_TAG
+{
+	IMG_UINT32 			ui32BufferCount;
+	IMG_UINT32			ui32BufferDeviceID;
+	PVRSRV_PIXEL_FORMAT	pixelformat;
+	IMG_UINT32			ui32ByteStride;
+	IMG_UINT32			ui32Width;
+	IMG_UINT32			ui32Height;
+	IMG_UINT32			ui32Flags;
+	IMG_CHAR			szDeviceName[MAX_BUFFER_DEVICE_NAME_SIZE];
+} BUFFER_INFO;
+
+typedef enum _OVERLAY_DEINTERLACE_MODE_
+{
+	WEAVE=0x0,
+	BOB_ODD,
+	BOB_EVEN,
+	BOB_EVEN_NONINTERLEAVED
+} OVERLAY_DEINTERLACE_MODE;
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/include4/sgx_options.h b/drivers/staging/cdv/pvr/include4/sgx_options.h
new file mode 100644
index 0000000..d2ddff6
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/sgx_options.h
@@ -0,0 +1,237 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if defined(DEBUG) || defined (INTERNAL_TEST)
+#define DEBUG_SET_OFFSET	OPTIONS_BIT0
+#define OPTIONS_BIT0		0x1U
+#else
+#define OPTIONS_BIT0		0x0
+#endif 
+
+#if defined(PDUMP) || defined (INTERNAL_TEST)
+#define PDUMP_SET_OFFSET	OPTIONS_BIT1
+#define OPTIONS_BIT1		(0x1U << 1)
+#else
+#define OPTIONS_BIT1		0x0
+#endif 
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) || defined (INTERNAL_TEST)
+#define PVRSRV_USSE_EDM_STATUS_DEBUG_SET_OFFSET		OPTIONS_BIT2
+#define OPTIONS_BIT2		(0x1U << 2)
+#else
+#define OPTIONS_BIT2		0x0
+#endif 
+
+#if defined(SUPPORT_HW_RECOVERY) || defined (INTERNAL_TEST)
+#define SUPPORT_HW_RECOVERY_SET_OFFSET	OPTIONS_BIT3
+#define OPTIONS_BIT3		(0x1U << 3)
+#else
+#define OPTIONS_BIT3		0x0
+#endif 
+
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+#define PVR_SECURE_HANDLES_SET_OFFSET	OPTIONS_BIT4
+#define OPTIONS_BIT4		(0x1U << 4)
+#else
+#if defined(PVR_SECURE_HANDLES) || defined (INTERNAL_TEST)
+#define PVR_SECURE_HANDLES_SET_OFFSET	OPTIONS_BIT4
+#define OPTIONS_BIT4		(0x1U << 4)
+#else
+#define OPTIONS_BIT4		0x0
+#endif 
+#endif
+
+#if defined(SGX_BYPASS_SYSTEM_CACHE) || defined (INTERNAL_TEST)
+#define SGX_BYPASS_SYSTEM_CACHE_SET_OFFSET	OPTIONS_BIT5
+#define OPTIONS_BIT5		(0x1U << 5)
+#else
+#define OPTIONS_BIT5		0x0
+#endif 
+
+#if defined(SGX_DMS_AGE_ENABLE) || defined (INTERNAL_TEST)
+#define SGX_DMS_AGE_ENABLE_SET_OFFSET	OPTIONS_BIT6
+#define OPTIONS_BIT6		(0x1U << 6)
+#else
+#define OPTIONS_BIT6		0x0
+#endif 
+
+#if defined(SGX_FAST_DPM_INIT) || defined (INTERNAL_TEST)
+#define SGX_FAST_DPM_INIT_SET_OFFSET	OPTIONS_BIT8
+#define OPTIONS_BIT8		(0x1U << 8)
+#else
+#define OPTIONS_BIT8		0x0
+#endif 
+
+#if defined(SGX_FEATURE_WRITEBACK_DCU) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_DCU_SET_OFFSET	OPTIONS_BIT9
+#define OPTIONS_BIT9		(0x1U << 9)
+#else
+#define OPTIONS_BIT9		0x0
+#endif 
+
+#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_MP_SET_OFFSET	OPTIONS_BIT10
+#define OPTIONS_BIT10		(0x1U << 10)
+#else
+#define OPTIONS_BIT10		0x0
+#endif 
+
+#if defined(SGX_FEATURE_MULTITHREADED_UKERNEL) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_MULTITHREADED_UKERNEL_SET_OFFSET	OPTIONS_BIT11
+#define OPTIONS_BIT11		(0x1U << 11)
+#else
+#define OPTIONS_BIT11		0x0
+#endif 
+
+
+
+#if defined(SGX_FEATURE_OVERLAPPED_SPM) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_OVERLAPPED_SPM_SET_OFFSET	OPTIONS_BIT12
+#define OPTIONS_BIT12		(0x1U << 12)
+#else
+#define OPTIONS_BIT12		0x0
+#endif 
+
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_SYSTEM_CACHE_SET_OFFSET	OPTIONS_BIT13
+#define OPTIONS_BIT13		(0x1U << 13)
+#else
+#define OPTIONS_BIT13		0x0
+#endif 
+
+#if defined(SGX_SUPPORT_HWPROFILING) || defined (INTERNAL_TEST)
+#define SGX_SUPPORT_HWPROFILING_SET_OFFSET	OPTIONS_BIT14
+#define OPTIONS_BIT14		(0x1U << 14)
+#else
+#define OPTIONS_BIT14		0x0
+#endif 
+
+
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) || defined (INTERNAL_TEST)
+#define SUPPORT_ACTIVE_POWER_MANAGEMENT_SET_OFFSET	OPTIONS_BIT15
+#define OPTIONS_BIT15		(0x1U << 15)
+#else
+#define OPTIONS_BIT15		0x0
+#endif 
+
+#if defined(SUPPORT_DISPLAYCONTROLLER_TILING) || defined (INTERNAL_TEST)
+#define SUPPORT_DISPLAYCONTROLLER_TILING_SET_OFFSET	OPTIONS_BIT16
+#define OPTIONS_BIT16		(0x1U << 16)
+#else
+#define OPTIONS_BIT16		0x0
+#endif 
+
+#if defined(SUPPORT_PERCONTEXT_PB) || defined (INTERNAL_TEST)
+#define SUPPORT_PERCONTEXT_PB_SET_OFFSET	OPTIONS_BIT17
+#define OPTIONS_BIT17		(0x1U << 17)
+#else
+#define OPTIONS_BIT17		0x0
+#endif 
+
+#if defined(SUPPORT_SGX_HWPERF) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_HWPERF_SET_OFFSET	OPTIONS_BIT18
+#define OPTIONS_BIT18		(0x1U << 18)
+#else
+#define OPTIONS_BIT18		0x0
+#endif 
+
+
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_MMU_DUMMY_PAGE_SET_OFFSET	OPTIONS_BIT19
+#define OPTIONS_BIT19		(0x1U << 19)
+#else
+#define OPTIONS_BIT19		0x0
+#endif 
+
+#if defined(SUPPORT_SGX_PRIORITY_SCHEDULING) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_PRIORITY_SCHEDULING_SET_OFFSET	OPTIONS_BIT20
+#define OPTIONS_BIT20		(0x1U << 20)
+#else
+#define OPTIONS_BIT20		0x0
+#endif 
+
+#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_LOW_LATENCY_SCHEDULING_SET_OFFSET	OPTIONS_BIT21
+#define OPTIONS_BIT21		(0x1U << 21)
+#else
+#define OPTIONS_BIT21		0x0
+#endif 
+
+#if defined(USE_SUPPORT_NO_TA3D_OVERLAP) || defined (INTERNAL_TEST)
+#define USE_SUPPORT_NO_TA3D_OVERLAP_SET_OFFSET	OPTIONS_BIT22
+#define OPTIONS_BIT22		(0x1U << 22)
+#else
+#define OPTIONS_BIT22		0x0
+#endif 
+
+#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
+#if defined(SGX_FEATURE_MP_CORE_COUNT)
+#define OPTIONS_HIGHBYTE ((SGX_FEATURE_MP_CORE_COUNT-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET)
+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET	28UL
+#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK		0xFF
+#else
+#define OPTIONS_HIGHBYTE (((SGX_FEATURE_MP_CORE_COUNT_TA-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET) |\
+		((SGX_FEATURE_MP_CORE_COUNT_3D-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET_3D))
+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET	24UL
+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET_3D	28UL
+#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK		0xFF
+#endif
+#else 
+#define OPTIONS_HIGHBYTE	0x0
+#endif 
+
+
+
+#define SGX_BUILD_OPTIONS	\
+	OPTIONS_BIT0 |\
+	OPTIONS_BIT1 |\
+	OPTIONS_BIT2 |\
+	OPTIONS_BIT3 |\
+	OPTIONS_BIT4 |\
+	OPTIONS_BIT5 |\
+	OPTIONS_BIT6 |\
+	OPTIONS_BIT8 |\
+	OPTIONS_BIT9 |\
+	OPTIONS_BIT10 |\
+	OPTIONS_BIT11 |\
+	OPTIONS_BIT12 |\
+	OPTIONS_BIT13 |\
+	OPTIONS_BIT14 |\
+	OPTIONS_BIT15 |\
+	OPTIONS_BIT16 |\
+	OPTIONS_BIT17 |\
+	OPTIONS_BIT18 |\
+	OPTIONS_BIT19 |\
+	OPTIONS_BIT20 |\
+	OPTIONS_BIT21 |\
+	OPTIONS_BIT22 |\
+	OPTIONS_HIGHBYTE
+
diff --git a/drivers/staging/cdv/pvr/include4/sgxapi_km.h b/drivers/staging/cdv/pvr/include4/sgxapi_km.h
new file mode 100644
index 0000000..a7e286c
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/sgxapi_km.h
@@ -0,0 +1,427 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __SGXAPI_KM_H__
+#define __SGXAPI_KM_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "sgxdefs.h"
+
+#if (defined(__linux__) || defined(__QNXNTO__)) && !defined(USE_CODE)
+	#if defined(__KERNEL__)
+		#include <asm/unistd.h>
+	#else
+		#include <unistd.h>
+	#endif
+#endif
+
+#define SGX_UNDEFINED_HEAP_ID					(~0LU)
+#define SGX_GENERAL_HEAP_ID						0
+#define SGX_TADATA_HEAP_ID						1
+#define SGX_KERNEL_CODE_HEAP_ID					2
+#define SGX_KERNEL_DATA_HEAP_ID					3
+#define SGX_PIXELSHADER_HEAP_ID					4
+#define SGX_VERTEXSHADER_HEAP_ID				5
+#define SGX_PDSPIXEL_CODEDATA_HEAP_ID			6
+#define SGX_PDSVERTEX_CODEDATA_HEAP_ID			7
+#define SGX_SYNCINFO_HEAP_ID					8
+#define SGX_SHARED_3DPARAMETERS_HEAP_ID				9
+#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID			10
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+#define SGX_GENERAL_MAPPING_HEAP_ID				11
+#endif
+#if defined(SGX_FEATURE_2D_HARDWARE)
+#define SGX_2D_HEAP_ID							12
+#else
+#if defined(FIX_HW_BRN_26915)
+#define SGX_CGBUFFER_HEAP_ID					13
+#endif
+#endif
+#if defined(FIX_HW_BRN_SAMPLE_CACHE)
+#define SGX_TEXTURE_HEAP_ID					14
+#endif
+
+#define SGX_MAX_HEAP_ID						15
+
+#if (defined(SUPPORT_PERCONTEXT_PB) || defined(SUPPORT_HYBRID_PB))
+#define SGX_3DPARAMETERS_HEAP_ID			SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID	
+#else
+#define SGX_3DPARAMETERS_HEAP_ID			SGX_SHARED_3DPARAMETERS_HEAP_ID
+#endif
+#if defined(SGX543) || defined(SGX544) || defined(SGX554)
+#define SGX_USE_CODE_SEGMENT_RANGE_BITS		23
+#else
+#define SGX_USE_CODE_SEGMENT_RANGE_BITS		19
+#endif
+
+#define SGX_MAX_TA_STATUS_VALS	32
+#define SGX_MAX_3D_STATUS_VALS	4
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+#define SGX_MAX_TA_DST_SYNCS			1
+#define SGX_MAX_TA_SRC_SYNCS			1
+#define SGX_MAX_3D_SRC_SYNCS			4
+#else
+#define SGX_MAX_SRC_SYNCS				8
+#define SGX_MAX_DST_SYNCS				1
+#endif
+
+
+#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+#define	PVRSRV_SGX_HWPERF_NUM_COUNTERS	8
+#define	PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS 11
+#else
+#define	PVRSRV_SGX_HWPERF_NUM_COUNTERS	9
+#define	PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS 8
+#endif 
+
+#define PVRSRV_SGX_HWPERF_INVALID					0x1
+
+#define PVRSRV_SGX_HWPERF_TRANSFER					0x2
+#define PVRSRV_SGX_HWPERF_TA						0x3
+#define PVRSRV_SGX_HWPERF_3D						0x4
+#define PVRSRV_SGX_HWPERF_2D						0x5
+#define PVRSRV_SGX_HWPERF_POWER						0x6
+#define PVRSRV_SGX_HWPERF_PERIODIC					0x7
+#define PVRSRV_SGX_HWPERF_3DSPM						0x8
+
+#define PVRSRV_SGX_HWPERF_MK_EVENT					0x101
+#define PVRSRV_SGX_HWPERF_MK_TA						0x102
+#define PVRSRV_SGX_HWPERF_MK_3D						0x103
+#define PVRSRV_SGX_HWPERF_MK_2D						0x104
+#define PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY				0x105
+#define PVRSRV_SGX_HWPERF_MK_TA_DUMMY					0x106
+#define PVRSRV_SGX_HWPERF_MK_3D_DUMMY					0x107
+#define PVRSRV_SGX_HWPERF_MK_2D_DUMMY					0x108
+#define PVRSRV_SGX_HWPERF_MK_TA_LOCKUP					0x109
+#define PVRSRV_SGX_HWPERF_MK_3D_LOCKUP					0x10A
+#define PVRSRV_SGX_HWPERF_MK_2D_LOCKUP					0x10B
+
+#define PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT			28
+#define PVRSRV_SGX_HWPERF_TYPE_OP_MASK				((1UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) - 1)
+#define PVRSRV_SGX_HWPERF_TYPE_OP_START				(0UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT)
+#define PVRSRV_SGX_HWPERF_TYPE_OP_END				(1Ul << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT)
+
+#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_START		(PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_END			(PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_TA_START				(PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_TA_END				(PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_3D_START				(PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_3D_END				(PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_2D_START				(PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_2D_END				(PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_POWER_START			(PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_POWER_END			(PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_PERIODIC				(PVRSRV_SGX_HWPERF_PERIODIC)
+#define PVRSRV_SGX_HWPERF_TYPE_3DSPM_START			(PVRSRV_SGX_HWPERF_3DSPM | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_3DSPM_END			(PVRSRV_SGX_HWPERF_3DSPM | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TRANSFER_DUMMY_START		(PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TRANSFER_DUMMY_END		(PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_DUMMY_START		(PVRSRV_SGX_HWPERF_MK_TA_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_DUMMY_END			(PVRSRV_SGX_HWPERF_MK_TA_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_DUMMY_START		(PVRSRV_SGX_HWPERF_MK_3D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_DUMMY_END			(PVRSRV_SGX_HWPERF_MK_3D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_DUMMY_START		(PVRSRV_SGX_HWPERF_MK_2D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_DUMMY_END			(PVRSRV_SGX_HWPERF_MK_2D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_LOCKUP			(PVRSRV_SGX_HWPERF_MK_TA_LOCKUP)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_LOCKUP			(PVRSRV_SGX_HWPERF_MK_3D_LOCKUP)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_LOCKUP			(PVRSRV_SGX_HWPERF_MK_2D_LOCKUP)
+
+#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_START		(PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_END			(PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_START			(PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_END			(PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_START			(PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_END			(PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_START			(PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_END			(PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+
+#define PVRSRV_SGX_HWPERF_STATUS_OFF				(0x0)
+#define PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS		(1UL << 0)
+#define PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON		(1UL << 1)
+#define PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON		(1UL << 2)
+#define PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON	(1UL << 3)
+
+
+typedef struct _PVRSRV_SGX_HWPERF_CB_ENTRY_
+{
+	IMG_UINT32	ui32FrameNo;
+	IMG_UINT32	ui32PID;
+	IMG_UINT32	ui32RTData;
+	IMG_UINT32	ui32Type;
+	IMG_UINT32	ui32Ordinal;
+	IMG_UINT32	ui32Info;
+	IMG_UINT32	ui32Clocksx16;
+		
+	IMG_UINT32	ui32Counters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+	IMG_UINT32	ui32MiscCounters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS];
+} PVRSRV_SGX_HWPERF_CB_ENTRY;
+
+
+typedef struct _CTL_STATUS_
+{
+	IMG_DEV_VIRTADDR	sStatusDevAddr;
+	IMG_UINT32			ui32StatusValue;
+} CTL_STATUS;
+
+
+typedef enum _SGX_MISC_INFO_REQUEST_
+{
+	SGX_MISC_INFO_REQUEST_CLOCKSPEED = 0,
+	SGX_MISC_INFO_REQUEST_SGXREV,
+	SGX_MISC_INFO_REQUEST_DRIVER_SGXREV,
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+	SGX_MISC_INFO_REQUEST_MEMREAD,
+	SGX_MISC_INFO_REQUEST_MEMCOPY,
+#endif 
+	SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS,
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+	SGX_MISC_INFO_REQUEST_SET_BREAKPOINT,
+	SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT,
+	SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT,
+#endif 
+	SGX_MISC_INFO_DUMP_DEBUG_INFO,
+	SGX_MISC_INFO_PANIC,
+	SGX_MISC_INFO_REQUEST_SPM,
+	SGX_MISC_INFO_REQUEST_ACTIVEPOWER,
+	SGX_MISC_INFO_REQUEST_LOCKUPS,
+	SGX_MISC_INFO_REQUEST_FORCE_I16 				=  0x7fff
+} SGX_MISC_INFO_REQUEST;
+
+
+typedef struct _PVRSRV_SGX_MISCINFO_FEATURES
+{
+	IMG_UINT32			ui32CoreRev;	
+	IMG_UINT32			ui32CoreID;		
+	IMG_UINT32			ui32DDKVersion;	
+	IMG_UINT32			ui32DDKBuild;	
+	IMG_UINT32			ui32CoreIdSW;	
+	IMG_UINT32			ui32CoreRevSW;	
+	IMG_UINT32			ui32BuildOptions;	
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+	IMG_UINT32			ui32DeviceMemValue;		
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+	IMG_DEV_VIRTADDR	sDevVAEDMStatusBuffer;	
+	IMG_PVOID			pvEDMStatusBuffer;		
+#endif
+} PVRSRV_SGX_MISCINFO_FEATURES;
+
+
+typedef struct _PVRSRV_SGX_MISCINFO_LOCKUPS
+{
+	IMG_UINT32			ui32HostDetectedLockups; 
+	IMG_UINT32			ui32uKernelDetectedLockups; 
+} PVRSRV_SGX_MISCINFO_LOCKUPS;
+
+
+typedef struct _PVRSRV_SGX_MISCINFO_ACTIVEPOWER
+{
+	IMG_UINT32			ui32NumActivePowerEvents; 
+} PVRSRV_SGX_MISCINFO_ACTIVEPOWER;
+
+
+typedef struct _PVRSRV_SGX_MISCINFO_SPM
+{
+	IMG_HANDLE			hRTDataSet;				
+	IMG_UINT32			ui32NumOutOfMemSignals; 
+	IMG_UINT32			ui32NumSPMRenders;	
+} PVRSRV_SGX_MISCINFO_SPM;
+
+
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+typedef struct _SGX_BREAKPOINT_INFO
+{
+	
+	IMG_BOOL					bBPEnable;
+	
+	IMG_UINT32					ui32BPIndex;
+	
+	IMG_UINT32                  ui32DataMasterMask;
+	
+	IMG_DEV_VIRTADDR			sBPDevVAddr, sBPDevVAddrEnd;
+	
+	IMG_BOOL                    bTrapped;
+	
+	IMG_BOOL                    bRead;
+	
+	IMG_BOOL                    bWrite;
+	
+	IMG_BOOL                    bTrappedBP;
+	
+	IMG_UINT32                  ui32CoreNum;
+	IMG_DEV_VIRTADDR            sTrappedBPDevVAddr;
+	IMG_UINT32                  ui32TrappedBPBurstLength;
+	IMG_BOOL                    bTrappedBPRead;
+	IMG_UINT32                  ui32TrappedBPDataMaster;
+	IMG_UINT32                  ui32TrappedBPTag;
+} SGX_BREAKPOINT_INFO;
+#endif 
+
+
+typedef struct _PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS
+{
+	
+	IMG_UINT32	ui32NewHWPerfStatus;
+	
+	#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+	
+	IMG_UINT32	aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+	
+	IMG_UINT32	aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+	#else
+	
+	IMG_UINT32	ui32PerfGroup;
+	#endif 
+} PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS;
+
+
+typedef struct _SGX_MISC_INFO_
+{
+	SGX_MISC_INFO_REQUEST	eRequest;	
+	IMG_UINT32				ui32Padding;
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+	IMG_DEV_VIRTADDR			sDevVAddrSrc;		
+	IMG_DEV_VIRTADDR			sDevVAddrDest;		
+	IMG_HANDLE					hDevMemContext;		
+#endif
+	union
+	{
+		IMG_UINT32	reserved;	
+		PVRSRV_SGX_MISCINFO_FEATURES						sSGXFeatures;
+		IMG_UINT32											ui32SGXClockSpeed;
+		PVRSRV_SGX_MISCINFO_ACTIVEPOWER						sActivePower;
+		PVRSRV_SGX_MISCINFO_LOCKUPS							sLockups;
+		PVRSRV_SGX_MISCINFO_SPM								sSPM;
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+		SGX_BREAKPOINT_INFO									sSGXBreakpointInfo;
+#endif
+		PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS				sSetHWPerfStatus;
+	} uData;
+} SGX_MISC_INFO;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+#define PVRSRV_MAX_BLT_SRC_SYNCS		3
+#endif
+
+
+#define SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH		256
+
+typedef struct _SGX_KICKTA_DUMPBITMAP_
+{
+	IMG_DEV_VIRTADDR	sDevBaseAddr;
+	IMG_UINT32			ui32Flags;
+	IMG_UINT32			ui32Width;
+	IMG_UINT32			ui32Height;
+	IMG_UINT32			ui32Stride;
+	IMG_UINT32			ui32PDUMPFormat;
+	IMG_UINT32			ui32BytesPP;
+	IMG_CHAR			pszName[SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH];
+} SGX_KICKTA_DUMPBITMAP, *PSGX_KICKTA_DUMPBITMAP;
+
+#define PVRSRV_SGX_PDUMP_CONTEXT_MAX_BITMAP_ARRAY_SIZE	(16)
+
+typedef struct _PVRSRV_SGX_PDUMP_CONTEXT_
+{
+	
+	IMG_UINT32						ui32CacheControl;
+
+} PVRSRV_SGX_PDUMP_CONTEXT;
+
+
+#if !defined (SUPPORT_SID_INTERFACE)
+typedef struct _SGX_KICKTA_DUMP_ROFF_
+{
+	IMG_HANDLE			hKernelMemInfo;						
+	IMG_UINT32			uiAllocIndex;						
+	IMG_UINT32			ui32Offset;							
+	IMG_UINT32			ui32Value;							
+	IMG_PCHAR			pszName;							
+} SGX_KICKTA_DUMP_ROFF, *PSGX_KICKTA_DUMP_ROFF;
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+typedef struct _SGX_KICKTA_DUMP_BUFFER_KM_
+#else
+typedef struct _SGX_KICKTA_DUMP_BUFFER_
+#endif
+{
+	IMG_UINT32			ui32SpaceUsed;
+	IMG_UINT32			ui32Start;							
+	IMG_UINT32			ui32End;							
+	IMG_UINT32			ui32BufferSize;						
+	IMG_UINT32			ui32BackEndLength;					
+	IMG_UINT32			uiAllocIndex;
+	IMG_HANDLE			hKernelMemInfo;						
+	IMG_PVOID			pvLinAddr;
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+	IMG_HANDLE			hCtrlKernelMemInfo;					
+	IMG_DEV_VIRTADDR	sCtrlDevVAddr;						
+#endif
+	IMG_PCHAR			pszName;							
+#if defined (SUPPORT_SID_INTERFACE)
+} SGX_KICKTA_DUMP_BUFFER_KM, *PSGX_KICKTA_DUMP_BUFFER_KM;
+#else
+} SGX_KICKTA_DUMP_BUFFER, *PSGX_KICKTA_DUMP_BUFFER;
+#endif
+
+#if !defined (SUPPORT_SID_INTERFACE)
+#ifdef PDUMP
+typedef struct _SGX_KICKTA_PDUMP_
+{
+	
+	PSGX_KICKTA_DUMPBITMAP		psPDumpBitmapArray;
+	IMG_UINT32						ui32PDumpBitmapSize;
+
+	
+	PSGX_KICKTA_DUMP_BUFFER	psBufferArray;
+	IMG_UINT32						ui32BufferArraySize;
+
+	
+	PSGX_KICKTA_DUMP_ROFF		psROffArray;
+	IMG_UINT32						ui32ROffArraySize;
+} SGX_KICKTA_PDUMP, *PSGX_KICKTA_PDUMP;
+#endif	
+#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	2
+#define SGX_MAX_TRANSFER_SYNC_OPS	5
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/include4/sgxscript.h b/drivers/staging/cdv/pvr/include4/sgxscript.h
new file mode 100644
index 0000000..df79e2f
--- /dev/null
+++ b/drivers/staging/cdv/pvr/include4/sgxscript.h
@@ -0,0 +1,81 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __SGXSCRIPT_H__
+#define __SGXSCRIPT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define	SGX_MAX_INIT_COMMANDS	64
+#define	SGX_MAX_DEINIT_COMMANDS	16
+
+typedef	enum _SGX_INIT_OPERATION
+{
+	SGX_INIT_OP_ILLEGAL = 0,
+	SGX_INIT_OP_WRITE_HW_REG,
+#if defined(PDUMP)
+	SGX_INIT_OP_PDUMP_HW_REG,
+#endif
+	SGX_INIT_OP_HALT
+} SGX_INIT_OPERATION;
+
+typedef union _SGX_INIT_COMMAND
+{
+	SGX_INIT_OPERATION eOp;
+	struct {
+		SGX_INIT_OPERATION eOp;
+		IMG_UINT32 ui32Offset;
+		IMG_UINT32 ui32Value;
+	} sWriteHWReg;
+#if defined(PDUMP)
+	struct {
+		SGX_INIT_OPERATION eOp;
+		IMG_UINT32 ui32Offset;
+		IMG_UINT32 ui32Value;
+	} sPDumpHWReg;
+#endif
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)			
+	struct {
+		SGX_INIT_OPERATION eOp;
+	} sWorkaroundBRN22997;
+#endif	
+} SGX_INIT_COMMAND;
+
+typedef struct _SGX_INIT_SCRIPTS_
+{
+	SGX_INIT_COMMAND asInitCommandsPart1[SGX_MAX_INIT_COMMANDS];
+	SGX_INIT_COMMAND asInitCommandsPart2[SGX_MAX_INIT_COMMANDS];
+	SGX_INIT_COMMAND asDeinitCommands[SGX_MAX_DEINIT_COMMANDS];
+} SGX_INIT_SCRIPTS;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/.gitignore b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/.gitignore
new file mode 100644
index 0000000..f558f8b
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/.gitignore
@@ -0,0 +1,6 @@
+bin_pc_i686*
+tmp_pc_i686*
+host_pc_i686*
+binary_pc_i686*
+*.o
+*.o.cmd
diff --git a/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/makefile.linux.common b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/makefile.linux.common
new file mode 100644
index 0000000..3cda2a7
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/makefile.linux.common
@@ -0,0 +1,37 @@
+#
+# 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
+#
+#
+#
+
+DISPLAY_CONTROLLER_SOURCES_ROOT = $(KBUILDROOT)/$(DISPLAY_CONTROLLER_DIR)
+
+INCLUDES += 	-I$(EURASIAROOT)/include4 \
+		-I$(EURASIAROOT)/services4/include \
+		-I$(EURASIAROOT)/services4/system/$(PVR_SYSTEM) \
+		-I$(EURASIAROOT)/services4/system/include \
+		-I$(EURASIAROOT)/services4/srvkm/env/linux/mrst
+
+SOURCES	+=	$(DISPLAY_CONTROLLER_SOURCES_ROOT)/mrstlfb_displayclass.c \
+			$(DISPLAY_CONTROLLER_SOURCES_ROOT)/mrstlfb_linux.c
+MODULE_CFLAGS += -DPVR_MRST_FB_SET_PAR_ON_INIT
diff --git a/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb.h b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb.h
new file mode 100644
index 0000000..d839cc9
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb.h
@@ -0,0 +1,309 @@
+/**********************************************************************
+ *
+ * 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 __MRSTLFB_H__
+#define __MRSTLFB_H__
+
+#include <drm/drmP.h>
+#include "psb_intel_reg.h"
+
+#define MRST_USING_INTERRUPTS
+
+#define PSB_HWSTAM                0x2098
+#define PSB_INSTPM                0x20C0
+#define PSB_INT_IDENTITY_R        0x20A4
+#define _PSB_VSYNC_PIPEB_FLAG     (1<<5)
+#define _PSB_VSYNC_PIPEA_FLAG     (1<<7)
+#define _PSB_IRQ_SGX_FLAG         (1<<18)
+#define _PSB_IRQ_MSVDX_FLAG       (1<<19)
+#define PSB_INT_MASK_R            0x20A8
+#define PSB_INT_ENABLE_R          0x20A0
+
+#define MAX_SWAPCHAINS			  1
+#define MAX_FLIPBUFFERS			  9
+
+/* IPC message and command defines used to enable/disable mipi panel voltages */
+#define	IPC_MSG_PANEL_ON_OFF	0xE9
+#define IPC_CMD_PANEL_ON	1
+#define IPC_CMD_PANEL_OFF	0
+
+typedef void *   MRST_HANDLE;
+
+typedef enum tag_mrst_bool
+{
+	MRST_FALSE = 0,
+	MRST_TRUE  = 1,
+} MRST_BOOL, *MRST_PBOOL;
+
+typedef int(* MRSTLFB_VSYNC_ISR_PFN)(struct drm_device* psDrmDevice, int iPipe);
+
+
+typedef struct MRSTLFB_BUFFER_TAG
+{
+	
+    IMG_UINT32		             	ui32BufferSize;
+	union {
+		
+		IMG_SYS_PHYADDR             *psNonCont;
+		
+		IMG_SYS_PHYADDR				sCont;
+	} uSysAddr;
+	
+	IMG_DEV_VIRTADDR             	sDevVAddr;
+	
+    IMG_CPU_VIRTADDR             	sCPUVAddr;    
+	
+	PVRSRV_SYNC_DATA             	*psSyncData;
+	
+	MRST_BOOL					 	bIsContiguous;
+	
+	MRST_BOOL					 	bIsAllocated;
+
+	IMG_UINT32						ui32OwnerTaskID;
+
+	MRST_BOOL						bFromPages;
+	
+	struct page			*buffer_pages[0];	
+} MRSTLFB_BUFFER;
+
+typedef struct MRSTLFB_VSYNC_FLIP_ITEM_TAG
+{
+
+
+
+	MRST_HANDLE      hCmdComplete;
+
+	unsigned long    ulSwapInterval;
+
+	MRST_BOOL        bValid;
+
+	MRST_BOOL        bFlipped;
+
+	MRST_BOOL        bCmdCompleted;
+
+
+
+
+
+	MRSTLFB_BUFFER*	psBuffer;
+} MRSTLFB_VSYNC_FLIP_ITEM;
+
+typedef struct MRSTLFB_SWAPCHAIN_TAG
+{
+	
+	unsigned long       ulBufferCount;
+
+	IMG_UINT32			ui32SwapChainID;
+
+	
+	MRSTLFB_BUFFER     **ppsBuffer;
+
+	
+	unsigned long	    ulSwapChainLength;
+
+	
+	MRSTLFB_VSYNC_FLIP_ITEM	*psVSyncFlips;
+
+	
+	unsigned long       ulInsertIndex;
+	
+	
+	unsigned long       ulRemoveIndex;
+
+	
+	PVRSRV_DC_DISP2SRV_KMJTABLE	*psPVRJTable;
+
+	
+	struct drm_driver         *psDrmDriver;
+
+	
+	struct drm_device         *psDrmDev;
+
+	struct MRSTLFB_SWAPCHAIN_TAG *psNext;
+
+	struct MRSTLFB_DEVINFO_TAG *psDevInfo;
+	unsigned long 		ui32Height;
+	unsigned long		ui32Width;
+	unsigned long		ui32ByteStride;
+
+} MRSTLFB_SWAPCHAIN;
+
+typedef struct MRSTLFB_FBINFO_TAG
+{
+	unsigned long       ulFBSize;
+	unsigned long       ulBufferSize;
+	unsigned long       ulRoundedBufferSize;
+	unsigned long       ulWidth;
+	unsigned long       ulHeight;
+	unsigned long       ulByteStride;
+
+
+
+	IMG_SYS_PHYADDR     sSysAddr;
+	IMG_CPU_VIRTADDR    sCPUVAddr;
+        IMG_DEV_VIRTADDR    sDevVAddr;
+
+
+	PVRSRV_PIXEL_FORMAT ePixelFormat;
+}MRSTLFB_FBINFO;
+
+/**
+ * If DRI is enable then extemding drm_device
+ */
+typedef struct MRSTLFB_DEVINFO_TAG
+{
+	unsigned int           uiDeviceID;
+
+	struct drm_device 	*psDrmDevice;
+
+	
+
+	MRSTLFB_BUFFER          sSystemBuffer;
+
+	
+	PVRSRV_DC_DISP2SRV_KMJTABLE	sPVRJTable;
+	
+	
+	PVRSRV_DC_SRV2DISP_KMJTABLE	sDCJTable;
+
+	
+	unsigned long           ulRefCount;
+
+	MRSTLFB_SWAPCHAIN      *psCurrentSwapChain;
+
+	MRSTLFB_SWAPCHAIN      *apsSwapChains[MAX_SWAPCHAINS];
+
+	IMG_UINT32	   	ui32SwapChainNum;
+
+	
+	void *pvRegs;
+
+	
+	unsigned long ulSetFlushStateRefCount;
+
+	
+	MRST_BOOL           bFlushCommands;
+
+	
+	MRST_BOOL           bBlanked;
+
+	
+	struct fb_info         *psLINFBInfo;
+
+	
+	struct notifier_block   sLINNotifBlock;
+
+	
+	spinlock_t             sSwapChainLock;
+
+	
+
+	
+	IMG_DEV_VIRTADDR	sDisplayDevVAddr;
+
+	DISPLAY_INFO            sDisplayInfo;
+
+	
+	DISPLAY_FORMAT          sDisplayFormat;
+	
+	
+	DISPLAY_DIMS            sDisplayDim;
+
+	IMG_UINT32		ui32MainPipe;
+
+	
+	MRST_BOOL bSuspended;
+
+	
+	MRST_BOOL bLeaveVT;
+
+	
+	unsigned long ulLastFlipAddr;
+
+	
+	MRST_BOOL bLastFlipAddrValid;
+}  MRSTLFB_DEVINFO;
+
+#if 0
+#define	MRSTLFB_PAGE_SIZE 4096
+#define	MRSTLFB_PAGE_MASK (MRSTLFB_PAGE_SIZE - 1)
+#define	MRSTLFB_PAGE_TRUNC (~MRSTLFB_PAGE_MASK)
+
+#define	MRSTLFB_PAGE_ROUNDUP(x) (((x) + MRSTLFB_PAGE_MASK) & MRSTLFB_PAGE_TRUNC)
+#endif
+
+#ifdef	DEBUG
+#define	DEBUG_PRINTK(x) printk x
+#else
+#define	DEBUG_PRINTK(x)
+#endif
+
+#define DISPLAY_DEVICE_NAME "PowerVR Cedartrail Linux Display Driver"
+#define	DRVNAME	"cdvlfb"
+#define	DEVNAME	DRVNAME
+#define	DRIVER_PREFIX DRVNAME
+
+typedef enum _MRST_ERROR_
+{
+	MRST_OK                             =  0,
+	MRST_ERROR_GENERIC                  =  1,
+	MRST_ERROR_OUT_OF_MEMORY            =  2,
+	MRST_ERROR_TOO_FEW_BUFFERS          =  3,
+	MRST_ERROR_INVALID_PARAMS           =  4,
+	MRST_ERROR_INIT_FAILURE             =  5,
+	MRST_ERROR_CANT_REGISTER_CALLBACK   =  6,
+	MRST_ERROR_INVALID_DEVICE           =  7,
+	MRST_ERROR_DEVICE_REGISTER_FAILED   =  8
+} MRST_ERROR;
+
+
+#ifndef UNREFERENCED_PARAMETER
+#define	UNREFERENCED_PARAMETER(param) (param) = (param)
+#endif
+
+MRST_ERROR MRSTLFBInit(struct drm_device * dev);
+MRST_ERROR MRSTLFBDeinit(void);
+
+int MRSTLFBAllocBuffer(struct drm_device *dev, IMG_UINT32 ui32Size, MRSTLFB_BUFFER **ppBuffer);
+int MRSTLFBFreeBuffer(struct drm_device *dev, MRSTLFB_BUFFER **ppBuffer);
+
+void *MRSTLFBAllocKernelMem(unsigned long ulSize);
+void MRSTLFBFreeKernelMem(void *pvMem);
+MRST_ERROR MRSTLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable);
+MRST_ERROR MRSTLFBInstallVSyncISR (MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_VSYNC_ISR_PFN pVsyncHandler);
+MRST_ERROR MRSTLFBUninstallVSyncISR(MRSTLFB_DEVINFO *psDevInfo);
+void MRSTLFBEnableVSyncInterrupt(MRSTLFB_DEVINFO *psDevInfo);
+void MRSTLFBDisableVSyncInterrupt(MRSTLFB_DEVINFO *psDevInfo);
+
+void MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo,  unsigned long uiAddr);
+
+void MRSTLFBSuspend(void);
+void MRSTLFBResume(void);
+int MRSTLFBAllocBufferPages(struct drm_device *dev, IMG_UINT32 ui32Size, MRSTLFB_BUFFER **ppBuffer);
+int MRSTLFBFreeBufferPages(struct drm_device *dev, MRSTLFB_BUFFER **ppBuffer);
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c
new file mode 100644
index 0000000..2b7fa83
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c
@@ -0,0 +1,1745 @@
+/**********************************************************************
+ *
+ * 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 <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+#include <asm/intel_scu_ipc.h>
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+#include "mrstlfb.h"
+
+#include "psb_fb.h"
+#include "psb_drv.h"
+#include "psb_powermgmt.h"
+
+IMG_UINT32 gui32MRSTDisplayDeviceID;
+
+PVRSRV_ERROR MRSTLFBPrePowerState(IMG_HANDLE 		 hDevHandle,
+				  PVRSRV_DEV_POWER_STATE eNewPowerState,
+				  PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+PVRSRV_ERROR MRSTLFBPostPowerState(IMG_HANDLE 		  hDevHandle,
+				   PVRSRV_DEV_POWER_STATE eNewPowerState,
+				   PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+#ifdef MODESET_640x480
+extern int psb_to_640 (struct fb_info* info);
+#endif
+
+extern void mrst_init_LGE_MIPI(struct drm_device *dev);
+extern void mrst_init_NSC_MIPI_bridge(struct drm_device *dev);
+
+struct psbfb_par {
+  struct drm_device *dev;
+  void *psbfb;
+
+  int dpms_state;
+
+  int crtc_count;
+
+  uint32_t crtc_ids[2];
+};
+
+extern void* psbfb_vdc_reg(struct drm_device* dev);
+
+static void *gpvAnchor;
+
+
+#define MRSTLFB_COMMAND_COUNT		1
+
+static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = 0;
+
+static MRSTLFB_DEVINFO * GetAnchorPtr(void)
+{
+	return (MRSTLFB_DEVINFO *)gpvAnchor;
+}
+
+static void SetAnchorPtr(MRSTLFB_DEVINFO *psDevInfo)
+{
+	gpvAnchor = (void*)psDevInfo;
+}
+
+static int MRSTLFB_dimension_match(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_SWAPCHAIN *psSwapChain)
+{
+	int dimension_match = 1;
+
+	/* When the psSwapchain is NULL, it means that it will explicitly switch
+	 * to the system buffer. So it is considered as match.
+	 */
+	if (!psSwapChain) 
+		return dimension_match;
+
+	if ((psSwapChain->ui32Height != psDevInfo->sDisplayDim.ui32Height) ||
+		(psSwapChain->ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride) ||
+		(psSwapChain->ui32Width != psDevInfo->sDisplayDim.ui32Width))
+		dimension_match = 0;
+
+	return dimension_match;
+}
+
+static void MRSTLFBFlip(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_BUFFER *psBuffer, int dim_match)
+{
+	unsigned long ulAddr = (unsigned long)psBuffer->sDevVAddr.uiAddr;
+
+	if (!psDevInfo->bSuspended && !psDevInfo->bLeaveVT && dim_match)
+	{
+		MRSTLFBFlipToSurface(psDevInfo, ulAddr);
+	}
+
+	psDevInfo->ulLastFlipAddr = ulAddr;
+	psDevInfo->bLastFlipAddrValid = MRST_TRUE;
+}
+
+static void MRSTLFBRestoreLastFlip(MRSTLFB_DEVINFO *psDevInfo)
+{
+	if (!psDevInfo->bSuspended && !psDevInfo->bLeaveVT)
+	{
+		if (psDevInfo->bLastFlipAddrValid)
+		{
+			MRSTLFBFlipToSurface(psDevInfo, psDevInfo->ulLastFlipAddr);
+		}
+	}
+}
+
+static void MRSTLFBClearSavedFlip(MRSTLFB_DEVINFO *psDevInfo)
+{
+	psDevInfo->bLastFlipAddrValid = MRST_FALSE;
+}
+
+static void FlushInternalVSyncQueue(MRSTLFB_SWAPCHAIN *psSwapChain, MRST_BOOL bFlip, int dim_match)
+{
+	MRSTLFB_VSYNC_FLIP_ITEM *psFlipItem;
+	unsigned long            ulMaxIndex;
+	unsigned long            i;
+	
+	psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
+	ulMaxIndex = psSwapChain->ulSwapChainLength - 1;
+
+	for(i = 0; i < psSwapChain->ulSwapChainLength; i++)
+	{
+		if (psFlipItem->bValid == MRST_FALSE)
+		{
+			continue;
+		}
+
+		DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Flushing swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex));
+
+		if(psFlipItem->bFlipped == MRST_FALSE)
+		{
+			if (bFlip)
+			{
+				
+				MRSTLFBFlip(psSwapChain->psDevInfo, psFlipItem->psBuffer, dim_match);
+			}
+		}
+		
+		if(psFlipItem->bCmdCompleted == MRST_FALSE)
+		{
+			DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Calling command complete for swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex));
+
+			psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, MRST_TRUE);
+		}
+
+		
+		psSwapChain->ulRemoveIndex++;
+		
+		if(psSwapChain->ulRemoveIndex > ulMaxIndex)
+		{
+			psSwapChain->ulRemoveIndex = 0;
+		}
+
+		
+		psFlipItem->bFlipped = MRST_FALSE;
+		psFlipItem->bCmdCompleted = MRST_FALSE;
+		psFlipItem->bValid = MRST_FALSE;
+		
+		
+		psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
+	}
+
+	psSwapChain->ulInsertIndex = 0;
+	psSwapChain->ulRemoveIndex = 0;
+}
+
+static void DRMLFBFlipBuffer(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_SWAPCHAIN *psSwapChain, MRSTLFB_BUFFER *psBuffer) 
+{
+	int dim_match = MRSTLFB_dimension_match(psDevInfo, psSwapChain);
+	if(psSwapChain != NULL) 
+	{
+		if(psDevInfo->psCurrentSwapChain != NULL)
+		{
+			
+			if(psDevInfo->psCurrentSwapChain != psSwapChain) 
+				FlushInternalVSyncQueue(psDevInfo->psCurrentSwapChain, MRST_FALSE, dim_match);
+		}
+		psDevInfo->psCurrentSwapChain = psSwapChain;
+	}
+
+	MRSTLFBFlip(psDevInfo, psBuffer, dim_match);
+}
+
+static void SetFlushStateNoLock(MRSTLFB_DEVINFO* psDevInfo,
+                                        MRST_BOOL bFlushState)
+{
+	if (bFlushState)
+	{
+		if (psDevInfo->ulSetFlushStateRefCount == 0)
+		{
+			psDevInfo->bFlushCommands = MRST_TRUE;
+			if (psDevInfo->psCurrentSwapChain != NULL)
+			{
+				int dim_match = MRSTLFB_dimension_match(psDevInfo,
+							psDevInfo->psCurrentSwapChain);
+				FlushInternalVSyncQueue(psDevInfo->psCurrentSwapChain, MRST_TRUE, dim_match);
+			}
+		}
+		psDevInfo->ulSetFlushStateRefCount++;
+	}
+	else
+	{
+		if (psDevInfo->ulSetFlushStateRefCount != 0)
+		{
+			psDevInfo->ulSetFlushStateRefCount--;
+			if (psDevInfo->ulSetFlushStateRefCount == 0)
+			{
+				psDevInfo->bFlushCommands = MRST_FALSE;
+			}
+		}
+	}
+}
+
+static IMG_VOID SetFlushState(MRSTLFB_DEVINFO* psDevInfo,
+                                      MRST_BOOL bFlushState)
+{
+	unsigned long ulLockFlags;
+
+	spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+	SetFlushStateNoLock(psDevInfo, bFlushState);
+
+	spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
+}
+
+static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
+{
+	MRSTLFB_DEVINFO *psDevInfo = (MRSTLFB_DEVINFO *)hDevice;
+
+	switch (ui32State)
+	{
+		case DC_STATE_FLUSH_COMMANDS:
+			SetFlushState(psDevInfo, MRST_TRUE);
+			break;
+		case DC_STATE_NO_FLUSH_COMMANDS:
+			SetFlushState(psDevInfo, MRST_FALSE);
+			break;
+		default:
+			break;
+	}
+
+	return;
+}
+
+static int FrameBufferEvents(struct notifier_block *psNotif,
+                             unsigned long event, void *data)
+{
+	MRSTLFB_DEVINFO *psDevInfo;
+	struct fb_event *psFBEvent = (struct fb_event *)data;
+	MRST_BOOL bBlanked;
+
+	
+	if (event != FB_EVENT_BLANK)
+	{
+		return 0;
+	}
+
+	psDevInfo = GetAnchorPtr();
+
+	bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? MRST_TRUE: MRST_FALSE;
+
+	if (bBlanked != psDevInfo->bBlanked)
+	{
+		psDevInfo->bBlanked = bBlanked;
+
+		SetFlushState(psDevInfo, bBlanked);
+	}
+
+	return 0;
+}
+
+
+static MRST_ERROR UnblankDisplay(MRSTLFB_DEVINFO *psDevInfo)
+{
+	int res;
+
+	console_lock();
+	res = fb_blank(psDevInfo->psLINFBInfo, 0);
+	console_unlock();
+	if (res != 0)
+	{
+		printk(KERN_WARNING DRIVER_PREFIX
+			": fb_blank failed (%d)", res);
+		return (MRST_ERROR_GENERIC);
+	}
+
+	return (MRST_OK);
+}
+
+static MRST_ERROR EnableLFBEventNotification(MRSTLFB_DEVINFO *psDevInfo)
+{
+	int                res;
+	MRST_ERROR         eError;
+
+	
+	memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock));
+
+	psDevInfo->sLINNotifBlock.notifier_call = FrameBufferEvents;
+	psDevInfo->bBlanked = MRST_FALSE;
+
+	res = fb_register_client(&psDevInfo->sLINNotifBlock);
+	if (res != 0)
+	{
+		printk(KERN_WARNING DRIVER_PREFIX
+			": fb_register_client failed (%d)", res);
+
+		return (MRST_ERROR_GENERIC);
+	}
+
+	eError = UnblankDisplay(psDevInfo);
+	if (eError != MRST_OK)
+	{
+		DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
+			": UnblankDisplay failed (%d)", eError));
+		return eError;
+	}
+
+	return (MRST_OK);
+}
+
+static MRST_ERROR DisableLFBEventNotification(MRSTLFB_DEVINFO *psDevInfo)
+{
+	int res;
+
+
+	res = fb_unregister_client(&psDevInfo->sLINNotifBlock);
+	if (res != 0)
+	{
+		printk(KERN_WARNING DRIVER_PREFIX
+			": fb_unregister_client failed (%d)", res);
+		return (MRST_ERROR_GENERIC);
+	}
+
+	return (MRST_OK);
+}
+
+static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID,
+                                 IMG_HANDLE *phDevice,
+                                 PVRSRV_SYNC_DATA* psSystemBufferSyncData)
+{
+	MRSTLFB_DEVINFO *psDevInfo;
+	MRST_ERROR eError;
+
+	UNREFERENCED_PARAMETER(ui32DeviceID);
+
+	psDevInfo = GetAnchorPtr();
+
+	
+	psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData;
+
+	psDevInfo->ulSetFlushStateRefCount = 0;
+	psDevInfo->bFlushCommands = MRST_FALSE;
+
+	eError = EnableLFBEventNotification(psDevInfo);
+	if (eError != MRST_OK)
+	{
+		printk(KERN_WARNING DRIVER_PREFIX ": Couldn't enable framebuffer event notification\n");
+		return PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE;
+	}
+
+	
+	*phDevice = (IMG_HANDLE)psDevInfo;
+	
+	return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
+{
+	MRSTLFB_DEVINFO *psDevInfo = (MRSTLFB_DEVINFO *)hDevice;
+	MRST_ERROR eError;
+
+	eError = DisableLFBEventNotification(psDevInfo);
+	if (eError != MRST_OK)
+	{
+		printk(KERN_WARNING DRIVER_PREFIX ": Couldn't disable framebuffer event notification\n");
+		return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
+	}
+
+	return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice,
+                                  IMG_UINT32 *pui32NumFormats,
+                                  DISPLAY_FORMAT *psFormat)
+{
+	MRSTLFB_DEVINFO	*psDevInfo;
+
+	if(!hDevice || !pui32NumFormats)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
+
+	*pui32NumFormats = 1;
+
+	if(psFormat)
+	{
+		psFormat[0] = psDevInfo->sDisplayFormat;
+	}
+
+	return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice,
+                               DISPLAY_FORMAT *psFormat,
+                               IMG_UINT32 *pui32NumDims,
+                               DISPLAY_DIMS *psDim)
+{
+	MRSTLFB_DEVINFO	*psDevInfo;
+
+	if(!hDevice || !psFormat || !pui32NumDims)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
+
+	*pui32NumDims = 1;
+
+
+	if(psDim)
+	{
+		psDim[0] = psDevInfo->sDisplayDim;
+	}
+
+	return (PVRSRV_OK);
+}
+
+
+static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer)
+{
+	MRSTLFB_DEVINFO	*psDevInfo;
+
+	if(!hDevice || !phBuffer)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
+
+	
+	
+	*phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer;
+
+	return (PVRSRV_OK);
+}
+
+
+static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
+{
+	MRSTLFB_DEVINFO	*psDevInfo;
+
+	if(!hDevice || !psDCInfo)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
+
+	*psDCInfo = psDevInfo->sDisplayInfo;
+
+	return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE        hDevice,
+                                    IMG_HANDLE        hBuffer, 
+                                    IMG_SYS_PHYADDR   **ppsSysAddr,
+                                    IMG_SIZE_T        *pui32ByteSize,
+                                    IMG_VOID          **ppvCpuVAddr,
+                                    IMG_HANDLE        *phOSMapInfo,
+                                    IMG_BOOL          *pbIsContiguous,
+	                            IMG_UINT32	      *pui32TilingStride)
+{
+	MRSTLFB_BUFFER *psSystemBuffer;
+
+	UNREFERENCED_PARAMETER(pui32TilingStride);
+
+	if(!hDevice)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	if(!hBuffer)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+	psSystemBuffer = (MRSTLFB_BUFFER *)hBuffer;
+
+	if (!ppsSysAddr)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	if( psSystemBuffer->bIsContiguous ) 
+		*ppsSysAddr = &psSystemBuffer->uSysAddr.sCont;
+	else
+		*ppsSysAddr = psSystemBuffer->uSysAddr.psNonCont;
+
+	if (!pui32ByteSize)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+	*pui32ByteSize = psSystemBuffer->ui32BufferSize;
+
+	if (ppvCpuVAddr)
+	{
+		*ppvCpuVAddr = psSystemBuffer->sCPUVAddr;
+	}
+
+	if (phOSMapInfo)
+	{
+		*phOSMapInfo = (IMG_HANDLE)0;
+	}
+
+	if (pbIsContiguous)
+	{
+		*pbIsContiguous = psSystemBuffer->bIsContiguous;
+	}
+
+	return (PVRSRV_OK);
+}
+
+
+
+static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice,
+                                      IMG_UINT32 ui32Flags,
+                                      DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
+                                      DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
+                                      IMG_UINT32 ui32BufferCount,
+                                      PVRSRV_SYNC_DATA **ppsSyncData,
+                                      IMG_UINT32 ui32OEMFlags,
+                                      IMG_HANDLE *phSwapChain,
+                                      IMG_UINT32 *pui32SwapChainID)
+{
+	MRSTLFB_DEVINFO	*psDevInfo;
+	MRSTLFB_SWAPCHAIN *psSwapChain;
+	MRSTLFB_BUFFER **ppsBuffer;
+	MRSTLFB_VSYNC_FLIP_ITEM *psVSyncFlips;
+	IMG_UINT32 i;
+	IMG_UINT32 iSCId = MAX_SWAPCHAINS;
+	PVRSRV_ERROR eError = PVRSRV_ERROR_NOT_SUPPORTED;
+	unsigned long ulLockFlags;
+	struct drm_device* psDrmDev;
+	unsigned long ulSwapChainLength;
+
+	UNREFERENCED_PARAMETER(ui32OEMFlags);
+	
+	
+	if(!hDevice
+	|| !psDstSurfAttrib
+	|| !psSrcSurfAttrib
+	|| !ppsSyncData
+	|| !phSwapChain)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
+		
+	
+	if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)
+	{
+		return (PVRSRV_ERROR_TOOMANYBUFFERS);
+	}
+	
+	
+	ulSwapChainLength = ui32BufferCount + 1;
+	
+
+	
+	if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat
+	|| psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride
+	|| psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width
+	|| psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height)
+	{
+
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat
+	|| psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride
+	|| psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width
+	|| psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height)
+	{
+
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+
+	UNREFERENCED_PARAMETER(ui32Flags);
+
+
+	psSwapChain = (MRSTLFB_SWAPCHAIN*)MRSTLFBAllocKernelMem(sizeof(MRSTLFB_SWAPCHAIN));
+	if(!psSwapChain)
+	{
+		return (PVRSRV_ERROR_OUT_OF_MEMORY);
+	}
+
+	for(iSCId = 0;iSCId < MAX_SWAPCHAINS;++iSCId) 
+	{
+		if( psDevInfo->apsSwapChains[iSCId] == NULL )
+		{
+			psDevInfo->apsSwapChains[iSCId] = psSwapChain;
+			break;
+		}
+	}
+
+	if(iSCId == MAX_SWAPCHAINS) 
+	{
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto ErrorFreeSwapChain;
+	}
+
+	ppsBuffer = (MRSTLFB_BUFFER**)MRSTLFBAllocKernelMem(sizeof(MRSTLFB_BUFFER*) * ui32BufferCount);
+	if(!ppsBuffer)
+	{
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto ErrorFreeSwapChain;
+	}
+
+	psVSyncFlips = (MRSTLFB_VSYNC_FLIP_ITEM *)MRSTLFBAllocKernelMem(sizeof(MRSTLFB_VSYNC_FLIP_ITEM) * ulSwapChainLength);
+	if (!psVSyncFlips)
+	{
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto ErrorFreeBuffers;
+	}
+
+	psSwapChain->ulSwapChainLength = ulSwapChainLength;
+	psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
+	psSwapChain->ppsBuffer = ppsBuffer;
+	psSwapChain->psVSyncFlips = psVSyncFlips;
+	psSwapChain->ulInsertIndex = 0;
+	psSwapChain->ulRemoveIndex = 0;
+	psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable;
+	/* save the dimension info of system buffer for the new swapchain*/
+	psSwapChain->ui32Height = psDevInfo->sDisplayDim.ui32Height;
+	psSwapChain->ui32ByteStride = psDevInfo->sDisplayDim.ui32ByteStride;
+	psSwapChain->ui32Width = psDevInfo->sDisplayDim.ui32Width;
+	
+	memset(ppsBuffer, 0, sizeof(MRSTLFB_BUFFER *) * ui32BufferCount);
+	for (i = 0; i < ui32BufferCount; i++)
+	{
+		unsigned long bufSize = psDevInfo->sDisplayDim.ui32ByteStride * psDevInfo->sDisplayDim.ui32Height;
+		if (MRSTLFBAllocBufferPages(psDevInfo->psDrmDevice, bufSize, &ppsBuffer[i]) != MRST_OK) {
+			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+			goto ErrorFreeVSyncFlips;
+		}
+		ppsBuffer[i]->psSyncData = ppsSyncData[i];		
+	}
+
+	
+	for (i = 0; i < ulSwapChainLength; i++)
+	{
+		psVSyncFlips[i].bValid = MRST_FALSE;
+		psVSyncFlips[i].bFlipped = MRST_FALSE;
+		psVSyncFlips[i].bCmdCompleted = MRST_FALSE;
+	}
+
+
+	psDrmDev = psDevInfo->psDrmDevice;
+
+	psSwapChain->psDevInfo = psDevInfo;
+	psSwapChain->psDrmDev = psDrmDev;
+	psSwapChain->psDrmDriver = psDrmDev->driver;
+
+	spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
+   
+	psSwapChain->ui32SwapChainID = *pui32SwapChainID = iSCId+1;
+
+	if(psDevInfo->psCurrentSwapChain == NULL)
+		psDevInfo->psCurrentSwapChain = psSwapChain;
+
+	psDevInfo->ui32SwapChainNum++;
+	if(psDevInfo->ui32SwapChainNum == 1)
+	{
+		MRSTLFBEnableVSyncInterrupt(psDevInfo);
+	}
+
+	spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+	
+	*phSwapChain = (IMG_HANDLE)psSwapChain;
+
+	return (PVRSRV_OK);
+
+ErrorFreeVSyncFlips:
+	for (i = 0; i < ui32BufferCount; i++) {
+		MRSTLFBFreeBufferPages(psDevInfo->psDrmDevice, &ppsBuffer[i]);
+	}
+	MRSTLFBFreeKernelMem(psVSyncFlips);
+ErrorFreeBuffers:
+	MRSTLFBFreeKernelMem(ppsBuffer);
+ErrorFreeSwapChain:
+	if(iSCId != MAX_SWAPCHAINS && psDevInfo->apsSwapChains[iSCId] == psSwapChain ) 
+		psDevInfo->apsSwapChains[iSCId] = NULL;	
+	MRSTLFBFreeKernelMem(psSwapChain);
+
+	return eError;
+}
+
+static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
+	IMG_HANDLE hSwapChain)
+{
+	MRSTLFB_DEVINFO	*psDevInfo;
+	MRSTLFB_SWAPCHAIN *psSwapChain;
+	unsigned long ulLockFlags;
+	int i;
+	int dimension_match;
+
+	
+	if(!hDevice || !hSwapChain)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+	
+	psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
+	psSwapChain = (MRSTLFB_SWAPCHAIN*)hSwapChain;
+
+	spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
+	dimension_match =  MRSTLFB_dimension_match(psDevInfo, psSwapChain);
+
+	psDevInfo->ui32SwapChainNum--;
+
+	if(psDevInfo->ui32SwapChainNum == 0) 
+	{
+		MRSTLFBDisableVSyncInterrupt(psDevInfo);
+		psDevInfo->psCurrentSwapChain = NULL;
+	}
+
+	psDevInfo->apsSwapChains[ psSwapChain->ui32SwapChainID -1] = NULL;
+
+	
+	FlushInternalVSyncQueue(psSwapChain, (psDevInfo->ui32SwapChainNum == 0), dimension_match);
+
+	if (psDevInfo->ui32SwapChainNum == 0)
+	{
+		
+		DRMLFBFlipBuffer(psDevInfo, NULL, &psDevInfo->sSystemBuffer);
+		MRSTLFBClearSavedFlip(psDevInfo);
+	}
+
+	if(psDevInfo->psCurrentSwapChain == psSwapChain)
+		psDevInfo->psCurrentSwapChain = NULL;
+
+	spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+	
+	for (i = 0; i < psSwapChain->ulBufferCount; i++)
+	{
+		MRSTLFBFreeBufferPages(psDevInfo->psDrmDevice, &psSwapChain->ppsBuffer[i] );
+	}
+	MRSTLFBFreeKernelMem(psSwapChain->psVSyncFlips);
+	MRSTLFBFreeKernelMem(psSwapChain->ppsBuffer);
+	MRSTLFBFreeKernelMem(psSwapChain);
+
+	return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice,
+	IMG_HANDLE hSwapChain,
+	IMG_RECT *psRect)
+{
+	UNREFERENCED_PARAMETER(hDevice);
+	UNREFERENCED_PARAMETER(hSwapChain);
+	UNREFERENCED_PARAMETER(psRect);
+
+
+
+	return (PVRSRV_ERROR_NOT_SUPPORTED);
+}
+
+static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice,
+                                 IMG_HANDLE hSwapChain,
+                                 IMG_RECT *psRect)
+{
+	UNREFERENCED_PARAMETER(hDevice);
+	UNREFERENCED_PARAMETER(hSwapChain);
+	UNREFERENCED_PARAMETER(psRect);
+
+
+
+	return (PVRSRV_ERROR_NOT_SUPPORTED);
+}
+
+static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice,
+                                      IMG_HANDLE hSwapChain,
+                                      IMG_UINT32 ui32CKColour)
+{
+	UNREFERENCED_PARAMETER(hDevice);
+	UNREFERENCED_PARAMETER(hSwapChain);
+	UNREFERENCED_PARAMETER(ui32CKColour);
+
+
+
+	return (PVRSRV_ERROR_NOT_SUPPORTED);
+}
+
+static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice,
+                                      IMG_HANDLE hSwapChain,
+                                      IMG_UINT32 ui32CKColour)
+{
+	UNREFERENCED_PARAMETER(hDevice);
+	UNREFERENCED_PARAMETER(hSwapChain);
+	UNREFERENCED_PARAMETER(ui32CKColour);
+
+
+
+	return (PVRSRV_ERROR_NOT_SUPPORTED);
+}
+
+static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice,
+                                 IMG_HANDLE hSwapChain,
+                                 IMG_UINT32 *pui32BufferCount,
+                                 IMG_HANDLE *phBuffer)
+{
+	MRSTLFB_SWAPCHAIN *psSwapChain;
+	unsigned long      i;
+
+
+	if(!hDevice
+	|| !hSwapChain
+	|| !pui32BufferCount
+	|| !phBuffer)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	psSwapChain = (MRSTLFB_SWAPCHAIN*)hSwapChain;
+
+
+	*pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount;
+
+
+	for(i=0; i<psSwapChain->ulBufferCount; i++)
+	{
+		phBuffer[i] = (IMG_HANDLE)psSwapChain->ppsBuffer[i];
+	}
+	
+	return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
+                                   IMG_HANDLE hBuffer,
+                                   IMG_UINT32 ui32SwapInterval,
+                                   IMG_HANDLE hPrivateTag,
+                                   IMG_UINT32 ui32ClipRectCount,
+                                   IMG_RECT *psClipRect)
+{
+	UNREFERENCED_PARAMETER(ui32SwapInterval);
+	UNREFERENCED_PARAMETER(hPrivateTag);
+	UNREFERENCED_PARAMETER(psClipRect);
+
+	if(!hDevice
+	|| !hBuffer
+	|| (ui32ClipRectCount != 0))
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice,
+                                   IMG_HANDLE hSwapChain)
+{
+	if(!hDevice || !hSwapChain)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	
+	return (PVRSRV_OK);
+}
+
+static MRST_BOOL MRSTLFBVSyncIHandler(MRSTLFB_DEVINFO *psDevInfo)
+{
+	MRST_BOOL bStatus = MRST_TRUE;
+	MRSTLFB_VSYNC_FLIP_ITEM *psFlipItem;
+	unsigned long ulMaxIndex;
+	unsigned long ulLockFlags;
+	MRSTLFB_SWAPCHAIN *psSwapChain;
+
+	spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+	
+	psSwapChain = psDevInfo->psCurrentSwapChain;
+	if (psSwapChain == NULL)
+	{
+		goto ExitUnlock;
+	}
+
+	
+	if (psDevInfo->bFlushCommands || psDevInfo->bSuspended || psDevInfo->bLeaveVT)
+	{
+		goto ExitUnlock;
+	}
+
+	psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
+	ulMaxIndex = psSwapChain->ulSwapChainLength - 1;
+
+	while(psFlipItem->bValid)
+	{	
+		
+		if(psFlipItem->bFlipped)
+		{
+			
+			if(!psFlipItem->bCmdCompleted)
+			{
+				
+				MRST_BOOL bScheduleMISR;
+				
+				bScheduleMISR = MRST_TRUE;
+
+				
+				psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, bScheduleMISR);
+
+				
+				psFlipItem->bCmdCompleted = MRST_TRUE;
+			}
+
+			
+			psFlipItem->ulSwapInterval--;
+
+		
+			if(psFlipItem->ulSwapInterval == 0)
+			{	
+				
+				psSwapChain->ulRemoveIndex++;
+				
+				if(psSwapChain->ulRemoveIndex > ulMaxIndex)
+				{
+					psSwapChain->ulRemoveIndex = 0;
+				}
+				
+				
+				psFlipItem->bCmdCompleted = MRST_FALSE;
+				psFlipItem->bFlipped = MRST_FALSE;
+	
+				
+				psFlipItem->bValid = MRST_FALSE;
+			}
+			else
+			{
+				
+				break;
+			}
+		}
+		else
+		{
+			
+			DRMLFBFlipBuffer(psDevInfo, psSwapChain, psFlipItem->psBuffer);
+			
+			
+			psFlipItem->bFlipped = MRST_TRUE;
+			
+			
+			break;
+		}
+		
+		
+		psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
+	}
+		
+ExitUnlock:
+	spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+	return bStatus;
+}
+
+#if defined(MRST_USING_INTERRUPTS)
+static int
+MRSTLFBVSyncISR(struct drm_device *psDrmDevice, int iPipe)
+{
+	MRSTLFB_DEVINFO *psDevInfo = GetAnchorPtr();
+	struct drm_psb_private *dev_priv = psb_priv(psDrmDevice);	
+	
+	if (iPipe == dev_priv->ui32MainPipe)
+		MRSTLFBVSyncIHandler(psDevInfo);
+ 	
+	return 0;
+}
+#endif
+
+
+static IMG_BOOL ProcessFlip(IMG_HANDLE  hCmdCookie,
+                            IMG_UINT32  ui32DataSize,
+                            IMG_VOID   *pvData)
+{
+	DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
+	MRSTLFB_DEVINFO *psDevInfo;
+	MRSTLFB_BUFFER *psBuffer;
+	MRSTLFB_SWAPCHAIN *psSwapChain;
+#if defined(MRST_USING_INTERRUPTS)
+	MRSTLFB_VSYNC_FLIP_ITEM* psFlipItem;
+#endif
+	unsigned long ulLockFlags;
+
+
+	if(!hCmdCookie || !pvData)
+	{
+		return IMG_FALSE;
+	}
+
+
+	psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
+
+	if (psFlipCmd == IMG_NULL || sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize)
+	{
+		return IMG_FALSE;
+	}
+
+
+	psDevInfo = (MRSTLFB_DEVINFO*)psFlipCmd->hExtDevice;
+
+	psBuffer = (MRSTLFB_BUFFER*)psFlipCmd->hExtBuffer;
+	psSwapChain = (MRSTLFB_SWAPCHAIN*) psFlipCmd->hExtSwapChain;
+
+	spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+#if defined(MRST_USING_INTERRUPTS)
+	
+	if(psFlipCmd->ui32SwapInterval == 0 || psDevInfo->bFlushCommands)
+	{
+#endif
+		DRMLFBFlipBuffer(psDevInfo, psSwapChain, psBuffer);
+
+		
+	
+		psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE);
+
+#if defined(MRST_USING_INTERRUPTS)
+		goto ExitTrueUnlock;
+	}
+
+	psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulInsertIndex];
+
+	
+	if(psFlipItem->bValid == MRST_FALSE)
+	{
+		unsigned long ulMaxIndex = psSwapChain->ulSwapChainLength - 1;
+		
+		if(psSwapChain->ulInsertIndex == psSwapChain->ulRemoveIndex)
+		{
+			
+			DRMLFBFlipBuffer(psDevInfo, psSwapChain, psBuffer);
+
+			psFlipItem->bFlipped = MRST_TRUE;
+		}
+		else
+		{
+			psFlipItem->bFlipped = MRST_FALSE;
+		}
+
+		psFlipItem->hCmdComplete = (MRST_HANDLE)hCmdCookie;
+		psFlipItem->ulSwapInterval = (unsigned long)psFlipCmd->ui32SwapInterval;
+		psFlipItem->psBuffer = psBuffer;
+		psFlipItem->bValid = MRST_TRUE;
+
+		psSwapChain->ulInsertIndex++;
+		if(psSwapChain->ulInsertIndex > ulMaxIndex)
+		{
+			psSwapChain->ulInsertIndex = 0;
+		}
+
+		goto ExitTrueUnlock;
+	}
+	
+	spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
+	return IMG_FALSE;
+
+ExitTrueUnlock:
+#endif
+	spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
+	return IMG_TRUE;
+}
+
+
+#if defined(PVR_MRST_FB_SET_PAR_ON_INIT)
+static void MRSTFBSetPar(struct fb_info *psLINFBInfo)
+{
+	console_lock();
+
+	if (psLINFBInfo->fbops->fb_set_par != NULL)
+	{
+		int res;
+
+		res = psLINFBInfo->fbops->fb_set_par(psLINFBInfo);
+		if (res != 0)
+		{
+			printk(KERN_WARNING DRIVER_PREFIX
+				": fb_set_par failed: %d\n", res);
+
+		}
+	}
+	else
+	{
+		printk(KERN_WARNING DRIVER_PREFIX
+			": fb_set_par not set - HW cursor may not work\n");
+	}
+
+	console_unlock();
+}
+#endif
+
+void MRSTLFBSuspend(void)
+{
+	MRSTLFB_DEVINFO *psDevInfo = GetAnchorPtr();
+	unsigned long ulLockFlags;
+
+	spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+	if (!psDevInfo->bSuspended)
+	{
+#if !defined(PVR_MRST_STYLE_PM)
+		if(psDevInfo->ui32SwapChainNum != 0)
+		{
+			MRSTLFBDisableVSyncInterrupt(psDevInfo);
+		}
+#endif
+		psDevInfo->bSuspended = MRST_TRUE;
+	}
+
+	spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
+}
+
+void MRSTLFBResume(void)
+{
+	MRSTLFB_DEVINFO *psDevInfo = GetAnchorPtr();
+	unsigned long ulLockFlags;
+
+	spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+	if (psDevInfo->bSuspended)
+	{
+#if !defined(PVR_MRST_STYLE_PM)
+		if(psDevInfo->ui32SwapChainNum != 0)
+		{
+			MRSTLFBEnableVSyncInterrupt(psDevInfo);
+		}
+#endif
+		psDevInfo->bSuspended = MRST_FALSE;
+
+		MRSTLFBRestoreLastFlip(psDevInfo);
+	}
+
+	spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+#if !defined(PVR_MRST_STYLE_PM)
+	(void) UnblankDisplay(psDevInfo);
+#endif
+}
+
+#ifdef DRM_PVR_USE_INTEL_FB
+#include "mm.h"
+int MRSTLFBHandleChangeFB(struct drm_device* dev, struct psb_framebuffer *psbfb)
+{
+	MRSTLFB_DEVINFO *psDevInfo = GetAnchorPtr();
+	int i;
+	struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
+	struct psb_gtt * pg = dev_priv->pg;
+	LinuxMemArea *psLinuxMemArea = NULL;
+	MRSTLFB_BUFFER *pBuffer;
+
+	if (!psDevInfo->sSystemBuffer.bIsContiguous) {
+		MRSTLFBFreeKernelMem( psDevInfo->sSystemBuffer.uSysAddr.psNonCont );
+		psDevInfo->sSystemBuffer.uSysAddr.psNonCont = NULL;
+	}
+	psDevInfo->sDisplayFormat.pixelformat = (psbfb->base.depth == 16) ? PVRSRV_PIXEL_FORMAT_RGB565 : PVRSRV_PIXEL_FORMAT_ARGB8888;
+
+	psDevInfo->sDisplayDim.ui32ByteStride = psbfb->base.pitch;
+	psDevInfo->sDisplayDim.ui32Width = psbfb->base.width;
+	psDevInfo->sDisplayDim.ui32Height = psbfb->base.height;
+
+	psDevInfo->sSystemBuffer.ui32BufferSize = psbfb->size;
+
+	if (psbfb->pvrBO != NULL)
+	{
+		psDevInfo->sSystemBuffer.sCPUVAddr = psbfb->pvrBO->pvLinAddrKM;
+		psDevInfo->sSystemBuffer.sDevVAddr.uiAddr = psbfb->offset;
+	}
+	else
+	{
+		if (dev_priv->fb_reloc) {
+			/* 
+			 * the frame buffer has been relocated
+			 * because the stolen memory isn't large enough
+			 */
+			pBuffer = (MRSTLFB_BUFFER *)dev_priv->fb_reloc;
+			psDevInfo->sSystemBuffer.sCPUVAddr = pBuffer->sCPUVAddr;
+			psDevInfo->sSystemBuffer.sDevVAddr.uiAddr = pBuffer->sDevVAddr.uiAddr;
+		} else {
+			psDevInfo->sSystemBuffer.sCPUVAddr = pg->vram_addr;
+			psDevInfo->sSystemBuffer.sDevVAddr.uiAddr = 0;
+		}
+	}
+
+	psDevInfo->sSystemBuffer.bIsAllocated = MRST_FALSE;
+
+	if (psbfb->pvrBO != NULL)
+	{
+		psLinuxMemArea = (LinuxMemArea *)psbfb->pvrBO->sMemBlk.hOSMemHandle;
+	}
+
+	if ((dev_priv->fb_reloc == NULL) &&
+	    ((psbfb->pvrBO == NULL) || (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ALLOC_PAGES)))
+	{
+		psDevInfo->sSystemBuffer.bIsContiguous = MRST_TRUE;
+		psDevInfo->sSystemBuffer.uSysAddr.sCont.uiAddr = pg->stolen_base;
+	} else {
+		psDevInfo->sSystemBuffer.bIsContiguous = MRST_FALSE;
+		psDevInfo->sSystemBuffer.uSysAddr.psNonCont = MRSTLFBAllocKernelMem( sizeof( IMG_SYS_PHYADDR ) * (psbfb->size >> PAGE_SHIFT));	
+		if (psDevInfo->sSystemBuffer.uSysAddr.psNonCont == NULL) {
+			WARN_ON_ONCE(1);
+			printk(KERN_ERR "Out of Memory in HandleChangeFB\n");
+			return -ENOMEM;
+		}
+		if (dev_priv->fb_reloc && (psbfb->pvrBO == NULL)) {
+			pBuffer = (MRSTLFB_BUFFER *)dev_priv->fb_reloc;
+			for (i = 0; i < psbfb->size >> PAGE_SHIFT; i++)
+				psDevInfo->sSystemBuffer.uSysAddr.psNonCont[i].uiAddr =
+					pBuffer->uSysAddr.psNonCont[i].uiAddr;
+		} else {
+			struct page **page_list = psLinuxMemArea->uData.sPageList.pvPageList;
+			for (i = 0; i < psbfb->size >> PAGE_SHIFT; i++)
+				psDevInfo->sSystemBuffer.uSysAddr.psNonCont[i].uiAddr =
+					page_to_pfn(page_list[i]) << PAGE_SHIFT;
+		}
+	}
+
+	return 0;
+}
+
+
+uint32_t MRSTLFBGetSize(MRSTLFB_BUFFER *pBuffer)
+{
+	return pBuffer->ui32BufferSize;
+}
+
+void* MRSTLFBGetCPUVAddr(MRSTLFB_BUFFER *pBuffer)
+{
+	return pBuffer->sCPUVAddr;
+}
+
+uint32_t MRSTLFBGetDevVAddr(MRSTLFB_BUFFER *pBuffer)
+{
+	return pBuffer->sDevVAddr.uiAddr;
+}
+
+#endif
+
+static int MRSTLFBFindMainPipe(struct drm_device *dev)  
+{
+	struct drm_crtc *crtc;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)  
+	{
+		if ( drm_helper_crtc_in_use(crtc) ) 
+		{
+			struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+			return psb_intel_crtc->pipe;
+		}
+	}	
+	
+	return 0;
+}
+
+
+static MRST_ERROR InitDev(MRSTLFB_DEVINFO *psDevInfo)
+{
+	MRST_ERROR eError = MRST_ERROR_GENERIC;
+	struct fb_info *psLINFBInfo;
+	struct drm_device * psDrmDevice = psDevInfo->psDrmDevice;
+	struct drm_psb_private * psDrmPrivate = (struct drm_psb_private *)psDrmDevice->dev_private;
+	struct psb_fbdev * psPsbFBDev = (struct psb_fbdev *)psDrmPrivate->fbdev;
+	struct drm_framebuffer * psDrmFB;
+	struct psb_framebuffer *psbfb;
+	int i;
+
+	psDrmFB = psPsbFBDev->psb_fb_helper.fb;
+	if(!psDrmFB) {
+		printk(KERN_INFO"%s:Cannot find drm FB", __FUNCTION__);
+		return eError;
+	}
+	psbfb = to_psb_fb(psDrmFB);
+
+	psLINFBInfo = (struct fb_info*)psPsbFBDev->psb_fb_helper.fbdev;
+
+#if defined(PVR_MRST_FB_SET_PAR_ON_INIT)
+	MRSTFBSetPar(psLINFBInfo);
+#endif
+
+	
+	psDevInfo->sSystemBuffer.bIsContiguous = MRST_TRUE;
+	psDevInfo->sSystemBuffer.bIsAllocated = MRST_FALSE;
+
+	MRSTLFBHandleChangeFB(psDrmDevice, psbfb);
+
+    
+	psDevInfo->sDisplayFormat.pixelformat = PVRSRV_PIXEL_FORMAT_ARGB8888;
+	psDevInfo->psLINFBInfo = psLINFBInfo;
+
+	/*
+	 * Ugly. This will always select the pipe B as the main pipe on CDV.
+	 * If the external monitor is connected during loading the gfx kernel driver,
+	 * it will select the pipe A as the main pipe. Then maybe the wrong main pipe
+	 * is selected when the external monitor is explicitly turned off.
+	 * To be simple, currently we only choose the LVDS pipe as the main pipe.
+	 * Otherwise we will have to handle the scenario when the main pipe is switched.
+	 */
+	psDevInfo->ui32MainPipe = MRSTLFBFindMainPipe(psDevInfo->psDrmDevice);
+	psDrmPrivate->ui32MainPipe = psDevInfo->ui32MainPipe;
+	DRM_DEBUG_KMS("main pipe is %d\n", psDrmPrivate->ui32MainPipe);
+	
+	for(i = 0;i < MAX_SWAPCHAINS;++i) 
+	{
+		psDevInfo->apsSwapChains[i] = NULL;
+	}
+
+	
+	
+	
+	psDevInfo->pvRegs = psbfb_vdc_reg(psDevInfo->psDrmDevice);
+
+	if (psDevInfo->pvRegs == NULL)
+	{
+		eError = PVRSRV_ERROR_BAD_MAPPING;
+		printk(KERN_WARNING DRIVER_PREFIX ": Couldn't map registers needed for flipping\n");
+		return eError;
+	}
+
+	return MRST_OK;
+}
+
+static void DeInitDev(MRSTLFB_DEVINFO *psDevInfo)
+{
+
+}
+
+MRST_ERROR MRSTLFBInit(struct drm_device * dev)
+{
+	MRSTLFB_DEVINFO		*psDevInfo;
+	//struct drm_psb_private *psDrmPriv = (struct drm_psb_private *)dev->dev_private;
+
+	psDevInfo = GetAnchorPtr();
+
+	if (psDevInfo == NULL)
+	{
+		PFN_CMD_PROC	 		pfnCmdProcList[MRSTLFB_COMMAND_COUNT];
+		IMG_UINT32				aui32SyncCountList[MRSTLFB_COMMAND_COUNT][2];
+
+		psDevInfo = (MRSTLFB_DEVINFO *)MRSTLFBAllocKernelMem(sizeof(MRSTLFB_DEVINFO));
+
+		if(!psDevInfo)
+		{
+			return (MRST_ERROR_OUT_OF_MEMORY);
+		}
+
+
+		memset(psDevInfo, 0, sizeof(MRSTLFB_DEVINFO));
+
+
+		SetAnchorPtr((void*)psDevInfo);
+
+		psDevInfo->psDrmDevice = dev;
+		psDevInfo->ulRefCount = 0;
+
+
+		if(InitDev(psDevInfo) != MRST_OK)
+		{
+			return (MRST_ERROR_INIT_FAILURE);
+		}
+
+		if(MRSTLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &pfnGetPVRJTable) != MRST_OK)
+		{
+			return (MRST_ERROR_INIT_FAILURE);
+		}
+
+
+		if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable))
+		{
+			return (MRST_ERROR_INIT_FAILURE);
+		}
+
+
+		spin_lock_init(&psDevInfo->sSwapChainLock);
+
+		psDevInfo->psCurrentSwapChain = NULL;
+		psDevInfo->bFlushCommands = MRST_FALSE;
+
+		psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = MAX_FLIPBUFFERS;
+		psDevInfo->sDisplayInfo.ui32MaxSwapChains = MAX_SWAPCHAINS;
+		psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3;
+		psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0;
+
+		strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
+	
+
+		DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+			": Maximum number of swap chain buffers: %u\n",
+			psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers));
+
+
+		
+
+		psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
+		psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
+		psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
+		psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
+		psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
+		psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
+		psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
+		psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
+		psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
+		psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain;
+		psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
+		psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
+		psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
+		psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
+		psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
+		psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
+		psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem;
+		psDevInfo->sDCJTable.pfnSetDCState = SetDCState;
+
+
+		if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice (
+			&psDevInfo->sDCJTable,
+			&psDevInfo->uiDeviceID ) != PVRSRV_OK)
+		{
+			return (MRST_ERROR_DEVICE_REGISTER_FAILED);
+		}
+
+		printk("Device ID: %d\n", (int)psDevInfo->uiDeviceID);
+
+
+#if defined (MRST_USING_INTERRUPTS)
+	
+	if(MRSTLFBInstallVSyncISR(psDevInfo,MRSTLFBVSyncISR) != MRST_OK)
+	{
+		DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX	"ISR Installation failed\n"));
+		return (MRST_ERROR_INIT_FAILURE);
+	}
+#endif
+
+	
+	pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
+	
+	
+	aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; 
+	aui32SyncCountList[DC_FLIP_COMMAND][1] = 2; 
+	
+
+	if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList (psDevInfo->uiDeviceID,
+								&pfnCmdProcList[0],
+								aui32SyncCountList,
+								MRSTLFB_COMMAND_COUNT) != PVRSRV_OK)
+	  {
+	    printk(KERN_WARNING DRIVER_PREFIX ": Can't register callback\n");
+	    return (MRST_ERROR_CANT_REGISTER_CALLBACK);
+	  }
+
+
+	}
+
+	
+	//psDrmPriv->psb_change_fb_handler = MRSTLFBHandleChangeFB;	
+
+	//psDrmPriv->psb_leave_vt_handler = DRMLFBLeaveVTHandler;
+	//psDrmPriv->psb_enter_vt_handler = DRMLFBEnterVTHandler;
+	
+	psDevInfo->ulRefCount++;
+
+	
+	return (MRST_OK);	
+}
+
+MRST_ERROR MRSTLFBDeinit(void)
+{
+	MRSTLFB_DEVINFO *psDevInfo, *psDevFirst;
+
+	psDevFirst = GetAnchorPtr();
+	psDevInfo = psDevFirst;
+
+
+	if (psDevInfo == NULL)
+	{
+		return (MRST_ERROR_GENERIC);
+	}
+
+
+	psDevInfo->ulRefCount--;
+
+	psDevInfo->psDrmDevice = NULL;
+	if (psDevInfo->ulRefCount == 0)
+	{
+
+		PVRSRV_DC_DISP2SRV_KMJTABLE	*psJTable = &psDevInfo->sPVRJTable;
+
+		if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList (psDevInfo->uiDeviceID, MRSTLFB_COMMAND_COUNT) != PVRSRV_OK)
+		{
+			return (MRST_ERROR_GENERIC);
+		}
+
+		if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterPowerDevice((IMG_UINT32)psDevInfo->uiDeviceID,
+								       IMG_NULL, IMG_NULL,
+								       IMG_NULL, IMG_NULL, IMG_NULL,
+								       PVRSRV_DEV_POWER_STATE_ON,
+								       PVRSRV_DEV_POWER_STATE_ON) != PVRSRV_OK)
+		{
+			return (MRST_ERROR_GENERIC);
+		}
+
+
+#if defined (MRST_USING_INTERRUPTS)
+		
+		if(MRSTLFBUninstallVSyncISR(psDevInfo) != MRST_OK)
+		{
+			return (MRST_ERROR_GENERIC);
+		}
+#endif
+
+		if (psJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->uiDeviceID) != PVRSRV_OK)
+		{
+			return (MRST_ERROR_GENERIC);
+		}
+
+		DeInitDev(psDevInfo);
+
+
+		MRSTLFBFreeKernelMem(psDevInfo);
+	}
+
+
+	SetAnchorPtr(NULL);
+
+
+	return (MRST_OK);
+}
+
+int MRSTLFBAllocBuffer(struct drm_device *dev, IMG_UINT32 ui32Size, MRSTLFB_BUFFER **ppBuffer)
+
+{
+	IMG_VOID *pvBuf;
+	IMG_UINT32 ulPagesNumber;
+	IMG_UINT32 ulCounter;
+	int i, ret;
+
+	pvBuf = __vmalloc( ui32Size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, __pgprot((pgprot_val(PAGE_KERNEL ) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) );
+	if( pvBuf == NULL )
+	{
+		return MRST_ERROR_OUT_OF_MEMORY;
+	}
+
+	ulPagesNumber = (ui32Size + PAGE_SIZE -1) / PAGE_SIZE;
+
+	*ppBuffer = MRSTLFBAllocKernelMem( sizeof( MRSTLFB_BUFFER ) );
+	if (*ppBuffer == NULL) {
+		/* Free the allocated memory */
+		vfree(pvBuf);
+		return MRST_ERROR_OUT_OF_MEMORY;
+	}
+
+	(*ppBuffer)->sCPUVAddr = pvBuf;
+	(*ppBuffer)->ui32BufferSize = ui32Size;
+	(*ppBuffer)->uSysAddr.psNonCont = MRSTLFBAllocKernelMem( sizeof( IMG_SYS_PHYADDR ) * ulPagesNumber);
+
+	if ((*ppBuffer)->uSysAddr.psNonCont == NULL) {
+		/* Free the allocated memory */
+		vfree(pvBuf);
+		MRSTLFBFreeKernelMem(*ppBuffer);
+		*ppBuffer = NULL;
+		return MRST_ERROR_OUT_OF_MEMORY;
+	}
+
+	(*ppBuffer)->bIsAllocated = MRST_TRUE;
+	(*ppBuffer)->bIsContiguous = MRST_FALSE;
+	(*ppBuffer)->ui32OwnerTaskID = task_tgid_nr(current);
+	(*ppBuffer)->bFromPages	= MRST_FALSE;
+
+	i = 0;
+	for(ulCounter = 0; ulCounter < ui32Size; ulCounter += PAGE_SIZE)
+	{
+		(*ppBuffer)->uSysAddr.psNonCont[i++].uiAddr = vmalloc_to_pfn( pvBuf + ulCounter ) << PAGE_SHIFT;
+	}
+
+	ret = psb_gtt_map_pvr_memory(dev, (unsigned int)*ppBuffer,
+					(*ppBuffer)->ui32OwnerTaskID,
+					(IMG_CPU_PHYADDR*) (*ppBuffer)->uSysAddr.psNonCont,
+					ulPagesNumber, &(*ppBuffer)->sDevVAddr.uiAddr );
+	if (ret == 0) {
+		(*ppBuffer)->sDevVAddr.uiAddr <<= PAGE_SHIFT;
+
+		return MRST_OK;
+	} else {
+		vfree(pvBuf);
+		MRSTLFBFreeKernelMem((*ppBuffer)->uSysAddr.psNonCont);
+		MRSTLFBFreeKernelMem(*ppBuffer);
+		*ppBuffer = NULL;
+		return MRST_ERROR_OUT_OF_MEMORY;	
+	}
+}
+
+int MRSTLFBFreeBuffer(struct drm_device *dev, MRSTLFB_BUFFER **ppBuffer)
+{
+	if((*ppBuffer == NULL) || !(*ppBuffer)->bIsAllocated ||
+					(*ppBuffer)->bFromPages)
+		return MRST_ERROR_INVALID_PARAMS;
+
+	psb_gtt_unmap_pvr_memory(dev, (unsigned int)*ppBuffer,
+				 (*ppBuffer)->ui32OwnerTaskID);
+
+	vfree( (*ppBuffer)->sCPUVAddr );
+
+	MRSTLFBFreeKernelMem( (*ppBuffer)->uSysAddr.psNonCont );
+
+	MRSTLFBFreeKernelMem( *ppBuffer);
+
+	*ppBuffer = NULL;
+
+	return MRST_OK;
+}
+
+int MRSTLFBAllocBufferPages(struct drm_device *dev, IMG_UINT32 ui32Size, MRSTLFB_BUFFER **ppBuffer)
+{
+	IMG_UINT32 ulPagesNumber;
+	int i, ret;
+	int pagecount;
+	struct page *temp_page;
+
+	ulPagesNumber = (ui32Size + PAGE_SIZE -1) / PAGE_SIZE;
+
+	*ppBuffer = MRSTLFBAllocKernelMem( sizeof( MRSTLFB_BUFFER ) + ulPagesNumber * sizeof (struct pages *));
+	if (*ppBuffer == NULL) {
+		return MRST_ERROR_OUT_OF_MEMORY;
+	}
+
+	(*ppBuffer)->sCPUVAddr = NULL;
+	(*ppBuffer)->ui32BufferSize = ui32Size;
+	(*ppBuffer)->uSysAddr.psNonCont = MRSTLFBAllocKernelMem( sizeof( IMG_SYS_PHYADDR ) * ulPagesNumber);
+
+	if ((*ppBuffer)->uSysAddr.psNonCont == NULL) {
+		/* Free the allocated memory */
+		MRSTLFBFreeKernelMem(*ppBuffer);
+		*ppBuffer = NULL;
+		return MRST_ERROR_OUT_OF_MEMORY;
+	}
+	pagecount = 0;
+	for (i = 0; i < ulPagesNumber; i++) {
+		temp_page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
+                if (temp_page == NULL)
+                        goto error_page;
+
+                get_page(temp_page);
+        	(*ppBuffer)->buffer_pages[i] = temp_page;
+		pagecount++;        
+	}
+	(*ppBuffer)->bIsAllocated = MRST_TRUE;
+	(*ppBuffer)->bIsContiguous = MRST_FALSE;
+	(*ppBuffer)->ui32OwnerTaskID = task_tgid_nr(current);
+	(*ppBuffer)->bFromPages	= MRST_TRUE;
+	set_pages_array_uc((*ppBuffer)->buffer_pages, ulPagesNumber);
+	for( i=0; i < ulPagesNumber; i++)
+	{
+		(*ppBuffer)->uSysAddr.psNonCont[i].uiAddr = page_to_pfn((*ppBuffer)->buffer_pages[i]) << PAGE_SHIFT;
+	}
+
+	ret = psb_gtt_map_pvr_memory(dev, (unsigned int)*ppBuffer,
+					(*ppBuffer)->ui32OwnerTaskID,
+					(IMG_CPU_PHYADDR*) (*ppBuffer)->uSysAddr.psNonCont,
+					ulPagesNumber, &(*ppBuffer)->sDevVAddr.uiAddr );
+	if (ret)
+		goto error_map_pvr;
+
+	(*ppBuffer)->sDevVAddr.uiAddr <<= PAGE_SHIFT;
+	return MRST_OK;
+
+error_map_pvr:
+	set_pages_array_wb((*ppBuffer)->buffer_pages, ulPagesNumber);
+error_page:
+	for (i = 0; i < pagecount; i++) {
+		temp_page = (*ppBuffer)->buffer_pages[i];
+		put_page(temp_page);
+		__free_page(temp_page);
+	}
+	MRSTLFBFreeKernelMem((*ppBuffer)->uSysAddr.psNonCont);
+	MRSTLFBFreeKernelMem(*ppBuffer);
+	*ppBuffer = NULL;
+	return MRST_ERROR_OUT_OF_MEMORY;	
+	
+}
+
+
+int MRSTLFBFreeBufferPages(struct drm_device *dev, MRSTLFB_BUFFER **ppBuffer)
+{
+	int i, ulPagesNumber;
+	struct page *temp_page;
+	if((*ppBuffer == NULL) || !(*ppBuffer)->bIsAllocated || !(*ppBuffer)->bFromPages)
+		return MRST_ERROR_INVALID_PARAMS;
+
+	ulPagesNumber = ((*ppBuffer)->ui32BufferSize + PAGE_SIZE -1) / PAGE_SIZE;
+	psb_gtt_unmap_pvr_memory(dev, (unsigned int)*ppBuffer,
+				 (*ppBuffer)->ui32OwnerTaskID);
+	
+	set_pages_array_wb((*ppBuffer)->buffer_pages, ulPagesNumber);
+	for (i = 0; i < ulPagesNumber; i++) {
+		temp_page = (*ppBuffer)->buffer_pages[i];
+		put_page(temp_page);
+		__free_page(temp_page);
+	}
+	MRSTLFBFreeKernelMem( (*ppBuffer)->uSysAddr.psNonCont );
+
+	MRSTLFBFreeKernelMem( *ppBuffer);
+
+	*ppBuffer = NULL;
+
+	return MRST_OK;
+}
diff --git a/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c
new file mode 100644
index 0000000..d33bfad
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c
@@ -0,0 +1,192 @@
+/**********************************************************************
+ *
+ * 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 <linux/version.h>
+
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+
+#include <drm/drmP.h>
+
+#include <asm/io.h>
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+#include "pvrmodule.h"
+#include "pvr_drm.h"
+#include "mrstlfb.h"
+#include "kerneldisplay.h"
+#include "psb_irq.h"
+
+#include "psb_drv.h"
+
+#define	MAKESTRING(x) # x
+
+#if !defined(DISPLAY_CONTROLLER)
+#define DISPLAY_CONTROLLER pvrlfb
+#endif
+
+//#define MAKENAME_HELPER(x, y) x ## y
+//#define	MAKENAME2(x, y) MAKENAME_HELPER(x, y)
+//#define	MAKENAME(x) MAKENAME2(DISPLAY_CONTROLLER, x)
+
+#define unref__ __attribute__ ((unused))
+
+
+extern int fb_idx;
+
+void *MRSTLFBAllocKernelMem(unsigned long ulSize)
+{
+	return kzalloc(ulSize, GFP_KERNEL);
+}
+
+void MRSTLFBFreeKernelMem(void *pvMem)
+{
+	kfree(pvMem);
+}
+
+
+MRST_ERROR MRSTLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable)
+{
+	if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0)
+	{
+		return (MRST_ERROR_INVALID_PARAMS);
+	}
+
+
+	*ppfnFuncTable = PVRGetDisplayClassJTable;
+
+	return (MRST_OK);
+}
+
+static void MRSTLFBVSyncWriteReg(MRSTLFB_DEVINFO *psDevInfo, unsigned long ulOffset, unsigned long ulValue)
+{
+
+	void *pvRegAddr = (void *)(psDevInfo->pvRegs + ulOffset);
+	mb();
+	iowrite32(ulValue, pvRegAddr);
+}
+
+unsigned long MRSTLFBVSyncReadReg(MRSTLFB_DEVINFO * psDevinfo, unsigned long ulOffset)
+{
+	mb();
+	return ioread32((char *)psDevinfo->pvRegs + ulOffset);
+}
+
+void MRSTLFBEnableVSyncInterrupt(MRSTLFB_DEVINFO * psDevinfo)
+{
+#if defined(MRST_USING_INTERRUPTS)
+    struct drm_psb_private *dev_priv =
+	(struct drm_psb_private *) psDevinfo->psDrmDevice->dev_private;
+    dev_priv->vblanksEnabledForFlips = true;
+    psb_enable_vblank(psDevinfo->psDrmDevice, dev_priv->ui32MainPipe);
+#endif
+}
+
+void MRSTLFBDisableVSyncInterrupt(MRSTLFB_DEVINFO * psDevinfo)
+{
+#if defined(MRST_USING_INTERRUPTS)
+    struct drm_device * dev = psDevinfo->psDrmDevice;
+    struct drm_psb_private *dev_priv =
+	(struct drm_psb_private *) psDevinfo->psDrmDevice->dev_private;
+    dev_priv->vblanksEnabledForFlips = false;
+    if (!dev->vblank_enabled[dev_priv->ui32MainPipe])
+	psb_disable_vblank(psDevinfo->psDrmDevice, dev_priv->ui32MainPipe);
+#endif
+}
+
+#if defined(MRST_USING_INTERRUPTS)
+MRST_ERROR MRSTLFBInstallVSyncISR(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_VSYNC_ISR_PFN pVsyncHandler)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
+	dev_priv->psb_vsync_handler = pVsyncHandler;
+	return (MRST_OK);
+}
+
+
+MRST_ERROR MRSTLFBUninstallVSyncISR(MRSTLFB_DEVINFO	*psDevInfo)
+{
+	struct drm_psb_private *dev_priv =
+	    (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
+	dev_priv->psb_vsync_handler = NULL;
+	return (MRST_OK);
+}
+#endif 
+
+
+void MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo,  unsigned long uiAddr)
+{
+	int dspbase = (psDevInfo->ui32MainPipe == 0 ? DSPABASE : DSPBBASE);
+	int dspsurf = (psDevInfo->ui32MainPipe == 0 ? DSPASURF : DSPBSURF);
+
+	if (IS_CDV(psDevInfo->psDrmDevice)) {
+		dspsurf = DSPASURF;
+		MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
+
+		dspsurf = DSPBSURF;
+		MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
+	} else {
+		MRSTLFBVSyncWriteReg(psDevInfo, dspbase, uiAddr);
+	}
+}
+
+
+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev)
+{
+	if(MRSTLFBInit(dev) != MRST_OK)
+	{
+		printk(KERN_WARNING DRIVER_PREFIX ": MRSTLFB_Init: MRSTLFBInit failed\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev)
+{    
+	if(MRSTLFBDeinit() != MRST_OK)
+	{
+		printk(KERN_WARNING DRIVER_PREFIX "%s: can't deinit device\n", __FUNCTION__);
+	}
+}
+
+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Suspend)(struct drm_device unref__ *dev)
+{
+	MRSTLFBSuspend();
+
+	return 0;
+}
+
+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Resume)(struct drm_device unref__ *dev)
+{
+	MRSTLFBResume();
+
+	return 0;
+}
diff --git a/drivers/staging/cdv/pvr/services4/include/env/linux-intel/pvr_drm_shared.h b/drivers/staging/cdv/pvr/services4/include/env/linux-intel/pvr_drm_shared.h
new file mode 100644
index 0000000..5510cf9
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/env/linux-intel/pvr_drm_shared.h
@@ -0,0 +1,50 @@
+/**********************************************************************
+ *
+ * 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(__PVR_DRM_SHARED_H__)
+#define __PVR_DRM_SHARED_H__
+
+#define PVR_DRM_SRVKM_CMD	0x12
+#define	PVR_DRM_DISP_CMD	0x13
+#define	PVR_DRM_BC_CMD		0x14
+#define PVR_DRM_IS_MASTER_CMD	0x15
+#define PVR_DRM_UNPRIV_CMD	0x16
+#define PVR_DRM_DBGDRV_CMD	0x1E
+
+#define	PVR_DRM_UNPRIV_INIT_SUCCESFUL	0
+#define	PVR_DRM_UNPRIV_BUSID_TYPE	1
+#define	PVR_DRM_UNPRIV_BUSID_FIELD	2
+
+#define	PVR_DRM_BUS_TYPE_PCI		0
+
+#define	PVR_DRM_PCI_DOMAIN		0
+#define	PVR_DRM_PCI_BUS			1
+#define	PVR_DRM_PCI_DEV			2
+#define	PVR_DRM_PCI_FUNC		3
+
+#endif
+
+
diff --git a/drivers/staging/cdv/pvr/services4/include/env/linux/pvr_drm_shared.h b/drivers/staging/cdv/pvr/services4/include/env/linux/pvr_drm_shared.h
new file mode 100644
index 0000000..5510cf9
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/env/linux/pvr_drm_shared.h
@@ -0,0 +1,50 @@
+/**********************************************************************
+ *
+ * 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(__PVR_DRM_SHARED_H__)
+#define __PVR_DRM_SHARED_H__
+
+#define PVR_DRM_SRVKM_CMD	0x12
+#define	PVR_DRM_DISP_CMD	0x13
+#define	PVR_DRM_BC_CMD		0x14
+#define PVR_DRM_IS_MASTER_CMD	0x15
+#define PVR_DRM_UNPRIV_CMD	0x16
+#define PVR_DRM_DBGDRV_CMD	0x1E
+
+#define	PVR_DRM_UNPRIV_INIT_SUCCESFUL	0
+#define	PVR_DRM_UNPRIV_BUSID_TYPE	1
+#define	PVR_DRM_UNPRIV_BUSID_FIELD	2
+
+#define	PVR_DRM_BUS_TYPE_PCI		0
+
+#define	PVR_DRM_PCI_DOMAIN		0
+#define	PVR_DRM_PCI_BUS			1
+#define	PVR_DRM_PCI_DEV			2
+#define	PVR_DRM_PCI_FUNC		3
+
+#endif
+
+
diff --git a/drivers/staging/cdv/pvr/services4/include/kernelbuffer.h b/drivers/staging/cdv/pvr/services4/include/kernelbuffer.h
new file mode 100644
index 0000000..4cd36d2
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/kernelbuffer.h
@@ -0,0 +1,72 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined (__KERNELBUFFER_H__)
+#define __KERNELBUFFER_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+typedef PVRSRV_ERROR (*PFN_OPEN_BC_DEVICE)(IMG_UINT32, IMG_HANDLE*);
+typedef PVRSRV_ERROR (*PFN_CLOSE_BC_DEVICE)(IMG_UINT32, IMG_HANDLE);
+typedef PVRSRV_ERROR (*PFN_GET_BC_INFO)(IMG_HANDLE, BUFFER_INFO*);
+typedef PVRSRV_ERROR (*PFN_GET_BC_BUFFER)(IMG_HANDLE, IMG_UINT32, PVRSRV_SYNC_DATA*, IMG_HANDLE*);
+
+typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG
+{
+	IMG_UINT32							ui32TableSize;
+	PFN_OPEN_BC_DEVICE					pfnOpenBCDevice;
+	PFN_CLOSE_BC_DEVICE					pfnCloseBCDevice;
+	PFN_GET_BC_INFO						pfnGetBCInfo;
+	PFN_GET_BC_BUFFER					pfnGetBCBuffer;
+	PFN_GET_BUFFER_ADDR					pfnGetBufferAddr;
+
+} PVRSRV_BC_SRV2BUFFER_KMJTABLE;
+
+
+typedef PVRSRV_ERROR (*PFN_BC_REGISTER_BUFFER_DEV)(PVRSRV_BC_SRV2BUFFER_KMJTABLE*, IMG_UINT32*);
+typedef IMG_VOID (*PFN_BC_SCHEDULE_DEVICES)(IMG_VOID);
+typedef PVRSRV_ERROR (*PFN_BC_REMOVE_BUFFER_DEV)(IMG_UINT32);	
+
+typedef struct PVRSRV_BC_BUFFER2SRV_KMJTABLE_TAG
+{
+	IMG_UINT32							ui32TableSize;
+	PFN_BC_REGISTER_BUFFER_DEV			pfnPVRSRVRegisterBCDevice;
+	PFN_BC_SCHEDULE_DEVICES				pfnPVRSRVScheduleDevices;
+	PFN_BC_REMOVE_BUFFER_DEV			pfnPVRSRVRemoveBCDevice;
+
+} PVRSRV_BC_BUFFER2SRV_KMJTABLE, *PPVRSRV_BC_BUFFER2SRV_KMJTABLE;
+
+typedef IMG_BOOL (*PFN_BC_GET_PVRJTABLE) (PPVRSRV_BC_BUFFER2SRV_KMJTABLE); 
+
+IMG_IMPORT IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
diff --git a/drivers/staging/cdv/pvr/services4/include/kerneldisplay.h b/drivers/staging/cdv/pvr/services4/include/kerneldisplay.h
new file mode 100644
index 0000000..cdbef00
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/kerneldisplay.h
@@ -0,0 +1,165 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined (__KERNELDISPLAY_H__)
+#define __KERNELDISPLAY_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+typedef PVRSRV_ERROR (*PFN_OPEN_DC_DEVICE)(IMG_UINT32, IMG_HANDLE*, PVRSRV_SYNC_DATA*);
+typedef PVRSRV_ERROR (*PFN_CLOSE_DC_DEVICE)(IMG_HANDLE);
+typedef PVRSRV_ERROR (*PFN_ENUM_DC_FORMATS)(IMG_HANDLE, IMG_UINT32*, DISPLAY_FORMAT*);
+typedef PVRSRV_ERROR (*PFN_ENUM_DC_DIMS)(IMG_HANDLE,
+										 DISPLAY_FORMAT*,
+										 IMG_UINT32*,
+										 DISPLAY_DIMS*);
+typedef PVRSRV_ERROR (*PFN_GET_DC_SYSTEMBUFFER)(IMG_HANDLE, IMG_HANDLE*);
+typedef PVRSRV_ERROR (*PFN_GET_DC_INFO)(IMG_HANDLE, DISPLAY_INFO*);
+typedef PVRSRV_ERROR (*PFN_CREATE_DC_SWAPCHAIN)(IMG_HANDLE,
+												IMG_UINT32, 
+												DISPLAY_SURF_ATTRIBUTES*, 
+												DISPLAY_SURF_ATTRIBUTES*,
+												IMG_UINT32, 
+												PVRSRV_SYNC_DATA**,
+												IMG_UINT32,
+												IMG_HANDLE*, 
+												IMG_UINT32*);
+typedef PVRSRV_ERROR (*PFN_DESTROY_DC_SWAPCHAIN)(IMG_HANDLE, 
+												 IMG_HANDLE);
+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_GET_DC_BUFFERS)(IMG_HANDLE,
+										   IMG_HANDLE,
+										   IMG_UINT32*,
+										   IMG_HANDLE*);
+typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_BUFFER)(IMG_HANDLE,
+											  IMG_HANDLE,
+											  IMG_UINT32,
+											  IMG_HANDLE,
+											  IMG_UINT32,
+											  IMG_RECT*);
+typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_SYSTEM)(IMG_HANDLE, IMG_HANDLE);
+typedef IMG_VOID (*PFN_QUERY_SWAP_COMMAND_ID)(IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_UINT16*, IMG_BOOL*);
+typedef IMG_VOID (*PFN_SET_DC_STATE)(IMG_HANDLE, IMG_UINT32);
+
+typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG
+{
+	IMG_UINT32						ui32TableSize;
+	PFN_OPEN_DC_DEVICE				pfnOpenDCDevice;
+	PFN_CLOSE_DC_DEVICE				pfnCloseDCDevice;
+	PFN_ENUM_DC_FORMATS				pfnEnumDCFormats;
+	PFN_ENUM_DC_DIMS				pfnEnumDCDims;
+	PFN_GET_DC_SYSTEMBUFFER			pfnGetDCSystemBuffer;
+	PFN_GET_DC_INFO					pfnGetDCInfo;
+	PFN_GET_BUFFER_ADDR				pfnGetBufferAddr;
+	PFN_CREATE_DC_SWAPCHAIN			pfnCreateDCSwapChain;
+	PFN_DESTROY_DC_SWAPCHAIN		pfnDestroyDCSwapChain;
+	PFN_SET_DC_DSTRECT				pfnSetDCDstRect;
+	PFN_SET_DC_SRCRECT				pfnSetDCSrcRect;
+	PFN_SET_DC_DSTCK				pfnSetDCDstColourKey;
+	PFN_SET_DC_SRCCK				pfnSetDCSrcColourKey;
+	PFN_GET_DC_BUFFERS				pfnGetDCBuffers;
+	PFN_SWAP_TO_DC_BUFFER			pfnSwapToDCBuffer;
+	PFN_SWAP_TO_DC_SYSTEM			pfnSwapToDCSystem;
+	PFN_SET_DC_STATE				pfnSetDCState;
+	PFN_QUERY_SWAP_COMMAND_ID		pfnQuerySwapCommandID;
+
+} PVRSRV_DC_SRV2DISP_KMJTABLE;
+
+typedef IMG_BOOL (*PFN_ISR_HANDLER)(IMG_VOID*);
+
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_DISPLAY_DEV)(PVRSRV_DC_SRV2DISP_KMJTABLE*, IMG_UINT32*);
+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_DISPLAY_DEV)(IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_OEM_FUNCTION)(IMG_UINT32, IMG_VOID*, IMG_UINT32, IMG_VOID*, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_COMMANDPROCLIST)(IMG_UINT32, PPFN_CMD_PROC,IMG_UINT32[][2], IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_COMMANDPROCLIST)(IMG_UINT32, IMG_UINT32);
+typedef IMG_VOID (*PFN_DC_CMD_COMPLETE)(IMG_HANDLE, IMG_BOOL);
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_SYS_ISR)(PFN_ISR_HANDLER, IMG_VOID*, IMG_UINT32, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POST_POWER,
+											  PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE,
+											  IMG_HANDLE, PVRSRV_DEV_POWER_STATE, PVRSRV_DEV_POWER_STATE);
+
+typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG
+{
+	IMG_UINT32						ui32TableSize;
+	PFN_DC_REGISTER_DISPLAY_DEV		pfnPVRSRVRegisterDCDevice;
+	PFN_DC_REMOVE_DISPLAY_DEV		pfnPVRSRVRemoveDCDevice;
+	PFN_DC_OEM_FUNCTION				pfnPVRSRVOEMFunction;
+	PFN_DC_REGISTER_COMMANDPROCLIST	pfnPVRSRVRegisterCmdProcList;
+	PFN_DC_REMOVE_COMMANDPROCLIST	pfnPVRSRVRemoveCmdProcList;
+	PFN_DC_CMD_COMPLETE				pfnPVRSRVCmdComplete;
+	PFN_DC_REGISTER_SYS_ISR			pfnPVRSRVRegisterSystemISRHandler;
+	PFN_DC_REGISTER_POWER			pfnPVRSRVRegisterPowerDevice;
+	PFN_DC_CMD_COMPLETE				pfnPVRSRVFreeCmdCompletePacket;
+} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE;
+
+
+typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG
+{
+	
+	IMG_HANDLE hExtDevice;
+
+	
+	IMG_HANDLE hExtSwapChain;
+
+	
+	IMG_HANDLE hExtBuffer;
+
+	
+	IMG_HANDLE hPrivateTag;
+
+	
+	IMG_UINT32 ui32ClipRectCount;
+
+	
+	IMG_RECT *psClipRect;
+
+	
+	IMG_UINT32	ui32SwapInterval;
+
+} DISPLAYCLASS_FLIP_COMMAND;
+
+#define DC_FLIP_COMMAND		0
+
+#define DC_STATE_NO_FLUSH_COMMANDS		0
+#define DC_STATE_FLUSH_COMMANDS			1
+
+
+typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE);
+
+IMG_IMPORT IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/staging/cdv/pvr/services4/include/pdump.h b/drivers/staging/cdv/pvr/services4/include/pdump.h
new file mode 100644
index 0000000..c41a6d4
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/pdump.h
@@ -0,0 +1,37 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SERVICES_PDUMP_H_
+#define _SERVICES_PDUMP_H_
+
+#define PDUMP_FLAGS_NEVER			0x08000000U
+#define PDUMP_FLAGS_LASTFRAME		0x10000000U
+#define PDUMP_FLAGS_RESETLFBUFFER	0x20000000U
+#define PDUMP_FLAGS_CONTINUOUS		0x40000000U
+#define PDUMP_FLAGS_PERSISTENT		0x80000000U
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/include/pvr_bridge.h b/drivers/staging/cdv/pvr/services4/include/pvr_bridge.h
new file mode 100644
index 0000000..6495c57
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/pvr_bridge.h
@@ -0,0 +1,1764 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __PVR_BRIDGE_H__
+#define __PVR_BRIDGE_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "servicesint.h"
+
+#ifdef __linux__
+
+		#include <linux/ioctl.h>
+    
+    #define PVRSRV_IOC_GID      'g'
+    #define PVRSRV_IO(INDEX)    _IO(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
+    #define PVRSRV_IOW(INDEX)   _IOW(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
+    #define PVRSRV_IOR(INDEX)   _IOR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
+    #define PVRSRV_IOWR(INDEX)  _IOWR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
+
+#else 
+
+		#if defined(__QNXNTO__)
+			#define PVRSRV_IOC_GID      (0x0UL)
+		#else
+			#error Unknown platform: Cannot define ioctls
+		#endif
+
+	#define PVRSRV_IO(INDEX)    (PVRSRV_IOC_GID + (INDEX))
+	#define PVRSRV_IOW(INDEX)   (PVRSRV_IOC_GID + (INDEX))
+	#define PVRSRV_IOR(INDEX)   (PVRSRV_IOC_GID + (INDEX))
+	#define PVRSRV_IOWR(INDEX)  (PVRSRV_IOC_GID + (INDEX))
+
+	#define PVRSRV_BRIDGE_BASE                  PVRSRV_IOC_GID
+#endif 
+
+
+#define PVRSRV_BRIDGE_CORE_CMD_FIRST			0UL
+#define PVRSRV_BRIDGE_ENUM_DEVICES				PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+0)	
+#define PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+1)	
+#define PVRSRV_BRIDGE_RELEASE_DEVICEINFO		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+2)	
+#define PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+3)	
+#define PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+4)	
+#define PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+5)	
+#define PVRSRV_BRIDGE_ALLOC_DEVICEMEM			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+6)	
+#define PVRSRV_BRIDGE_FREE_DEVICEMEM			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+7)	
+#define PVRSRV_BRIDGE_GETFREE_DEVICEMEM			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+8)	
+#define PVRSRV_BRIDGE_CREATE_COMMANDQUEUE		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+9)	
+#define PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+10)	
+#define	PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+11)   
+#define PVRSRV_BRIDGE_CONNECT_SERVICES			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+12)	
+#define PVRSRV_BRIDGE_DISCONNECT_SERVICES		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+13)	
+#define PVRSRV_BRIDGE_WRAP_DEVICE_MEM			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+14)	
+#define PVRSRV_BRIDGE_GET_DEVICEMEMINFO			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+15)	
+#define PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+16)
+#define PVRSRV_BRIDGE_FREE_DEV_VIRTMEM			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+17)
+#define PVRSRV_BRIDGE_MAP_EXT_MEMORY			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+18)
+#define PVRSRV_BRIDGE_UNMAP_EXT_MEMORY			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+19)
+#define PVRSRV_BRIDGE_MAP_DEV_MEMORY			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+20)
+#define PVRSRV_BRIDGE_UNMAP_DEV_MEMORY			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+21)
+#define PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY	PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+22)
+#define PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY	PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+23)
+#define PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+24)
+#define PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER	PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+25)
+#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+26)
+#define PVRSRV_BRIDGE_RELEASE_MMAP_DATA			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+27)
+#define PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+28)
+#define PVRSRV_BRIDGE_MAP_DEV_MEMORY_2			PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+29)
+#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2		PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+30)
+#define PVRSRV_BRIDGE_CORE_CMD_LAST				(PVRSRV_BRIDGE_CORE_CMD_FIRST+30)
+
+#define PVRSRV_BRIDGE_SIM_CMD_FIRST				(PVRSRV_BRIDGE_CORE_CMD_LAST+1)
+#define PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT		PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+0)	
+#define PVRSRV_BRIDGE_REGISTER_SIM_PROCESS		PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+1)	
+#define PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS	PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+2)	
+#define PVRSRV_BRIDGE_SIM_CMD_LAST				(PVRSRV_BRIDGE_SIM_CMD_FIRST+2)
+
+#define PVRSRV_BRIDGE_MAPPING_CMD_FIRST			(PVRSRV_BRIDGE_SIM_CMD_LAST+1)
+#define PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE		PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+0)	
+#define PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE		PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+1)	
+#define PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP		PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2)	
+#define PVRSRV_BRIDGE_MAPPING_CMD_LAST			(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2)
+
+#define PVRSRV_BRIDGE_STATS_CMD_FIRST			(PVRSRV_BRIDGE_MAPPING_CMD_LAST+1)
+#define	PVRSRV_BRIDGE_GET_FB_STATS				PVRSRV_IOWR(PVRSRV_BRIDGE_STATS_CMD_FIRST+0)	
+#define PVRSRV_BRIDGE_STATS_CMD_LAST			(PVRSRV_BRIDGE_STATS_CMD_FIRST+0)
+
+#define PVRSRV_BRIDGE_MISC_CMD_FIRST			(PVRSRV_BRIDGE_STATS_CMD_LAST+1)
+#define PVRSRV_BRIDGE_GET_MISC_INFO				PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+0)	
+#define PVRSRV_BRIDGE_RELEASE_MISC_INFO			PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+1)	
+#define PVRSRV_BRIDGE_MISC_CMD_LAST				(PVRSRV_BRIDGE_MISC_CMD_FIRST+1)
+
+#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
+#define PVRSRV_BRIDGE_OVERLAY_CMD_FIRST			(PVRSRV_BRIDGE_MISC_CMD_LAST+1)
+#define PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES		PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+0)	
+#define PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES		PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)	
+#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST			(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)
+#else
+#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST			PVRSRV_BRIDGE_MISC_CMD_LAST
+#endif
+
+#if defined(PDUMP)
+#define PVRSRV_BRIDGE_PDUMP_CMD_FIRST			(PVRSRV_BRIDGE_OVERLAY_CMD_LAST+1)
+#define PVRSRV_BRIDGE_PDUMP_INIT			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+0)	
+#define PVRSRV_BRIDGE_PDUMP_MEMPOL			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+1)	
+#define PVRSRV_BRIDGE_PDUMP_DUMPMEM			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2)	
+#define PVRSRV_BRIDGE_PDUMP_REG				PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+3)	
+#define PVRSRV_BRIDGE_PDUMP_REGPOL			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+4)	
+#define PVRSRV_BRIDGE_PDUMP_COMMENT			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+5)	
+#define PVRSRV_BRIDGE_PDUMP_SETFRAME			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+6)	
+#define PVRSRV_BRIDGE_PDUMP_ISCAPTURING			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+7)	
+#define PVRSRV_BRIDGE_PDUMP_DUMPBITMAP			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+8)	
+#define PVRSRV_BRIDGE_PDUMP_DUMPREADREG			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+9)	
+#define PVRSRV_BRIDGE_PDUMP_SYNCPOL			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+10)	
+#define PVRSRV_BRIDGE_PDUMP_DUMPSYNC			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+11)	
+#define PVRSRV_BRIDGE_PDUMP_MEMPAGES			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+12)	
+#define PVRSRV_BRIDGE_PDUMP_DRIVERINFO			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+13)	
+#define PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR		PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+15)	
+#define PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ	PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+16)
+#define PVRSRV_BRIDGE_PDUMP_STARTINITPHASE			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+17)
+#define PVRSRV_BRIDGE_PDUMP_STOPINITPHASE			PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18)
+#define PVRSRV_BRIDGE_PDUMP_CMD_LAST			(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18)
+#else
+#define PVRSRV_BRIDGE_PDUMP_CMD_LAST			PVRSRV_BRIDGE_OVERLAY_CMD_LAST
+#endif
+
+#define PVRSRV_BRIDGE_OEM_CMD_FIRST				(PVRSRV_BRIDGE_PDUMP_CMD_LAST+1)
+#define PVRSRV_BRIDGE_GET_OEMJTABLE				PVRSRV_IOWR(PVRSRV_BRIDGE_OEM_CMD_FIRST+0)	
+#define PVRSRV_BRIDGE_OEM_CMD_LAST				(PVRSRV_BRIDGE_OEM_CMD_FIRST+0)
+
+#define PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST		(PVRSRV_BRIDGE_OEM_CMD_LAST+1)
+#define PVRSRV_BRIDGE_ENUM_CLASS				PVRSRV_IOWR(PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_DEVCLASS_CMD_LAST			(PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0)
+
+#define PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST		(PVRSRV_BRIDGE_DEVCLASS_CMD_LAST+1)
+#define PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE	PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS	PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER	PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+4)
+#define PVRSRV_BRIDGE_GET_DISPCLASS_INFO		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+5)
+#define PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+6)
+#define PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+7)
+#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+8)
+#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+9)
+#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+10)
+#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+11)
+#define PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS		PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+12)
+#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER	PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+13)
+#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM	PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14)
+#define PVRSRV_BRIDGE_DISPCLASS_CMD_LAST		(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14)
+
+#define PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST		(PVRSRV_BRIDGE_DISPCLASS_CMD_LAST+1)
+#define PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE	PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE	PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO		PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER	PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_BUFCLASS_CMD_LAST			(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3)
+
+#define PVRSRV_BRIDGE_WRAP_CMD_FIRST			(PVRSRV_BRIDGE_BUFCLASS_CMD_LAST+1)
+#define PVRSRV_BRIDGE_WRAP_EXT_MEMORY			PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY			PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_WRAP_CMD_LAST				(PVRSRV_BRIDGE_WRAP_CMD_FIRST+1)
+
+#define PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST		(PVRSRV_BRIDGE_WRAP_CMD_LAST+1)
+#define PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM		PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM		PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_MAP_MEMINFO_MEM			PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_UNMAP_MEMINFO_MEM			PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST		(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
+
+#define PVRSRV_BRIDGE_INITSRV_CMD_FIRST			(PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST+1)
+#define PVRSRV_BRIDGE_INITSRV_CONNECT			PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_INITSRV_DISCONNECT		PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_INITSRV_CMD_LAST			(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
+
+#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_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_SYNC_OPS_CMD_FIRST		(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST+1)
+#define PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ	PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ	PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS	PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS	PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN       PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+4)
+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN   PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+5)
+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ	PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+6)
+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA	PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+7)
+#define PVRSRV_BRIDGE_ALLOC_SYNC_INFO           PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+8)
+#define PVRSRV_BRIDGE_FREE_SYNC_INFO            PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+9)
+#define PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST			(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+9)
+
+#define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD		(PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST+1)
+
+
+#define PVRSRV_KERNEL_MODE_CLIENT				1
+
+typedef struct PVRSRV_BRIDGE_RETURN_TAG
+{
+	PVRSRV_ERROR eError;
+	IMG_VOID *pvData;
+
+}PVRSRV_BRIDGE_RETURN;
+
+
+typedef struct PVRSRV_BRIDGE_PACKAGE_TAG
+{
+	IMG_UINT32				ui32BridgeID;			
+	IMG_UINT32				ui32Size;				
+	IMG_VOID				*pvParamIn;				
+	IMG_UINT32				ui32InBufferSize;		
+	IMG_VOID				*pvParamOut;			
+	IMG_UINT32				ui32OutBufferSize;		
+
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hKernelServices;		
+#else
+	IMG_HANDLE				hKernelServices;		
+#endif
+}PVRSRV_BRIDGE_PACKAGE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CONNECT_SERVICES_TAG
+{
+	IMG_UINT32		ui32BridgeFlags; 
+	IMG_UINT32		ui32Flags;
+} PVRSRV_BRIDGE_IN_CONNECT_SERVICES;
+
+typedef struct PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	IMG_UINT32			uiDevIndex;
+	PVRSRV_DEVICE_TYPE	eDeviceType;
+
+} PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ENUMCLASS_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	PVRSRV_DEVICE_CLASS sDeviceClass;
+} PVRSRV_BRIDGE_IN_ENUMCLASS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDeviceKM;
+#else
+	IMG_HANDLE			hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDeviceKM;
+#else
+	IMG_HANDLE			hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDeviceKM;
+#else
+	IMG_HANDLE			hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDeviceKM;
+#else
+	IMG_HANDLE			hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDeviceKM;
+#else
+	IMG_HANDLE			hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDeviceKM;
+#else
+	IMG_HANDLE			hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+
+} PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	PVRSRV_DEVICE_CLASS DeviceClass;
+	IMG_VOID*			pvDevInfo;
+
+}PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+	IMG_SID	 			hDevMemContext;
+#else
+	IMG_HANDLE			hDevCookie;
+	IMG_HANDLE 			hDevMemContext;
+#endif
+
+}PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+
+}PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID 			hDevCookie;
+	IMG_SID 			hDevMemContext;
+#else
+	IMG_HANDLE 			hDevCookie;
+	IMG_HANDLE 			hDevMemContext;
+#endif
+
+}PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+	IMG_SID				hDevMemHeap;
+#else
+	IMG_HANDLE			hDevCookie;
+	IMG_HANDLE			hDevMemHeap;
+#endif
+	IMG_UINT32			ui32Attribs;
+	IMG_SIZE_T			ui32Size;
+	IMG_SIZE_T			ui32Alignment;
+
+}PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM;
+
+typedef struct PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER_TAG
+{
+	IMG_UINT32  ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID     hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+
+}PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER;
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER_TAG
+{
+	IMG_UINT32      ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID         hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	IMG_PVOID				 pvLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID         hMappingInfo;
+#else
+	IMG_HANDLE				 hMappingInfo;
+#endif
+
+}PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER;
+
+typedef struct PVRSRV_BRIDGE_IN_FREEDEVICEMEM_TAG
+{
+	IMG_UINT32              ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hDevCookie;
+	IMG_SID                 hKernelMemInfo;
+#else
+	IMG_HANDLE				hDevCookie;
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+
+}PVRSRV_BRIDGE_IN_FREEDEVICEMEM;
+
+typedef struct PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM_TAG
+{
+	IMG_UINT32      ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID         hDevCookie;
+	IMG_SID         hKernelMemInfo;
+#else
+	IMG_HANDLE				hDevCookie;
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+
+}PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM;
+
+typedef struct PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	IMG_UINT32			ui32Flags;
+
+} PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM;
+
+typedef struct PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+	IMG_SIZE_T			ui32QueueSize;
+
+}PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+	PVRSRV_QUEUE_INFO	*psQueueInfo;
+
+}PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hMHandle;	 
+#else
+	IMG_HANDLE			hMHandle;	 
+#endif
+} PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA;
+
+
+typedef struct PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hMHandle;	 
+#else
+	IMG_HANDLE			hMHandle;	 
+#endif
+} PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA;
+
+
+typedef struct PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevMemHeap;
+#else
+	IMG_HANDLE			hDevMemHeap;
+#endif
+	IMG_DEV_VIRTADDR	*psDevVAddr;
+	IMG_SIZE_T			ui32Size;
+	IMG_SIZE_T			ui32Alignment;
+
+}PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES_TAG
+{
+	PVRSRV_ERROR    eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID         hKernelServices;
+#else
+	IMG_HANDLE		hKernelServices;
+#endif
+}PVRSRV_BRIDGE_OUT_CONNECT_SERVICES;
+
+typedef struct PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM_TAG
+{
+	PVRSRV_ERROR            eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hKernelMemInfo;
+	IMG_SID                 hKernelSyncInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+	PVRSRV_KERNEL_SYNC_INFO	*psKernelSyncInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM;
+
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM_TAG
+{
+	IMG_UINT32              ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM;
+
+
+typedef struct PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hKernelMemInfo;
+	IMG_SID					hDstDevMemHeap;
+#else
+	IMG_HANDLE				hKernelMemInfo;
+	IMG_HANDLE				hDstDevMemHeap;
+#endif
+
+}PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY_TAG
+{
+	PVRSRV_ERROR            eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hDstKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psDstKernelMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO  sDstClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO sDstClientSyncInfo;
+
+}PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY_TAG
+{
+	IMG_UINT32              ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO		*psKernelMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY_TAG
+{
+	IMG_UINT32       ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID          hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	IMG_SYS_PHYADDR *psSysPAddr;
+	IMG_UINT32       ui32Flags;
+
+}PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY;
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY_TAG
+{
+	IMG_UINT32					ui32BridgeFlags; 
+	PVRSRV_CLIENT_MEM_INFO		sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO		sClientSyncInfo;
+	IMG_UINT32					ui32Flags;
+
+}PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY;
+
+typedef struct PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY_TAG
+{
+	IMG_UINT32		ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hDeviceClassBuffer;
+	IMG_SID			hDevMemContext;
+#else
+	IMG_HANDLE		hDeviceClassBuffer;
+	IMG_HANDLE		hDevMemContext;
+#endif
+
+}PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY_TAG
+{
+	PVRSRV_ERROR            eError;
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hKernelMemInfo;
+	IMG_SID                 hMappingInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+	IMG_HANDLE				hMappingInfo;
+#endif
+
+}PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY_TAG
+{
+	IMG_UINT32              ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPOL_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	IMG_UINT32 ui32Offset;
+	IMG_UINT32 ui32Value;
+	IMG_UINT32 ui32Mask;
+	PDUMP_POLL_OPERATOR		eOperator;
+	IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_MEMPOL;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfo;
+#else
+	PVRSRV_KERNEL_SYNC_INFO	*psKernelSyncInfo;
+#endif
+	IMG_BOOL   bIsRead;
+	IMG_BOOL   bUseLastOpDumpVal;
+	IMG_UINT32 ui32Value;
+	IMG_UINT32 ui32Mask;
+
+}PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_PVOID  pvLinAddr;
+	IMG_PVOID  pvAltLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	IMG_UINT32 ui32Offset;
+	IMG_UINT32 ui32Bytes;
+	IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_PVOID  pvAltLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfo;
+#else
+	PVRSRV_KERNEL_SYNC_INFO	*psKernelSyncInfo;
+#endif
+	IMG_UINT32 ui32Offset;
+	IMG_UINT32 ui32Bytes;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPREG_TAG
+{
+	IMG_UINT32		ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hDevCookie;
+#else
+	IMG_HANDLE		hDevCookie;
+#endif
+	PVRSRV_HWREG	sHWReg;
+	IMG_UINT32		ui32Flags;
+	IMG_CHAR		szRegRegion[32];
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPREG;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_REGPOL_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+	PVRSRV_HWREG sHWReg;
+	IMG_UINT32 ui32Mask;
+	IMG_UINT32 ui32Flags;
+	IMG_CHAR   szRegRegion[32];
+}PVRSRV_BRIDGE_IN_PDUMP_REGPOL;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	PVRSRV_HWREG sHWReg;
+	IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+	IMG_SID				hKernelMemInfo;
+#else
+	IMG_HANDLE			hDevCookie;
+	IMG_HANDLE			hKernelMemInfo;
+#endif
+	IMG_DEV_PHYADDR		*pPages;
+	IMG_UINT32			ui32NumPages;
+	IMG_DEV_VIRTADDR	sDevVAddr;
+	IMG_UINT32			ui32Start;
+	IMG_UINT32			ui32Length;
+	IMG_UINT32			ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_COMMENT_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_CHAR szComment[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
+	IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_COMMENT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SETFRAME_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_UINT32 ui32Frame;
+
+}PVRSRV_BRIDGE_IN_PDUMP_SETFRAME;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_BITMAP_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+	IMG_CHAR   szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+	IMG_UINT32 ui32FileOffset;
+	IMG_UINT32 ui32Width;
+	IMG_UINT32 ui32Height;
+	IMG_UINT32 ui32StrideInBytes;
+	IMG_DEV_VIRTADDR sDevBaseAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevMemContext;
+#else
+	IMG_HANDLE hDevMemContext;
+#endif
+	IMG_UINT32 ui32Size;
+	PDUMP_PIXEL_FORMAT ePixelFormat;
+	PDUMP_MEM_FORMAT eMemFormat;
+	IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_BITMAP;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_READREG_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+	IMG_CHAR   szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+	IMG_UINT32 ui32FileOffset;
+	IMG_UINT32 ui32Address;
+	IMG_UINT32 ui32Size;
+	IMG_UINT32 ui32Flags;
+	IMG_CHAR   szRegRegion[32];
+
+}PVRSRV_BRIDGE_IN_PDUMP_READREG;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_CHAR szString[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
+	IMG_BOOL bContinuous;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelMemInfo;
+#else
+	IMG_HANDLE hKernelMemInfo;
+#endif
+	IMG_UINT32 ui32Offset;
+	IMG_DEV_PHYADDR sPDDevPAddr;
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR;
+
+typedef struct PVRSRV_BRIDGE_PDUM_IN_CYCLE_COUNT_REG_READ_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+	IMG_UINT32 ui32RegOffset;
+	IMG_BOOL bLastFrame;
+}PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ;
+
+typedef struct PVRSRV_BRIDGE_OUT_ENUMDEVICE_TAG
+{
+	PVRSRV_ERROR eError;
+	IMG_UINT32 ui32NumDevices;
+	PVRSRV_DEVICE_IDENTIFIER asDeviceIdentifier[PVRSRV_MAX_DEVICES];
+
+}PVRSRV_BRIDGE_OUT_ENUMDEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO_TAG
+{
+
+	PVRSRV_ERROR		eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+
+} PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_ENUMCLASS_TAG
+{
+	PVRSRV_ERROR eError;
+	IMG_UINT32 ui32NumDevices;
+	IMG_UINT32 ui32DevID[PVRSRV_MAX_DEVICES];
+
+}PVRSRV_BRIDGE_OUT_ENUMCLASS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE_TAG
+{
+	IMG_UINT32		ui32BridgeFlags; 
+	IMG_UINT32		ui32DeviceID;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hDevCookie;
+#else
+	IMG_HANDLE		hDevCookie;
+#endif
+
+}PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE;
+
+typedef struct PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE_TAG
+{
+	PVRSRV_ERROR	eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hDeviceKM;
+#else
+	IMG_HANDLE		hDeviceKM;
+#endif
+
+}PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hDevCookie;
+	IMG_SID					hDevMemContext;
+#else
+	IMG_HANDLE              hDevCookie;
+	IMG_HANDLE				hDevMemContext;
+#endif
+	IMG_VOID				*pvLinAddr;
+	IMG_SIZE_T              ui32ByteSize;
+	IMG_SIZE_T              ui32PageOffset;
+	IMG_BOOL                bPhysContig;
+	IMG_UINT32				ui32NumPageTableEntries;
+	IMG_SYS_PHYADDR         *psSysPAddr;
+	IMG_UINT32				ui32Flags;
+
+}PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY;
+
+typedef struct PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY_TAG
+{
+	PVRSRV_ERROR	eError;
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO	sClientSyncInfo;
+
+}PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY;
+
+typedef struct PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelMemInfo;
+#else
+	IMG_HANDLE hKernelMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO	sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY;
+
+
+#define PVRSRV_MAX_DC_DISPLAY_FORMATS			10
+#define PVRSRV_MAX_DC_DISPLAY_DIMENSIONS		10
+#define PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS			9
+#define PVRSRV_MAX_DC_CLIP_RECTS				32
+
+typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS_TAG
+{
+	PVRSRV_ERROR	eError;
+	IMG_UINT32		ui32Count;
+	DISPLAY_FORMAT	asFormat[PVRSRV_MAX_DC_DISPLAY_FORMATS];
+
+}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS_TAG
+{
+	IMG_UINT32		ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hDeviceKM;
+#else
+	IMG_HANDLE		hDeviceKM;
+#endif
+	DISPLAY_FORMAT	sFormat;
+
+}PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS_TAG
+{
+	PVRSRV_ERROR	eError;
+	IMG_UINT32		ui32Count;
+	DISPLAY_DIMS	asDim[PVRSRV_MAX_DC_DISPLAY_DIMENSIONS];
+
+}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO_TAG
+{
+	PVRSRV_ERROR	eError;
+	DISPLAY_INFO	sDisplayInfo;
+
+}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER_TAG
+{
+	PVRSRV_ERROR	eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hBuffer;
+#else
+	IMG_HANDLE		hBuffer;
+#endif
+
+}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDeviceKM;
+#else
+	IMG_HANDLE				hDeviceKM;
+#endif
+	IMG_UINT32				ui32Flags;
+	DISPLAY_SURF_ATTRIBUTES	sDstSurfAttrib;
+	DISPLAY_SURF_ATTRIBUTES	sSrcSurfAttrib;
+	IMG_UINT32				ui32BufferCount;
+	IMG_UINT32				ui32OEMFlags;
+	IMG_UINT32				ui32SwapChainID;
+
+} PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN_TAG
+{
+	PVRSRV_ERROR		eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hSwapChain;
+#else
+	IMG_HANDLE			hSwapChain;
+#endif
+	IMG_UINT32			ui32SwapChainID;
+
+} PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN;
+
+
+typedef struct PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDeviceKM;
+	IMG_SID				hSwapChain;
+#else
+	IMG_HANDLE			hDeviceKM;
+	IMG_HANDLE			hSwapChain;
+#endif
+
+} PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDeviceKM;
+	IMG_SID				hSwapChain;
+#else
+	IMG_HANDLE			hDeviceKM;
+	IMG_HANDLE			hSwapChain;
+#endif
+	IMG_RECT			sRect;
+
+} PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDeviceKM;
+	IMG_SID				hSwapChain;
+#else
+	IMG_HANDLE			hDeviceKM;
+	IMG_HANDLE			hSwapChain;
+#endif
+	IMG_UINT32			ui32CKColour;
+
+} PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDeviceKM;
+	IMG_SID				hSwapChain;
+#else
+	IMG_HANDLE			hDeviceKM;
+	IMG_HANDLE			hSwapChain;
+#endif
+
+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS_TAG
+{
+	PVRSRV_ERROR		eError;
+	IMG_UINT32			ui32BufferCount;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+#else
+	IMG_HANDLE			ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+#endif
+
+} PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDeviceKM;
+	IMG_SID				hBuffer;
+#else
+	IMG_HANDLE			hDeviceKM;
+	IMG_HANDLE			hBuffer;
+#endif
+	IMG_UINT32			ui32SwapInterval;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hPrivateTag;
+#else
+	IMG_HANDLE			hPrivateTag;
+#endif
+	IMG_UINT32			ui32ClipRectCount;
+	IMG_RECT			sClipRect[PVRSRV_MAX_DC_CLIP_RECTS];
+
+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDeviceKM;
+	IMG_SID				hSwapChain;
+#else
+	IMG_HANDLE			hDeviceKM;
+	IMG_HANDLE			hSwapChain;
+#endif
+
+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM;
+
+
+typedef struct PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	IMG_UINT32			ui32DeviceID;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+
+} PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE_TAG
+{
+	PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID      hDeviceKM;
+#else
+	IMG_HANDLE			hDeviceKM;
+#endif
+
+} PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO_TAG
+{
+	PVRSRV_ERROR		eError;
+	BUFFER_INFO			sBufferInfo;
+
+} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDeviceKM;
+#else
+	IMG_HANDLE			hDeviceKM;
+#endif
+	IMG_UINT32 ui32BufferIndex;
+
+} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER_TAG
+{
+	PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID      hBuffer;
+#else
+	IMG_HANDLE			hBuffer;
+#endif
+
+} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO_TAG
+{
+	PVRSRV_ERROR		eError;
+	IMG_UINT32			ui32ClientHeapCount;
+	PVRSRV_HEAP_INFO	sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+
+} PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT_TAG
+{
+	PVRSRV_ERROR		eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevMemContext;
+#else
+	IMG_HANDLE			hDevMemContext;
+#endif
+	IMG_UINT32			ui32ClientHeapCount;
+	PVRSRV_HEAP_INFO	sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+
+} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP_TAG
+{
+	PVRSRV_ERROR		eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevMemHeap;
+#else
+	IMG_HANDLE			hDevMemHeap;
+#endif
+
+} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM_TAG
+{
+	PVRSRV_ERROR            eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+} PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM_TAG
+{
+	PVRSRV_ERROR			eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hMemInfo;
+#else
+	IMG_HANDLE				hMemInfo;
+#endif
+#if defined(SUPPORT_MEMINFO_IDS)
+	IMG_UINT64				ui64Stamp;
+#endif
+
+} PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER_TAG
+{
+	PVRSRV_ERROR			eError;
+	IMG_PVOID				pvLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hMappingInfo;
+#else
+	IMG_HANDLE				hMappingInfo;
+#endif
+
+}PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM_TAG
+{
+	PVRSRV_ERROR eError;
+	IMG_SIZE_T ui32Total;
+	IMG_SIZE_T ui32Free;
+	IMG_SIZE_T ui32LargestBlock;
+
+} PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM;
+
+
+#include "pvrmmap.h"
+typedef struct PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA_TAG
+{
+    PVRSRV_ERROR		eError;
+
+    
+     IMG_UINT32			ui32MMapOffset;
+
+    
+    IMG_UINT32			ui32ByteOffset;
+
+    
+    IMG_UINT32 			ui32RealByteSize;
+
+    
+    IMG_UINT32			ui32UserVAddr;
+
+} PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA;
+
+typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA_TAG
+{
+    PVRSRV_ERROR		eError;
+
+    
+    IMG_BOOL			bMUnmap;
+
+    
+    IMG_UINT32			ui32UserVAddr;
+
+    
+    IMG_UINT32			ui32RealByteSize;
+} PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA;
+typedef struct PVRSRV_BRIDGE_IN_GET_MISC_INFO_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	PVRSRV_MISC_INFO	sMiscInfo;
+
+}PVRSRV_BRIDGE_IN_GET_MISC_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_MISC_INFO_TAG
+{
+	PVRSRV_ERROR		eError;
+	PVRSRV_MISC_INFO	sMiscInfo;
+
+}PVRSRV_BRIDGE_OUT_GET_MISC_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	PVRSRV_MISC_INFO	sMiscInfo;
+
+}PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO_TAG
+{
+	PVRSRV_ERROR		eError;
+	PVRSRV_MISC_INFO	sMiscInfo;
+
+}PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING_TAG
+{
+	PVRSRV_ERROR eError;
+	IMG_BOOL bIsCapturing;
+
+} PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING;
+
+typedef struct PVRSRV_BRIDGE_IN_GET_FB_STATS_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_SIZE_T ui32Total;
+	IMG_SIZE_T ui32Available;
+
+} PVRSRV_BRIDGE_IN_GET_FB_STATS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+	IMG_SYS_PHYADDR		sSysPhysAddr;
+	IMG_UINT32			uiSizeInBytes;
+
+} PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE_TAG
+{
+	IMG_PVOID			pvUserAddr;
+	IMG_UINT32			uiActualSize;
+	IMG_PVOID			pvProcess;
+
+} PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+	IMG_PVOID			pvUserAddr;
+	IMG_PVOID			pvProcess;
+
+} PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP_TAG
+{
+	IMG_PVOID			*ppvTbl;
+	IMG_UINT32			uiTblSize;
+
+} PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP;
+
+
+#if !defined (SUPPORT_SID_INTERFACE)
+typedef struct PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	IMG_HANDLE			hDevCookie;
+	IMG_PVOID			pvProcess;
+
+} PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS_TAG
+{
+	IMG_SYS_PHYADDR		sRegsPhysBase;			
+	IMG_VOID			*pvRegsBase;			
+	IMG_PVOID			pvProcess;
+	IMG_UINT32			ulNoOfEntries;
+	IMG_PVOID			pvTblLinAddr;
+
+} PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	IMG_HANDLE			hDevCookie;
+	IMG_PVOID			pvProcess;
+	IMG_VOID			*pvRegsBase;			
+
+} PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS;
+
+typedef struct PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	IMG_HANDLE			hDevCookie;
+	IMG_UINT32			ui32StatusAndMask;
+	PVRSRV_ERROR 		eError;
+
+} PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT;
+#endif 
+
+typedef struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+	IMG_BOOL			bInitSuccesful;
+} PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+    IMG_UINT32 ui32Flags;
+    IMG_SIZE_T ui32Size;
+}PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM_TAG
+{
+	PVRSRV_ERROR            eError;
+#if defined (SUPPORT_SID_INTERFACE)
+#else
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+}PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hKernelMemInfo;
+	IMG_SID                 hMappingInfo;
+#else
+	IMG_UINT32              ui32BridgeFlags; 
+	PVRSRV_KERNEL_MEM_INFO	*psKernelMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+}PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM_TAG
+{
+	PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelMemInfo;
+#else
+	IMG_HANDLE hKernelMemInfo;
+#endif
+}PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM_TAG
+{
+	PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
+	PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID                 hKernelMemInfo;
+#else
+	PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
+#endif
+	PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+}PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM_TAG
+{
+	PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAI_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hOSEventKM;
+#else
+	IMG_HANDLE	hOSEventKM;
+#endif
+} 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
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_UINT32   hOSEvent;
+#else
+	IMG_HANDLE hOSEvent;
+#endif
+	PVRSRV_ERROR eError;
+} PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN;
+
+typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE_TAG
+{
+	PVRSRV_EVENTOBJECT sEventObject;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hOSEventKM;
+#else
+	IMG_HANDLE hOSEventKM;
+#endif
+} PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE;
+
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ_TAG
+{
+	PVRSRV_ERROR eError;
+
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfoModObj;
+#else
+	IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+
+} PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ;
+
+typedef struct PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfoModObj;
+#else
+	IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+} PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ;
+
+typedef struct PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfoModObj;
+	IMG_SID    hKernelSyncInfo;
+#else
+	IMG_HANDLE hKernelSyncInfoModObj;
+	IMG_HANDLE hKernelSyncInfo;
+#endif
+	IMG_UINT32 ui32ModifyFlags;
+
+} PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS;
+
+typedef struct PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfoModObj;
+#else
+	IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+} PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS;
+
+typedef struct PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS_TAG
+{
+	PVRSRV_ERROR eError;
+
+	
+	IMG_UINT32 ui32ReadOpsPending;
+	IMG_UINT32 ui32WriteOpsPending;
+
+} PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfo;
+#else
+	IMG_HANDLE hKernelSyncInfo;
+#endif
+
+} PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN;
+
+typedef struct PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN_TAG
+{
+	PVRSRV_ERROR eError;
+
+	IMG_UINT32 ui32ReadOpsPending;
+	IMG_UINT32 ui32WriteOpsPending;
+
+} PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfo;
+#else
+	IMG_HANDLE hKernelSyncInfo;
+#endif
+	IMG_UINT32 ui32ReadOpsPendingSnapshot;
+	IMG_UINT32 ui32WriteOpsPendingSnapshot;
+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfoModObj;
+#else
+	IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfo;
+#else
+	IMG_HANDLE hKernelSyncInfo;
+#endif
+	IMG_UINT32 ui32Delta;
+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA;
+
+typedef struct PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+} PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO;
+
+typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO_TAG
+{
+	PVRSRV_ERROR eError;
+
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfo;
+#else
+	IMG_HANDLE hKernelSyncInfo;
+#endif
+} PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO;
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_SYNC_INFO_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hKernelSyncInfo;
+#else
+	IMG_HANDLE hKernelSyncInfo;
+#endif
+} PVRSRV_BRIDGE_IN_FREE_SYNC_INFO;
+
+typedef struct PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS_TAG
+{
+	IMG_SID				hKernelMemInfo;
+	IMG_UINT32			ui32Attribs;
+} PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS;
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/include/pvr_bridge_km.h b/drivers/staging/cdv/pvr/services4/include/pvr_bridge_km.h
new file mode 100644
index 0000000..1175b76
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/pvr_bridge_km.h
@@ -0,0 +1,305 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __PVR_BRIDGE_KM_H_
+#define __PVR_BRIDGE_KM_H_
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "pvr_bridge.h"
+#include "perproc.h"
+
+#if defined(__linux__)
+PVRSRV_ERROR LinuxBridgeInit(IMG_VOID);
+IMG_VOID LinuxBridgeDeInit(IMG_VOID);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
+												   PVRSRV_DEVICE_IDENTIFIER *psDevIdList);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM(IMG_UINT32			uiDevIndex,
+													PVRSRV_DEVICE_TYPE	eDeviceType,
+													IMG_HANDLE			*phDevCookie);
+							
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
+													 PVRSRV_QUEUE_INFO **ppsQueueInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+													PVRSRV_HEAP_INFO_KM *psHeapInfo);
+#else
+													PVRSRV_HEAP_INFO *psHeapInfo);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE					hDevCookie,
+														 PVRSRV_PER_PROCESS_DATA	*psPerProc,
+														 IMG_HANDLE					*phDevMemContext,
+														 IMG_UINT32					*pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+														 PVRSRV_HEAP_INFO_KM		*psHeapInfo,
+#else
+														 PVRSRV_HEAP_INFO			*psHeapInfo,
+#endif
+														 IMG_BOOL					*pbCreated,
+														 IMG_BOOL					*pbShared);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
+														  IMG_HANDLE hDevMemContext,
+														  IMG_BOOL *pbDestroyed);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE				hDevCookie,
+															IMG_HANDLE			hDevMemContext,
+															IMG_UINT32			*pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+															PVRSRV_HEAP_INFO_KM	*psHeapInfo,
+#else
+															PVRSRV_HEAP_INFO	*psHeapInfo,
+#endif
+															IMG_BOOL 			*pbShared
+					);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE					hDevCookie,
+												 PVRSRV_PER_PROCESS_DATA	*psPerProc,
+												 IMG_HANDLE					hDevMemHeap,
+												 IMG_UINT32					ui32Flags,
+												 IMG_SIZE_T					ui32Size,
+												 IMG_SIZE_T					ui32Alignment,
+												 PVRSRV_KERNEL_MEM_INFO		**ppsMemInfo);
+
+
+#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
+	#define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo, logStr) \
+		(PVR_TRACE(("PVRSRVAllocDeviceMemKM(" #devCookie ", " #perProc ", " #devMemHeap ", " #flags ", " #size \
+			", " #alignment "," #memInfo "): " logStr " (size = 0x%x)", size)),\
+			_PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo))
+#else
+	#define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo, logStr) \
+			_PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo)
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE			hDevCookie,
+												PVRSRV_KERNEL_MEM_INFO	*psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE			hDevCookie,
+												PVRSRV_KERNEL_MEM_INFO	*psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMemKM(IMG_HANDLE		hDevMemHeap,
+														 IMG_DEV_VIRTADDR	*psDevVAddr,
+														 IMG_SIZE_T			ui32Size,
+														 IMG_SIZE_T			ui32Alignment,
+														 PVRSRV_KERNEL_MEM_INFO	**ppsMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMemKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+												  PVRSRV_KERNEL_MEM_INFO	*psSrcMemInfo,
+												  IMG_HANDLE				hDstDevMemHeap,
+												  PVRSRV_KERNEL_MEM_INFO	**ppsDstMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE				hDevCookie,
+												PVRSRV_PER_PROCESS_DATA	*psPerProc,
+												IMG_HANDLE				hDevMemContext,
+												IMG_SIZE_T 				ui32ByteSize, 
+												IMG_SIZE_T				ui32PageOffset,
+												IMG_BOOL				bPhysContig,
+												IMG_SYS_PHYADDR	 		*psSysAddr,
+												IMG_VOID 				*pvLinAddr,
+												IMG_UINT32				ui32Flags,
+												PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVEnumerateDCKM(PVRSRV_DEVICE_CLASS DeviceClass,
+								 IMG_UINT32 *pui32DevCount,
+								 IMG_UINT32 *pui32DevID );
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVOpenDCDeviceKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+								  IMG_UINT32				ui32DeviceID,
+								  IMG_HANDLE 				hDevCookie,
+								  IMG_HANDLE 				*phDeviceKM);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVCloseDCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVEnumDCFormatsKM(IMG_HANDLE hDeviceKM,
+								   IMG_UINT32 *pui32Count,
+								   DISPLAY_FORMAT *psFormat);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVEnumDCDimsKM(IMG_HANDLE hDeviceKM,
+								DISPLAY_FORMAT *psFormat,
+								IMG_UINT32 *pui32Count,
+								DISPLAY_DIMS *psDim);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(IMG_HANDLE hDeviceKM,
+									   IMG_HANDLE *phBuffer);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetDCInfoKM(IMG_HANDLE hDeviceKM,
+							   DISPLAY_INFO *psDisplayInfo);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+									   IMG_HANDLE				hDeviceKM,
+									   IMG_UINT32				ui32Flags,
+									   DISPLAY_SURF_ATTRIBUTES	*psDstSurfAttrib,
+									   DISPLAY_SURF_ATTRIBUTES	*psSrcSurfAttrib,
+									   IMG_UINT32				ui32BufferCount,
+									   IMG_UINT32				ui32OEMFlags,
+									   IMG_HANDLE				*phSwapChain,
+									   IMG_UINT32				*pui32SwapChainID);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE	hSwapChain);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE	hDeviceKM,
+								  IMG_HANDLE	hSwapChain,
+								  IMG_RECT	*psRect);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE	hDeviceKM,
+								  IMG_HANDLE	hSwapChain,
+								  IMG_RECT	*psRect);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE	hDeviceKM,
+									   IMG_HANDLE	hSwapChain,
+									   IMG_UINT32	ui32CKColour);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE	hDeviceKM,
+									IMG_HANDLE		hSwapChain,
+									IMG_UINT32		ui32CKColour);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE	hDeviceKM,
+								  IMG_HANDLE	hSwapChain,
+								  IMG_UINT32	*pui32BufferCount,
+								  IMG_HANDLE	*phBuffer);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE	hDeviceKM,
+									IMG_HANDLE	hBuffer,
+									IMG_UINT32	ui32SwapInterval,
+									IMG_HANDLE	hPrivateTag,
+									IMG_UINT32	ui32ClipRectCount,
+									IMG_RECT	*psClipRect);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE	hDeviceKM,
+									IMG_HANDLE	hSwapChain);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVOpenBCDeviceKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+								  IMG_UINT32				ui32DeviceID,
+								  IMG_HANDLE				hDevCookie,
+								  IMG_HANDLE				*phDeviceKM);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVCloseBCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetBCInfoKM(IMG_HANDLE	hDeviceKM,
+							   BUFFER_INFO	*psBufferInfo);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetBCBufferKM(IMG_HANDLE	hDeviceKM,
+								 IMG_UINT32	ui32BufferIndex,
+								 IMG_HANDLE	*phBuffer);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+													   IMG_HANDLE				hDevMemContext,
+													   IMG_HANDLE				hDeviceClassBuffer,
+													   PVRSRV_KERNEL_MEM_INFO	**ppsMemInfo,
+													   IMG_HANDLE				*phOSMapInfo);
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVChangeDeviceMemoryAttributesKM(IMG_HANDLE hKernelMemInfo,
+															   IMG_UINT32 ui32Attribs);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
+												   IMG_SIZE_T *pui32Total,
+												   IMG_SIZE_T *pui32Free,
+												   IMG_SIZE_T *pui32LargestBlock);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE					hDevCookie,
+												IMG_HANDLE					hDevMemContext,
+												PVRSRV_KERNEL_SYNC_INFO	**ppsKernelSyncInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO	*psKernelSyncInfo);
+
+IMG_IMPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO_KM *psMiscInfo);
+#else
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo);
+#endif
+
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+							 IMG_UINT32 				ui32Flags,
+							 IMG_SIZE_T 				ui32Size,
+							 PVRSRV_KERNEL_MEM_INFO		**ppsKernelMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/include/pvrmmap.h b/drivers/staging/cdv/pvr/services4/include/pvrmmap.h
new file mode 100644
index 0000000..242d953
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/pvrmmap.h
@@ -0,0 +1,44 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __PVRMMAP_H__
+#define __PVRMMAP_H__
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_SID *phMappingInfo, IMG_SID hMHandle);
+#else
+PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_HANDLE *phMappingInfo, IMG_HANDLE hMHandle);
+#endif
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_SID hMappingInfo, IMG_SID hMHandle);
+#else
+IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_HANDLE hMappingInfo, IMG_HANDLE hMHandle);
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/include/pvrsrv_errors.h b/drivers/staging/cdv/pvr/services4/include/pvrsrv_errors.h
new file mode 100644
index 0000000..5474984
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/pvrsrv_errors.h
@@ -0,0 +1,266 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined (__PVRSRV_ERRORS_H__)
+#define __PVRSRV_ERRORS_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+	switch (eError)
+	{
+		case PVRSRV_OK:									return "No Errors";
+		case PVRSRV_ERROR_OUT_OF_MEMORY:				return "PVRSRV_ERROR_OUT_OF_MEMORY - Unable to allocate required memory";
+		case PVRSRV_ERROR_TOO_FEW_BUFFERS:				return "PVRSRV_ERROR_TOO_FEW_BUFFERS";
+		case PVRSRV_ERROR_INVALID_PARAMS:				return "PVRSRV_ERROR_INVALID_PARAMS";
+		case PVRSRV_ERROR_INIT_FAILURE:					return "PVRSRV_ERROR_INIT_FAILURE";
+		case PVRSRV_ERROR_CANT_REGISTER_CALLBACK:		return "PVRSRV_ERROR_CANT_REGISTER_CALLBACK";
+		case PVRSRV_ERROR_INVALID_DEVICE:				return "PVRSRV_ERROR_INVALID_DEVICE";
+		case PVRSRV_ERROR_NOT_OWNER:					return "PVRSRV_ERROR_NOT_OWNER";
+		case PVRSRV_ERROR_BAD_MAPPING:					return "PVRSRV_ERROR_BAD_MAPPING";
+		case PVRSRV_ERROR_TIMEOUT:						return "PVRSRV_ERROR_TIMEOUT";
+		case PVRSRV_ERROR_FLIP_CHAIN_EXISTS:			return "PVRSRV_ERROR_FLIP_CHAIN_EXISTS";
+		case PVRSRV_ERROR_INVALID_SWAPINTERVAL:			return "PVRSRV_ERROR_INVALID_SWAPINTERVAL";
+		case PVRSRV_ERROR_SCENE_INVALID:				return "PVRSRV_ERROR_SCENE_INVALID";
+		case PVRSRV_ERROR_STREAM_ERROR:					return "PVRSRV_ERROR_STREAM_ERROR";
+		case PVRSRV_ERROR_FAILED_DEPENDENCIES:			return "PVRSRV_ERROR_FAILED_DEPENDENCIES";
+		case PVRSRV_ERROR_CMD_NOT_PROCESSED:			return "PVRSRV_ERROR_CMD_NOT_PROCESSED";
+		case PVRSRV_ERROR_CMD_TOO_BIG:					return "PVRSRV_ERROR_CMD_TOO_BIG";
+		case PVRSRV_ERROR_DEVICE_REGISTER_FAILED:		return "PVRSRV_ERROR_DEVICE_REGISTER_FAILED";
+		case PVRSRV_ERROR_TOOMANYBUFFERS:				return "PVRSRV_ERROR_TOOMANYBUFFERS";
+		case PVRSRV_ERROR_NOT_SUPPORTED:				return "PVRSRV_ERROR_NOT_SUPPORTED - fix";
+		case PVRSRV_ERROR_PROCESSING_BLOCKED:			return "PVRSRV_ERROR_PROCESSING_BLOCKED";
+
+		case PVRSRV_ERROR_CANNOT_FLUSH_QUEUE:			return "PVRSRV_ERROR_CANNOT_FLUSH_QUEUE";
+		case PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE:		return "PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE";
+		case PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS:		return "PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS";
+		case PVRSRV_ERROR_RETRY:						return "PVRSRV_ERROR_RETRY";
+
+		case PVRSRV_ERROR_DDK_VERSION_MISMATCH:			return "PVRSRV_ERROR_DDK_VERSION_MISMATCH";
+		case PVRSRV_ERROR_BUILD_MISMATCH:				return "PVRSRV_ERROR_BUILD_MISMATCH";
+		case PVRSRV_ERROR_CORE_REVISION_MISMATCH:		return "PVRSRV_ERROR_CORE_REVISION_MISMATCH";
+
+		case PVRSRV_ERROR_UPLOAD_TOO_BIG:				return "PVRSRV_ERROR_UPLOAD_TOO_BIG";
+
+		case PVRSRV_ERROR_INVALID_FLAGS:				return "PVRSRV_ERROR_INVALID_FLAGS";
+		case PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS:	return "PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS";
+
+		case PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY:		return "PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY";
+		case PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR:			return "PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR";
+		case PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED:		return "PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED";
+
+		case PVRSRV_ERROR_BRIDGE_CALL_FAILED:			return "PVRSRV_ERROR_BRIDGE_CALL_FAILED";
+		case PVRSRV_ERROR_IOCTL_CALL_FAILED:			return "PVRSRV_ERROR_IOCTL_CALL_FAILED";
+
+		case PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND:		return "PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND";
+		case PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND:		return "PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND";
+		case PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT:return "PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT";
+
+		case PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND:			return "PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND";
+		case PVRSRV_ERROR_PCI_CALL_FAILED:				return "PVRSRV_ERROR_PCI_CALL_FAILED";
+		case PVRSRV_ERROR_PCI_REGION_TOO_SMALL:			return "PVRSRV_ERROR_PCI_REGION_TOO_SMALL";
+		case PVRSRV_ERROR_PCI_REGION_UNAVAILABLE:		return "PVRSRV_ERROR_PCI_REGION_UNAVAILABLE";
+		case PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH:		return "PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH";
+
+		case PVRSRV_ERROR_REGISTER_BASE_NOT_SET:		return "PVRSRV_ERROR_REGISTER_BASE_NOT_SET";
+
+        case PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE:       return "PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE";
+
+		case PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM:		return "PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM";
+		case PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY:	return "PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY";
+		case PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC:	return "PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC";
+		case PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR:		return "PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR";
+
+		case PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY:	return "PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY";
+		case PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY:	return "PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY";
+
+		case PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES:		return "PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES";
+		case PVRSRV_ERROR_FAILED_TO_FREE_PAGES:			return "PVRSRV_ERROR_FAILED_TO_FREE_PAGES";
+		case PVRSRV_ERROR_FAILED_TO_COPY_PAGES:			return "PVRSRV_ERROR_FAILED_TO_COPY_PAGES";
+		case PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES:			return "PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES";
+		case PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES:		return "PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES";
+		case PVRSRV_ERROR_STILL_MAPPED:					return "PVRSRV_ERROR_STILL_MAPPED";
+		case PVRSRV_ERROR_MAPPING_NOT_FOUND:			return "PVRSRV_ERROR_MAPPING_NOT_FOUND";
+		case PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT:	return "PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT";
+		case PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE:		return "PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE";
+
+		case PVRSRV_ERROR_INVALID_SEGMENT_BLOCK:		return "PVRSRV_ERROR_INVALID_SEGMENT_BLOCK";
+		case PVRSRV_ERROR_INVALID_SGXDEVDATA:			return "PVRSRV_ERROR_INVALID_SGXDEVDATA";
+		case PVRSRV_ERROR_INVALID_DEVINFO:				return "PVRSRV_ERROR_INVALID_DEVINFO";
+		case PVRSRV_ERROR_INVALID_MEMINFO:				return "PVRSRV_ERROR_INVALID_MEMINFO";
+		case PVRSRV_ERROR_INVALID_MISCINFO:				return "PVRSRV_ERROR_INVALID_MISCINFO";
+		case PVRSRV_ERROR_UNKNOWN_IOCTL:				return "PVRSRV_ERROR_UNKNOWN_IOCTL";
+		case PVRSRV_ERROR_INVALID_CONTEXT:				return "PVRSRV_ERROR_INVALID_CONTEXT";
+		case PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT:	return "PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT";
+		case PVRSRV_ERROR_INVALID_HEAP:					return "PVRSRV_ERROR_INVALID_HEAP";
+		case PVRSRV_ERROR_INVALID_KERNELINFO:			return "PVRSRV_ERROR_INVALID_KERNELINFO";
+		case PVRSRV_ERROR_UNKNOWN_POWER_STATE:			return "PVRSRV_ERROR_UNKNOWN_POWER_STATE";
+		case PVRSRV_ERROR_INVALID_HANDLE_TYPE:			return "PVRSRV_ERROR_INVALID_HANDLE_TYPE";
+		case PVRSRV_ERROR_INVALID_WRAP_TYPE:			return "PVRSRV_ERROR_INVALID_WRAP_TYPE";
+		case PVRSRV_ERROR_INVALID_PHYS_ADDR:			return "PVRSRV_ERROR_INVALID_PHYS_ADDR";
+		case PVRSRV_ERROR_INVALID_CPU_ADDR:				return "PVRSRV_ERROR_INVALID_CPU_ADDR";
+		case PVRSRV_ERROR_INVALID_HEAPINFO:				return "PVRSRV_ERROR_INVALID_HEAPINFO";
+		case PVRSRV_ERROR_INVALID_PERPROC:				return "PVRSRV_ERROR_INVALID_PERPROC";
+		case PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO:	return "PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO";
+		case PVRSRV_ERROR_INVALID_MAP_REQUEST:			return "PVRSRV_ERROR_INVALID_MAP_REQUEST";
+		case PVRSRV_ERROR_INVALID_UNMAP_REQUEST:		return "PVRSRV_ERROR_INVALID_UNMAP_REQUEST";
+		case PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP:	return "PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP";
+		case PVRSRV_ERROR_MAPPING_STILL_IN_USE:			return "PVRSRV_ERROR_MAPPING_STILL_IN_USE";
+
+		case PVRSRV_ERROR_EXCEEDED_HW_LIMITS:			return "PVRSRV_ERROR_EXCEEDED_HW_LIMITS";
+		case PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED:	return "PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED";
+
+		case PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA:return "PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA";
+		case PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT:		return "PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT";
+		case PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT:		return "PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT";
+		case PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT:		return "PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT";
+		case PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT:		return "PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT";
+		case PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD:		return "PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD";
+		case PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD:		return "PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD";
+		case PVRSRV_ERROR_THREAD_READ_ERROR:			return "PVRSRV_ERROR_THREAD_READ_ERROR";
+		case PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER:return "PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER";
+		case PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR:		return "PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR";
+		case PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR:		return "PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR";
+		case PVRSRV_ERROR_ISR_ALREADY_INSTALLED:		return "PVRSRV_ERROR_ISR_ALREADY_INSTALLED";
+		case PVRSRV_ERROR_ISR_NOT_INSTALLED:			return "PVRSRV_ERROR_ISR_NOT_INSTALLED";
+		case PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT:return "PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT";
+		case PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO:		return "PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO";
+		case PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT:	return "PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT";
+		case PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES:		return "PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES";
+		case PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT:	return "PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT";
+		case PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE:	return "PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE";
+
+		case PVRSRV_ERROR_INVALID_CCB_COMMAND:			return "PVRSRV_ERROR_INVALID_CCB_COMMAND";
+
+		case PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE:		return "PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE";
+		case PVRSRV_ERROR_INVALID_LOCK_ID:				return "PVRSRV_ERROR_INVALID_LOCK_ID";
+		case PVRSRV_ERROR_RESOURCE_NOT_LOCKED:			return "PVRSRV_ERROR_RESOURCE_NOT_LOCKED";
+
+		case PVRSRV_ERROR_FLIP_FAILED:					return "PVRSRV_ERROR_FLIP_FAILED";
+		case PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED:		return "PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED";
+
+		case PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE:	return "PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE";
+
+		case PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED:	return "PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED";
+		case PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG:			return "PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG";
+		case PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG:	return "PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG";
+		case PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG:		return "PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG";
+
+		case PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID:	return "PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID";
+
+		case PVRSRV_ERROR_BLIT_SETUP_FAILED:			return "PVRSRV_ERROR_BLIT_SETUP_FAILED";
+
+		case PVRSRV_ERROR_PDUMP_NOT_AVAILABLE:			return "PVRSRV_ERROR_PDUMP_NOT_AVAILABLE";
+		case PVRSRV_ERROR_PDUMP_BUFFER_FULL:			return "PVRSRV_ERROR_PDUMP_BUFFER_FULL";
+		case PVRSRV_ERROR_PDUMP_BUF_OVERFLOW:			return "PVRSRV_ERROR_PDUMP_BUF_OVERFLOW";
+		case PVRSRV_ERROR_PDUMP_NOT_ACTIVE:				return "PVRSRV_ERROR_PDUMP_NOT_ACTIVE";
+		case PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES:return "PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES";
+
+		case PVRSRV_ERROR_MUTEX_DESTROY_FAILED:			return "PVRSRV_ERROR_MUTEX_DESTROY_FAILED";
+		case PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR:	return "PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR";
+
+		case PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE:	return "PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE";
+		case PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND:return "PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND";
+
+		case PVRSRV_ERROR_PROCESS_NOT_INITIALISED:		return "PVRSRV_ERROR_PROCESS_NOT_INITIALISED";
+		case PVRSRV_ERROR_PROCESS_NOT_FOUND:			return "PVRSRV_ERROR_PROCESS_NOT_FOUND";
+		case PVRSRV_ERROR_SRV_CONNECT_FAILED:			return "PVRSRV_ERROR_SRV_CONNECT_FAILED";
+		case PVRSRV_ERROR_SRV_DISCONNECT_FAILED:		return "PVRSRV_ERROR_SRV_DISCONNECT_FAILED";
+		case PVRSRV_ERROR_DEINT_PHASE_FAILED:			return "PVRSRV_ERROR_DEINT_PHASE_FAILED";
+		case PVRSRV_ERROR_INIT2_PHASE_FAILED:			return "PVRSRV_ERROR_INIT2_PHASE_FAILED";
+
+		case PVRSRV_ERROR_NO_DC_DEVICES_FOUND:			return "PVRSRV_ERROR_NO_DC_DEVICES_FOUND";
+		case PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE:		return "PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE";
+		case PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE:		return "PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE";
+		case PVRSRV_ERROR_NO_DEVICEDATA_FOUND:			return "PVRSRV_ERROR_NO_DEVICEDATA_FOUND";
+		case PVRSRV_ERROR_NO_DEVICENODE_FOUND:			return "PVRSRV_ERROR_NO_DEVICENODE_FOUND";
+		case PVRSRV_ERROR_NO_CLIENTNODE_FOUND:			return "PVRSRV_ERROR_NO_CLIENTNODE_FOUND";
+		case PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE:		return "PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE";
+
+		case PVRSRV_ERROR_UNABLE_TO_INIT_TASK:			return "PVRSRV_ERROR_UNABLE_TO_INIT_TASK";
+		case PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK:		return "PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK";
+		case PVRSRV_ERROR_UNABLE_TO_KILL_TASK:			return "PVRSRV_ERROR_UNABLE_TO_KILL_TASK";
+
+		case PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER:		return "PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER";
+		case PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER:		return "PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER";
+		case PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER:		return "PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER";
+
+		case PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT:			return "PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT";
+		case PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION:		return "PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION";
+
+		case PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE:	return "PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE";
+		case PVRSRV_ERROR_HANDLE_NOT_ALLOCATED:			return "PVRSRV_ERROR_HANDLE_NOT_ALLOCATED";
+		case PVRSRV_ERROR_HANDLE_TYPE_MISMATCH:			return "PVRSRV_ERROR_HANDLE_TYPE_MISMATCH";
+		case PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE:			return "PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE";
+		case PVRSRV_ERROR_HANDLE_NOT_SHAREABLE:			return "PVRSRV_ERROR_HANDLE_NOT_SHAREABLE";
+		case PVRSRV_ERROR_HANDLE_NOT_FOUND:				return "PVRSRV_ERROR_HANDLE_NOT_FOUND";
+		case PVRSRV_ERROR_INVALID_SUBHANDLE:			return "PVRSRV_ERROR_INVALID_SUBHANDLE";
+		case PVRSRV_ERROR_HANDLE_BATCH_IN_USE:			return "PVRSRV_ERROR_HANDLE_BATCH_IN_USE";
+		case PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE:	return "PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE";
+
+		case PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE:	return "PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE";
+		case PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED:return "PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED";
+
+		case PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE:	return "PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE";
+		case PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP:	return "PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP";
+
+		case PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE:	return "PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE";
+
+		case PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE:	return "PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE";
+		case PVRSRV_ERROR_INVALID_DEVICEID:				return "PVRSRV_ERROR_INVALID_DEVICEID";
+		case PVRSRV_ERROR_DEVICEID_NOT_FOUND:			return "PVRSRV_ERROR_DEVICEID_NOT_FOUND";
+
+		case PVRSRV_ERROR_MEMORY_TEST_FAILED:			return "PVRSRV_ERROR_MEMORY_TEST_FAILED";
+		case PVRSRV_ERROR_CPUPADDR_TEST_FAILED:			return "PVRSRV_ERROR_CPUPADDR_TEST_FAILED";
+		case PVRSRV_ERROR_COPY_TEST_FAILED:				return "PVRSRV_ERROR_COPY_TEST_FAILED";
+
+		case PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED:	return "PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED";
+
+		case PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK:		return "PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK";
+		case PVRSRV_ERROR_CLOCK_REQUEST_FAILED:			return "PVRSRV_ERROR_CLOCK_REQUEST_FAILED";
+		case PVRSRV_ERROR_DISABLE_CLOCK_FAILURE:		return "PVRSRV_ERROR_DISABLE_CLOCK_FAILURE";
+		case PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE:		return "PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE";
+		case PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE:	return "PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE";
+		case PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK:		return "PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK";
+		case PVRSRV_ERROR_UNABLE_TO_GET_CLOCK:			return "PVRSRV_ERROR_UNABLE_TO_GET_CLOCK";
+		case PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK:	return "PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK";
+		case PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK:	return "PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK";
+
+		case PVRSRV_ERROR_UNKNOWN_SGL_ERROR:			return "PVRSRV_ERROR_UNKNOWN_SGL_ERROR";
+	    case PVRSRV_ERROR_BAD_SYNC_STATE:               return "PVRSRV_ERROR_BAD_SYNC_STATE";
+
+		case PVRSRV_ERROR_FORCE_I32:					return "PVRSRV_ERROR_FORCE_I32";
+
+		default:
+			return "Unknown PVRSRV error number";
+	}
+
+#if defined (__cplusplus)
+}
+#endif
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/include/servicesint.h b/drivers/staging/cdv/pvr/services4/include/servicesint.h
new file mode 100644
index 0000000..efd8f50
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/servicesint.h
@@ -0,0 +1,381 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined (__SERVICESINT_H__)
+#define __SERVICESINT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "services.h"
+#include "sysinfo.h"
+
+#define HWREC_DEFAULT_TIMEOUT	(500)
+
+#define DRIVERNAME_MAXLENGTH	(100)
+
+#define	ALIGNSIZE(size, alignshift)	(((size) + ((1UL << (alignshift))-1)) & ~((1UL << (alignshift))-1))
+
+#ifndef MAX
+#define MAX(a,b) 					(((a) > (b)) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) 					(((a) < (b)) ? (a) : (b))
+#endif
+
+typedef enum _PVRSRV_MEMTYPE_
+{
+	PVRSRV_MEMTYPE_UNKNOWN		= 0,
+	PVRSRV_MEMTYPE_DEVICE		= 1,
+	PVRSRV_MEMTYPE_DEVICECLASS	= 2,
+	PVRSRV_MEMTYPE_WRAPPED		= 3,
+	PVRSRV_MEMTYPE_MAPPED		= 4,
+} PVRSRV_MEMTYPE;
+
+typedef struct _PVRSRV_KERNEL_MEM_INFO_
+{
+	
+	IMG_PVOID				pvLinAddrKM;
+
+	
+	IMG_DEV_VIRTADDR		sDevVAddr;
+
+	
+	IMG_UINT32				ui32Flags;
+
+	
+	IMG_SIZE_T				uAllocSize;
+
+	
+	PVRSRV_MEMBLK			sMemBlk;
+
+	
+	IMG_PVOID				pvSysBackupBuffer;
+
+	
+	IMG_UINT32				ui32RefCount;
+
+	
+	IMG_BOOL				bPendingFree;
+
+
+#if defined(SUPPORT_MEMINFO_IDS)
+	#if !defined(USE_CODE)
+	
+	IMG_UINT64				ui64Stamp;
+	#else 
+	IMG_UINT32				dummy1;
+	IMG_UINT32				dummy2;
+	#endif 
+#endif 
+
+	
+	struct _PVRSRV_KERNEL_SYNC_INFO_	*psKernelSyncInfo;
+
+	PVRSRV_MEMTYPE				memType;
+
+    
+
+
+
+
+
+
+	struct {
+        
+
+		IMG_BOOL bInUse;
+
+        
+		IMG_HANDLE hDevCookieInt;
+
+        
+		IMG_UINT32 ui32ShareIndex;
+
+        
+
+		IMG_UINT32 ui32OrigReqAttribs;
+		IMG_UINT32 ui32OrigReqSize;
+		IMG_UINT32 ui32OrigReqAlignment;
+	} sShareMemWorkaround;
+} PVRSRV_KERNEL_MEM_INFO;
+
+
+typedef struct _PVRSRV_KERNEL_SYNC_INFO_
+{
+	
+	PVRSRV_SYNC_DATA		*psSyncData;
+
+	
+	IMG_DEV_VIRTADDR		sWriteOpsCompleteDevVAddr;
+
+	
+	IMG_DEV_VIRTADDR		sReadOpsCompleteDevVAddr;
+
+	
+	PVRSRV_KERNEL_MEM_INFO	*psSyncDataMemInfoKM;
+
+	
+	
+	IMG_UINT32              ui32RefCount;
+
+	
+	IMG_HANDLE hResItem;
+
+	
+	IMG_UINT32		ui32UID;
+} PVRSRV_KERNEL_SYNC_INFO;
+
+typedef struct _PVRSRV_DEVICE_SYNC_OBJECT_
+{
+	
+	IMG_UINT32			ui32ReadOpsPendingVal;
+	IMG_DEV_VIRTADDR	sReadOpsCompleteDevVAddr;
+	IMG_UINT32			ui32WriteOpsPendingVal;
+	IMG_DEV_VIRTADDR	sWriteOpsCompleteDevVAddr;
+} PVRSRV_DEVICE_SYNC_OBJECT;
+
+typedef struct _PVRSRV_SYNC_OBJECT
+{
+	PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfoKM;
+	IMG_UINT32				ui32WriteOpsPending;
+	IMG_UINT32				ui32ReadOpsPending;
+
+}PVRSRV_SYNC_OBJECT, *PPVRSRV_SYNC_OBJECT;
+
+typedef struct _PVRSRV_COMMAND
+{
+	IMG_SIZE_T			uCmdSize;		
+	IMG_UINT32			ui32DevIndex;		
+	IMG_UINT32			CommandType;		
+	IMG_UINT32			ui32DstSyncCount;	
+	IMG_UINT32			ui32SrcSyncCount;	
+	PVRSRV_SYNC_OBJECT	*psDstSync;			
+	PVRSRV_SYNC_OBJECT	*psSrcSync;			
+	IMG_SIZE_T			uDataSize;		
+	IMG_UINT32			ui32ProcessID;		
+	IMG_VOID			*pvData;			
+}PVRSRV_COMMAND, *PPVRSRV_COMMAND;
+
+
+typedef struct _PVRSRV_QUEUE_INFO_
+{
+	IMG_VOID			*pvLinQueueKM;			
+	IMG_VOID			*pvLinQueueUM;			
+	volatile IMG_SIZE_T	ui32ReadOffset;			
+	volatile IMG_SIZE_T	ui32WriteOffset;		
+	IMG_UINT32			*pui32KickerAddrKM;		
+	IMG_UINT32			*pui32KickerAddrUM;		
+	IMG_SIZE_T			ui32QueueSize;			
+
+	IMG_UINT32			ui32ProcessID;			
+
+	IMG_HANDLE			hMemBlock[2];
+
+	struct _PVRSRV_QUEUE_INFO_ *psNextKM;		
+}PVRSRV_QUEUE_INFO;
+
+
+typedef struct _PVRSRV_HEAP_INFO_KM_
+{
+	IMG_UINT32			ui32HeapID;
+	IMG_DEV_VIRTADDR	sDevVAddrBase;
+
+	IMG_HANDLE 			hDevMemHeap;
+	IMG_UINT32			ui32HeapByteSize;
+	IMG_UINT32			ui32Attribs;
+	IMG_UINT32			ui32XTileStride;
+}PVRSRV_HEAP_INFO_KM;
+
+
+typedef struct _PVRSRV_EVENTOBJECT_KM_
+{
+	
+	IMG_CHAR	szName[EVENTOBJNAME_MAXLENGTH];
+	
+	IMG_HANDLE	hOSEventKM;
+
+} PVRSRV_EVENTOBJECT_KM;
+
+
+typedef struct _PVRSRV_MISC_INFO_KM_
+{
+	IMG_UINT32	ui32StateRequest;		
+	IMG_UINT32	ui32StatePresent;		
+
+	
+	IMG_VOID	*pvSOCTimerRegisterKM;
+	IMG_VOID	*pvSOCTimerRegisterUM;
+	IMG_HANDLE	hSOCTimerRegisterOSMemHandle;
+	IMG_HANDLE	hSOCTimerRegisterMappingInfo;
+
+	
+	IMG_VOID	*pvSOCClockGateRegs;
+	IMG_UINT32	ui32SOCClockGateRegsSize;
+
+	
+	IMG_CHAR	*pszMemoryStr;
+	IMG_UINT32	ui32MemoryStrLen;
+
+	
+	PVRSRV_EVENTOBJECT_KM	sGlobalEventObject;
+	IMG_HANDLE				hOSGlobalEvent;
+
+	
+	IMG_UINT32	aui32DDKVersion[4];
+
+	
+	struct
+	{
+		
+		IMG_BOOL bDeferOp;
+
+		
+		PVRSRV_MISC_INFO_CPUCACHEOP_TYPE eCacheOpType;
+
+		PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+		
+		IMG_VOID *pvBaseVAddr;
+
+		
+		IMG_UINT32	ui32Length;
+	} sCacheOpCtl;
+} PVRSRV_MISC_INFO_KM;
+
+
+typedef PVRSRV_ERROR (*PFN_INSERT_CMD) (PVRSRV_QUEUE_INFO*,
+										PVRSRV_COMMAND**,
+										IMG_UINT32,
+										IMG_UINT16,
+										IMG_UINT32,
+										PVRSRV_KERNEL_SYNC_INFO*[],
+										IMG_UINT32,
+										PVRSRV_KERNEL_SYNC_INFO*[],
+										IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_SUBMIT_CMD) (PVRSRV_QUEUE_INFO*, PVRSRV_COMMAND*, IMG_BOOL);
+
+
+typedef struct PVRSRV_DEVICECLASS_BUFFER_TAG
+{
+	PFN_GET_BUFFER_ADDR		pfnGetBufferAddr;
+	IMG_HANDLE				hDevMemContext;
+	IMG_HANDLE				hExtDevice;
+	IMG_HANDLE				hExtBuffer;
+	PVRSRV_KERNEL_SYNC_INFO	*psKernelSyncInfo;
+	IMG_UINT32				ui32MemMapRefCount;
+} PVRSRV_DEVICECLASS_BUFFER;
+
+
+typedef struct PVRSRV_CLIENT_DEVICECLASS_INFO_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID     hDeviceKM;
+#else
+	IMG_HANDLE hDeviceKM;
+#endif
+	IMG_HANDLE	hServices;
+} PVRSRV_CLIENT_DEVICECLASS_INFO;
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVGetWriteOpsPending)
+#endif
+static INLINE
+IMG_UINT32 PVRSRVGetWriteOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp)
+{
+	IMG_UINT32 ui32WriteOpsPending;
+
+	if(bIsReadOp)
+	{
+		ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending;
+	}
+	else
+	{
+		
+
+
+		ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+	}
+
+	return ui32WriteOpsPending;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVGetReadOpsPending)
+#endif
+static INLINE
+IMG_UINT32 PVRSRVGetReadOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp)
+{
+	IMG_UINT32 ui32ReadOpsPending;
+
+	if(bIsReadOp)
+	{
+		ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+	}
+	else
+	{
+		ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending;
+	}
+
+	return ui32ReadOpsPending;
+}
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVQueueCommand(IMG_HANDLE hQueueInfo,
+								PVRSRV_COMMAND *psCommand);
+
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
+PVRSRVAllocSharedSysMem(const PVRSRV_CONNECTION *psConnection,
+						IMG_UINT32 ui32Flags,
+						IMG_SIZE_T ui32Size,
+						PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
+PVRSRVFreeSharedSysMem(const PVRSRV_CONNECTION *psConnection,
+					   PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVUnrefSharedSysMem(const PVRSRV_CONNECTION *psConnection,
+                        PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
+PVRSRVMapMemInfoMem(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+                    IMG_SID hKernelMemInfo,
+#else
+                    IMG_HANDLE hKernelMemInfo,
+#endif
+                    PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
+
+
+#if defined (__cplusplus)
+}
+#endif
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/include/sgx_bridge.h b/drivers/staging/cdv/pvr/services4/include/sgx_bridge.h
new file mode 100644
index 0000000..ec630a5
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/sgx_bridge.h
@@ -0,0 +1,666 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined(__SGX_BRIDGE_H__)
+#define __SGX_BRIDGE_H__
+
+#if defined (SUPPORT_SID_INTERFACE)
+#include "sgxapi.h"
+#else
+#include "sgxapi_km.h"
+#endif
+#include "sgxinfo.h"
+#include "pvr_bridge.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+#define PVRSRV_BRIDGE_SGX_CMD_BASE (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1)
+#define PVRSRV_BRIDGE_SGX_GETCLIENTINFO			PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+0)
+#define PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO		PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+1)
+#define PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO	PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+2)
+#define PVRSRV_BRIDGE_SGX_DOKICK				PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+3)
+#define PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR		PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+4)
+#define PVRSRV_BRIDGE_SGX_READREGISTRYDWORD		PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+5)
+
+#define PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE   PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+9)
+
+#if defined(TRANSFER_QUEUE)
+#define PVRSRV_BRIDGE_SGX_SUBMITTRANSFER			PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+13)
+#endif
+#define PVRSRV_BRIDGE_SGX_GETMISCINFO				PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+14)
+#define PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT			PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+15)
+#define PVRSRV_BRIDGE_SGX_DEVINITPART2				PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+16)
+
+#define PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC			PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+17)
+#define PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC			PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+18)
+#define PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC			PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+19)
+#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_SCHEDULE_PROCESS_QUEUES		PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+28)
+
+#define PVRSRV_BRIDGE_SGX_READ_HWPERF_CB			PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+29)
+#define PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY      PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+30)
+#define PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY      PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+31)
+
+#if defined(PDUMP)
+#define PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY		PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+32)
+#define PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS	PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+33)
+#define PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS	PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+34)
+#define PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS	PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+35)
+#define PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB				PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+36)
+#define PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM					PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+37)
+#endif
+
+
+
+#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+37)
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_HANDLE hDevMemHeap;
+	IMG_DEV_VIRTADDR sDevVAddr;
+}PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR;
+
+ 
+typedef struct PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR
+{
+	PVRSRV_ERROR		eError;
+	IMG_DEV_PHYADDR		DevPAddr;
+	IMG_CPU_PHYADDR		CpuPAddr;
+}PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR;
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY_TAG
+ {
+ 	IMG_UINT32				ui32BridgeFlags; 
+ #if defined (SUPPORT_SID_INTERFACE)
+ 	IMG_SID					hDevCookie;
+	IMG_SID					hHWTransferContext;
+ #else
+ 	IMG_HANDLE				hDevCookie;
+	IMG_HANDLE				hHWTransferContext;
+ #endif
+    IMG_UINT32              ui32Priority;
+    IMG_UINT32              ui32OffsetOfPriorityField;
+}PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY;
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDevCookie;
+	IMG_SID					hHWRenderContext;
+#else
+	IMG_HANDLE				hDevCookie;
+	IMG_HANDLE				hHWRenderContext;
+#endif
+    IMG_UINT32              ui32Priority;
+    IMG_UINT32              ui32OffsetOfPriorityField;
+}PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY;
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_GETCLIENTINFO_TAG
+{
+	IMG_UINT32					ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID						hDevCookie;
+#else
+	IMG_HANDLE					hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_GETCLIENTINFO;
+
+ 
+typedef struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO_TAG
+{
+	SGX_INTERNAL_DEVINFO	sSGXInternalDevInfo;
+	PVRSRV_ERROR				eError;
+}PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO;
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDevCookie;
+#else
+	IMG_HANDLE				hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO;
+
+ 
+typedef struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO_TAG
+{
+	SGX_CLIENT_INFO  	sClientInfo;
+	PVRSRV_ERROR			eError;
+}PVRSRV_BRIDGE_OUT_GETCLIENTINFO;
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+	SGX_CLIENT_INFO  	sClientInfo;
+}PVRSRV_BRIDGE_IN_RELEASECLIENTINFO;
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_ISPBREAKPOLL_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDevCookie;
+#else
+	IMG_HANDLE				hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_ISPBREAKPOLL;
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_DOKICK_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDevCookie;
+#else
+	IMG_HANDLE				hDevCookie;
+#endif
+	SGX_CCB_KICK			sCCBKick;
+}PVRSRV_BRIDGE_IN_DOKICK;
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDevCookie;
+#else
+	IMG_HANDLE				hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES;
+
+
+#if defined(TRANSFER_QUEUE)
+ 
+typedef struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDevCookie;
+#else
+	IMG_HANDLE				hDevCookie;
+#endif
+	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; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDevCookie;
+#else
+	IMG_HANDLE				hDevCookie;
+#endif
+	PVRSRV_2D_SGX_KICK 		sKick;
+} PVRSRV_BRIDGE_IN_SUBMIT2D;
+#endif
+#endif
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_READREGDWORD_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDevCookie;
+#else
+	IMG_HANDLE				hDevCookie;
+#endif
+    IMG_PCHAR				pszKey;
+    IMG_PCHAR				pszValue;
+}PVRSRV_BRIDGE_IN_READREGDWORD;
+
+ 
+typedef struct PVRSRV_BRIDGE_OUT_READREGDWORD_TAG
+{
+	PVRSRV_ERROR	eError;
+	IMG_UINT32		ui32Data;
+}PVRSRV_BRIDGE_OUT_READREGDWORD;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO_TAG
+{
+	IMG_UINT32		ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hDevCookie;
+#else
+	IMG_HANDLE		hDevCookie;
+#endif
+	SGX_MISC_INFO	*psMiscInfo;
+}PVRSRV_BRIDGE_IN_SGXGETMISCINFO;
+
+typedef struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT_TAG
+{
+	IMG_UINT32		ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hDevCookie;
+#else
+	IMG_HANDLE		hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT_TAG
+{
+	PVRSRV_ERROR			eError;
+	SGX_BRIDGE_INFO_FOR_SRVINIT	sInitInfo;
+}PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2_TAG
+{
+	IMG_UINT32		ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hDevCookie;
+#else
+	IMG_HANDLE		hDevCookie;
+#endif
+	SGX_BRIDGE_INIT_INFO	sInitInfo;
+}PVRSRV_BRIDGE_IN_SGXDEVINITPART2;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXDEVINITPART2_TAG
+{
+	PVRSRV_ERROR 	eError;
+	IMG_UINT32 		ui32KMBuildOptions;
+
+}PVRSRV_BRIDGE_OUT_SGXDEVINITPART2;
+
+ 
+typedef struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE_TAG
+{
+	IMG_UINT32				ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hDevCookie;
+	IMG_SID					hKernSyncInfo;
+#else
+	IMG_HANDLE				hDevCookie;
+	IMG_HANDLE				hKernSyncInfo;
+#endif
+	IMG_BOOL				bWaitForComplete;
+}PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE;
+
+
+#define PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS 10
+
+typedef struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+	IMG_BOOL   bLockOnFailure;
+	IMG_UINT32 ui32TotalPBSize;
+}PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID hKernelMemInfo;
+	IMG_SID hSharedPBDesc;
+	IMG_SID hSharedPBDescKernelMemInfoHandle;
+	IMG_SID hHWPBDescKernelMemInfoHandle;
+	IMG_SID hBlockKernelMemInfoHandle;
+	IMG_SID hHWBlockKernelMemInfoHandle;
+	IMG_SID ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS];
+#else
+	IMG_HANDLE hKernelMemInfo;
+	IMG_HANDLE hSharedPBDesc;
+	IMG_HANDLE hSharedPBDescKernelMemInfoHandle;
+	IMG_HANDLE hHWPBDescKernelMemInfoHandle;
+	IMG_HANDLE hBlockKernelMemInfoHandle;
+	IMG_HANDLE hHWBlockKernelMemInfoHandle;
+	IMG_HANDLE ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS];
+#endif
+	IMG_UINT32 ui32SharedPBDescSubKernelMemInfoHandlesCount;
+	PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hSharedPBDesc;
+#else
+	IMG_HANDLE hSharedPBDesc;
+#endif
+}PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC_TAG
+{
+	PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_UINT32 ui32TotalPBSize;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+	IMG_SID    hSharedPBDescKernelMemInfo;
+	IMG_SID    hHWPBDescKernelMemInfo;
+	IMG_SID    hBlockKernelMemInfo;
+	IMG_SID    hHWBlockKernelMemInfo;
+	IMG_SID    *phKernelMemInfoHandles;
+#else
+	IMG_HANDLE hDevCookie;
+	IMG_HANDLE hSharedPBDescKernelMemInfo;
+	IMG_HANDLE hHWPBDescKernelMemInfo;
+	IMG_HANDLE hBlockKernelMemInfo;
+	IMG_HANDLE hHWBlockKernelMemInfo;
+	IMG_HANDLE *phKernelMemInfoHandles;
+#endif
+	IMG_UINT32 ui32KernelMemInfoHandlesCount;
+	IMG_DEV_VIRTADDR sHWPBDescDevVAddr;
+}PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC_TAG
+{
+	PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID      hSharedPBDesc;
+#else
+	IMG_HANDLE hSharedPBDesc;
+#endif
+}PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC;
+
+
+#ifdef	PDUMP
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	SGX_KICKTA_DUMP_BUFFER *psBufferArray;
+	IMG_UINT32 ui32BufferArrayLength;
+	IMG_BOOL bDumpPolls;
+} PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+	IMG_SID    hDevMemContext;
+#else
+	IMG_HANDLE hDevCookie;
+	IMG_HANDLE hDevMemContext;
+#endif
+	IMG_UINT32 ui32DumpFrameNum;
+	IMG_BOOL   bLastFrame;
+	IMG_UINT32 *pui32Registers;
+	IMG_UINT32 ui32NumRegisters;
+}PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMPCOUNTER_REGISTERS_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+	IMG_UINT32 ui32DumpFrameNum;
+	IMG_BOOL bLastFrame;
+	IMG_UINT32 *pui32Registers;
+	IMG_UINT32 ui32NumRegisters;
+}PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+	IMG_UINT32 ui32DumpFrameNum;
+	IMG_UINT32 ui32TAKickCount;
+	IMG_BOOL bLastFrame;
+	IMG_UINT32 *pui32Registers;
+	IMG_UINT32 ui32NumRegisters;
+}PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB_TAG
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+	IMG_SID				hDevMemContext;
+#else
+	IMG_HANDLE			hDevCookie;
+	IMG_HANDLE			hDevMemContext;
+#endif
+	IMG_CHAR			szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+	IMG_UINT32			ui32FileOffset;
+	IMG_UINT32			ui32PDumpFlags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM
+{
+	IMG_UINT32			ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hDevCookie;
+	IMG_SID				hDevMemContext;
+#else
+	IMG_HANDLE			hDevCookie;
+#endif
+	IMG_CHAR			szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+	IMG_UINT32			ui32FileOffset;
+	IMG_DEV_VIRTADDR 	sDevVAddr;
+	IMG_UINT32			ui32Size;
+#if !defined (SUPPORT_SID_INTERFACE)
+	IMG_HANDLE			hDevMemContext;
+#endif
+	IMG_UINT32			ui32PDumpFlags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM;
+
+#endif
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+    IMG_CPU_VIRTADDR pHWRenderContextCpuVAddr;
+    IMG_UINT32       ui32HWRenderContextSize;
+    IMG_UINT32       ui32OffsetToPDDevPAddr;
+    IMG_HANDLE       hDevMemContext;
+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
+{
+	PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hHWRenderContext;
+#else
+	IMG_HANDLE hHWRenderContext;
+#endif
+    IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_BOOL   bForceCleanup;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+	IMG_SID    hHWRenderContext;
+#else
+	IMG_HANDLE hDevCookie;
+	IMG_HANDLE hHWRenderContext;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+    IMG_CPU_VIRTADDR pHWTransferContextCpuVAddr;
+    IMG_UINT32       ui32HWTransferContextSize;
+    IMG_UINT32       ui32OffsetToPDDevPAddr;
+    IMG_HANDLE       hDevMemContext;
+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
+{
+	PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID      hHWTransferContext;
+#else
+	IMG_HANDLE hHWTransferContext;
+#endif
+    IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_BOOL   bForceCleanup;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+	IMG_SID    hHWTransferContext;
+#else
+	IMG_HANDLE hDevCookie;
+	IMG_HANDLE hHWTransferContext;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+	IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr;
+}PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET;
+
+ 
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+#else
+	IMG_HANDLE hDevCookie;
+#endif
+    IMG_CPU_VIRTADDR pHW2DContextCpuVAddr;
+    IMG_UINT32       ui32HW2DContextSize;
+    IMG_UINT32       ui32OffsetToPDDevPAddr;
+    IMG_HANDLE       hDevMemContext;
+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG
+{
+	PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hHW2DContext;
+#else
+	IMG_HANDLE hHW2DContext;
+#endif
+    IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT_TAG
+{
+	IMG_UINT32 ui32BridgeFlags; 
+	IMG_BOOL   bForceCleanup;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID    hDevCookie;
+	IMG_SID    hHW2DContext;
+#else
+	IMG_HANDLE hDevCookie;
+	IMG_HANDLE hHW2DContext;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT;
+
+#define	SGX2D_MAX_BLT_CMD_SIZ		256	
+#endif 
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB_TAG
+{
+	IMG_UINT32					ui32BridgeFlags; 
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID						hDevCookie;
+#else
+	IMG_HANDLE					hDevCookie;
+#endif
+	IMG_UINT32					ui32ArraySize;
+	PVRSRV_SGX_HWPERF_CB_ENTRY	*psHWPerfCBData;
+} PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB_TAG
+{
+	PVRSRV_ERROR		eError;
+	IMG_UINT32			ui32DataCount;
+	IMG_UINT32			ui32ClockSpeed;
+	IMG_UINT32			ui32HostTimeStamp;
+} PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB;
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/include/sgx_mkif_km.h b/drivers/staging/cdv/pvr/services4/include/sgx_mkif_km.h
new file mode 100644
index 0000000..d5cffdb
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/sgx_mkif_km.h
@@ -0,0 +1,347 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined (__SGX_MKIF_KM_H__)
+#define __SGX_MKIF_KM_H__
+
+#include "img_types.h"
+#include "servicesint.h"
+#include "sgxapi_km.h"
+
+
+#if !defined (SGX_MP_CORE_SELECT)
+#if defined(SGX_FEATURE_MP)
+	#define SGX_REG_BANK_SHIFT 			(14)
+	#define SGX_REG_BANK_SIZE 			(1 << SGX_REG_BANK_SHIFT)
+	#define SGX_REG_BANK_BASE_INDEX		(2)
+	#define	SGX_REG_BANK_MASTER_INDEX	(1)
+	#define SGX_MP_CORE_SELECT(x,i) 	(x + ((i + SGX_REG_BANK_BASE_INDEX) * SGX_REG_BANK_SIZE))
+	#define SGX_MP_MASTER_SELECT(x) 	(x + (SGX_REG_BANK_MASTER_INDEX * SGX_REG_BANK_SIZE))
+#else
+	#define SGX_MP_CORE_SELECT(x,i) 	(x)
+#endif 
+#endif
+
+
+typedef struct _SGXMKIF_COMMAND_
+{
+	IMG_UINT32				ui32ServiceAddress;		
+	IMG_UINT32				ui32CacheControl;		
+	IMG_UINT32				ui32Data[6];			
+} SGXMKIF_COMMAND;
+
+
+typedef struct _PVRSRV_SGX_KERNEL_CCB_
+{
+	SGXMKIF_COMMAND		asCommands[256];		
+} PVRSRV_SGX_KERNEL_CCB;
+
+
+typedef struct _PVRSRV_SGX_CCB_CTL_
+{
+	IMG_UINT32				ui32WriteOffset;		
+	IMG_UINT32				ui32ReadOffset;			
+} PVRSRV_SGX_CCB_CTL;
+
+
+typedef struct _SGXMKIF_HOST_CTL_
+{
+#if defined(PVRSRV_USSE_EDM_BREAKPOINTS)
+	IMG_UINT32				ui32BreakpointDisable;
+	IMG_UINT32				ui32Continue;
+#endif
+
+	volatile IMG_UINT32		ui32InitStatus;				
+	volatile IMG_UINT32		ui32PowerStatus;			
+	volatile IMG_UINT32		ui32CleanupStatus;			
+#if defined(FIX_HW_BRN_28889)
+	volatile IMG_UINT32		ui32InvalStatus;			
+#endif
+#if defined(SUPPORT_HW_RECOVERY)
+	IMG_UINT32				ui32uKernelDetectedLockups;	
+	IMG_UINT32				ui32HostDetectedLockups;	
+	IMG_UINT32				ui32HWRecoverySampleRate;	
+#endif 
+	IMG_UINT32				ui32uKernelTimerClock;		
+	IMG_UINT32				ui32ActivePowManSampleRate;	
+	IMG_UINT32				ui32InterruptFlags; 		
+	IMG_UINT32				ui32InterruptClearFlags; 	
+	IMG_UINT32				ui32BPSetClearSignal;		
+
+	IMG_UINT32				ui32NumActivePowerEvents;	
+
+	IMG_UINT32				ui32TimeWraps;				
+	IMG_UINT32				ui32HostClock;				
+	IMG_UINT32				ui32AssertFail;				
+
+#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+	IMG_UINT32				aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS];	
+	IMG_UINT32				aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS];	
+#else
+	IMG_UINT32				ui32PerfGroup;									
+#endif 
+
+#if defined(FIX_HW_BRN_31939)
+	IMG_UINT32				ui32BRN31939Mem;
+#endif
+
+	IMG_UINT32				ui32OpenCLDelayCount;			
+} SGXMKIF_HOST_CTL;
+
+#define	SGXMKIF_CMDTA_CTRLFLAGS_READY			0x00000001
+typedef struct _SGXMKIF_CMDTA_SHARED_
+{
+	IMG_UINT32			ui32CtrlFlags;
+	
+	IMG_UINT32			ui32NumTAStatusVals;
+	IMG_UINT32			ui32Num3DStatusVals;
+
+	
+	IMG_UINT32			ui32TATQSyncWriteOpsPendingVal;
+	IMG_DEV_VIRTADDR	sTATQSyncWriteOpsCompleteDevVAddr;
+	IMG_UINT32			ui32TATQSyncReadOpsPendingVal;
+	IMG_DEV_VIRTADDR	sTATQSyncReadOpsCompleteDevVAddr;
+
+	
+	IMG_UINT32			ui323DTQSyncWriteOpsPendingVal;
+	IMG_DEV_VIRTADDR	s3DTQSyncWriteOpsCompleteDevVAddr;
+	IMG_UINT32			ui323DTQSyncReadOpsPendingVal;
+	IMG_DEV_VIRTADDR	s3DTQSyncReadOpsCompleteDevVAddr;
+
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+	
+	IMG_UINT32					ui32NumTASrcSyncs;
+	PVRSRV_DEVICE_SYNC_OBJECT	asTASrcSyncs[SGX_MAX_TA_SRC_SYNCS];
+	IMG_UINT32					ui32NumTADstSyncs;
+	PVRSRV_DEVICE_SYNC_OBJECT	asTADstSyncs[SGX_MAX_TA_DST_SYNCS];
+	IMG_UINT32					ui32Num3DSrcSyncs;
+	PVRSRV_DEVICE_SYNC_OBJECT	as3DSrcSyncs[SGX_MAX_3D_SRC_SYNCS];
+#else
+	
+	IMG_UINT32			ui32NumSrcSyncs;
+	PVRSRV_DEVICE_SYNC_OBJECT	asSrcSyncs[SGX_MAX_SRC_SYNCS];
+#endif
+
+	
+	PVRSRV_DEVICE_SYNC_OBJECT	sTA3DDependency;
+
+	CTL_STATUS			sCtlTAStatusInfo[SGX_MAX_TA_STATUS_VALS];
+	CTL_STATUS			sCtl3DStatusInfo[SGX_MAX_3D_STATUS_VALS];
+
+} SGXMKIF_CMDTA_SHARED;
+
+#define SGXTQ_MAX_STATUS						SGX_MAX_TRANSFER_STATUS_VALS + 2
+
+#define SGXMKIF_TQFLAGS_NOSYNCUPDATE			0x00000001
+#define SGXMKIF_TQFLAGS_KEEPPENDING				0x00000002
+#define SGXMKIF_TQFLAGS_TATQ_SYNC				0x00000004
+#define SGXMKIF_TQFLAGS_3DTQ_SYNC				0x00000008
+#if defined(SGX_FEATURE_FAST_RENDER_CONTEXT_SWITCH)
+#define SGXMKIF_TQFLAGS_CTXSWITCH				0x00000010
+#endif
+#define SGXMKIF_TQFLAGS_DUMMYTRANSFER			0x00000020
+
+typedef struct _SGXMKIF_TRANSFERCMD_SHARED_
+{
+	
+
+ 	IMG_UINT32			ui32NumSrcSyncs;
+ 	PVRSRV_DEVICE_SYNC_OBJECT	asSrcSyncs[SGX_MAX_SRC_SYNCS];
+	
+
+ 	IMG_UINT32			ui32NumDstSyncs;
+ 	PVRSRV_DEVICE_SYNC_OBJECT	asDstSyncs[SGX_MAX_DST_SYNCS];	
+	
+	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];
+} SGXMKIF_TRANSFERCMD_SHARED, *PSGXMKIF_TRANSFERCMD_SHARED;
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _SGXMKIF_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;
+} SGXMKIF_2DCMD_SHARED, *PSGXMKIF_2DCMD_SHARED;
+#endif 
+
+
+typedef struct _SGXMKIF_HWDEVICE_SYNC_LIST_
+{
+	IMG_DEV_VIRTADDR	sAccessDevAddr;
+	IMG_UINT32			ui32NumSyncObjects;
+	
+	PVRSRV_DEVICE_SYNC_OBJECT	asSyncData[1];
+} SGXMKIF_HWDEVICE_SYNC_LIST, *PSGXMKIF_HWDEVICE_SYNC_LIST;
+
+
+#define PVRSRV_USSE_EDM_INIT_COMPLETE			(1UL << 0)	
+
+#define PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE				(1UL << 2)	
+#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE			(1UL << 3)	
+#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE	(1UL << 4)	
+#define PVRSRV_USSE_EDM_POWMAN_NO_WORK						(1UL << 5)	
+
+#define PVRSRV_USSE_EDM_INTERRUPT_HWR			(1UL << 0)	
+#define PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER	(1UL << 1)	
+
+#define PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE 	(1UL << 0)	
+
+#if defined(FIX_HW_BRN_28889)
+#define PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE 		(1UL << 0)	
+#endif
+
+#define PVRSRV_USSE_MISCINFO_READY		0x1UL
+#define PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES	0x2UL	
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+#define PVRSRV_USSE_MISCINFO_MEMREAD			0x4UL	
+#define PVRSRV_USSE_MISCINFO_MEMWRITE			0x8UL	
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+#define PVRSRV_USSE_MISCINFO_MEMREAD_FAIL		0x1UL << 31	
+#endif
+#endif
+
+
+#define	PVRSRV_CLEANUPCMD_RT		0x1U
+#define	PVRSRV_CLEANUPCMD_RC		0x2U
+#define	PVRSRV_CLEANUPCMD_TC		0x3U
+#define	PVRSRV_CLEANUPCMD_2DC		0x4U
+#define	PVRSRV_CLEANUPCMD_PB		0x5U
+
+#define PVRSRV_POWERCMD_POWEROFF	0x1U
+#define PVRSRV_POWERCMD_IDLE		0x2U
+#define PVRSRV_POWERCMD_RESUME		0x3U
+
+#define PVRSRV_CTXSUSPCMD_SUSPEND	0x1U
+#define PVRSRV_CTXSUSPCMD_RESUME	0x2U
+
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+#define SGX_BIF_DIR_LIST_INDEX_EDM	(SGX_FEATURE_BIF_NUM_DIRLISTS - 1)
+#else
+#define SGX_BIF_DIR_LIST_INDEX_EDM	(0)
+#endif
+
+#define	SGXMKIF_CC_INVAL_BIF_PT	0x1
+#define	SGXMKIF_CC_INVAL_BIF_PD	0x2
+#define SGXMKIF_CC_INVAL_BIF_SL	0x4
+#define SGXMKIF_CC_INVAL_DATA	0x8
+
+
+typedef struct _SGX_MISCINFO_STRUCT_SIZES_
+{
+#if defined (SGX_FEATURE_2D_HARDWARE)
+	IMG_UINT32	ui32Sizeof_2DCMD;
+	IMG_UINT32	ui32Sizeof_2DCMD_SHARED;
+#endif
+	IMG_UINT32	ui32Sizeof_CMDTA;
+	IMG_UINT32	ui32Sizeof_CMDTA_SHARED;
+	IMG_UINT32	ui32Sizeof_TRANSFERCMD;
+	IMG_UINT32	ui32Sizeof_TRANSFERCMD_SHARED;
+	IMG_UINT32	ui32Sizeof_3DREGISTERS;
+	IMG_UINT32	ui32Sizeof_HWPBDESC;
+	IMG_UINT32	ui32Sizeof_HWRENDERCONTEXT;
+	IMG_UINT32	ui32Sizeof_HWRENDERDETAILS;
+	IMG_UINT32	ui32Sizeof_HWRTDATA;
+	IMG_UINT32	ui32Sizeof_HWRTDATASET;
+	IMG_UINT32	ui32Sizeof_HWTRANSFERCONTEXT;
+	IMG_UINT32	ui32Sizeof_HOST_CTL;
+	IMG_UINT32	ui32Sizeof_COMMAND;
+} SGX_MISCINFO_STRUCT_SIZES;
+
+
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+typedef struct _PVRSRV_SGX_MISCINFO_MEMACCESS
+{
+	IMG_DEV_VIRTADDR	sDevVAddr;		
+	IMG_DEV_PHYADDR		sPDDevPAddr;	
+} PVRSRV_SGX_MISCINFO_MEMACCESS;
+#endif
+
+typedef struct _PVRSRV_SGX_MISCINFO_INFO
+{
+	IMG_UINT32						ui32MiscInfoFlags;
+	PVRSRV_SGX_MISCINFO_FEATURES	sSGXFeatures;		
+	SGX_MISCINFO_STRUCT_SIZES		sSGXStructSizes;	
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+	PVRSRV_SGX_MISCINFO_MEMACCESS	sSGXMemAccessSrc;	
+	PVRSRV_SGX_MISCINFO_MEMACCESS	sSGXMemAccessDest;	
+#endif
+} PVRSRV_SGX_MISCINFO_INFO;
+
+#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG
+#define SGXMK_TRACE_BUFFER_SIZE 512
+#endif 
+
+#define SGXMKIF_HWPERF_CB_SIZE					0x100	
+
+typedef struct _SGXMKIF_HWPERF_CB_ENTRY_
+{
+	IMG_UINT32	ui32FrameNo;
+	IMG_UINT32	ui32PID;
+	IMG_UINT32	ui32RTData;
+	IMG_UINT32	ui32Type;
+	IMG_UINT32	ui32Ordinal;
+	IMG_UINT32	ui32Info;
+	IMG_UINT32	ui32TimeWraps;
+	IMG_UINT32	ui32Time;
+	
+	IMG_UINT32	ui32Counters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+	IMG_UINT32	ui32MiscCounters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS];
+} SGXMKIF_HWPERF_CB_ENTRY;
+
+typedef struct _SGXMKIF_HWPERF_CB_
+{
+	IMG_UINT32				ui32Woff;
+	IMG_UINT32				ui32Roff;
+	IMG_UINT32				ui32Ordinal;
+	SGXMKIF_HWPERF_CB_ENTRY psHWPerfCBData[SGXMKIF_HWPERF_CB_SIZE];
+} SGXMKIF_HWPERF_CB;
+
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/include/sgxinfo.h b/drivers/staging/cdv/pvr/services4/include/sgxinfo.h
new file mode 100644
index 0000000..ab4f7d3
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/include/sgxinfo.h
@@ -0,0 +1,463 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined (__SGXINFO_H__)
+#define __SGXINFO_H__
+
+#include "sgxscript.h"
+#include "servicesint.h"
+#include "services.h"
+#if !defined (SUPPORT_SID_INTERFACE)
+#include "sgxapi_km.h"
+#endif
+#include "sgx_mkif_km.h"
+
+
+#define SGX_MAX_DEV_DATA			24
+#define	SGX_MAX_INIT_MEM_HANDLES	18
+
+
+typedef struct _SGX_BRIDGE_INFO_FOR_SRVINIT
+{
+	IMG_DEV_PHYADDR sPDDevPAddr;
+	PVRSRV_HEAP_INFO asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+} SGX_BRIDGE_INFO_FOR_SRVINIT;
+
+
+typedef enum _SGXMKIF_CMD_TYPE_
+{
+	SGXMKIF_CMD_TA				= 0,
+	SGXMKIF_CMD_TRANSFER		= 1,
+	SGXMKIF_CMD_2D				= 2,
+	SGXMKIF_CMD_POWER			= 3,
+	SGXMKIF_CMD_CONTEXTSUSPEND	= 4,
+	SGXMKIF_CMD_CLEANUP			= 5,
+	SGXMKIF_CMD_GETMISCINFO		= 6,
+	SGXMKIF_CMD_PROCESS_QUEUES	= 7,
+	SGXMKIF_CMD_DATABREAKPOINT	= 8,
+	SGXMKIF_CMD_SETHWPERFSTATUS	= 9,
+ 	SGXMKIF_CMD_FLUSHPDCACHE	= 10,
+ 	SGXMKIF_CMD_MAX				= 11,
+
+	SGXMKIF_CMD_FORCE_I32   	= -1,
+
+} SGXMKIF_CMD_TYPE;
+
+
+typedef struct _SGX_BRIDGE_INIT_INFO_
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hKernelCCBMemInfo;
+	IMG_SID		hKernelCCBCtlMemInfo;
+	IMG_SID		hKernelCCBEventKickerMemInfo;
+	IMG_SID		hKernelSGXHostCtlMemInfo;
+	IMG_SID		hKernelSGXTA3DCtlMemInfo;
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+	IMG_SID		hKernelSGXPTLAWriteBackMemInfo;
+#endif
+	IMG_SID		hKernelSGXMiscMemInfo;
+#else
+	IMG_HANDLE	hKernelCCBMemInfo;
+	IMG_HANDLE	hKernelCCBCtlMemInfo;
+	IMG_HANDLE	hKernelCCBEventKickerMemInfo;
+	IMG_HANDLE	hKernelSGXHostCtlMemInfo;
+	IMG_HANDLE	hKernelSGXTA3DCtlMemInfo;
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+	IMG_HANDLE	hKernelSGXPTLAWriteBackMemInfo;
+#endif
+	IMG_HANDLE	hKernelSGXMiscMemInfo;
+#endif
+
+	IMG_UINT32	aui32HostKickAddr[SGXMKIF_CMD_MAX];
+
+	SGX_INIT_SCRIPTS sScripts;
+
+	IMG_UINT32	ui32ClientBuildOptions;
+	SGX_MISCINFO_STRUCT_SIZES	sSGXStructSizes;
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hKernelHWProfilingMemInfo;
+#else
+	IMG_HANDLE	hKernelHWProfilingMemInfo;
+#endif
+#endif
+#if defined(SUPPORT_SGX_HWPERF)
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hKernelHWPerfCBMemInfo;
+#else
+	IMG_HANDLE	hKernelHWPerfCBMemInfo;
+#endif
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hKernelTASigBufferMemInfo;
+	IMG_SID		hKernel3DSigBufferMemInfo;
+#else
+	IMG_HANDLE	hKernelTASigBufferMemInfo;
+	IMG_HANDLE	hKernel3DSigBufferMemInfo;
+#endif
+
+#if defined(FIX_HW_BRN_29702)
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hKernelCFIMemInfo;
+#else
+	IMG_HANDLE	hKernelCFIMemInfo;
+#endif
+#endif
+#if defined(FIX_HW_BRN_29823)
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hKernelDummyTermStreamMemInfo;
+#else
+	IMG_HANDLE	hKernelDummyTermStreamMemInfo;
+#endif
+#endif
+
+#if defined(FIX_HW_BRN_31542)
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID hKernelClearClipWAVDMStreamMemInfo;
+	IMG_SID hKernelClearClipWAIndexStreamMemInfo;
+	IMG_SID hKernelClearClipWAPDSMemInfo;
+	IMG_SID hKernelClearClipWAUSEMemInfo;
+	IMG_SID hKernelClearClipWAParamMemInfo;
+	IMG_SID hKernelClearClipWAPMPTMemInfo;
+	IMG_SID hKernelClearClipWATPCMemInfo;
+	IMG_SID hKernelClearClipWAPSGRgnHdrMemInfo;
+#else
+	IMG_HANDLE hKernelClearClipWAVDMStreamMemInfo;
+	IMG_HANDLE hKernelClearClipWAIndexStreamMemInfo;
+	IMG_HANDLE hKernelClearClipWAPDSMemInfo;
+	IMG_HANDLE hKernelClearClipWAUSEMemInfo;
+	IMG_HANDLE hKernelClearClipWAParamMemInfo;
+	IMG_HANDLE hKernelClearClipWAPMPTMemInfo;
+	IMG_HANDLE hKernelClearClipWATPCMemInfo;
+	IMG_HANDLE hKernelClearClipWAPSGRgnHdrMemInfo;
+#endif
+#endif
+
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+	IMG_HANDLE	hKernelVDMSnapShotBufferMemInfo;
+	IMG_HANDLE	hKernelVDMCtrlStreamBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+	defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+	IMG_HANDLE	hKernelVDMStateUpdateBufferMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hKernelEDMStatusBufferMemInfo;
+#else
+	IMG_HANDLE	hKernelEDMStatusBufferMemInfo;
+#endif
+#endif
+
+	IMG_UINT32 ui32EDMTaskReg0;
+	IMG_UINT32 ui32EDMTaskReg1;
+
+	IMG_UINT32 ui32ClkGateCtl;
+	IMG_UINT32 ui32ClkGateCtl2;
+	IMG_UINT32 ui32ClkGateStatusReg;
+	IMG_UINT32 ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+	IMG_UINT32 ui32MasterClkGateStatusReg;
+	IMG_UINT32 ui32MasterClkGateStatusMask;
+	IMG_UINT32 ui32MasterClkGateStatus2Reg;
+	IMG_UINT32 ui32MasterClkGateStatus2Mask;
+#endif 
+
+	IMG_UINT32 ui32CacheControl;
+
+	IMG_UINT32	asInitDevData[SGX_MAX_DEV_DATA];
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
+#else
+	IMG_HANDLE	asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
+#endif
+
+} SGX_BRIDGE_INIT_INFO;
+
+
+typedef struct _SGX_DEVICE_SYNC_LIST_
+{
+	PSGXMKIF_HWDEVICE_SYNC_LIST	psHWDeviceSyncList;
+
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hKernelHWSyncListMemInfo;
+#else
+	IMG_HANDLE				hKernelHWSyncListMemInfo;
+#endif
+	PVRSRV_CLIENT_MEM_INFO	*psHWDeviceSyncListClientMemInfo;
+	PVRSRV_CLIENT_MEM_INFO	*psAccessResourceClientMemInfo;
+
+	volatile IMG_UINT32		*pui32Lock;
+
+	struct _SGX_DEVICE_SYNC_LIST_	*psNext;
+
+	
+	IMG_UINT32			ui32NumSyncObjects;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				ahSyncHandles[1];
+#else
+	IMG_HANDLE			ahSyncHandles[1];
+#endif
+} SGX_DEVICE_SYNC_LIST, *PSGX_DEVICE_SYNC_LIST;
+
+
+typedef struct _SGX_INTERNEL_STATUS_UPDATE_
+{
+	CTL_STATUS				sCtlStatus;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID					hKernelMemInfo;
+#else
+	IMG_HANDLE				hKernelMemInfo;
+#endif
+} SGX_INTERNEL_STATUS_UPDATE;
+
+
+typedef struct _SGX_CCB_KICK_
+{
+	SGXMKIF_COMMAND		sCommand;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hCCBKernelMemInfo;
+#else
+	IMG_HANDLE	hCCBKernelMemInfo;
+#endif
+
+	IMG_UINT32	ui32NumDstSyncObjects;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hKernelHWSyncListMemInfo;
+#else
+	IMG_HANDLE	hKernelHWSyncListMemInfo;
+#endif
+
+	
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		*pahDstSyncHandles;
+#else
+	IMG_HANDLE	*pahDstSyncHandles;
+#endif
+
+	IMG_UINT32	ui32NumTAStatusVals;
+	IMG_UINT32	ui32Num3DStatusVals;
+
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+	SGX_INTERNEL_STATUS_UPDATE	asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS];
+	SGX_INTERNEL_STATUS_UPDATE	as3DStatusUpdate[SGX_MAX_3D_STATUS_VALS];
+#else
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
+	IMG_SID		ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
+#else
+	IMG_HANDLE	ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
+	IMG_HANDLE	ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
+#endif
+#endif
+
+	IMG_BOOL	bFirstKickOrResume;
+#if (defined(NO_HARDWARE) || defined(PDUMP))
+	IMG_BOOL	bTerminateOrAbort;
+#endif
+	IMG_BOOL	bLastInScene;
+
+	
+	IMG_UINT32	ui32CCBOffset;
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+	
+	IMG_UINT32	ui32NumTASrcSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
+#else
+	IMG_HANDLE	ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
+#endif
+	IMG_UINT32	ui32NumTADstSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
+#else
+	IMG_HANDLE	ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
+#endif
+	IMG_UINT32	ui32Num3DSrcSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
+#else
+	IMG_HANDLE	ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
+#endif
+#else
+	
+	IMG_UINT32	ui32NumSrcSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
+#else
+	IMG_HANDLE	ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
+#endif
+#endif
+
+	
+	IMG_BOOL	bTADependency;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID		hTA3DSyncInfo;
+
+	IMG_SID		hTASyncInfo;
+	IMG_SID		h3DSyncInfo;
+#else
+	IMG_HANDLE	hTA3DSyncInfo;
+
+	IMG_HANDLE	hTASyncInfo;
+	IMG_HANDLE	h3DSyncInfo;
+#endif
+#if defined(PDUMP)
+	IMG_UINT32	ui32CCBDumpWOff;
+#endif
+#if defined(NO_HARDWARE)
+	IMG_UINT32	ui32WriteOpsPendingVal;
+#endif
+	IMG_HANDLE	hDevMemContext;
+} SGX_CCB_KICK;
+
+
+#define SGX_KERNEL_USE_CODE_BASE_INDEX		15
+
+
+typedef struct _SGX_CLIENT_INFO_
+{
+	IMG_UINT32					ui32ProcessID;			
+	IMG_VOID					*pvProcess;				
+	PVRSRV_MISC_INFO			sMiscInfo;				
+
+	IMG_UINT32					asDevData[SGX_MAX_DEV_DATA];
+
+} SGX_CLIENT_INFO;
+
+typedef struct _SGX_INTERNAL_DEVINFO_
+{
+	IMG_UINT32			ui32Flags;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID				hHostCtlKernelMemInfoHandle;
+#else
+	IMG_HANDLE			hHostCtlKernelMemInfoHandle;
+#endif
+	IMG_BOOL			bForcePTOff;
+} SGX_INTERNAL_DEVINFO;
+
+
+typedef struct _SGX_INTERNAL_DEVINFO_KM_
+{
+	IMG_UINT32			ui32Flags;
+	IMG_HANDLE			hHostCtlKernelMemInfoHandle;
+	IMG_BOOL			bForcePTOff;
+} SGX_INTERNAL_DEVINFO_KM;
+
+
+#if defined(TRANSFER_QUEUE)
+typedef struct _PVRSRV_TRANSFER_SGX_KICK_
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hCCBMemInfo;
+#else
+	IMG_HANDLE		hCCBMemInfo;
+#endif
+	IMG_UINT32		ui32SharedCmdCCBOffset;
+
+	IMG_DEV_VIRTADDR 	sHWTransferContextDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hTASyncInfo;
+	IMG_SID			h3DSyncInfo;
+#else
+	IMG_HANDLE		hTASyncInfo;
+	IMG_HANDLE		h3DSyncInfo;
+#endif
+
+	IMG_UINT32		ui32NumSrcSync;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#else
+	IMG_HANDLE		ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#endif
+
+	IMG_UINT32		ui32NumDstSync;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#else
+	IMG_HANDLE		ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#endif
+
+	IMG_UINT32		ui32Flags;
+
+	IMG_UINT32		ui32PDumpFlags;
+#if defined(PDUMP)
+	IMG_UINT32		ui32CCBDumpWOff;
+#endif
+	IMG_HANDLE		hDevMemContext;
+} PVRSRV_TRANSFER_SGX_KICK, *PPVRSRV_TRANSFER_SGX_KICK;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _PVRSRV_2D_SGX_KICK_
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hCCBMemInfo;
+#else
+	IMG_HANDLE		hCCBMemInfo;
+#endif
+	IMG_UINT32		ui32SharedCmdCCBOffset;
+
+	IMG_DEV_VIRTADDR 	sHW2DContextDevVAddr;
+
+	IMG_UINT32		ui32NumSrcSync;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
+
+	
+	IMG_SID	 		hDstSyncInfo;
+
+	
+	IMG_SID			hTASyncInfo;
+
+	
+	IMG_SID			h3DSyncInfo;
+#else
+	IMG_HANDLE		ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
+
+	
+	IMG_HANDLE 		hDstSyncInfo;
+
+	
+	IMG_HANDLE		hTASyncInfo;
+
+	
+	IMG_HANDLE		h3DSyncInfo;
+#endif
+
+	IMG_UINT32		ui32PDumpFlags;
+#if defined(PDUMP)
+	IMG_UINT32		ui32CCBDumpWOff;
+#endif
+	IMG_HANDLE		hDevMemContext;
+} PVRSRV_2D_SGX_KICK, *PPVRSRV_2D_SGX_KICK;
+#endif	
+#endif	
+
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/bridged/.gitignore b/drivers/staging/cdv/pvr/services4/srvkm/bridged/.gitignore
new file mode 100644
index 0000000..2f89523
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/bridged/.gitignore
@@ -0,0 +1,5 @@
+bin_pc_i686*
+tmp_pc_i686*
+host_pc_i686*
+*.o
+*.o.cmd
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c b/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c
new file mode 100644
index 0000000..2ad7167
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c
@@ -0,0 +1,4744 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+
+#include <stddef.h>
+
+#include "img_defs.h"
+#include "services.h"
+#include "pvr_bridge_km.h"
+#include "pvr_debug.h"
+#include "ra.h"
+#include "pvr_bridge.h"
+#if defined(SUPPORT_SGX)
+#include "sgx_bridge.h"
+#endif
+#if defined(SUPPORT_VGX)
+#include "vgx_bridge.h"
+#endif
+#if defined(SUPPORT_MSVDX)
+#include "msvdx_bridge.h"
+#endif
+#include "perproc.h"
+#include "device.h"
+#include "buffer_manager.h"
+
+#include "pdump_km.h"
+#include "syscommon.h"
+
+#include "bridged_pvr_bridge.h"
+#if defined(SUPPORT_SGX)
+#include "bridged_sgx_bridge.h"
+#endif
+#if defined(SUPPORT_VGX)
+#include "bridged_vgx_bridge.h"
+#endif
+#if defined(SUPPORT_MSVDX)
+#include "bridged_msvdx_bridge.h"
+#endif
+
+#include "env_data.h"
+
+#if defined (__linux__) || defined(__QNXNTO__)
+#include "mmap.h"
+#endif
+
+
+#include "srvkm.h"
+
+PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
+
+#if defined(DEBUG_BRIDGE_KM)
+PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
+#endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+static IMG_BOOL abSharedDeviceMemHeap[PVRSRV_MAX_CLIENT_HEAPS];
+static IMG_BOOL *pbSharedDeviceMemHeap = abSharedDeviceMemHeap;
+#else
+static IMG_BOOL *pbSharedDeviceMemHeap = (IMG_BOOL*)IMG_NULL;
+#endif
+
+
+#if defined(DEBUG_BRIDGE_KM)
+PVRSRV_ERROR
+CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
+                    IMG_UINT32 ui32BridgeID,
+                    IMG_VOID *pvDest,
+                    IMG_VOID *pvSrc,
+                    IMG_UINT32 ui32Size)
+{
+	PVRSRV_ERROR ret;
+	ret = OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size);
+
+	if (ret == PVRSRV_OK) {
+		g_BridgeDispatchTable[ui32BridgeID].ui32CopyFromUserTotalBytes += ui32Size;
+		g_BridgeGlobalStats.ui32TotalCopyFromUserBytes += ui32Size;
+	}
+	return ret;
+}
+PVRSRV_ERROR
+CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
+                  IMG_UINT32 ui32BridgeID,
+                  IMG_VOID *pvDest,
+                  IMG_VOID *pvSrc,
+                  IMG_UINT32 ui32Size)
+{
+	PVRSRV_ERROR ret;
+	ret = OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size);
+	if (ret == PVRSRV_OK) {
+		g_BridgeDispatchTable[ui32BridgeID].ui32CopyToUserTotalBytes += ui32Size;
+		g_BridgeGlobalStats.ui32TotalCopyToUserBytes += ui32Size;
+	}
+	return ret;
+}
+#endif
+
+
+static IMG_INT
+PVRSRVEnumerateDevicesBW(IMG_UINT32 ui32BridgeID,
+						 IMG_VOID *psBridgeIn,
+						 PVRSRV_BRIDGE_OUT_ENUMDEVICE *psEnumDeviceOUT,
+						 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DEVICES);
+
+    	PVR_UNREFERENCED_PARAMETER(psPerProc);
+    	PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+	psEnumDeviceOUT->eError =
+		PVRSRVEnumerateDevicesKM(&psEnumDeviceOUT->ui32NumDevices,
+								 psEnumDeviceOUT->asDeviceIdentifier);
+	return 0;
+}
+
+static IMG_INT
+PVRSRVAcquireDeviceDataBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO *psAcquireDevInfoIN,
+						  PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO *psAcquireDevInfoOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO);
+
+	psAcquireDevInfoOUT->eError =
+		PVRSRVAcquireDeviceDataKM(psAcquireDevInfoIN->uiDevIndex,
+								  psAcquireDevInfoIN->eDeviceType,
+								  &hDevCookieInt);
+	if(psAcquireDevInfoOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+    
+	psAcquireDevInfoOUT->eError =
+		PVRSRVAllocHandle(psPerProc->psHandleBase,
+						  &psAcquireDevInfoOUT->hDevCookie,
+						  hDevCookieInt,
+						  PVRSRV_HANDLE_TYPE_DEV_NODE,
+						  PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVCreateDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
+                               PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT *psCreateDevMemContextIN,
+                               PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT *psCreateDevMemContextOUT,
+                               PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_HANDLE hDevMemContextInt;
+	IMG_UINT32 i;
+	IMG_BOOL bCreated;
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+#endif
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT);
+
+
+	NEW_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS + 1)
+
+	psCreateDevMemContextOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+				psCreateDevMemContextIN->hDevCookie,
+				PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psCreateDevMemContextOUT->eError =
+		PVRSRVCreateDeviceMemContextKM(hDevCookieInt,
+									   psPerProc,
+									   &hDevMemContextInt,
+									   &psCreateDevMemContextOUT->ui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+									   &asHeapInfo[0],
+#else
+									   &psCreateDevMemContextOUT->sHeapInfo[0],
+#endif
+									   &bCreated,
+									   pbSharedDeviceMemHeap);
+
+	if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	if(bCreated)
+	{
+		PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+						  &psCreateDevMemContextOUT->hDevMemContext,
+						  hDevMemContextInt,
+						  PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
+						  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+	}
+	else
+	{
+		psCreateDevMemContextOUT->eError =
+			PVRSRVFindHandle(psPerProc->psHandleBase,
+							 &psCreateDevMemContextOUT->hDevMemContext,
+							 hDevMemContextInt,
+							 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+		if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+	for(i = 0; i < psCreateDevMemContextOUT->ui32ClientHeapCount; i++)
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		IMG_SID hDevMemHeapExt;
+#else
+		IMG_HANDLE hDevMemHeapExt;
+#endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+		if(abSharedDeviceMemHeap[i])
+#endif
+		{
+
+#if defined (SUPPORT_SID_INTERFACE)
+			PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+								&hDevMemHeapExt,
+								asHeapInfo[i].hDevMemHeap,
+								PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+								PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#else
+			PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
+								psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
+								PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+								PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#endif
+		}
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+		else
+		{
+
+			if(bCreated)
+			{
+#if defined (SUPPORT_SID_INTERFACE)
+				PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+									   &hDevMemHeapExt,
+									   asHeapInfo[i].hDevMemHeap,
+									   PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+									   PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+									   psCreateDevMemContextOUT->hDevMemContext);
+#else
+				PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
+									 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
+									 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+									 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+									 psCreateDevMemContextOUT->hDevMemContext);
+#endif
+			}
+			else
+			{
+				psCreateDevMemContextOUT->eError =
+					PVRSRVFindHandle(psPerProc->psHandleBase,
+									 &hDevMemHeapExt,
+#if defined (SUPPORT_SID_INTERFACE)
+									 asHeapInfo[i].hDevMemHeap,
+#else
+									 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
+#endif
+									 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+				if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+				{
+					return 0;
+				}
+			}
+		}
+#endif
+		psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
+#if defined (SUPPORT_SID_INTERFACE)
+		psCreateDevMemContextOUT->sHeapInfo[i].ui32HeapID       = asHeapInfo[i].ui32HeapID;
+		psCreateDevMemContextOUT->sHeapInfo[i].sDevVAddrBase    = asHeapInfo[i].sDevVAddrBase;
+		psCreateDevMemContextOUT->sHeapInfo[i].ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
+		psCreateDevMemContextOUT->sHeapInfo[i].ui32Attribs      = asHeapInfo[i].ui32Attribs;
+		psCreateDevMemContextOUT->sHeapInfo[i].ui32XTileStride  = asHeapInfo[i].ui32XTileStride;
+#endif
+	}
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc)
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVDestroyDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
+								PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT *psDestroyDevMemContextIN,
+								PVRSRV_BRIDGE_RETURN *psRetOUT,
+								PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_HANDLE hDevMemContextInt;
+	IMG_BOOL bDestroyed;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+						   psDestroyDevMemContextIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
+						   psDestroyDevMemContextIN->hDevMemContext,
+						   PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVDestroyDeviceMemContextKM(hDevCookieInt, hDevMemContextInt, &bDestroyed);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	if(bDestroyed)
+	{
+		psRetOUT->eError =
+			PVRSRVReleaseHandle(psPerProc->psHandleBase,
+								psDestroyDevMemContextIN->hDevMemContext,
+								PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+	}
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVGetDeviceMemHeapInfoBW(IMG_UINT32 ui32BridgeID,
+							   PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoIN,
+							   PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoOUT,
+							   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_HANDLE hDevMemContextInt;
+	IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+#endif
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS)
+
+	psGetDevMemHeapInfoOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+						   psGetDevMemHeapInfoIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psGetDevMemHeapInfoOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
+						   psGetDevMemHeapInfoIN->hDevMemContext,
+						   PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+	if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psGetDevMemHeapInfoOUT->eError =
+		PVRSRVGetDeviceMemHeapInfoKM(hDevCookieInt,
+									   hDevMemContextInt,
+									   &psGetDevMemHeapInfoOUT->ui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+									   &asHeapInfo[0],
+#else
+									   &psGetDevMemHeapInfoOUT->sHeapInfo[0],
+#endif
+									   pbSharedDeviceMemHeap);
+
+	if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	for(i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++)
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		IMG_SID hDevMemHeapExt;
+#else
+		IMG_HANDLE hDevMemHeapExt;
+#endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+		if(abSharedDeviceMemHeap[i])
+#endif
+		{
+
+#if defined (SUPPORT_SID_INTERFACE)
+			PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+								&hDevMemHeapExt,
+								asHeapInfo[i].hDevMemHeap,
+								PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+								PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#else
+			PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
+							  psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
+							  PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+							  PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#endif
+		}
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+		else
+		{
+
+			psGetDevMemHeapInfoOUT->eError =
+				PVRSRVFindHandle(psPerProc->psHandleBase,
+								 &hDevMemHeapExt,
+#if defined (SUPPORT_SID_INTERFACE)
+								 asHeapInfo[i].hDevMemHeap,
+#else
+								 psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
+#endif
+								 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+			if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+			{
+				return 0;
+			}
+		}
+#endif
+		psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
+#if defined (SUPPORT_SID_INTERFACE)
+		psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32HeapID       = asHeapInfo[i].ui32HeapID;
+		psGetDevMemHeapInfoOUT->sHeapInfo[i].sDevVAddrBase    = asHeapInfo[i].sDevVAddrBase;
+		psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
+		psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32Attribs      = asHeapInfo[i].ui32Attribs;
+		psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32XTileStride  = asHeapInfo[i].ui32XTileStride;
+#endif
+	}
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc)
+
+	return 0;
+}
+
+
+#if defined(OS_PVRSRV_ALLOC_DEVICE_MEM_BW)
+IMG_INT
+PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
+					   PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
+					   PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
+					   PVRSRV_PER_PROCESS_DATA *psPerProc);
+#else
+static IMG_INT
+PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
+					   PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
+					   PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
+					   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+	IMG_HANDLE hDevCookieInt;
+	IMG_HANDLE hDevMemHeapInt;
+	IMG_UINT32 ui32ShareIndex;
+	IMG_BOOL bUseShareMemWorkaround;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_DEVICEMEM);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc, 2)
+
+	psAllocDeviceMemOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+						   psAllocDeviceMemIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psAllocDeviceMemOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemHeapInt,
+						   psAllocDeviceMemIN->hDevMemHeap,
+						   PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+
+	if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+
+	bUseShareMemWorkaround = ((psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_XPROC) != 0) ? IMG_TRUE : IMG_FALSE;
+	ui32ShareIndex = 7654321; 
+
+	if (bUseShareMemWorkaround)
+	{
+
+
+
+		psAllocDeviceMemOUT->eError =
+			BM_XProcWorkaroundFindNewBufferAndSetShareIndex(&ui32ShareIndex);
+		if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+	psAllocDeviceMemOUT->eError =
+		PVRSRVAllocDeviceMemKM(hDevCookieInt,
+							   psPerProc,
+							   hDevMemHeapInt,
+							   psAllocDeviceMemIN->ui32Attribs,
+							   psAllocDeviceMemIN->ui32Size,
+							   psAllocDeviceMemIN->ui32Alignment,
+							   &psMemInfo,
+							   "" );
+
+	if (bUseShareMemWorkaround)
+	{
+		PVR_ASSERT(ui32ShareIndex != 7654321);
+		BM_XProcWorkaroundUnsetShareIndex(ui32ShareIndex);
+	}
+
+	if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psMemInfo->sShareMemWorkaround.bInUse = bUseShareMemWorkaround;
+	if (bUseShareMemWorkaround)
+	{
+		PVR_ASSERT(ui32ShareIndex != 7654321);
+		psMemInfo->sShareMemWorkaround.ui32ShareIndex = ui32ShareIndex;
+		psMemInfo->sShareMemWorkaround.hDevCookieInt = hDevCookieInt;
+		psMemInfo->sShareMemWorkaround.ui32OrigReqAttribs = psAllocDeviceMemIN->ui32Attribs;
+		psMemInfo->sShareMemWorkaround.ui32OrigReqSize = (IMG_UINT32)psAllocDeviceMemIN->ui32Size;
+		psMemInfo->sShareMemWorkaround.ui32OrigReqAlignment = (IMG_UINT32)psAllocDeviceMemIN->ui32Alignment;
+	}
+
+	OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo,
+			0,
+			sizeof(psAllocDeviceMemOUT->sClientMemInfo));
+
+	psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM =
+			psMemInfo->pvLinAddrKM;
+
+#if defined (__linux__)
+	psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = 0;
+#else
+	psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = psMemInfo->pvLinAddrKM;
+#endif
+	psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
+	psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
+	psAllocDeviceMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+#else
+	psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo,
+					  psMemInfo,
+					  PVRSRV_HANDLE_TYPE_MEM_INFO,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+#if defined (SUPPORT_SID_INTERFACE)
+	PVR_ASSERT(psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo != 0);
+
+	if (psMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+	{
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+							   &psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo,
+							   psMemInfo->sMemBlk.hOSMemHandle,
+							   PVRSRV_HANDLE_TYPE_MEM_INFO,
+							   PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+							   psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
+	}
+	else
+	{
+		psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = 0;
+	}
+#endif
+
+	if(psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ)
+	{
+
+		OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo,
+				 0,
+				 sizeof (PVRSRV_CLIENT_SYNC_INFO));
+		psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL;
+	}
+	else
+	{
+
+
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+		psAllocDeviceMemOUT->sClientSyncInfo.psSyncData =
+			psMemInfo->psKernelSyncInfo->psSyncData;
+		psAllocDeviceMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+			psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+		psAllocDeviceMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+			psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+		if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+		{
+			PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+									   &psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo,
+									   psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+									   PVRSRV_HANDLE_TYPE_SYNC_INFO,
+									   PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+									   psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
+		}
+		else
+		{
+			psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo = 0;
+		}
+#else
+		psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo =
+			psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+							 &psAllocDeviceMemOUT->sClientSyncInfo.hKernelSyncInfo,
+							 psMemInfo->psKernelSyncInfo,
+							 PVRSRV_HANDLE_TYPE_SYNC_INFO,
+							 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+							 psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
+
+		psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo =
+			&psAllocDeviceMemOUT->sClientSyncInfo;
+
+	}
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc)
+
+	return 0;
+}
+
+#endif 
+
+static IMG_INT
+PVRSRVFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_FREEDEVICEMEM *psFreeDeviceMemIN,
+					  PVRSRV_BRIDGE_RETURN *psRetOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_VOID *pvKernelMemInfo;
+
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_DEVICEMEM);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+						   psFreeDeviceMemIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+				&pvKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+						   psFreeDeviceMemIN->hKernelMemInfo,
+#else
+						   psFreeDeviceMemIN->psKernelMemInfo,
+#endif
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError = PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							psFreeDeviceMemIN->hKernelMemInfo,
+#else
+							psFreeDeviceMemIN->psKernelMemInfo,
+#endif
+							PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVExportDeviceMemBW(IMG_UINT32 ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM *psExportDeviceMemIN,
+					  PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
+#else
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+
+	PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM) ||
+			ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2));
+	PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+
+	psExportDeviceMemOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+				&hDevCookieInt,
+						   psExportDeviceMemIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psExportDeviceMemOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find devcookie"));
+		return 0;
+	}
+
+
+	psExportDeviceMemOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   (IMG_PVOID *)&psKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+						   psExportDeviceMemIN->hKernelMemInfo,
+#else
+						   psExportDeviceMemIN->psKernelMemInfo,
+#endif
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+	if(psExportDeviceMemOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find kernel meminfo"));
+		return 0;
+	}
+
+
+	psExportDeviceMemOUT->eError =
+		PVRSRVFindHandle(KERNEL_HANDLE_BASE,
+							 &psExportDeviceMemOUT->hMemInfo,
+							 psKernelMemInfo,
+							 PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psExportDeviceMemOUT->eError == PVRSRV_OK)
+	{
+
+		PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: allocation is already exported"));
+		return 0;
+	}
+
+
+	psExportDeviceMemOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
+													&psExportDeviceMemOUT->hMemInfo,
+													psKernelMemInfo,
+													PVRSRV_HANDLE_TYPE_MEM_INFO,
+													PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+	if (psExportDeviceMemOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: failed to allocate handle from global handle list"));
+		return 0;
+	}
+
+
+	psKernelMemInfo->ui32Flags |= PVRSRV_MEM_EXPORTED;
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVMapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
+							 PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN,
+							 PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDevMemOUT,
+							 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_KERNEL_MEM_INFO  *psSrcKernelMemInfo = IMG_NULL;
+	PVRSRV_KERNEL_MEM_INFO  *psDstKernelMemInfo = IMG_NULL;
+	IMG_HANDLE              hDstDevMemHeap = IMG_NULL;
+
+	PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY) ||
+			ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY_2));
+	PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2)
+
+
+	psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+												(IMG_VOID**)&psSrcKernelMemInfo,
+												psMapDevMemIN->hKernelMemInfo,
+												PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psMapDevMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+												&hDstDevMemHeap,
+												psMapDevMemIN->hDstDevMemHeap,
+												PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+	if(psMapDevMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	if (psSrcKernelMemInfo->sShareMemWorkaround.bInUse)
+	{
+		PVR_DPF((PVR_DBG_MESSAGE, "using the mem wrap workaround."));
+
+
+
+
+
+
+
+
+
+		psMapDevMemOUT->eError = BM_XProcWorkaroundSetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+		if(psMapDevMemOUT->eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryBW(): failed to recycle shared buffer"));
+			return 0;
+		}
+
+		psMapDevMemOUT->eError =
+			PVRSRVAllocDeviceMemKM(psSrcKernelMemInfo->sShareMemWorkaround.hDevCookieInt,
+								   psPerProc,
+								   hDstDevMemHeap,
+								   psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAttribs | PVRSRV_MEM_NO_SYNCOBJ,
+								   psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqSize,
+								   psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAlignment,
+								   &psDstKernelMemInfo,
+								   "" );
+
+
+		BM_XProcWorkaroundUnsetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+		if(psMapDevMemOUT->eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "lakjgfgewjlrgebhe"));
+			return 0;
+		}
+
+		if(psSrcKernelMemInfo->psKernelSyncInfo)
+		{
+			psSrcKernelMemInfo->psKernelSyncInfo->ui32RefCount++;
+		}
+
+		psDstKernelMemInfo->psKernelSyncInfo = psSrcKernelMemInfo->psKernelSyncInfo;
+	}
+	else
+	{
+
+		psMapDevMemOUT->eError = PVRSRVMapDeviceMemoryKM(psPerProc,
+														 psSrcKernelMemInfo,
+														 hDstDevMemHeap,
+														 &psDstKernelMemInfo);
+		if(psMapDevMemOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+
+	psDstKernelMemInfo->sShareMemWorkaround = psSrcKernelMemInfo->sShareMemWorkaround;
+
+	OSMemSet(&psMapDevMemOUT->sDstClientMemInfo,
+			0,
+			sizeof(psMapDevMemOUT->sDstClientMemInfo));
+	OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo,
+			0,
+			sizeof(psMapDevMemOUT->sDstClientSyncInfo));
+
+	psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM =
+			psDstKernelMemInfo->pvLinAddrKM;
+
+	psMapDevMemOUT->sDstClientMemInfo.pvLinAddr = 0;
+	psMapDevMemOUT->sDstClientMemInfo.sDevVAddr = psDstKernelMemInfo->sDevVAddr;
+	psMapDevMemOUT->sDstClientMemInfo.ui32Flags = psDstKernelMemInfo->ui32Flags;
+	psMapDevMemOUT->sDstClientMemInfo.uAllocSize = psDstKernelMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+#else
+	psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = psDstKernelMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo,
+					  psDstKernelMemInfo,
+					  PVRSRV_HANDLE_TYPE_MEM_INFO,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+	psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo = IMG_NULL;
+
+#if defined (SUPPORT_SID_INTERFACE)
+
+	if (psDstKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+	{
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+						&psMapDevMemOUT->sDstClientMemInfo.hMappingInfo,
+						psDstKernelMemInfo->sMemBlk.hOSMemHandle,
+						PVRSRV_HANDLE_TYPE_MEM_INFO,
+						PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+						psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
+	}
+	else
+	{
+		psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = 0;
+	}
+#endif
+
+
+	if(psDstKernelMemInfo->psKernelSyncInfo)
+	{
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+		psMapDevMemOUT->sDstClientSyncInfo.psSyncData =
+			psDstKernelMemInfo->psKernelSyncInfo->psSyncData;
+		psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr =
+			psDstKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+		psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr =
+			psDstKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+
+		if (psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+		{
+			PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+							&psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo,
+							psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+							PVRSRV_HANDLE_TYPE_MEM_INFO,
+							PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+							psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
+		}
+		else
+		{
+			psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo = 0;
+		}
+#else
+		psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo =
+			psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+		psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo = &psMapDevMemOUT->sDstClientSyncInfo;
+
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+					  &psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo,
+					  psDstKernelMemInfo->psKernelSyncInfo,
+					  PVRSRV_HANDLE_TYPE_SYNC_INFO,
+					  PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+					  psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
+	}
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc)
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVUnmapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
+							 PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY *psUnmapDevMemIN,
+							 PVRSRV_BRIDGE_RETURN *psRetOUT,
+							 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo = IMG_NULL;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEV_MEMORY);
+
+	psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+											(IMG_VOID**)&psKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+											psUnmapDevMemIN->hKernelMemInfo,
+#else
+											psUnmapDevMemIN->psKernelMemInfo,
+#endif
+											PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	if (psKernelMemInfo->sShareMemWorkaround.bInUse)
+	{
+		psRetOUT->eError = PVRSRVFreeDeviceMemKM(psKernelMemInfo->sShareMemWorkaround.hDevCookieInt, psKernelMemInfo);
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVUnmapDeviceMemoryBW: internal error, should expect FreeDeviceMem to fail"));
+			return 0;
+		}
+	}
+	else
+	{
+		psRetOUT->eError = PVRSRVUnmapDeviceMemoryKM(psKernelMemInfo);
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+	psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							psUnmapDevMemIN->hKernelMemInfo,
+#else
+							psUnmapDevMemIN->psKernelMemInfo,
+#endif
+							PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+	return 0;
+}
+
+
+
+static IMG_INT
+PVRSRVMapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
+							 PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY *psMapDevClassMemIN,
+							 PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psMapDevClassMemOUT,
+							 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+	IMG_HANDLE hOSMapInfo;
+	IMG_HANDLE hDeviceClassBufferInt;
+	IMG_HANDLE hDevMemContextInt;
+	PVRSRV_HANDLE_TYPE eHandleType;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc, 2)
+
+
+	psMapDevClassMemOUT->eError =
+		PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
+								  &hDeviceClassBufferInt,
+								  &eHandleType,
+								  psMapDevClassMemIN->hDeviceClassBuffer);
+
+	if(psMapDevClassMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	psMapDevClassMemOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+				   &hDevMemContextInt,
+				   psMapDevClassMemIN->hDevMemContext,
+				   PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+	if(psMapDevClassMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	switch(eHandleType)
+	{
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+		case PVRSRV_HANDLE_TYPE_DISP_BUFFER:
+		case PVRSRV_HANDLE_TYPE_BUF_BUFFER:
+#else
+		case PVRSRV_HANDLE_TYPE_NONE:
+#endif
+			break;
+		default:
+			psMapDevClassMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE;
+			return 0;
+	}
+
+	psMapDevClassMemOUT->eError =
+		PVRSRVMapDeviceClassMemoryKM(psPerProc,
+									 hDevMemContextInt,
+									 hDeviceClassBufferInt,
+									 &psMemInfo,
+									 &hOSMapInfo);
+	if(psMapDevClassMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	OSMemSet(&psMapDevClassMemOUT->sClientMemInfo,
+			0,
+			sizeof(psMapDevClassMemOUT->sClientMemInfo));
+	OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo,
+			0,
+			sizeof(psMapDevClassMemOUT->sClientSyncInfo));
+
+	psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM =
+			psMemInfo->pvLinAddrKM;
+
+	psMapDevClassMemOUT->sClientMemInfo.pvLinAddr = 0;
+	psMapDevClassMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
+	psMapDevClassMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
+	psMapDevClassMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+	if (psMemInfo->sMemBlk.hOSMemHandle != 0)
+	{
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+					&psMapDevClassMemOUT->sClientMemInfo.hMappingInfo,
+					psMemInfo->sMemBlk.hOSMemHandle,
+					PVRSRV_HANDLE_TYPE_MEM_INFO,
+					PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+					psMapDevClassMemIN->hDeviceClassBuffer);
+	}
+	else
+	{
+		psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = 0;
+	}
+#else
+	psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+					  &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo,
+					  psMemInfo,
+					  PVRSRV_HANDLE_TYPE_MEM_INFO,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+					  psMapDevClassMemIN->hDeviceClassBuffer);
+
+	psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo = IMG_NULL;
+
+
+	if(psMemInfo->psKernelSyncInfo)
+	{
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+		psMapDevClassMemOUT->sClientSyncInfo.psSyncData =
+			psMemInfo->psKernelSyncInfo->psSyncData;
+		psMapDevClassMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+			psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+		psMapDevClassMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+			psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+		if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != 0)
+		{
+			PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+								&psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo,
+								psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+								PVRSRV_HANDLE_TYPE_SYNC_INFO,
+								PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+								psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo);
+		}
+		else
+		{
+			psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo = 0;
+		}
+#else
+		psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo =
+			psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+		psMapDevClassMemOUT->sClientMemInfo.psClientSyncInfo = &psMapDevClassMemOUT->sClientSyncInfo;
+
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+						  &psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo,
+						  psMemInfo->psKernelSyncInfo,
+						  PVRSRV_HANDLE_TYPE_SYNC_INFO,
+						  PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+						  psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo);
+	}
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc)
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVUnmapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
+							   PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY *psUnmapDevClassMemIN,
+							   PVRSRV_BRIDGE_RETURN *psRetOUT,
+							   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvKernelMemInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+						   psUnmapDevClassMemIN->hKernelMemInfo,
+#else
+						   psUnmapDevClassMemIN->psKernelMemInfo,
+#endif
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError = PVRSRVUnmapDeviceClassMemoryKM(pvKernelMemInfo);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							psUnmapDevClassMemIN->hKernelMemInfo,
+#else
+							psUnmapDevClassMemIN->psKernelMemInfo,
+#endif
+							PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+	return 0;
+}
+
+
+#if defined(OS_PVRSRV_WRAP_EXT_MEM_BW)
+IMG_INT
+PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
+					  PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc);
+#else 
+static IMG_INT
+PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
+					  PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_HANDLE hDevMemContextInt;
+	PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+	IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL;
+	IMG_UINT32 ui32PageTableSize = 0;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_WRAP_EXT_MEMORY);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc, 2)
+
+
+	psWrapExtMemOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+						   psWrapExtMemIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psWrapExtMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	psWrapExtMemOUT->eError =
+	PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
+				   psWrapExtMemIN->hDevMemContext,
+				   PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+	if(psWrapExtMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	if(psWrapExtMemIN->ui32NumPageTableEntries)
+	{
+		ui32PageTableSize = psWrapExtMemIN->ui32NumPageTableEntries
+						* sizeof(IMG_SYS_PHYADDR);
+
+		ASSIGN_AND_EXIT_ON_ERROR(psWrapExtMemOUT->eError,
+				OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  ui32PageTableSize,
+				  (IMG_VOID **)&psSysPAddr, 0,
+				  "Page Table"));
+
+		if(CopyFromUserWrapper(psPerProc,
+							   ui32BridgeID,
+							   psSysPAddr,
+							   psWrapExtMemIN->psSysPAddr,
+							   ui32PageTableSize) != PVRSRV_OK)
+		{
+			OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,  ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0);
+
+			return -EFAULT;
+		}
+	}
+
+	psWrapExtMemOUT->eError =
+		PVRSRVWrapExtMemoryKM(hDevCookieInt,
+							  psPerProc,
+							  hDevMemContextInt,
+							  psWrapExtMemIN->ui32ByteSize,
+							  psWrapExtMemIN->ui32PageOffset,
+							  psWrapExtMemIN->bPhysContig,
+							  psSysPAddr,
+							  psWrapExtMemIN->pvLinAddr,
+							  psWrapExtMemIN->ui32Flags,
+							  &psMemInfo);
+
+	if(psWrapExtMemIN->ui32NumPageTableEntries)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+			  ui32PageTableSize,
+			  (IMG_VOID *)psSysPAddr, 0);
+
+	}
+
+	if(psWrapExtMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM =
+			psMemInfo->pvLinAddrKM;
+
+
+	psWrapExtMemOUT->sClientMemInfo.pvLinAddr = 0;
+	psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
+	psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
+	psWrapExtMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+#else
+	psWrapExtMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo,
+					  psMemInfo,
+					  PVRSRV_HANDLE_TYPE_MEM_INFO,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+#if defined (SUPPORT_SID_INTERFACE)
+
+	if (psMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+	{
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+						&psWrapExtMemOUT->sClientMemInfo.hMappingInfo,
+						psMemInfo->sMemBlk.hOSMemHandle,
+						PVRSRV_HANDLE_TYPE_MEM_INFO,
+						PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+						psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
+	}
+	else
+	{
+		psWrapExtMemOUT->sClientMemInfo.hMappingInfo = 0;
+	}
+#endif
+
+
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+	psWrapExtMemOUT->sClientSyncInfo.psSyncData =
+		psMemInfo->psKernelSyncInfo->psSyncData;
+	psWrapExtMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+		psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+	psWrapExtMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+		psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+
+	if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+	{
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+						&psWrapExtMemOUT->sClientSyncInfo.hMappingInfo,
+						psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+						PVRSRV_HANDLE_TYPE_MEM_INFO,
+						PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+						psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
+	}
+	else
+	{
+		psWrapExtMemOUT->sClientSyncInfo.hMappingInfo = 0;
+	}
+#else
+	psWrapExtMemOUT->sClientSyncInfo.hMappingInfo =
+		psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+	psWrapExtMemOUT->sClientMemInfo.psClientSyncInfo = &psWrapExtMemOUT->sClientSyncInfo;
+
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+					  &psWrapExtMemOUT->sClientSyncInfo.hKernelSyncInfo,
+					  (IMG_HANDLE)psMemInfo->psKernelSyncInfo,
+					  PVRSRV_HANDLE_TYPE_SYNC_INFO,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+					  psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc)
+
+	return 0;
+}
+#endif 
+
+static IMG_INT
+PVRSRVUnwrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
+						PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY *psUnwrapExtMemIN,
+						PVRSRV_BRIDGE_RETURN *psRetOUT,
+						PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvMemInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvMemInfo,
+						   psUnwrapExtMemIN->hKernelMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVUnwrapExtMemoryKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVReleaseHandle(psPerProc->psHandleBase,
+						   psUnwrapExtMemIN->hKernelMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVGetFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
+						 PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM *psGetFreeDeviceMemIN,
+						 PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM *psGetFreeDeviceMemOUT,
+						 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETFREE_DEVICEMEM);
+
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+	psGetFreeDeviceMemOUT->eError =
+		PVRSRVGetFreeDeviceMemKM(psGetFreeDeviceMemIN->ui32Flags,
+								 &psGetFreeDeviceMemOUT->ui32Total,
+								 &psGetFreeDeviceMemOUT->ui32Free,
+								 &psGetFreeDeviceMemOUT->ui32LargestBlock);
+
+	return 0;
+}
+
+static IMG_INT
+PVRMMapOSMemHandleToMMapDataBW(IMG_UINT32 ui32BridgeID,
+								  PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *psMMapDataIN,
+								  PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *psMMapDataOUT,
+								  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA);
+
+#if defined (__linux__) || defined(__QNXNTO__)
+	psMMapDataOUT->eError =
+		PVRMMapOSMemHandleToMMapData(psPerProc,
+										psMMapDataIN->hMHandle,
+										&psMMapDataOUT->ui32MMapOffset,
+										&psMMapDataOUT->ui32ByteOffset,
+										&psMMapDataOUT->ui32RealByteSize,
+										&psMMapDataOUT->ui32UserVAddr);
+#else
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+	PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
+
+	psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+#endif
+	return 0;
+}
+
+
+static IMG_INT
+PVRMMapReleaseMMapDataBW(IMG_UINT32 ui32BridgeID,
+								  PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA *psMMapDataIN,
+								  PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *psMMapDataOUT,
+								  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RELEASE_MMAP_DATA);
+
+#if defined (__linux__) || defined(__QNXNTO__)
+	psMMapDataOUT->eError =
+		PVRMMapReleaseMMapData(psPerProc,
+										psMMapDataIN->hMHandle,
+										&psMMapDataOUT->bMUnmap,
+										&psMMapDataOUT->ui32RealByteSize,
+										&psMMapDataOUT->ui32UserVAddr);
+#else
+
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+	PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
+
+	psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+#endif
+	return 0;
+}
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+static IMG_INT
+PVRSRVChangeDeviceMemoryAttributesBW(IMG_UINT32 ui32BridgeID,
+                                     PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS *psChgMemAttribIN,
+                                     PVRSRV_BRIDGE_RETURN *psRetOUT,
+                                     PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hKernelMemInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+							&hKernelMemInfo,
+							psChgMemAttribIN->hKernelMemInfo,
+							PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVChangeDeviceMemoryAttributesKM(hKernelMemInfo, psChgMemAttribIN->ui32Attribs);
+
+	return 0;
+}
+#else
+static IMG_INT
+PVRSRVChangeDeviceMemoryAttributesBW(IMG_UINT32 ui32BridgeID,
+                                     PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS *psChgMemAttribIN,
+                                     PVRSRV_BRIDGE_RETURN *psRetOUT,
+                                     PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+	PVR_UNREFERENCED_PARAMETER(psChgMemAttribIN);
+	PVR_UNREFERENCED_PARAMETER(psRetOUT);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+	return 0;
+}
+#endif
+
+#ifdef PDUMP
+static IMG_INT
+PDumpIsCaptureFrameBW(IMG_UINT32 ui32BridgeID,
+					  IMG_VOID *psBridgeIn,
+					  PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING *psPDumpIsCapturingOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_ISCAPTURING);
+	PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+	psPDumpIsCapturingOUT->bIsCapturing = PDumpIsCaptureFrameKM();
+	psPDumpIsCapturingOUT->eError = PVRSRV_OK;
+
+	return 0;
+}
+
+static IMG_INT
+PDumpCommentBW(IMG_UINT32 ui32BridgeID,
+			   PVRSRV_BRIDGE_IN_PDUMP_COMMENT *psPDumpCommentIN,
+			   PVRSRV_BRIDGE_RETURN *psRetOUT,
+			   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_COMMENT);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+	psRetOUT->eError = PDumpCommentKM(&psPDumpCommentIN->szComment[0],
+									  psPDumpCommentIN->ui32Flags);
+	return 0;
+}
+
+static IMG_INT
+PDumpSetFrameBW(IMG_UINT32 ui32BridgeID,
+				PVRSRV_BRIDGE_IN_PDUMP_SETFRAME *psPDumpSetFrameIN,
+				PVRSRV_BRIDGE_RETURN *psRetOUT,
+				PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SETFRAME);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+	psRetOUT->eError = PDumpSetFrameKM(psPDumpSetFrameIN->ui32Frame);
+
+	return 0;
+}
+
+static IMG_INT
+PDumpRegWithFlagsBW(IMG_UINT32 ui32BridgeID,
+					PVRSRV_BRIDGE_IN_PDUMP_DUMPREG *psPDumpRegDumpIN,
+					PVRSRV_BRIDGE_RETURN *psRetOUT,
+					PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REG);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   (IMG_VOID **)&psDeviceNode,
+						   psPDumpRegDumpIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError = PDumpRegWithFlagsKM (psPDumpRegDumpIN->szRegRegion,
+											psPDumpRegDumpIN->sHWReg.ui32RegAddr,
+											psPDumpRegDumpIN->sHWReg.ui32RegVal,
+											psPDumpRegDumpIN->ui32Flags);
+
+	return 0;
+}
+
+static IMG_INT
+PDumpRegPolBW(IMG_UINT32 ui32BridgeID,
+			  PVRSRV_BRIDGE_IN_PDUMP_REGPOL *psPDumpRegPolIN,
+			  PVRSRV_BRIDGE_RETURN *psRetOUT,
+			  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REGPOL);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   (IMG_VOID **)&psDeviceNode,
+						   psPDumpRegPolIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	psRetOUT->eError =
+		PDumpRegPolWithFlagsKM(psPDumpRegPolIN->szRegRegion,
+							   psPDumpRegPolIN->sHWReg.ui32RegAddr,
+							   psPDumpRegPolIN->sHWReg.ui32RegVal,
+							   psPDumpRegPolIN->ui32Mask,
+							   psPDumpRegPolIN->ui32Flags,
+							   PDUMP_POLL_OPERATOR_EQUAL);
+
+	return 0;
+}
+
+static IMG_INT
+PDumpMemPolBW(IMG_UINT32 ui32BridgeID,
+			  PVRSRV_BRIDGE_IN_PDUMP_MEMPOL *psPDumpMemPolIN,
+			  PVRSRV_BRIDGE_RETURN *psRetOUT,
+			  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvMemInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPOL);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+                           psPDumpMemPolIN->hKernelMemInfo,
+#else
+						   psPDumpMemPolIN->psKernelMemInfo,
+#endif
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PDumpMemPolKM(((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo),
+					  psPDumpMemPolIN->ui32Offset,
+					  psPDumpMemPolIN->ui32Value,
+					  psPDumpMemPolIN->ui32Mask,
+					  psPDumpMemPolIN->eOperator,
+					  psPDumpMemPolIN->ui32Flags,
+					  MAKEUNIQUETAG(pvMemInfo));
+
+	return 0;
+}
+
+static IMG_INT
+PDumpMemBW(IMG_UINT32 ui32BridgeID,
+		   PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM *psPDumpMemDumpIN,
+		   PVRSRV_BRIDGE_RETURN *psRetOUT,
+		   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvMemInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+						   psPDumpMemDumpIN->hKernelMemInfo,
+#else
+						   psPDumpMemDumpIN->psKernelMemInfo,
+#endif
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PDumpMemUM(psPerProc,
+				   psPDumpMemDumpIN->pvAltLinAddr,
+				   psPDumpMemDumpIN->pvLinAddr,
+				   pvMemInfo,
+				   psPDumpMemDumpIN->ui32Offset,
+				   psPDumpMemDumpIN->ui32Bytes,
+				   psPDumpMemDumpIN->ui32Flags,
+				   MAKEUNIQUETAG(pvMemInfo));
+
+	return 0;
+}
+
+static IMG_INT
+PDumpBitmapBW(IMG_UINT32 ui32BridgeID,
+			  PVRSRV_BRIDGE_IN_PDUMP_BITMAP *psPDumpBitmapIN,
+			  PVRSRV_BRIDGE_RETURN *psRetOUT,
+			  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_HANDLE hDevMemContextInt;
+
+	PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
+						   psPDumpBitmapIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(	psPerProc->psHandleBase,
+							&hDevMemContextInt,
+							psPDumpBitmapIN->hDevMemContext,
+							PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PDumpBitmapKM(psDeviceNode,
+					  &psPDumpBitmapIN->szFileName[0],
+					  psPDumpBitmapIN->ui32FileOffset,
+					  psPDumpBitmapIN->ui32Width,
+					  psPDumpBitmapIN->ui32Height,
+					  psPDumpBitmapIN->ui32StrideInBytes,
+					  psPDumpBitmapIN->sDevBaseAddr,
+					  hDevMemContextInt,
+					  psPDumpBitmapIN->ui32Size,
+					  psPDumpBitmapIN->ePixelFormat,
+					  psPDumpBitmapIN->eMemFormat,
+					  psPDumpBitmapIN->ui32Flags);
+
+	return 0;
+}
+
+static IMG_INT
+PDumpReadRegBW(IMG_UINT32 ui32BridgeID,
+			   PVRSRV_BRIDGE_IN_PDUMP_READREG *psPDumpReadRegIN,
+			   PVRSRV_BRIDGE_RETURN *psRetOUT,
+			   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
+						   psPDumpReadRegIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	psRetOUT->eError =
+		PDumpReadRegKM(&psPDumpReadRegIN->szRegRegion[0],
+					   &psPDumpReadRegIN->szFileName[0],
+					   psPDumpReadRegIN->ui32FileOffset,
+					   psPDumpReadRegIN->ui32Address,
+					   psPDumpReadRegIN->ui32Size,
+					   psPDumpReadRegIN->ui32Flags);
+
+	return 0;
+}
+
+static IMG_INT
+PDumpMemPagesBW(IMG_UINT32 ui32BridgeID,
+				  PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES *psPDumpMemPagesIN,
+				  PVRSRV_BRIDGE_RETURN *psRetOUT,
+				  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPAGES);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   (IMG_VOID **)&psDeviceNode,
+						   psPDumpMemPagesIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	return 0;
+}
+
+static IMG_INT
+PDumpDriverInfoBW(IMG_UINT32 ui32BridgeID,
+				  PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO *psPDumpDriverInfoIN,
+				  PVRSRV_BRIDGE_RETURN *psRetOUT,
+				  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_UINT32 ui32PDumpFlags;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DRIVERINFO);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+	ui32PDumpFlags = 0;
+	if(psPDumpDriverInfoIN->bContinuous)
+	{
+		ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS;
+	}
+	psRetOUT->eError =
+		PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0],
+						  ui32PDumpFlags);
+
+	return 0;
+}
+
+static IMG_INT
+PDumpSyncDumpBW(IMG_UINT32 ui32BridgeID,
+				PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC *psPDumpSyncDumpIN,
+				PVRSRV_BRIDGE_RETURN *psRetOUT,
+				PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_UINT32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes;
+	IMG_VOID *pvSyncInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPSYNC);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+                           psPDumpSyncDumpIN->hKernelSyncInfo,
+#else
+						   psPDumpSyncDumpIN->psKernelSyncInfo,
+#endif
+						   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PDumpMemUM(psPerProc,
+				   psPDumpSyncDumpIN->pvAltLinAddr,
+				   IMG_NULL,
+				   ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
+				   psPDumpSyncDumpIN->ui32Offset,
+				   ui32Bytes,
+				   0,
+				   MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
+
+	return 0;
+}
+
+static IMG_INT
+PDumpSyncPolBW(IMG_UINT32 ui32BridgeID,
+			   PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL *psPDumpSyncPolIN,
+			   PVRSRV_BRIDGE_RETURN *psRetOUT,
+			   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_UINT32 ui32Offset;
+	IMG_VOID *pvSyncInfo;
+	IMG_UINT32 ui32Value;
+	IMG_UINT32 ui32Mask;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL);
+
+	psRetOUT->eError =
+        PVRSRVLookupHandle(psPerProc->psHandleBase,
+                           &pvSyncInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+						   psPDumpSyncPolIN->hKernelSyncInfo,
+#else
+						   psPDumpSyncPolIN->psKernelSyncInfo,
+#endif
+						   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	if(psPDumpSyncPolIN->bIsRead)
+	{
+		ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
+	}
+	else
+	{
+		ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
+	}
+
+	
+	if (psPDumpSyncPolIN->bUseLastOpDumpVal)
+	{
+		if(psPDumpSyncPolIN->bIsRead)
+		{
+			ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastReadOpDumpVal;
+		}
+		else
+		{
+			ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastOpDumpVal;
+		}
+		ui32Mask = 0xffffffff;
+	}
+	else
+	{
+		ui32Value = psPDumpSyncPolIN->ui32Value;
+		ui32Mask =  psPDumpSyncPolIN->ui32Mask;
+	}
+
+	psRetOUT->eError =
+		PDumpMemPolKM(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
+					  ui32Offset,
+					  ui32Value,
+					  ui32Mask,
+					  PDUMP_POLL_OPERATOR_EQUAL,
+					  0,
+					  MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
+
+	return 0;
+}
+
+
+static IMG_INT
+PDumpCycleCountRegReadBW(IMG_UINT32 ui32BridgeID,
+						 PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ *psPDumpCycleCountRegReadIN,
+						 PVRSRV_BRIDGE_RETURN *psRetOUT,
+						 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   (IMG_VOID **)&psDeviceNode,
+						   psPDumpCycleCountRegReadIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	PDumpCycleCountRegRead(&psDeviceNode->sDevId,
+						   psPDumpCycleCountRegReadIN->ui32RegOffset,
+						   psPDumpCycleCountRegReadIN->bLastFrame);
+
+	psRetOUT->eError = PVRSRV_OK;
+
+	return 0;
+}
+
+static IMG_INT
+PDumpPDDevPAddrBW(IMG_UINT32 ui32BridgeID,
+				  PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN,
+				  PVRSRV_BRIDGE_RETURN *psRetOUT,
+				  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvMemInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &pvMemInfo,
+						   psPDumpPDDevPAddrIN->hKernelMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PDumpPDDevPAddrKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo,
+						  psPDumpPDDevPAddrIN->ui32Offset,
+						  psPDumpPDDevPAddrIN->sPDDevPAddr,
+						  MAKEUNIQUETAG(pvMemInfo),
+						  PDUMP_PD_UNIQUETAG);
+	return 0;
+}
+
+static IMG_INT
+PDumpStartInitPhaseBW(IMG_UINT32 ui32BridgeID,
+					  IMG_VOID *psBridgeIn,
+					  PVRSRV_BRIDGE_RETURN *psRetOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STARTINITPHASE);
+	PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+	psRetOUT->eError = PDumpStartInitPhaseKM();
+
+	return 0;
+}
+
+static IMG_INT
+PDumpStopInitPhaseBW(IMG_UINT32 ui32BridgeID,
+					  IMG_VOID *psBridgeIn,
+					  PVRSRV_BRIDGE_RETURN *psRetOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STOPINITPHASE);
+	PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+	psRetOUT->eError = PDumpStopInitPhaseKM();
+
+	return 0;
+}
+
+#endif 
+
+
+static IMG_INT
+PVRSRVGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
+					PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN,
+					PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT,
+					PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_MISC_INFO_KM sMiscInfo = {0};
+#endif
+	PVRSRV_ERROR eError;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO);
+#if defined (SUPPORT_SID_INTERFACE)
+	sMiscInfo.ui32StateRequest = psGetMiscInfoIN->sMiscInfo.ui32StateRequest;
+	sMiscInfo.ui32StatePresent = psGetMiscInfoIN->sMiscInfo.ui32StatePresent;
+	sMiscInfo.ui32MemoryStrLen = psGetMiscInfoIN->sMiscInfo.ui32MemoryStrLen;
+	sMiscInfo.pszMemoryStr     = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
+
+	OSMemCopy(&sMiscInfo.sCacheOpCtl,
+			  &psGetMiscInfoIN->sMiscInfo.sCacheOpCtl,
+			  sizeof(sMiscInfo.sCacheOpCtl));
+#else
+
+	OSMemCopy(&psGetMiscInfoOUT->sMiscInfo,
+			  &psGetMiscInfoIN->sMiscInfo,
+			  sizeof(PVRSRV_MISC_INFO));
+#endif
+
+	if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) &&
+	    ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) &&
+	    ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
+	{
+
+		psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		return 0;
+	}
+
+	if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) ||
+	    ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) ||
+	    ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
+	{
+
+#if defined (SUPPORT_SID_INTERFACE)
+		ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
+				OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
+						(IMG_VOID **)&sMiscInfo.pszMemoryStr, 0,
+						"Output string buffer"));
+		psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&sMiscInfo);
+
+
+		eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
+									psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
+									sMiscInfo.pszMemoryStr,
+									sMiscInfo.ui32MemoryStrLen);
+#else
+		ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
+				OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+		                    psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
+		                    (IMG_VOID **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0,
+							"Output string buffer"));
+
+		psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
+
+
+		eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
+					   psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
+					   psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
+					   psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen);
+#endif
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+				     sMiscInfo.ui32MemoryStrLen,
+				     (IMG_VOID *)sMiscInfo.pszMemoryStr, 0);
+#else
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+			  psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
+			 (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0);
+#endif
+
+
+		psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
+
+		if(eError != PVRSRV_OK)
+		{
+
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user"));
+			return -EFAULT;
+		}
+	}
+	else
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&sMiscInfo);
+#else
+		psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
+#endif
+	}
+
+
+	if (psGetMiscInfoOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+	if (sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
+#else
+		if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
+#endif
+		{
+			psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+													&psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
+#if defined (SUPPORT_SID_INTERFACE)
+					sMiscInfo.sGlobalEventObject.hOSEventKM,
+#else
+													psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
+#endif
+													PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
+													PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+			if (psGetMiscInfoOUT->eError != PVRSRV_OK)
+			{
+				return 0;
+			}
+
+#if defined (SUPPORT_SID_INTERFACE)
+			OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.szName,
+							sMiscInfo.sGlobalEventObject.szName,
+							EVENTOBJNAME_MAXLENGTH);
+
+#endif
+		}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	if (sMiscInfo.hSOCTimerRegisterOSMemHandle)
+#else
+	if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle)
+#endif
+	{
+
+		psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+						  &psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+					sMiscInfo.hSOCTimerRegisterOSMemHandle,
+#else
+						  psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
+#endif
+						  PVRSRV_HANDLE_TYPE_SOC_TIMER,
+						  PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+		if (psGetMiscInfoOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+#if defined (SUPPORT_SID_INTERFACE)
+	else
+	{
+		psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle = 0;
+	}
+
+
+	psGetMiscInfoOUT->sMiscInfo.ui32StateRequest = sMiscInfo.ui32StateRequest;
+	psGetMiscInfoOUT->sMiscInfo.ui32StatePresent = sMiscInfo.ui32StatePresent;
+
+	psGetMiscInfoOUT->sMiscInfo.pvSOCTimerRegisterKM = sMiscInfo.pvSOCTimerRegisterKM;
+	psGetMiscInfoOUT->sMiscInfo.pvSOCTimerRegisterUM = sMiscInfo.pvSOCTimerRegisterUM;
+	psGetMiscInfoOUT->sMiscInfo.pvSOCClockGateRegs   = sMiscInfo.pvSOCClockGateRegs;
+
+	psGetMiscInfoOUT->sMiscInfo.ui32SOCClockGateRegsSize = sMiscInfo.ui32SOCClockGateRegsSize;
+
+	OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.aui32DDKVersion,
+				&sMiscInfo.aui32DDKVersion,
+				sizeof(psGetMiscInfoOUT->sMiscInfo.aui32DDKVersion));
+	OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sCacheOpCtl,
+				&sMiscInfo.sCacheOpCtl,
+				sizeof(psGetMiscInfoOUT->sMiscInfo.sCacheOpCtl));
+#endif
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVConnectBW(IMG_UINT32 ui32BridgeID,
+				PVRSRV_BRIDGE_IN_CONNECT_SERVICES *psConnectServicesIN,
+				PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT,
+				PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES);
+
+#if defined(PDUMP)
+
+	if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PERSIST) != 0)
+	{
+		psPerProc->bPDumpPersistent = IMG_TRUE;
+	}
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+	if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PDUMP_ACTIVE) != 0)
+	{
+		psPerProc->bPDumpActive = IMG_TRUE;
+	}
+#endif 
+#else
+	PVR_UNREFERENCED_PARAMETER(psConnectServicesIN);
+#endif
+	psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData;
+	psConnectServicesOUT->eError = PVRSRV_OK;
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVDisconnectBW(IMG_UINT32 ui32BridgeID,
+				   IMG_VOID *psBridgeIn,
+				   PVRSRV_BRIDGE_RETURN *psRetOUT,
+				   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+	PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DISCONNECT_SERVICES);
+
+
+	psRetOUT->eError = PVRSRV_OK;
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVEnumerateDCBW(IMG_UINT32 ui32BridgeID,
+					PVRSRV_BRIDGE_IN_ENUMCLASS *psEnumDispClassIN,
+					PVRSRV_BRIDGE_OUT_ENUMCLASS *psEnumDispClassOUT,
+					PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_CLASS);
+
+	psEnumDispClassOUT->eError =
+		PVRSRVEnumerateDCKM(psEnumDispClassIN->sDeviceClass,
+							&psEnumDispClassOUT->ui32NumDevices,
+							&psEnumDispClassOUT->ui32DevID[0]);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVOpenDCDeviceBW(IMG_UINT32 ui32BridgeID,
+					 PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceIN,
+					 PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceOUT,
+					 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_HANDLE hDispClassInfoInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc, 1)
+
+	psOpenDispClassDeviceOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psOpenDispClassDeviceIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psOpenDispClassDeviceOUT->eError =
+		PVRSRVOpenDCDeviceKM(psPerProc,
+							 psOpenDispClassDeviceIN->ui32DeviceID,
+							 hDevCookieInt,
+							 &hDispClassInfoInt);
+
+	if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psOpenDispClassDeviceOUT->hDeviceKM,
+					  hDispClassInfoInt,
+					  PVRSRV_HANDLE_TYPE_DISP_INFO,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+	COMMIT_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc)
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVCloseDCDeviceBW(IMG_UINT32 ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE *psCloseDispClassDeviceIN,
+					  PVRSRV_BRIDGE_RETURN *psRetOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfoInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfoInt,
+						   psCloseDispClassDeviceIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError = PVRSRVCloseDCDeviceKM(pvDispClassInfoInt, IMG_FALSE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVReleaseHandle(psPerProc->psHandleBase,
+							psCloseDispClassDeviceIN->hDeviceKM,
+							PVRSRV_HANDLE_TYPE_DISP_INFO);
+	return 0;
+}
+
+static IMG_INT
+PVRSRVEnumDCFormatsBW(IMG_UINT32 ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsIN,
+					  PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfoInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS);
+
+	psEnumDispClassFormatsOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfoInt,
+						   psEnumDispClassFormatsIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psEnumDispClassFormatsOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psEnumDispClassFormatsOUT->eError =
+		PVRSRVEnumDCFormatsKM(pvDispClassInfoInt,
+							  &psEnumDispClassFormatsOUT->ui32Count,
+							  psEnumDispClassFormatsOUT->asFormat);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVEnumDCDimsBW(IMG_UINT32 ui32BridgeID,
+				   PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsIN,
+				   PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsOUT,
+				   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfoInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS);
+
+	psEnumDispClassDimsOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfoInt,
+						   psEnumDispClassDimsIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+
+	if(psEnumDispClassDimsOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psEnumDispClassDimsOUT->eError =
+		PVRSRVEnumDCDimsKM(pvDispClassInfoInt,
+						   &psEnumDispClassDimsIN->sFormat,
+						   &psEnumDispClassDimsOUT->ui32Count,
+						   psEnumDispClassDimsOUT->asDim);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVGetDCSystemBufferBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN,  
+						  PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hBufferInt;
+	IMG_VOID *pvDispClassInfoInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc, 1)
+
+	psGetDispClassSysBufferOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfoInt,
+						   psGetDispClassSysBufferIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psGetDispClassSysBufferOUT->eError =
+		PVRSRVGetDCSystemBufferKM(pvDispClassInfoInt,
+								  &hBufferInt);
+
+	if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+						 &psGetDispClassSysBufferOUT->hBuffer,
+						 hBufferInt,
+						 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+						 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
+						 psGetDispClassSysBufferIN->hDeviceKM);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc)
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVGetDCInfoBW(IMG_UINT32 ui32BridgeID,
+				  PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO *psGetDispClassInfoIN,
+				  PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *psGetDispClassInfoOUT,
+				  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_INFO);
+
+	psGetDispClassInfoOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfo,
+						   psGetDispClassInfoIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psGetDispClassInfoOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psGetDispClassInfoOUT->eError =
+		PVRSRVGetDCInfoKM(pvDispClassInfo,
+						  &psGetDispClassInfoOUT->sDisplayInfo);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVCreateDCSwapChainBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainIN,
+						  PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfo;
+	IMG_HANDLE hSwapChainInt;
+	IMG_UINT32  ui32SwapChainID;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc, 1)
+
+	psCreateDispClassSwapChainOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfo,
+						   psCreateDispClassSwapChainIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+
+	if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	ui32SwapChainID = psCreateDispClassSwapChainIN->ui32SwapChainID;
+
+	psCreateDispClassSwapChainOUT->eError =
+		PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo,
+								  psCreateDispClassSwapChainIN->ui32Flags,
+								  &psCreateDispClassSwapChainIN->sDstSurfAttrib,
+								  &psCreateDispClassSwapChainIN->sSrcSurfAttrib,
+								  psCreateDispClassSwapChainIN->ui32BufferCount,
+								  psCreateDispClassSwapChainIN->ui32OEMFlags,
+								  &hSwapChainInt,
+								  &ui32SwapChainID);
+
+	if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	psCreateDispClassSwapChainOUT->ui32SwapChainID = ui32SwapChainID;
+
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+					  &psCreateDispClassSwapChainOUT->hSwapChain,
+					  hSwapChainInt,
+					  PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+					  psCreateDispClassSwapChainIN->hDeviceKM);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc)
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVDestroyDCSwapChainBW(IMG_UINT32 ui32BridgeID,
+						   PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN *psDestroyDispClassSwapChainIN,
+						   PVRSRV_BRIDGE_RETURN *psRetOUT,
+						   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvSwapChain;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSwapChain,
+						   psDestroyDispClassSwapChainIN->hSwapChain,
+						   PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVDestroyDCSwapChainKM(pvSwapChain);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVReleaseHandle(psPerProc->psHandleBase,
+							psDestroyDispClassSwapChainIN->hSwapChain,
+							PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVSetDCDstRectBW(IMG_UINT32 ui32BridgeID,
+					 PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassDstRectIN,
+					 PVRSRV_BRIDGE_RETURN *psRetOUT,
+					 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfo;
+	IMG_VOID *pvSwapChain;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfo,
+						   psSetDispClassDstRectIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvSwapChain,
+						   psSetDispClassDstRectIN->hSwapChain,
+						   PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVSetDCDstRectKM(pvDispClassInfo,
+							 pvSwapChain,
+							 &psSetDispClassDstRectIN->sRect);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVSetDCSrcRectBW(IMG_UINT32 ui32BridgeID,
+					 PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassSrcRectIN,
+					 PVRSRV_BRIDGE_RETURN *psRetOUT,
+					 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfo;
+	IMG_VOID *pvSwapChain;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfo,
+						   psSetDispClassSrcRectIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvSwapChain,
+						   psSetDispClassSrcRectIN->hSwapChain,
+						   PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVSetDCSrcRectKM(pvDispClassInfo,
+							 pvSwapChain,
+							 &psSetDispClassSrcRectIN->sRect);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVSetDCDstColourKeyBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
+						  PVRSRV_BRIDGE_RETURN *psRetOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfo;
+	IMG_VOID *pvSwapChain;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfo,
+						   psSetDispClassColKeyIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvSwapChain,
+						   psSetDispClassColKeyIN->hSwapChain,
+						   PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVSetDCDstColourKeyKM(pvDispClassInfo,
+								  pvSwapChain,
+								  psSetDispClassColKeyIN->ui32CKColour);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVSetDCSrcColourKeyBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
+						  PVRSRV_BRIDGE_RETURN *psRetOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfo;
+	IMG_VOID *pvSwapChain;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfo,
+						   psSetDispClassColKeyIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvSwapChain,
+						   psSetDispClassColKeyIN->hSwapChain,
+						   PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVSetDCSrcColourKeyKM(pvDispClassInfo,
+								  pvSwapChain,
+								  psSetDispClassColKeyIN->ui32CKColour);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVGetDCBuffersBW(IMG_UINT32 ui32BridgeID,
+					 PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersIN,
+					 PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersOUT,
+					 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID    *pvDispClassInfo;
+	IMG_VOID    *pvSwapChain;
+	IMG_UINT32   i;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_HANDLE  *pahBuffer;
+#endif
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc, PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
+
+	psGetDispClassBuffersOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfo,
+						   psGetDispClassBuffersIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psGetDispClassBuffersOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvSwapChain,
+						   psGetDispClassBuffersIN->hSwapChain,
+						   PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+	if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	psGetDispClassBuffersOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+													sizeof(IMG_HANDLE) * PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS,
+													(IMG_PVOID *)&pahBuffer, 0,
+													"Temp Swapchain Buffers");
+
+	if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+#endif
+
+	psGetDispClassBuffersOUT->eError =
+		PVRSRVGetDCBuffersKM(pvDispClassInfo,
+							 pvSwapChain,
+							 &psGetDispClassBuffersOUT->ui32BufferCount,
+#if defined (SUPPORT_SID_INTERFACE)
+				pahBuffer);
+#else
+				psGetDispClassBuffersOUT->ahBuffer);
+#endif
+	if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
+
+	for(i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++)
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		IMG_SID hBufferExt;
+#else
+		IMG_HANDLE hBufferExt;
+#endif
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+							&hBufferExt,
+							pahBuffer[i],
+							PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+							(PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
+							psGetDispClassBuffersIN->hSwapChain);
+#else
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+							 &hBufferExt,
+							 psGetDispClassBuffersOUT->ahBuffer[i],
+							 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+							 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
+							 psGetDispClassBuffersIN->hSwapChain);
+#endif
+
+		psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+				sizeof(IMG_HANDLE) * PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS,
+				(IMG_PVOID)pahBuffer, 0);
+#endif
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc)
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVSwapToDCBufferBW(IMG_UINT32 ui32BridgeID,
+					   PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER *psSwapDispClassBufferIN,
+					   PVRSRV_BRIDGE_RETURN *psRetOUT,
+					   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID  *pvDispClassInfo;
+	IMG_VOID  *pvSwapChainBuf;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_HANDLE hPrivateTag;
+#endif
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfo,
+						   psSwapDispClassBufferIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupSubHandle(psPerProc->psHandleBase,
+						   &pvSwapChainBuf,
+						   psSwapDispClassBufferIN->hBuffer,
+						   PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+						   psSwapDispClassBufferIN->hDeviceKM);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	if (psSwapDispClassBufferIN->hPrivateTag != 0)
+	{
+		psRetOUT->eError =
+			PVRSRVLookupSubHandle(psPerProc->psHandleBase,
+								&hPrivateTag,
+								psSwapDispClassBufferIN->hPrivateTag,
+								PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+								psSwapDispClassBufferIN->hDeviceKM);
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+	else
+	{
+		hPrivateTag = IMG_NULL;
+	}
+#endif
+
+
+	psRetOUT->eError =
+		PVRSRVSwapToDCBufferKM(pvDispClassInfo,
+							   pvSwapChainBuf,
+							   psSwapDispClassBufferIN->ui32SwapInterval,
+#if defined (SUPPORT_SID_INTERFACE)
+				hPrivateTag,
+#else
+							   psSwapDispClassBufferIN->hPrivateTag,
+#endif
+							   psSwapDispClassBufferIN->ui32ClipRectCount,
+							   psSwapDispClassBufferIN->sClipRect);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVSwapToDCSystemBW(IMG_UINT32 ui32BridgeID,
+					   PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM *psSwapDispClassSystemIN,
+					   PVRSRV_BRIDGE_RETURN *psRetOUT,
+					   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvDispClassInfo;
+	IMG_VOID *pvSwapChain;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvDispClassInfo,
+						   psSwapDispClassSystemIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_DISP_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupSubHandle(psPerProc->psHandleBase,
+						   &pvSwapChain,
+						   psSwapDispClassSystemIN->hSwapChain,
+						   PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
+						   psSwapDispClassSystemIN->hDeviceKM);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+	psRetOUT->eError =
+		PVRSRVSwapToDCSystemKM(pvDispClassInfo,
+							   pvSwapChain);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVOpenBCDeviceBW(IMG_UINT32 ui32BridgeID,
+					 PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceIN,
+					 PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceOUT,
+					 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_HANDLE hBufClassInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc, 1)
+
+	psOpenBufferClassDeviceOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psOpenBufferClassDeviceIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psOpenBufferClassDeviceOUT->eError =
+		PVRSRVOpenBCDeviceKM(psPerProc,
+							 psOpenBufferClassDeviceIN->ui32DeviceID,
+							 hDevCookieInt,
+							 &hBufClassInfo);
+	if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psOpenBufferClassDeviceOUT->hDeviceKM,
+					  hBufClassInfo,
+					  PVRSRV_HANDLE_TYPE_BUF_INFO,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc)
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVCloseBCDeviceBW(IMG_UINT32 ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE *psCloseBufferClassDeviceIN,
+					  PVRSRV_BRIDGE_RETURN *psRetOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvBufClassInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvBufClassInfo,
+						   psCloseBufferClassDeviceIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_BUF_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVCloseBCDeviceKM(pvBufClassInfo, IMG_FALSE);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+										   psCloseBufferClassDeviceIN->hDeviceKM,
+										   PVRSRV_HANDLE_TYPE_BUF_INFO);
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVGetBCInfoBW(IMG_UINT32 ui32BridgeID,
+				  PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO *psGetBufferClassInfoIN,
+				  PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO *psGetBufferClassInfoOUT,
+				  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvBufClassInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO);
+
+	psGetBufferClassInfoOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvBufClassInfo,
+						   psGetBufferClassInfoIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_BUF_INFO);
+	if(psGetBufferClassInfoOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psGetBufferClassInfoOUT->eError =
+		PVRSRVGetBCInfoKM(pvBufClassInfo,
+						  &psGetBufferClassInfoOUT->sBufferInfo);
+	return 0;
+}
+
+static IMG_INT
+PVRSRVGetBCBufferBW(IMG_UINT32 ui32BridgeID,
+					PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferIN,
+					PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferOUT,
+					PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_VOID *pvBufClassInfo;
+	IMG_HANDLE hBufferInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc, 1)
+
+	psGetBufferClassBufferOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvBufClassInfo,
+						   psGetBufferClassBufferIN->hDeviceKM,
+						   PVRSRV_HANDLE_TYPE_BUF_INFO);
+	if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psGetBufferClassBufferOUT->eError =
+		PVRSRVGetBCBufferKM(pvBufClassInfo,
+							psGetBufferClassBufferIN->ui32BufferIndex,
+							&hBufferInt);
+
+	if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+						 &psGetBufferClassBufferOUT->hBuffer,
+						 hBufferInt,
+						 PVRSRV_HANDLE_TYPE_BUF_BUFFER,
+						 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE |  PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
+						 psGetBufferClassBufferIN->hDeviceKM);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc)
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVAllocSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
+							 PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemIN,
+							 PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemOUT,
+							 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc, 1)
+
+	psAllocSharedSysMemOUT->eError =
+		PVRSRVAllocSharedSysMemoryKM(psPerProc,
+									 psAllocSharedSysMemIN->ui32Flags,
+									 psAllocSharedSysMemIN->ui32Size,
+									 &psKernelMemInfo);
+	if(psAllocSharedSysMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo,
+			0,
+			sizeof(psAllocSharedSysMemOUT->sClientMemInfo));
+
+	psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM =
+			psKernelMemInfo->pvLinAddrKM;
+
+	psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = 0;
+	psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags =
+		psKernelMemInfo->ui32Flags;
+	psAllocSharedSysMemOUT->sClientMemInfo.uAllocSize =
+		psKernelMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+	if (psKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+	{
+		PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+							&psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo,
+							psKernelMemInfo->sMemBlk.hOSMemHandle,
+							PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
+							PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+	}
+	else
+	{
+		psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = 0;
+	}
+#else
+	psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo,
+					  psKernelMemInfo,
+					  PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc)
+
+	return 0;
+}
+
+static IMG_INT
+PVRSRVFreeSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
+							PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM *psFreeSharedSysMemIN,
+							PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM *psFreeSharedSysMemOUT,
+							PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM);
+
+	psFreeSharedSysMemOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   (IMG_VOID **)&psKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+						   psFreeSharedSysMemIN->hKernelMemInfo,
+#else
+						   psFreeSharedSysMemIN->psKernelMemInfo,
+#endif
+						   PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+
+	if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
+		return 0;
+
+	psFreeSharedSysMemOUT->eError =
+		PVRSRVFreeSharedSysMemoryKM(psKernelMemInfo);
+	if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
+		return 0;
+#if defined (SUPPORT_SID_INTERFACE)
+	if (psFreeSharedSysMemIN->hMappingInfo != 0)
+	{
+		psFreeSharedSysMemOUT->eError =
+			PVRSRVReleaseHandle(psPerProc->psHandleBase,
+								psFreeSharedSysMemIN->hMappingInfo,
+								PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+		if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+#endif
+
+	psFreeSharedSysMemOUT->eError =
+		PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							psFreeSharedSysMemIN->hKernelMemInfo,
+#else
+							psFreeSharedSysMemIN->psKernelMemInfo,
+#endif
+							PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+	return 0;
+}
+
+static IMG_INT
+PVRSRVMapMemInfoMemBW(IMG_UINT32 ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM *psMapMemInfoMemIN,
+					  PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM *psMapMemInfoMemOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+	PVRSRV_HANDLE_TYPE eHandleType;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID     hParent;
+#else
+	IMG_HANDLE  hParent;
+#endif
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_MEMINFO_MEM);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc, 2)
+
+	psMapMemInfoMemOUT->eError =
+		PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
+						   (IMG_VOID **)&psKernelMemInfo,
+						   &eHandleType,
+						   psMapMemInfoMemIN->hKernelMemInfo);
+	if(psMapMemInfoMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	switch (eHandleType)
+	{
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+		case PVRSRV_HANDLE_TYPE_MEM_INFO:
+		case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
+		case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
+#else
+		case PVRSRV_HANDLE_TYPE_NONE:
+#endif
+			break;
+		default:
+			psMapMemInfoMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE;
+			return 0;
+	}
+
+
+	psMapMemInfoMemOUT->eError =
+		PVRSRVGetParentHandle(psPerProc->psHandleBase,
+					&hParent,
+					psMapMemInfoMemIN->hKernelMemInfo,
+					eHandleType);
+	if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+#if defined (SUPPORT_SID_INTERFACE)
+	if (hParent == 0)
+#else
+	if (hParent == IMG_NULL)
+#endif
+	{
+		hParent = psMapMemInfoMemIN->hKernelMemInfo;
+	}
+
+	OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo,
+			0,
+			sizeof(psMapMemInfoMemOUT->sClientMemInfo));
+
+	psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM =
+			psKernelMemInfo->pvLinAddrKM;
+
+	psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = 0;
+	psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr =
+		psKernelMemInfo->sDevVAddr;
+	psMapMemInfoMemOUT->sClientMemInfo.ui32Flags =
+		psKernelMemInfo->ui32Flags;
+	psMapMemInfoMemOUT->sClientMemInfo.uAllocSize =
+		psKernelMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+	if (psKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+	{
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+						&psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo,
+						psKernelMemInfo->sMemBlk.hOSMemHandle,
+						PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+						PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+						hParent);
+	}
+	else
+	{
+		psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = 0;
+	}
+#else
+	psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+					  &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo,
+					  psKernelMemInfo,
+					  PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+					  PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+					  hParent);
+
+	if(psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
+	{
+
+		OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo,
+				0,
+				sizeof (PVRSRV_CLIENT_SYNC_INFO));
+	}
+	else
+	{
+
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+		psMapMemInfoMemOUT->sClientSyncInfo.psSyncData =
+			psKernelMemInfo->psKernelSyncInfo->psSyncData;
+		psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+			psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+		psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+			psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+		if (psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+		{
+			PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+								&psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo,
+								psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+								PVRSRV_HANDLE_TYPE_SYNC_INFO,
+								PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+								psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
+		}
+		else
+		{
+			psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo = 0;
+		}
+#else
+		psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo =
+			psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+		psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo = &psMapMemInfoMemOUT->sClientSyncInfo;
+
+		PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+							 &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo,
+							 psKernelMemInfo->psKernelSyncInfo,
+							 PVRSRV_HANDLE_TYPE_SYNC_INFO,
+							 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+							 psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
+	}
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc)
+
+	return 0;
+}
+
+IMG_INT
+DummyBW(IMG_UINT32 ui32BridgeID,
+		IMG_VOID *psBridgeIn,
+		IMG_VOID *psBridgeOut,
+		PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+#if !defined(DEBUG)
+	PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+#endif
+	PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+	PVR_UNREFERENCED_PARAMETER(psBridgeOut);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+#if defined(DEBUG_BRIDGE_KM)
+	PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u (%s) mapped to "
+			 "Dummy Wrapper (probably not what you want!)",
+			 __FUNCTION__, ui32BridgeID, g_BridgeDispatchTable[ui32BridgeID].pszIOCName));
+#else
+	PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u mapped to "
+			 "Dummy Wrapper (probably not what you want!)",
+			 __FUNCTION__, ui32BridgeID));
+#endif
+	return -ENOTTY;
+}
+
+
+IMG_VOID
+_SetDispatchTableEntry(IMG_UINT32 ui32Index,
+                       const IMG_CHAR *pszIOCName,
+                       BridgeWrapperFunction pfFunction,
+                       const IMG_CHAR *pszFunctionName,
+		       size_t in_size, size_t out_size)
+{
+	static IMG_UINT32 ui32PrevIndex = ~0UL;     
+#if !defined(DEBUG)
+	PVR_UNREFERENCED_PARAMETER(pszIOCName);
+#endif
+#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM)
+	PVR_UNREFERENCED_PARAMETER(pszFunctionName);
+#endif
+
+#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE)
+
+	PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s", __FUNCTION__, ui32Index, pszIOCName, pszFunctionName));
+#endif
+
+
+	if(g_BridgeDispatchTable[ui32Index].pfFunction)
+	{
+#if defined(DEBUG_BRIDGE_KM)
+		PVR_DPF((PVR_DBG_ERROR,
+				 "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry for %s",
+				 __FUNCTION__, pszIOCName, g_BridgeDispatchTable[ui32Index].pszIOCName));
+#else
+		PVR_DPF((PVR_DBG_ERROR,
+				 "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry (index=%u)",
+				 __FUNCTION__, pszIOCName, ui32Index));
+#endif
+		PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
+	}
+
+
+	if((ui32PrevIndex != ~0UL) &&
+	   ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) ||
+		(ui32Index <= ui32PrevIndex)))
+	{
+#if defined(DEBUG_BRIDGE_KM)
+		PVR_DPF((PVR_DBG_WARNING,
+				 "%s: There is a gap in the dispatch table between indices %u (%s) and %u (%s)",
+				 __FUNCTION__, ui32PrevIndex, g_BridgeDispatchTable[ui32PrevIndex].pszIOCName,
+				 ui32Index, pszIOCName));
+#else
+		PVR_DPF((PVR_DBG_WARNING,
+				 "%s: There is a gap in the dispatch table between indices %u and %u (%s)",
+				 __FUNCTION__, (IMG_UINT)ui32PrevIndex, (IMG_UINT)ui32Index, pszIOCName));
+#endif
+		PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
+	}
+
+	g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction;
+	g_BridgeDispatchTable[ui32Index].in_size = in_size;
+	g_BridgeDispatchTable[ui32Index].out_size = out_size;
+#if defined(DEBUG_BRIDGE_KM)
+	g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName;
+	g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName;
+	g_BridgeDispatchTable[ui32Index].ui32CallCount = 0;
+	g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0;
+#endif
+
+	ui32PrevIndex = ui32Index;
+}
+
+static IMG_INT
+PVRSRVInitSrvConnectBW(IMG_UINT32 ui32BridgeID,
+					   IMG_VOID *psBridgeIn,
+					   PVRSRV_BRIDGE_RETURN *psRetOUT,
+					   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT);
+	PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+
+	if((OSProcHasPrivSrvInit() == IMG_FALSE) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
+	{
+		psRetOUT->eError = PVRSRV_ERROR_SRV_CONNECT_FAILED;
+		return 0;
+	}
+
+#if defined (__linux__) || defined(__QNXNTO__)
+	PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE);
+#endif
+	psPerProc->bInitProcess = IMG_TRUE;
+
+	psRetOUT->eError = PVRSRV_OK;
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVInitSrvDisconnectBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN,
+						  PVRSRV_BRIDGE_RETURN *psRetOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_DISCONNECT);
+
+	if(!psPerProc->bInitProcess)
+	{
+		psRetOUT->eError = PVRSRV_ERROR_SRV_DISCONNECT_FAILED;
+		return 0;
+	}
+
+	psPerProc->bInitProcess = IMG_FALSE;
+
+	PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE);
+	PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE);
+
+	psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful);
+
+	PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL ,
+				((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful))
+				? IMG_TRUE : IMG_FALSE);
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVEventObjectWaitBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN,
+						  PVRSRV_BRIDGE_RETURN *psRetOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hOSEventKM;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT);
+
+	psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hOSEventKM,
+						   psEventObjectWaitIN->hOSEventKM,
+						   PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError = OSEventObjectWaitKM(hOSEventKM);
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVEventObjectOpenBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN,
+						  PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_EVENTOBJECT_KM sEventObject;
+	IMG_HANDLE hOSEvent;
+#endif
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1)
+
+	psEventObjectOpenOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &sEventObject.hOSEventKM,
+#else
+						   &psEventObjectOpenIN->sEventObject.hOSEventKM,
+#endif
+						   psEventObjectOpenIN->sEventObject.hOSEventKM,
+						   PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
+
+	if(psEventObjectOpenOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	OSMemCopy(&sEventObject.szName,
+			  &psEventObjectOpenIN->sEventObject.szName,
+			  EVENTOBJNAME_MAXLENGTH);
+
+	psEventObjectOpenOUT->eError = OSEventObjectOpenKM(&sEventObject, &hOSEvent);
+#else
+	psEventObjectOpenOUT->eError = OSEventObjectOpenKM(&psEventObjectOpenIN->sEventObject, &psEventObjectOpenOUT->hOSEvent);
+#endif
+
+	if(psEventObjectOpenOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+						&psEventObjectOpenOUT->hOSEvent,
+						hOSEvent,
+						PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+						PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
+#else
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psEventObjectOpenOUT->hOSEvent,
+					  psEventObjectOpenOUT->hOSEvent,
+					  PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+					  PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
+#endif
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc)
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVEventObjectCloseBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN,
+						  PVRSRV_BRIDGE_RETURN *psRetOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hOSEventKM;
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_EVENTOBJECT_KM sEventObject;
+#endif
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &sEventObject.hOSEventKM,
+#else
+						   &psEventObjectCloseIN->sEventObject.hOSEventKM,
+#endif
+						   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;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	if(CopyFromUserWrapper(psPerProc, ui32BridgeID,
+							&sEventObject.szName,
+							&psEventObjectCloseIN->sEventObject.szName,
+							EVENTOBJNAME_MAXLENGTH) != PVRSRV_OK)
+	{
+
+		return -EFAULT;
+	}
+
+	psRetOUT->eError = OSEventObjectCloseKM(&sEventObject, hOSEventKM);
+#else
+	psRetOUT->eError = OSEventObjectCloseKM(&psEventObjectCloseIN->sEventObject, hOSEventKM);
+#endif
+
+	return 0;
+}
+
+
+typedef struct _MODIFY_SYNC_OP_INFO
+{
+	IMG_HANDLE  hResItem;
+	PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+	IMG_UINT32  ui32ModifyFlags;
+	IMG_UINT32  ui32ReadOpsPendingSnapShot;
+	IMG_UINT32  ui32WriteOpsPendingSnapShot;
+} MODIFY_SYNC_OP_INFO;
+
+
+static PVRSRV_ERROR DoQuerySyncOpsSatisfied(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+                                            IMG_UINT32 ui32ReadOpsPendingSnapShot,
+                                            IMG_UINT32 ui32WriteOpsPendingSnapShot)
+{
+	IMG_UINT32 ui32WriteOpsPending;
+	IMG_UINT32 ui32ReadOpsPending;
+
+
+	if (!psKernelSyncInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+
+
+
+
+
+
+
+
+
+
+	ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+	ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+
+	if((ui32WriteOpsPending - ui32WriteOpsPendingSnapShot >=
+		ui32WriteOpsPending - psKernelSyncInfo->psSyncData->ui32WriteOpsComplete) &&
+	   (ui32ReadOpsPending - ui32ReadOpsPendingSnapShot >=
+			 ui32ReadOpsPending - psKernelSyncInfo->psSyncData->ui32ReadOpsComplete))
+	{
+#if defined(PDUMP) && !defined(SUPPORT_VGX)
+
+		PDumpComment("Poll for read ops complete to reach value (pdump: %u, actual snapshot: %u)",
+					 psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					 ui32ReadOpsPendingSnapShot);
+		PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
+					  offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+					  psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					  0xFFFFFFFF,
+					  PDUMP_POLL_OPERATOR_EQUAL, 
+					  0,
+					  MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
+
+
+		PDumpComment("Poll for write ops complete to reach value (pdump: %u, actual snapshot: %u)",
+					 psKernelSyncInfo->psSyncData->ui32LastOpDumpVal,
+					 ui32WriteOpsPendingSnapShot);
+		PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
+					  offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+					  psKernelSyncInfo->psSyncData->ui32LastOpDumpVal,
+					  0xFFFFFFFF,
+					  PDUMP_POLL_OPERATOR_EQUAL, 
+					  0,
+					  MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
+
+
+#endif
+		return PVRSRV_OK;
+	}
+	else
+	{
+		return PVRSRV_ERROR_RETRY;
+	}
+}
+
+
+static PVRSRV_ERROR DoModifyCompleteSyncOps(MODIFY_SYNC_OP_INFO *psModSyncOpInfo)
+{
+	PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+
+	psKernelSyncInfo = psModSyncOpInfo->psKernelSyncInfo;
+
+	if (!psKernelSyncInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+
+	if((psModSyncOpInfo->ui32WriteOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32WriteOpsComplete)
+	   || (psModSyncOpInfo->ui32ReadOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32ReadOpsComplete))
+	{
+		return PVRSRV_ERROR_BAD_SYNC_STATE;
+	}
+
+
+	if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
+	{
+		psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++;
+	}
+
+
+	if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
+	{
+		psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR ModifyCompleteSyncOpsCallBack(IMG_PVOID		pvParam,
+                                                    IMG_UINT32  ui32Param,
+                                                    IMG_BOOL    bDummy)
+{
+	MODIFY_SYNC_OP_INFO     *psModSyncOpInfo;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	if (!pvParam)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: invalid parameter"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psModSyncOpInfo = (MODIFY_SYNC_OP_INFO*)pvParam;
+
+	if (psModSyncOpInfo->psKernelSyncInfo)
+	{
+
+		LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+		{
+			if (DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo,
+										psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
+						psModSyncOpInfo->ui32WriteOpsPendingSnapShot) == PVRSRV_OK)
+			{
+				goto OpFlushedComplete;
+			}
+			PVR_DPF((PVR_DBG_WARNING, "ModifyCompleteSyncOpsCallBack: waiting for current Ops to flush"));
+			OSSleepms(1);
+		} END_LOOP_UNTIL_TIMEOUT();
+
+		PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: timeout whilst waiting for current Ops to flush."));
+		PVR_DPF((PVR_DBG_ERROR, "  Write ops pending snapshot = %d, write ops complete = %d",
+				 psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
+				 psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32WriteOpsComplete));
+		PVR_DPF((PVR_DBG_ERROR, "  Read ops pending snapshot = %d, write ops complete = %d",
+				 psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
+				 psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOpsComplete));
+
+		return PVRSRV_ERROR_TIMEOUT;
+
+OpFlushedComplete:
+
+		DoModifyCompleteSyncOps(psModSyncOpInfo);
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,  sizeof(MODIFY_SYNC_OP_INFO), (IMG_VOID *)psModSyncOpInfo, 0);
+
+
+
+	PVRSRVScheduleDeviceCallbacks();
+
+	return PVRSRV_OK;
+}
+
+
+static IMG_INT
+PVRSRVCreateSyncInfoModObjBW(IMG_UINT32                                         ui32BridgeID,
+									 IMG_VOID                                           *psBridgeIn,
+									 PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ  *psCreateSyncInfoModObjOUT,
+									 PVRSRV_PER_PROCESS_DATA		   		            *psPerProc)
+{
+	MODIFY_SYNC_OP_INFO     *psModSyncOpInfo;
+
+	PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc, 1)
+
+	ASSIGN_AND_EXIT_ON_ERROR(psCreateSyncInfoModObjOUT->eError,
+			  OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+			  sizeof(MODIFY_SYNC_OP_INFO),
+			  (IMG_VOID **)&psModSyncOpInfo, 0,
+			  "ModSyncOpInfo (MODIFY_SYNC_OP_INFO)"));
+
+	psModSyncOpInfo->psKernelSyncInfo = IMG_NULL; 
+
+	psCreateSyncInfoModObjOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+																  &psCreateSyncInfoModObjOUT->hKernelSyncInfoModObj,
+																  psModSyncOpInfo,
+																  PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ,
+																  PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
+
+	if (psCreateSyncInfoModObjOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psModSyncOpInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+												  RESMAN_TYPE_MODIFY_SYNC_OPS,
+												  psModSyncOpInfo,
+												  0,
+												  &ModifyCompleteSyncOpsCallBack);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc)
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVDestroySyncInfoModObjBW(IMG_UINT32                                          ui32BridgeID,
+							  PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ          *psDestroySyncInfoModObjIN,
+							  PVRSRV_BRIDGE_RETURN                                *psDestroySyncInfoModObjOUT,
+							  PVRSRV_PER_PROCESS_DATA		   		              *psPerProc)
+{
+	MODIFY_SYNC_OP_INFO     *psModSyncOpInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ);
+
+	psDestroySyncInfoModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+																	(IMG_VOID**)&psModSyncOpInfo,
+																	psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
+																	PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+	if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVLookupHandle failed"));
+		return 0;
+	}
+
+	if(psModSyncOpInfo->psKernelSyncInfo != IMG_NULL)
+	{
+
+		psDestroySyncInfoModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		return 0;
+	}
+
+	psDestroySyncInfoModObjOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+																	 psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
+																	 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+
+	if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVReleaseHandle failed"));
+		return 0;
+	}
+
+	psDestroySyncInfoModObjOUT->eError = ResManFreeResByPtr(psModSyncOpInfo->hResItem, CLEANUP_WITH_POLL);
+	if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: ResManFreeResByPtr failed"));
+		return 0;
+	}
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVModifyPendingSyncOpsBW(IMG_UINT32									ui32BridgeID,
+						      PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS	*psModifySyncOpsIN,
+							  PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS	*psModifySyncOpsOUT,
+							  PVRSRV_PER_PROCESS_DATA					*psPerProc)
+{
+	PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+	MODIFY_SYNC_OP_INFO     *psModSyncOpInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS);
+
+	psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+													(IMG_VOID**)&psModSyncOpInfo,
+													psModifySyncOpsIN->hKernelSyncInfoModObj,
+													PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+	if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
+		return 0;
+	}
+
+	psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+													(IMG_VOID**)&psKernelSyncInfo,
+													psModifySyncOpsIN->hKernelSyncInfo,
+													PVRSRV_HANDLE_TYPE_SYNC_INFO);
+	if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
+		return 0;
+	}
+
+	if(psModSyncOpInfo->psKernelSyncInfo)
+	{
+
+		psModifySyncOpsOUT->eError = PVRSRV_ERROR_RETRY;
+		PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo Modification object is not empty"));
+		return 0;
+	}
+
+
+	psModSyncOpInfo->psKernelSyncInfo = psKernelSyncInfo;
+	psModSyncOpInfo->ui32ModifyFlags = psModifySyncOpsIN->ui32ModifyFlags;
+	psModSyncOpInfo->ui32ReadOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+	psModSyncOpInfo->ui32WriteOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+
+
+
+	psModifySyncOpsOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+	psModifySyncOpsOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+
+	if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
+	{
+		psKernelSyncInfo->psSyncData->ui32WriteOpsPending++;
+	}
+
+	if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
+	{
+		psKernelSyncInfo->psSyncData->ui32ReadOpsPending++;
+	}
+
+
+	psModifySyncOpsOUT->eError = ResManDissociateRes(psModSyncOpInfo->hResItem,
+													 psPerProc->hResManContext);
+
+	if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
+		return 0;
+	}
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVModifyCompleteSyncOpsBW(IMG_UINT32							ui32BridgeID,
+				      PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS		*psModifySyncOpsIN,
+					  PVRSRV_BRIDGE_RETURN							*psModifySyncOpsOUT,
+					  PVRSRV_PER_PROCESS_DATA						*psPerProc)
+{
+	MODIFY_SYNC_OP_INFO     *psModSyncOpInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS);
+
+	psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+													(IMG_VOID**)&psModSyncOpInfo,
+													psModifySyncOpsIN->hKernelSyncInfoModObj,
+													PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+	if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: PVRSRVLookupHandle failed"));
+		return 0;
+	}
+
+	if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
+	{
+
+		psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		return 0;
+	}
+
+	psModifySyncOpsOUT->eError = DoModifyCompleteSyncOps(psModSyncOpInfo);
+
+	if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: DoModifyCompleteSyncOps failed"));
+		return 0;
+	}
+
+	psModSyncOpInfo->psKernelSyncInfo = IMG_NULL;
+
+
+	PVRSRVScheduleDeviceCallbacks();
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsTakeTokenBW(IMG_UINT32									ui32BridgeID,
+						 PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN       *psSyncOpsTakeTokenIN,
+						 PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN      *psSyncOpsTakeTokenOUT,
+						 PVRSRV_PER_PROCESS_DATA					*psPerProc)
+{
+	PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN);
+
+	psSyncOpsTakeTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+													   (IMG_VOID**)&psKernelSyncInfo,
+													   psSyncOpsTakeTokenIN->hKernelSyncInfo,
+													   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+	if (psSyncOpsTakeTokenOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsTakeTokenBW: PVRSRVLookupHandle failed"));
+		return 0;
+	}
+
+
+
+	psSyncOpsTakeTokenOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+	psSyncOpsTakeTokenOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsFlushToTokenBW(IMG_UINT32                                         ui32BridgeID,
+							PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN		   *psSyncOpsFlushToTokenIN,
+							PVRSRV_BRIDGE_RETURN						       *psSyncOpsFlushToTokenOUT,
+							PVRSRV_PER_PROCESS_DATA		   		               *psPerProc)
+{
+	PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+	IMG_UINT32 ui32ReadOpsPendingSnapshot;
+	IMG_UINT32 ui32WriteOpsPendingSnapshot;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN);
+
+	psSyncOpsFlushToTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+														  (IMG_VOID**)&psKernelSyncInfo,
+														  psSyncOpsFlushToTokenIN->hKernelSyncInfo,
+														  PVRSRV_HANDLE_TYPE_SYNC_INFO);
+	if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: PVRSRVLookupHandle failed"));
+		return 0;
+	}
+
+	ui32ReadOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32ReadOpsPendingSnapshot;
+	ui32WriteOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32WriteOpsPendingSnapshot;
+
+	psSyncOpsFlushToTokenOUT->eError = DoQuerySyncOpsSatisfied(psKernelSyncInfo,
+															   ui32ReadOpsPendingSnapshot,
+								ui32WriteOpsPendingSnapshot);
+
+	if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK && psSyncOpsFlushToTokenOUT->eError != PVRSRV_ERROR_RETRY)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: DoQuerySyncOpsSatisfied failed"));
+		return 0;
+	}
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsFlushToModObjBW(IMG_UINT32                                         ui32BridgeID,
+							 PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ		    *psSyncOpsFlushToModObjIN,
+							 PVRSRV_BRIDGE_RETURN						        *psSyncOpsFlushToModObjOUT,
+							 PVRSRV_PER_PROCESS_DATA		   		            *psPerProc)
+{
+	MODIFY_SYNC_OP_INFO     *psModSyncOpInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ);
+
+	psSyncOpsFlushToModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+														   (IMG_VOID**)&psModSyncOpInfo,
+														   psSyncOpsFlushToModObjIN->hKernelSyncInfoModObj,
+														   PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+	if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: PVRSRVLookupHandle failed"));
+		return 0;
+	}
+
+	if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
+	{
+
+		psSyncOpsFlushToModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		return 0;
+	}
+
+	psSyncOpsFlushToModObjOUT->eError = DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo,
+																psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
+								psModSyncOpInfo->ui32WriteOpsPendingSnapShot);
+
+	if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK && psSyncOpsFlushToModObjOUT->eError != PVRSRV_ERROR_RETRY)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: DoQuerySyncOpsSatisfied failed"));
+		return 0;
+	}
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsFlushToDeltaBW(IMG_UINT32                                         ui32BridgeID,
+							PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA		   *psSyncOpsFlushToDeltaIN,
+							PVRSRV_BRIDGE_RETURN						       *psSyncOpsFlushToDeltaOUT,
+							PVRSRV_PER_PROCESS_DATA		   		               *psPerProc)
+{
+	PVRSRV_KERNEL_SYNC_INFO     *psSyncInfo;
+	IMG_UINT32 ui32DeltaRead;
+	IMG_UINT32 ui32DeltaWrite;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA);
+
+	psSyncOpsFlushToDeltaOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+														  (IMG_VOID**)&psSyncInfo,
+														  psSyncOpsFlushToDeltaIN->hKernelSyncInfo,
+														  PVRSRV_HANDLE_TYPE_SYNC_INFO);
+	if (psSyncOpsFlushToDeltaOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToDeltaBW: PVRSRVLookupHandle failed"));
+		return 0;
+	}
+
+
+	ui32DeltaRead = psSyncInfo->psSyncData->ui32ReadOpsPending - psSyncInfo->psSyncData->ui32ReadOpsComplete;
+	ui32DeltaWrite = psSyncInfo->psSyncData->ui32WriteOpsPending - psSyncInfo->psSyncData->ui32WriteOpsComplete;
+
+	if (ui32DeltaRead <= psSyncOpsFlushToDeltaIN->ui32Delta && ui32DeltaWrite <= psSyncOpsFlushToDeltaIN->ui32Delta)
+	{
+#if defined(PDUMP) && !defined(SUPPORT_VGX)
+
+		PDumpComment("Poll for read ops complete to delta (%u)",
+					 psSyncOpsFlushToDeltaIN->ui32Delta);
+		psSyncOpsFlushToDeltaOUT->eError =
+			PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM,
+						  offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+						  psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+						  0xFFFFFFFF,
+						  PDUMP_POLL_OPERATOR_GREATEREQUAL,
+						  0,
+						  MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+
+
+		PDumpComment("Poll for write ops complete to delta (%u)",
+					 psSyncOpsFlushToDeltaIN->ui32Delta);
+		psSyncOpsFlushToDeltaOUT->eError =
+			PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM,
+						  offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+						  psSyncInfo->psSyncData->ui32LastOpDumpVal,
+						  0xFFFFFFFF,
+						  PDUMP_POLL_OPERATOR_GREATEREQUAL,
+						  0,
+						  MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+#endif
+
+		psSyncOpsFlushToDeltaOUT->eError = PVRSRV_OK;
+	}
+	else
+	{
+		psSyncOpsFlushToDeltaOUT->eError = PVRSRV_ERROR_RETRY;
+	}
+
+	return 0;
+}
+
+
+static PVRSRV_ERROR
+FreeSyncInfoCallback(IMG_PVOID pvParam,
+                     IMG_UINT32 ui32Param,
+                     IMG_BOOL	bDummy)
+{
+	PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+	PVRSRV_ERROR eError;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)pvParam;
+
+	eError = PVRSRVFreeSyncInfoKM(psSyncInfo);
+	if (eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static IMG_INT
+PVRSRVAllocSyncInfoBW(IMG_UINT32                                         ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO                  *psAllocSyncInfoIN,
+					  PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO                 *psAllocSyncInfoOUT,
+					  PVRSRV_PER_PROCESS_DATA		   		            *psPerProc)
+{
+	PVRSRV_KERNEL_SYNC_INFO     *psSyncInfo;
+	PVRSRV_ERROR eError;
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_HANDLE hDevMemContext;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SYNC_INFO);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psAllocSyncInfoOUT->eError, psPerProc, 1)
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								(IMG_HANDLE *)&psDeviceNode,
+								psAllocSyncInfoIN->hDevCookie,
+								PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(eError != PVRSRV_OK)
+	{
+		goto allocsyncinfo_errorexit;
+	}
+
+	hDevMemContext = psDeviceNode->sDevMemoryInfo.pBMKernelContext;
+
+	eError = PVRSRVAllocSyncInfoKM(psDeviceNode,
+								   hDevMemContext,
+								   &psSyncInfo);
+
+	if (eError != PVRSRV_OK)
+	{
+		goto allocsyncinfo_errorexit;
+	}
+
+	eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+							   &psAllocSyncInfoOUT->hKernelSyncInfo,
+							   psSyncInfo,
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO,
+							   PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
+
+	if(eError != PVRSRV_OK)
+	{
+		goto allocsyncinfo_errorexit_freesyncinfo;
+	}
+
+	psSyncInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+											   RESMAN_TYPE_SYNC_INFO,
+											   psSyncInfo,
+											   0,
+											   FreeSyncInfoCallback);
+
+
+	goto allocsyncinfo_commit;
+
+
+allocsyncinfo_errorexit_freesyncinfo:
+	PVRSRVFreeSyncInfoKM(psSyncInfo);
+
+allocsyncinfo_errorexit:
+
+
+allocsyncinfo_commit:
+	psAllocSyncInfoOUT->eError = eError;
+	COMMIT_HANDLE_BATCH_OR_ERROR(eError, psPerProc);
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVFreeSyncInfoBW(IMG_UINT32                                          ui32BridgeID,
+					 PVRSRV_BRIDGE_IN_FREE_SYNC_INFO                     *psFreeSyncInfoIN,
+					 PVRSRV_BRIDGE_RETURN                                *psFreeSyncInfoOUT,
+					 PVRSRV_PER_PROCESS_DATA		   		             *psPerProc)
+{
+	PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+	PVRSRV_ERROR eError;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SYNC_INFO);
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								(IMG_VOID**)&psSyncInfo,
+								psFreeSyncInfoIN->hKernelSyncInfo,
+								PVRSRV_HANDLE_TYPE_SYNC_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVLookupHandle failed"));
+		psFreeSyncInfoOUT->eError = eError;
+		return 0;
+	}
+
+	eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+								 psFreeSyncInfoIN->hKernelSyncInfo,
+								 PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVReleaseHandle failed"));
+		psFreeSyncInfoOUT->eError = eError;
+		return 0;
+	}
+
+	eError = ResManFreeResByPtr(psSyncInfo->hResItem, CLEANUP_WITH_POLL);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: ResManFreeResByPtr failed"));
+		psFreeSyncInfoOUT->eError = eError;
+		return 0;
+	}
+
+	return 0;
+}
+
+
+PVRSRV_ERROR
+CommonBridgeInit(IMG_VOID)
+{
+	IMG_UINT32 i;
+
+	PVR_IO_NSTD(ENUM_DEVICES, PVRSRVEnumerateDevicesBW, 0, sizeof(PVRSRV_BRIDGE_OUT_ENUMDEVICE));
+	PVR_IO_RW(ACQUIRE_DEVICEINFO, PVRSRVAcquireDeviceDataBW);
+	PVR_IO_INV(RELEASE_DEVICEINFO);
+	PVR_IO_RW(CREATE_DEVMEMCONTEXT, PVRSRVCreateDeviceMemContextBW);
+	PVR_IO_W(DESTROY_DEVMEMCONTEXT, PVRSRVDestroyDeviceMemContextBW);
+	PVR_IO_RW(GET_DEVMEM_HEAPINFO, PVRSRVGetDeviceMemHeapInfoBW);
+	PVR_IO_NSTD(ALLOC_DEVICEMEM, PVRSRVAllocDeviceMemBW,
+			sizeof(PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM),
+			sizeof(PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM));
+
+	PVR_IO_NSTD(FREE_DEVICEMEM, PVRSRVFreeDeviceMemBW,
+			sizeof(PVRSRV_BRIDGE_IN_FREEDEVICEMEM),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+
+	PVR_IO_NSTD(GETFREE_DEVICEMEM, PVRSRVGetFreeDeviceMemBW,
+			sizeof(PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM),
+			sizeof(PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM));
+	PVR_IO_INV(CREATE_COMMANDQUEUE);
+	PVR_IO_INV(DESTROY_COMMANDQUEUE);
+	PVR_IO_RW(MHANDLE_TO_MMAP_DATA, PVRMMapOSMemHandleToMMapDataBW);
+	PVR_IO_RW(CONNECT_SERVICES, PVRSRVConnectBW);
+	PVR_IO_NSTD(DISCONNECT_SERVICES, PVRSRVDisconnectBW,
+			0, sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_INV(WRAP_DEVICE_MEM);
+	PVR_IO_INV(GET_DEVICEMEMINFO);
+	PVR_IO_INV(RESERVE_DEV_VIRTMEM);
+	PVR_IO_INV(FREE_DEV_VIRTMEM);
+	PVR_IO_INV(MAP_EXT_MEMORY);
+	PVR_IO_INV(UNMAP_EXT_MEMORY);
+	PVR_IO_RW(MAP_DEV_MEMORY, PVRSRVMapDeviceMemoryBW);
+	PVR_IO_W(UNMAP_DEV_MEMORY, PVRSRVUnmapDeviceMemoryBW);
+	PVR_IO_RW(MAP_DEVICECLASS_MEMORY, PVRSRVMapDeviceClassMemoryBW);
+	PVR_IO_W(UNMAP_DEVICECLASS_MEMORY, PVRSRVUnmapDeviceClassMemoryBW);
+	PVR_IO_INV(MAP_MEM_INFO_TO_USER);
+	PVR_IO_INV(UNMAP_MEM_INFO_FROM_USER);
+	PVR_IO_NSTD(EXPORT_DEVICEMEM, PVRSRVExportDeviceMemBW,
+			sizeof(PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM),
+			sizeof(PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM));
+	PVR_IO_RW(RELEASE_MMAP_DATA, PVRMMapReleaseMMapDataBW);
+
+	PVR_IO_W(CHG_DEV_MEM_ATTRIBS, PVRSRVChangeDeviceMemoryAttributesBW);
+	PVR_IO_NSTD(MAP_DEV_MEMORY_2, PVRSRVMapDeviceMemoryBW,
+			sizeof(PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY),
+			sizeof(PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY));
+	PVR_IO_NSTD(EXPORT_DEVICEMEM_2, PVRSRVExportDeviceMemBW,
+			sizeof(PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM),
+			sizeof(PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM));
+
+	PVR_IO_INV(PROCESS_SIMISR_EVENT);
+	PVR_IO_INV(REGISTER_SIM_PROCESS);
+	PVR_IO_INV(UNREGISTER_SIM_PROCESS);
+	PVR_IO_INV(MAPPHYSTOUSERSPACE);
+	PVR_IO_INV(UNMAPPHYSTOUSERSPACE);
+	PVR_IO_INV(GETPHYSTOUSERSPACEMAP);
+	PVR_IO_INV(GET_FB_STATS);
+	PVR_IO_RW(GET_MISC_INFO, PVRSRVGetMiscInfoBW);
+	PVR_IO_INV(RELEASE_MISC_INFO);
+
+#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
+	PVR_IO_INV(INIT_3D_OVL_BLT_RES);
+	PVR_IO_INV(DEINIT_3D_OVL_BLT_RES);
+#endif
+
+
+
+#if defined(PDUMP)
+	PVR_IO_INV(PDUMP_INIT);
+	PVR_IO_W(PDUMP_MEMPOL, PDumpMemPolBW);
+	PVR_IO_W(PDUMP_DUMPMEM, PDumpMemBW);
+	PVR_IO_NSTD(PDUMP_REG, PDumpRegWithFlagsBW,
+			sizeof(PVRSRV_BRIDGE_IN_PDUMP_DUMPREG),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_W(PDUMP_REGPOL, PDumpRegPolBW);
+	PVR_IO_W(PDUMP_COMMENT, PDumpCommentBW);
+	PVR_IO_W(PDUMP_SETFRAME, PDumpSetFrameBW);
+	PVR_IO_R(PDUMP_ISCAPTURING, PDumpIsCaptureFrameBW);
+	PVR_IO_NSTD(PDUMP_DUMPBITMAP, PDumpBitmapBW,
+			sizeof(PVRSRV_BRIDGE_IN_PDUMP_BITMAP),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(PDUMP_DUMPREADREG, PDumpReadRegBW,
+			sizeof(PVRSRV_BRIDGE_IN_PDUMP_READREG),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_W(PDUMP_SYNCPOL, PDumpSyncPolBW);
+	PVR_IO_W(PDUMP_DUMPSYNC, PDumpSyncDumpBW);
+	PVR_IO_W(PDUMP_MEMPAGES, PDumpMemPagesBW);
+	PVR_IO_W(PDUMP_DRIVERINFO, PDumpDriverInfoBW);
+	PVR_IO_W(PDUMP_DUMPPDDEVPADDR, PDumpPDDevPAddrBW);
+	PVR_IO_W(PDUMP_CYCLE_COUNT_REG_READ, PDumpCycleCountRegReadBW);
+	PVR_IO_NSTD(PDUMP_STARTINITPHASE, PDumpStartInitPhaseBW,
+			0, sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(PDUMP_STOPINITPHASE, PDumpStopInitPhaseBW,
+			0, sizeof(PVRSRV_BRIDGE_RETURN));
+#endif 
+
+	PVR_IO_INV(GET_OEMJTABLE);
+	PVR_IO_NSTD(ENUM_CLASS, PVRSRVEnumerateDCBW,
+			sizeof(PVRSRV_BRIDGE_IN_ENUMCLASS),
+			sizeof(PVRSRV_BRIDGE_OUT_ENUMCLASS));
+	PVR_IO_RW(OPEN_DISPCLASS_DEVICE, PVRSRVOpenDCDeviceBW);
+	PVR_IO_W(CLOSE_DISPCLASS_DEVICE, PVRSRVCloseDCDeviceBW);
+	PVR_IO_RW(ENUM_DISPCLASS_FORMATS, PVRSRVEnumDCFormatsBW);
+	PVR_IO_RW(ENUM_DISPCLASS_DIMS, PVRSRVEnumDCDimsBW);
+	PVR_IO_RW(GET_DISPCLASS_SYSBUFFER, PVRSRVGetDCSystemBufferBW);
+	PVR_IO_RW(GET_DISPCLASS_INFO, PVRSRVGetDCInfoBW);
+	PVR_IO_RW(CREATE_DISPCLASS_SWAPCHAIN, PVRSRVCreateDCSwapChainBW);
+	PVR_IO_W(DESTROY_DISPCLASS_SWAPCHAIN, PVRSRVDestroyDCSwapChainBW);
+	PVR_IO_NSTD(SET_DISPCLASS_DSTRECT, PVRSRVSetDCDstRectBW,
+			sizeof(PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SET_DISPCLASS_SRCRECT, PVRSRVSetDCSrcRectBW,
+			sizeof(PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SET_DISPCLASS_DSTCOLOURKEY, PVRSRVSetDCDstColourKeyBW,
+			sizeof(PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SET_DISPCLASS_SRCCOLOURKEY, PVRSRVSetDCSrcColourKeyBW,
+			sizeof(PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_RW(GET_DISPCLASS_BUFFERS, PVRSRVGetDCBuffersBW);
+	PVR_IO_W(SWAP_DISPCLASS_TO_BUFFER, PVRSRVSwapToDCBufferBW);
+	PVR_IO_W(SWAP_DISPCLASS_TO_SYSTEM, PVRSRVSwapToDCSystemBW);
+	PVR_IO_RW(OPEN_BUFFERCLASS_DEVICE, PVRSRVOpenBCDeviceBW);
+	PVR_IO_W(CLOSE_BUFFERCLASS_DEVICE, PVRSRVCloseBCDeviceBW);
+	PVR_IO_RW(GET_BUFFERCLASS_INFO, PVRSRVGetBCInfoBW);
+	PVR_IO_RW(GET_BUFFERCLASS_BUFFER, PVRSRVGetBCBufferBW);
+	PVR_IO_RW(WRAP_EXT_MEMORY, PVRSRVWrapExtMemoryBW);
+	PVR_IO_W(UNWRAP_EXT_MEMORY, PVRSRVUnwrapExtMemoryBW);
+	PVR_IO_RW(ALLOC_SHARED_SYS_MEM, PVRSRVAllocSharedSysMemoryBW);
+	PVR_IO_RW(FREE_SHARED_SYS_MEM, PVRSRVFreeSharedSysMemoryBW);
+	PVR_IO_RW(MAP_MEMINFO_MEM, PVRSRVMapMemInfoMemBW);
+
+	PVR_IO_NSTD(INITSRV_CONNECT, PVRSRVInitSrvConnectBW,
+			0, sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_W(INITSRV_DISCONNECT, PVRSRVInitSrvDisconnectBW);
+	PVR_IO_W(EVENT_OBJECT_WAIT, PVRSRVEventObjectWaitBW);
+	PVR_IO_RW(EVENT_OBJECT_OPEN, PVRSRVEventObjectOpenBW);
+	PVR_IO_W(EVENT_OBJECT_CLOSE, PVRSRVEventObjectCloseBW);
+	PVR_IO_NSTD(CREATE_SYNC_INFO_MOD_OBJ, PVRSRVCreateSyncInfoModObjBW,
+			0, sizeof(PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ));
+	PVR_IO_W(DESTROY_SYNC_INFO_MOD_OBJ, PVRSRVDestroySyncInfoModObjBW);
+	PVR_IO_RW(MODIFY_PENDING_SYNC_OPS, PVRSRVModifyPendingSyncOpsBW);
+	PVR_IO_W(MODIFY_COMPLETE_SYNC_OPS, PVRSRVModifyCompleteSyncOpsBW);
+	PVR_IO_RW(SYNC_OPS_TAKE_TOKEN, PVRSRVSyncOpsTakeTokenBW);
+	PVR_IO_W(SYNC_OPS_FLUSH_TO_TOKEN, PVRSRVSyncOpsFlushToTokenBW);
+	PVR_IO_W(SYNC_OPS_FLUSH_TO_MOD_OBJ, PVRSRVSyncOpsFlushToModObjBW);
+	PVR_IO_W(SYNC_OPS_FLUSH_TO_DELTA, PVRSRVSyncOpsFlushToDeltaBW);
+	PVR_IO_RW(ALLOC_SYNC_INFO, PVRSRVAllocSyncInfoBW);
+	PVR_IO_W(FREE_SYNC_INFO, PVRSRVFreeSyncInfoBW);
+
+#if defined (SUPPORT_SGX)
+	SetSGXDispatchTableEntry();
+#endif
+#if defined (SUPPORT_VGX)
+	SetVGXDispatchTableEntry();
+#endif
+#if defined (SUPPORT_MSVDX)
+	SetMSVDXDispatchTableEntry();
+#endif
+
+
+
+
+	for(i=0;i<BRIDGE_DISPATCH_TABLE_ENTRY_COUNT;i++)
+	{
+		if(!g_BridgeDispatchTable[i].pfFunction)
+		{
+			g_BridgeDispatchTable[i].pfFunction = &DummyBW;
+#if defined(DEBUG_BRIDGE_KM)
+			g_BridgeDispatchTable[i].pszIOCName = "_PVRSRV_BRIDGE_DUMMY";
+			g_BridgeDispatchTable[i].pszFunctionName = "DummyBW";
+			g_BridgeDispatchTable[i].ui32CallCount = 0;
+			g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0;
+			g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0;
+#endif
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
+					  PVRSRV_BRIDGE_PACKAGE   * psBridgePackageKM)
+{
+
+	IMG_VOID   * psBridgeIn;
+	IMG_VOID   * psBridgeOut;
+	BridgeWrapperFunction pfBridgeHandler;
+	PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *dte;
+	IMG_UINT32   ui32BridgeID = psBridgePackageKM->ui32BridgeID;
+	IMG_INT      err          = -EFAULT;
+
+	if(ui32BridgeID >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: ui32BridgeID = %d is out if range!",
+					__FUNCTION__, ui32BridgeID));
+		goto return_fault;
+	}
+
+	dte = &g_BridgeDispatchTable[ui32BridgeID];
+
+#if defined(DEBUG_TRACE_BRIDGE_KM)
+	PVR_DPF((PVR_DBG_ERROR, "%s: %s",
+			 __FUNCTION__,
+			 dte->pszIOCName));
+#endif
+
+#if defined(DEBUG_BRIDGE_KM)
+	dte->ui32CallCount++;
+	g_BridgeGlobalStats.ui32IOCTLCount++;
+#endif
+
+	if (psBridgePackageKM->ui32InBufferSize != dte->in_size ||
+			psBridgePackageKM->ui32OutBufferSize != dte->out_size) {
+		PVR_DPF((PVR_DBG_ERROR, "pvr: invalid param size for IOCTL#%d:\n"
+					"     kern/user in,out: %d/%d,%d/%d\n",
+					ui32BridgeID,
+					dte->in_size, psBridgePackageKM->ui32InBufferSize,
+					dte->out_size, psBridgePackageKM->ui32OutBufferSize));
+		err = -EINVAL;
+		goto return_fault;
+	}
+
+	if(!psPerProc->bInitProcess)
+	{
+		if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
+		{
+			if(!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed.  Driver unusable.",
+							__FUNCTION__));
+				goto return_fault;
+			}
+		}
+		else
+		{
+			if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING))
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation is in progress",
+							__FUNCTION__));
+				goto return_fault;
+			}
+			else
+			{
+
+				switch(ui32BridgeID)
+				{
+					case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_CONNECT_SERVICES):
+					case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_DISCONNECT_SERVICES):
+					case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_CONNECT):
+					case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_DISCONNECT):
+						break;
+					default:
+						PVR_DPF((PVR_DBG_ERROR, "%s: Driver initialisation not completed yet.",
+								 __FUNCTION__));
+						goto return_fault;
+				}
+			}
+		}
+	}
+
+
+
+#if defined(__linux__)
+	{
+
+		SYS_DATA *psSysData;
+
+		SysAcquireData(&psSysData);
+
+
+		psBridgeIn = ((ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData;
+		psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE);
+
+
+		if((psBridgePackageKM->ui32InBufferSize > PVRSRV_MAX_BRIDGE_IN_SIZE) || 
+				(psBridgePackageKM->ui32OutBufferSize > PVRSRV_MAX_BRIDGE_OUT_SIZE))
+		{
+			goto return_fault;
+		}
+
+
+		if(psBridgePackageKM->ui32InBufferSize > 0)
+		{
+			if(!OSAccessOK(PVR_VERIFY_READ,
+							psBridgePackageKM->pvParamIn,
+							psBridgePackageKM->ui32InBufferSize))
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: Invalid pvParamIn pointer", __FUNCTION__));
+			}
+
+			if(CopyFromUserWrapper(psPerProc,
+					               ui32BridgeID,
+								   psBridgeIn,
+								   psBridgePackageKM->pvParamIn,
+								   psBridgePackageKM->ui32InBufferSize)
+			  != PVRSRV_OK)
+			{
+				goto return_fault;
+			}
+		}
+	}
+#else
+	psBridgeIn  = psBridgePackageKM->pvParamIn;
+	psBridgeOut = psBridgePackageKM->pvParamOut;
+#endif
+
+	pfBridgeHandler = (BridgeWrapperFunction)dte->pfFunction;
+	err = pfBridgeHandler(ui32BridgeID,
+						  psBridgeIn,
+						  psBridgeOut,
+						  psPerProc);
+	if(err < 0)
+	{
+		goto return_fault;
+	}
+
+
+#if defined(__linux__)
+
+	if(CopyToUserWrapper(psPerProc,
+						 ui32BridgeID,
+						 psBridgePackageKM->pvParamOut,
+						 psBridgeOut,
+						 psBridgePackageKM->ui32OutBufferSize)
+	   != PVRSRV_OK)
+	{
+		goto return_fault;
+	}
+#endif
+
+	err = 0;
+return_fault:
+
+	ReleaseHandleBatch(psPerProc);
+
+	if (err)
+		PVR_DPF((PVR_DBG_ERROR, "pvr: ioctl#%d failed (%d)\n",
+					ui32BridgeID, err));
+
+	return err;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_pvr_bridge.h b/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_pvr_bridge.h
new file mode 100644
index 0000000..9a7b577
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_pvr_bridge.h
@@ -0,0 +1,252 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __BRIDGED_PVR_BRIDGE_H__
+#define __BRIDGED_PVR_BRIDGE_H__
+
+#include "pvr_bridge.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__linux__)
+#define PVRSRV_GET_BRIDGE_ID(X)	_IOC_NR(X)
+#else
+#define PVRSRV_GET_BRIDGE_ID(X)	((X) - PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST))
+#endif
+
+#ifndef ENOMEM
+#define ENOMEM	12
+#endif
+#ifndef EFAULT
+#define EFAULT	14
+#endif
+#ifndef ENOTTY
+#define ENOTTY	25
+#endif
+
+#if defined(DEBUG_BRIDGE_KM)
+PVRSRV_ERROR
+CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
+					IMG_UINT32 ui32BridgeID,
+					IMG_VOID *pvDest,
+					IMG_VOID *pvSrc,
+					IMG_UINT32 ui32Size);
+PVRSRV_ERROR
+CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData, 
+				  IMG_UINT32 ui32BridgeID,
+				  IMG_VOID *pvDest,
+				  IMG_VOID *pvSrc,
+				  IMG_UINT32 ui32Size);
+#else
+#define CopyFromUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \
+	OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size)
+#define CopyToUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \
+	OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size)
+#endif
+
+
+#define ASSIGN_AND_RETURN_ON_ERROR(error, src, res)		\
+	do							\
+	{							\
+		(error) = (src);				\
+		if ((error) != PVRSRV_OK) 			\
+		{						\
+			return (res);				\
+		}						\
+	} while ((error) != PVRSRV_OK);
+
+#define ASSIGN_AND_EXIT_ON_ERROR(error, src)		\
+	ASSIGN_AND_RETURN_ON_ERROR(error, src, 0)
+
+#if defined (PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NewHandleBatch)
+#endif
+static INLINE PVRSRV_ERROR
+NewHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc,
+					IMG_UINT32 ui32BatchSize)
+{
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(!psPerProc->bHandlesBatched);
+
+	eError = PVRSRVNewHandleBatch(psPerProc->psHandleBase, ui32BatchSize);
+
+	if (eError == PVRSRV_OK)
+	{
+		psPerProc->bHandlesBatched = IMG_TRUE;
+	}
+
+	return eError;
+}
+
+#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize)	\
+	ASSIGN_AND_EXIT_ON_ERROR(error, NewHandleBatch(psPerProc, ui32BatchSize))
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(CommitHandleBatch)
+#endif
+static INLINE PVRSRV_ERROR
+CommitHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVR_ASSERT(psPerProc->bHandlesBatched);
+
+	psPerProc->bHandlesBatched = IMG_FALSE;
+
+	return PVRSRVCommitHandleBatch(psPerProc->psHandleBase);
+}
+
+
+#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc) 			\
+	ASSIGN_AND_EXIT_ON_ERROR(error, CommitHandleBatch(psPerProc))
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ReleaseHandleBatch)
+#endif
+static INLINE IMG_VOID
+ReleaseHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	if (psPerProc->bHandlesBatched)
+	{
+		psPerProc->bHandlesBatched = IMG_FALSE;
+
+		PVRSRVReleaseHandleBatch(psPerProc->psHandleBase);
+	}
+}
+#else	
+#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize)
+#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc)
+#define ReleaseHandleBatch(psPerProc)
+#endif	
+
+IMG_INT
+DummyBW(IMG_UINT32 ui32BridgeID,
+		IMG_VOID *psBridgeIn,
+		IMG_VOID *psBridgeOut,
+		PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+typedef IMG_INT (*BridgeWrapperFunction)(IMG_UINT32 ui32BridgeID,
+									 IMG_VOID *psBridgeIn,
+									 IMG_VOID *psBridgeOut,
+									 PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+typedef struct _PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY
+{
+	BridgeWrapperFunction pfFunction; 
+	size_t in_size;
+	size_t out_size;
+#if defined(DEBUG_BRIDGE_KM)
+	const IMG_CHAR *pszIOCName; 
+	const IMG_CHAR *pszFunctionName; 
+	IMG_UINT32 ui32CallCount; 
+	IMG_UINT32 ui32CopyFromUserTotalBytes; 
+	IMG_UINT32 ui32CopyToUserTotalBytes; 
+#endif
+}PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY;
+
+#if defined(SUPPORT_VGX) || defined(SUPPORT_MSVDX)
+	#if defined(SUPPORT_VGX)
+		#define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_VGX_CMD+1)
+		#define PVRSRV_BRIDGE_LAST_DEVICE_CMD	   PVRSRV_BRIDGE_LAST_VGX_CMD
+	#else
+		#define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_MSVDX_CMD+1)
+		#define PVRSRV_BRIDGE_LAST_DEVICE_CMD	   PVRSRV_BRIDGE_LAST_MSVDX_CMD
+	#endif
+#else
+	#if defined(SUPPORT_SGX)
+		#define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_SGX_CMD+1)
+		#define PVRSRV_BRIDGE_LAST_DEVICE_CMD	   PVRSRV_BRIDGE_LAST_SGX_CMD
+	#else
+		#define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1)
+		#define PVRSRV_BRIDGE_LAST_DEVICE_CMD	   PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD
+	#endif
+#endif
+
+extern PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
+
+IMG_VOID
+_SetDispatchTableEntry(IMG_UINT32 ui32Index,
+					   const IMG_CHAR *pszIOCName,
+					   BridgeWrapperFunction pfFunction,
+					   const IMG_CHAR *pszFunctionName,
+					   size_t in_size, size_t out_size);
+
+#define __set_table(id, fn, in_size, out_size)					\
+	_SetDispatchTableEntry(PVRSRV_GET_BRIDGE_ID(id), #id,			\
+				(BridgeWrapperFunction)fn, #fn,			\
+				in_size, out_size)
+
+#define PVR_IO_RW(id, fn)							\
+	__set_table(PVRSRV_BRIDGE_##id, fn,					\
+		    sizeof(PVRSRV_BRIDGE_IN_##id), sizeof(PVRSRV_BRIDGE_OUT_##id))
+
+#define PVR_IO_R(id, fn)							\
+	__set_table(PVRSRV_BRIDGE_##id, fn, 0, sizeof(PVRSRV_BRIDGE_OUT_##id))
+
+#define PVR_IO_W(id, fn)							\
+	__set_table(PVRSRV_BRIDGE_##id, fn, sizeof(PVRSRV_BRIDGE_IN_##id), 	\
+		    sizeof(PVRSRV_BRIDGE_RETURN))
+
+#define PVR_IO_NSTD(id, fn, in_size, out_size)					\
+	__set_table(PVRSRV_BRIDGE_##id, fn, in_size, out_size)
+
+#define PVR_IO_INV(id)								\
+	__set_table(PVRSRV_BRIDGE_##id, DummyBW, 0, 0)
+ 
+#define DISPATCH_TABLE_GAP_THRESHOLD 5
+
+#if defined(DEBUG)
+#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_ASSERT(X == PVRSRV_GET_BRIDGE_ID(Y))
+#else
+#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_UNREFERENCED_PARAMETER(X)
+#endif
+
+
+#if defined(DEBUG_BRIDGE_KM)
+typedef struct _PVRSRV_BRIDGE_GLOBAL_STATS
+{
+	IMG_UINT32 ui32IOCTLCount;
+	IMG_UINT32 ui32TotalCopyFromUserBytes;
+	IMG_UINT32 ui32TotalCopyToUserBytes;
+}PVRSRV_BRIDGE_GLOBAL_STATS;
+
+extern PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
+#endif
+
+
+PVRSRV_ERROR CommonBridgeInit(IMG_VOID);
+
+IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
+					  PVRSRV_BRIDGE_PACKAGE   * psBridgePackageKM);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_support.c b/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_support.c
new file mode 100644
index 0000000..dad0800
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_support.c
@@ -0,0 +1,89 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "img_defs.h"
+#include "servicesint.h"
+#include "bridged_support.h"
+
+
+PVRSRV_ERROR
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_SID hMHandle)
+#else
+PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle)
+#endif
+{
+	IMG_HANDLE hMHandleInt;
+	PVRSRV_HANDLE_TYPE eHandleType;
+	PVRSRV_ERROR eError;
+
+	
+	eError = PVRSRVLookupHandleAnyType(psHandleBase, &hMHandleInt,
+							  &eHandleType,
+							  hMHandle);
+	if(eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	switch(eHandleType)
+	{
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+		case PVRSRV_HANDLE_TYPE_MEM_INFO:
+		case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
+		case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
+		{
+			PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hMHandleInt;
+
+			*phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle;
+
+			break;
+		}
+		case PVRSRV_HANDLE_TYPE_SYNC_INFO:
+		{
+			PVRSRV_KERNEL_SYNC_INFO *psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hMHandleInt;
+			PVRSRV_KERNEL_MEM_INFO *psMemInfo = psSyncInfo->psSyncDataMemInfoKM;
+			
+			*phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle;
+
+			break;
+		}
+		case  PVRSRV_HANDLE_TYPE_SOC_TIMER:
+		{
+			*phOSMemHandle = (IMG_VOID *)hMHandleInt;
+			break;
+		}
+#else
+		case  PVRSRV_HANDLE_TYPE_NONE:
+			*phOSMemHandle = (IMG_VOID *)hMHandleInt;
+			break;
+#endif
+		default:
+			return PVRSRV_ERROR_BAD_MAPPING;
+	}
+
+	return PVRSRV_OK;
+}
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_support.h b/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_support.h
new file mode 100644
index 0000000..d027290
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/bridged/bridged_support.h
@@ -0,0 +1,47 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __BRIDGED_SUPPORT_H__
+#define __BRIDGED_SUPPORT_H__
+
+#include "handle.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_SID hMHandle);
+#else
+PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c b/drivers/staging/cdv/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c
new file mode 100644
index 0000000..f736ddd
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c
@@ -0,0 +1,3847 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+
+#include <stddef.h>
+
+#include "img_defs.h"
+
+#if defined(SUPPORT_SGX)
+
+#include "services.h"
+#include "pvr_debug.h"
+#include "pvr_bridge.h"
+#include "sgx_bridge.h"
+#include "perproc.h"
+#include "power.h"
+#include "pvr_bridge_km.h"
+#include "sgx_bridge_km.h"
+#include "sgx_options.h"
+
+#if defined(SUPPORT_MSVDX)
+	#include "msvdx_bridge.h"
+#endif
+
+#include "bridged_pvr_bridge.h"
+#include "bridged_sgx_bridge.h"
+#include "sgxutils.h"
+#include "buffer_manager.h"
+#include "pdump_km.h"
+
+static IMG_INT
+SGXGetClientInfoBW(IMG_UINT32 ui32BridgeID,
+				   PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN,
+				   PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT,
+				   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETCLIENTINFO);
+
+	psGetClientInfoOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psGetClientInfoIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psGetClientInfoOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psGetClientInfoOUT->eError =
+		SGXGetClientInfoKM(hDevCookieInt,
+						   &psGetClientInfoOUT->sClientInfo);
+	return 0;
+}
+
+static IMG_INT
+SGXReleaseClientInfoBW(IMG_UINT32 ui32BridgeID,
+					   PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN,
+					   PVRSRV_BRIDGE_RETURN *psRetOUT,
+					   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_SGXDEV_INFO *psDevInfo;
+	IMG_HANDLE hDevCookieInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psReleaseClientInfoIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
+
+	PVR_ASSERT(psDevInfo->ui32ClientRefCount > 0);
+
+	
+	if (psDevInfo->ui32ClientRefCount > 0)
+	{
+		psDevInfo->ui32ClientRefCount--;
+	}
+	
+	psRetOUT->eError = PVRSRV_OK;
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXGetInternalDevInfoBW(IMG_UINT32 ui32BridgeID,
+						PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN,
+						PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT,
+						PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+#if defined (SUPPORT_SID_INTERFACE)
+	SGX_INTERNAL_DEVINFO_KM sSGXInternalDevInfo;
+#endif
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO);
+
+	psSGXGetInternalDevInfoOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSGXGetInternalDevInfoIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psSGXGetInternalDevInfoOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psSGXGetInternalDevInfoOUT->eError =
+		SGXGetInternalDevInfoKM(hDevCookieInt,
+#if defined (SUPPORT_SID_INTERFACE)
+								&sSGXInternalDevInfo);
+#else
+								&psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo);
+#endif
+
+	
+	psSGXGetInternalDevInfoOUT->eError =
+		PVRSRVAllocHandle(psPerProc->psHandleBase,
+						  &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+						  sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
+#else
+						  psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
+#endif
+						  PVRSRV_HANDLE_TYPE_MEM_INFO,
+						  PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXDoKickBW(IMG_UINT32 ui32BridgeID,
+			PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN,
+			PVRSRV_BRIDGE_RETURN *psRetOUT,
+			PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_UINT32 i;
+	IMG_INT ret = 0;
+	IMG_UINT32 ui32NumDstSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+	SGX_CCB_KICK_KM sCCBKickKM = {{0}};
+	IMG_HANDLE	ahSyncInfoHandles[16];
+#else
+	IMG_HANDLE *phKernelSyncInfoHandles = IMG_NULL;
+#endif
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psDoKickIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &sCCBKickKM.hCCBKernelMemInfo,
+#else
+						   &psDoKickIN->sCCBKick.hCCBKernelMemInfo,
+#endif
+						   psDoKickIN->sCCBKick.hCCBKernelMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	if (psDoKickIN->sCCBKick.ui32NumDstSyncObjects > 16)
+	{
+		return 0;
+	}
+			
+	if(psDoKickIN->sCCBKick.hTA3DSyncInfo != 0)
+#else
+	if(psDoKickIN->sCCBKick.hTA3DSyncInfo != IMG_NULL)
+#endif
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.hTA3DSyncInfo,
+#else
+							   &psDoKickIN->sCCBKick.hTA3DSyncInfo,
+#endif
+							   psDoKickIN->sCCBKick.hTA3DSyncInfo,
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	if(psDoKickIN->sCCBKick.hTASyncInfo != 0)
+#else
+	if(psDoKickIN->sCCBKick.hTASyncInfo != IMG_NULL)
+#endif
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.hTASyncInfo,
+#else
+							   &psDoKickIN->sCCBKick.hTASyncInfo,
+#endif
+							   psDoKickIN->sCCBKick.hTASyncInfo,
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+#if defined(FIX_HW_BRN_31620)
+	
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &psDoKickIN->sCCBKick.hDevMemContext,
+						   psDoKickIN->sCCBKick.hDevMemContext,
+						   PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+	if(psDoKickIN->sCCBKick.h3DSyncInfo != 0)
+#else
+	if(psDoKickIN->sCCBKick.h3DSyncInfo != IMG_NULL)
+#endif
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.h3DSyncInfo,
+#else
+							   &psDoKickIN->sCCBKick.h3DSyncInfo,
+#endif
+							   psDoKickIN->sCCBKick.h3DSyncInfo,
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+	
+	if (psDoKickIN->sCCBKick.ui32NumTASrcSyncs > SGX_MAX_TA_SRC_SYNCS)
+	{
+		psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	sCCBKickKM.ui32NumTASrcSyncs = psDoKickIN->sCCBKick.ui32NumTASrcSyncs;
+#endif
+	for(i=0; i<psDoKickIN->sCCBKick.ui32NumTASrcSyncs; i++)
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.ahTASrcKernelSyncInfo[i],
+#else
+							   &psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
+#endif
+							   psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+	if (psDoKickIN->sCCBKick.ui32NumTADstSyncs > SGX_MAX_TA_DST_SYNCS)
+	{
+		psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	sCCBKickKM.ui32NumTADstSyncs = psDoKickIN->sCCBKick.ui32NumTADstSyncs;
+#endif
+	for(i=0; i<psDoKickIN->sCCBKick.ui32NumTADstSyncs; i++)
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.ahTADstKernelSyncInfo[i],
+#else
+							   &psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
+#endif
+							   psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+	if (psDoKickIN->sCCBKick.ui32Num3DSrcSyncs > SGX_MAX_3D_SRC_SYNCS)
+	{
+		psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	sCCBKickKM.ui32Num3DSrcSyncs = psDoKickIN->sCCBKick.ui32Num3DSrcSyncs;
+#endif
+	for(i=0; i<psDoKickIN->sCCBKick.ui32Num3DSrcSyncs; i++)
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.ah3DSrcKernelSyncInfo[i],
+#else
+							   &psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
+#endif
+							   psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+#else
+	
+	if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS)
+	{
+		psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	sCCBKickKM.ui32NumSrcSyncs = psDoKickIN->sCCBKick.ui32NumSrcSyncs;
+#endif
+	for(i=0; i<psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++)
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.ahSrcKernelSyncInfo[i],
+#else
+							   &psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
+#endif
+							   psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+#endif
+
+	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 =
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.asTAStatusUpdate[i].hKernelMemInfo,
+#else
+							   &psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
+#endif
+							   psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
+							   PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+#if defined (SUPPORT_SID_INTERFACE)
+		sCCBKickKM.asTAStatusUpdate[i].sCtlStatus = psDoKickIN->sCCBKick.asTAStatusUpdate[i].sCtlStatus;
+#endif
+
+#else
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.ahTAStatusSyncInfo[i],
+#else
+							   &psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
+#endif
+							   psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+#endif
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+	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 =
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.as3DStatusUpdate[i].hKernelMemInfo,
+#else
+							   &psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
+#endif
+							   psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
+							   PVRSRV_HANDLE_TYPE_MEM_INFO);
+							   
+#if defined (SUPPORT_SID_INTERFACE)
+		sCCBKickKM.as3DStatusUpdate[i].sCtlStatus = psDoKickIN->sCCBKick.as3DStatusUpdate[i].sCtlStatus;
+#endif
+#else
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sCCBKickKM.ah3DStatusSyncInfo[i],
+#else
+							   &psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
+#endif
+							   psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+#endif
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+	ui32NumDstSyncs = psDoKickIN->sCCBKick.ui32NumDstSyncObjects;
+
+	if(ui32NumDstSyncs > 0)
+	{
+		if(!OSAccessOK(PVR_VERIFY_READ,
+						psDoKickIN->sCCBKick.pahDstSyncHandles,
+						ui32NumDstSyncs * sizeof(IMG_HANDLE)))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "%s: SGXDoKickBW:"
+					" Invalid pasDstSyncHandles pointer", __FUNCTION__));
+			return -EFAULT;
+		}
+
+		psRetOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+										ui32NumDstSyncs * sizeof(IMG_HANDLE),
+										(IMG_VOID **)&phKernelSyncInfoHandles,
+										0,
+										"Array of Synchronization Info Handles");
+		if (psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+
+#if defined (SUPPORT_SID_INTERFACE)
+		sCCBKickKM.pahDstSyncHandles = phKernelSyncInfoHandles;
+#else
+		if(CopyFromUserWrapper(psPerProc,
+							ui32BridgeID,
+							phKernelSyncInfoHandles,
+							psDoKickIN->sCCBKick.pahDstSyncHandles,
+							ui32NumDstSyncs * sizeof(IMG_HANDLE)) != PVRSRV_OK)
+		{
+			ret = -EFAULT;
+			goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
+		}
+
+		
+		psDoKickIN->sCCBKick.pahDstSyncHandles = phKernelSyncInfoHandles;
+#endif
+
+		for( i = 0; i < ui32NumDstSyncs; i++)
+		{
+			psRetOUT->eError =
+				PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+									&sCCBKickKM.pahDstSyncHandles[i],
+#else
+									&psDoKickIN->sCCBKick.pahDstSyncHandles[i],
+#endif
+									psDoKickIN->sCCBKick.pahDstSyncHandles[i],
+									PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+			if(psRetOUT->eError != PVRSRV_OK)
+			{
+				goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
+			}
+
+		}
+
+		psRetOUT->eError =
+					PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+									   &sCCBKickKM.hKernelHWSyncListMemInfo,
+#else
+									   &psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
+#endif
+									   psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
+									   PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
+		}
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	OSMemCopy(&sCCBKickKM.sCommand, &psDoKickIN->sCCBKick.sCommand, sizeof(sCCBKickKM.sCommand));
+
+	sCCBKickKM.ui32NumDstSyncObjects = psDoKickIN->sCCBKick.ui32NumDstSyncObjects;
+	sCCBKickKM.ui32NumTAStatusVals   = psDoKickIN->sCCBKick.ui32NumTAStatusVals;
+	sCCBKickKM.ui32Num3DStatusVals   = psDoKickIN->sCCBKick.ui32Num3DStatusVals;
+	sCCBKickKM.bFirstKickOrResume    = psDoKickIN->sCCBKick.bFirstKickOrResume;
+	sCCBKickKM.ui32CCBOffset         = psDoKickIN->sCCBKick.ui32CCBOffset;
+	sCCBKickKM.bTADependency         = psDoKickIN->sCCBKick.bTADependency;
+
+#if (defined(NO_HARDWARE) || defined(PDUMP))
+	sCCBKickKM.bTerminateOrAbort = psDoKickIN->sCCBKick.bTerminateOrAbort;
+#endif
+#if defined(PDUMP)
+	sCCBKickKM.ui32CCBDumpWOff = psDoKickIN->sCCBKick.ui32CCBDumpWOff;
+#endif
+
+#if defined(NO_HARDWARE)
+	sCCBKickKM.ui32WriteOpsPendingVal = psDoKickIN->sCCBKick.ui32WriteOpsPendingVal;
+#endif
+#endif 
+	psRetOUT->eError =
+		SGXDoKickKM(hDevCookieInt,
+#if defined (SUPPORT_SID_INTERFACE)
+					&sCCBKickKM);
+#else
+					&psDoKickIN->sCCBKick);
+#endif
+
+PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT:
+
+	if(phKernelSyncInfoHandles)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  ui32NumDstSyncs * sizeof(IMG_HANDLE),
+				  (IMG_VOID *)phKernelSyncInfoHandles,
+				  0);
+		
+	}
+	return ret;
+}
+
+
+static IMG_INT
+SGXScheduleProcessQueuesBW(IMG_UINT32 ui32BridgeID,
+			PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES *psScheduleProcQIN,
+			PVRSRV_BRIDGE_RETURN *psRetOUT,
+			PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psScheduleProcQIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError = SGXScheduleProcessQueuesKM(hDevCookieInt);
+
+	return 0;
+}
+
+
+#if defined(TRANSFER_QUEUE)
+static IMG_INT
+SGXSubmitTransferBW(IMG_UINT32 ui32BridgeID,
+			PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN,
+			PVRSRV_BRIDGE_RETURN *psRetOUT,
+			PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	PVRSRV_TRANSFER_SGX_KICK *psKick;
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_TRANSFER_SGX_KICK_KM sKickKM = {0};
+#endif
+	IMG_UINT32 i;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMITTRANSFER);
+	PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+	psKick = &psSubmitTransferIN->sKick;
+
+#if defined(FIX_HW_BRN_31620)
+	
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &psKick->hDevMemContext,
+						   psKick->hDevMemContext,
+						   PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+#endif
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSubmitTransferIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &sKickKM.hCCBMemInfo,
+#else
+						   &psKick->hCCBMemInfo,
+#endif
+						   psKick->hCCBMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	if (psKick->hTASyncInfo != IMG_NULL)
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sKickKM.hTASyncInfo,
+#else
+							   &psKick->hTASyncInfo,
+#endif
+							   psKick->hTASyncInfo,
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+	if (psKick->h3DSyncInfo != IMG_NULL)
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sKickKM.h3DSyncInfo,
+#else
+							   &psKick->h3DSyncInfo,
+#endif
+							   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,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sKickKM.ahSrcSyncInfo[i],
+#else
+							   &psKick->ahSrcSyncInfo[i],
+#endif
+							   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,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sKickKM.ahDstSyncInfo[i],
+#else
+							   &psKick->ahDstSyncInfo[i],
+#endif
+							   psKick->ahDstSyncInfo[i],
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	sKickKM.sHWTransferContextDevVAddr = psKick->sHWTransferContextDevVAddr;
+	sKickKM.ui32SharedCmdCCBOffset = psKick->ui32SharedCmdCCBOffset;
+	sKickKM.ui32NumSrcSync         = psKick->ui32NumSrcSync;
+	sKickKM.ui32NumDstSync         = psKick->ui32NumDstSync;
+	sKickKM.ui32Flags              = psKick->ui32Flags;
+	sKickKM.ui32PDumpFlags         = psKick->ui32PDumpFlags;
+#if defined(PDUMP)
+	sKickKM.ui32CCBDumpWOff        = psKick->ui32CCBDumpWOff;
+#endif
+
+	psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, &sKickKM);
+#else
+	psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick);
+#endif
+
+	return 0;
+}
+
+static IMG_INT
+SGXSetTransferContextPriorityBW(IMG_UINT32 ui32BridgeID,
+                        PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY *psSGXSetTransferContextPriorityIN,
+                        PVRSRV_BRIDGE_RETURN *psRetOUT,
+                        PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+    IMG_HANDLE hTransferContextInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSGXSetTransferContextPriorityIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hTransferContextInt,
+						   psSGXSetTransferContextPriorityIN->hHWTransferContext,
+						   PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+    psRetOUT->eError = SGXSetTransferContextPriorityKM(
+            hDevCookieInt, 
+            hTransferContextInt,
+            psSGXSetTransferContextPriorityIN->ui32Priority,
+            psSGXSetTransferContextPriorityIN->ui32OffsetOfPriorityField);
+
+    return 0;
+}
+
+static IMG_INT
+SGXSetRenderContextPriorityBW(IMG_UINT32 ui32BridgeID,
+                        PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY *psSGXSetRenderContextPriorityIN,
+                        PVRSRV_BRIDGE_RETURN *psRetOUT,
+                        PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+    IMG_HANDLE hRenderContextInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSGXSetRenderContextPriorityIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hRenderContextInt,
+						   psSGXSetRenderContextPriorityIN->hHWRenderContext,
+						   PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+    psRetOUT->eError = SGXSetRenderContextPriorityKM(
+            hDevCookieInt, 
+            hRenderContextInt,
+            psSGXSetRenderContextPriorityIN->ui32Priority,
+            psSGXSetRenderContextPriorityIN->ui32OffsetOfPriorityField);
+
+    return 0;
+}
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+static IMG_INT
+SGXSubmit2DBW(IMG_UINT32 ui32BridgeID,
+			PVRSRV_BRIDGE_IN_SUBMIT2D *psSubmit2DIN,
+			PVRSRV_BRIDGE_RETURN *psRetOUT,
+			PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	PVRSRV_2D_SGX_KICK   *psKick;
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_2D_SGX_KICK_KM sKickKM;
+#endif
+	IMG_UINT32 i;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMIT2D);
+	PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+	psKick = &psSubmit2DIN->sKick;
+
+#if defined(FIX_HW_BRN_31620)
+	
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &psKick->hDevMemContext,
+						   psKick->hDevMemContext,
+						   PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+#endif
+
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSubmit2DIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &sKickKM.hCCBMemInfo,
+#else
+						   &psKick->hCCBMemInfo,
+#endif
+						   psKick->hCCBMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	if (psKick->hTASyncInfo != 0)
+#else
+	if (psKick->hTASyncInfo != IMG_NULL)
+#endif
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sKickKM.hTASyncInfo,
+#else
+							   &psKick->hTASyncInfo,
+#endif
+							   psKick->hTASyncInfo,
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+#if defined (SUPPORT_SID_INTERFACE)
+	else
+	{
+		sKickKM.hTASyncInfo = IMG_NULL;
+	}
+#endif
+
+	if (psKick->h3DSyncInfo != IMG_NULL)
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sKickKM.h3DSyncInfo,
+#else
+							   &psKick->h3DSyncInfo,
+#endif
+							   psKick->h3DSyncInfo,
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+#if defined (SUPPORT_SID_INTERFACE)
+	else
+	{
+		sKickKM.h3DSyncInfo = IMG_NULL;
+	}
+#endif
+
+	if (psKick->ui32NumSrcSync > SGX_MAX_2D_SRC_SYNC_OPS)
+	{
+		psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		return 0;
+	}
+#if defined (SUPPORT_SID_INTERFACE)
+	for (i = 0; i < SGX_MAX_2D_SRC_SYNC_OPS; i++)
+	{
+		if (i < psKick->ui32NumSrcSync)
+		{
+			psRetOUT->eError =
+				PVRSRVLookupHandle(psPerProc->psHandleBase,
+								   &sKickKM.ahSrcSyncInfo[i],
+								   psKick->ahSrcSyncInfo[i],
+								   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+			if(psRetOUT->eError != PVRSRV_OK)
+			{
+				return 0;
+			}
+		}
+		else
+		{
+			sKickKM.ahSrcSyncInfo[i] = IMG_NULL;
+		}
+	}
+#else
+	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;
+		}
+	}
+#endif
+
+	if (psKick->hDstSyncInfo != IMG_NULL)
+	{
+		psRetOUT->eError =
+			PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &sKickKM.hDstSyncInfo,
+#else
+							   &psKick->hDstSyncInfo,
+#endif
+							   psKick->hDstSyncInfo,
+							   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+#if defined (SUPPORT_SID_INTERFACE)
+	else
+	{
+		sKickKM.hDstSyncInfo = IMG_NULL;
+	}
+
+	
+	sKickKM.ui32SharedCmdCCBOffset = psKick->ui32SharedCmdCCBOffset;
+	sKickKM.ui32NumSrcSync         = psKick->ui32NumSrcSync;
+	sKickKM.ui32PDumpFlags         = psKick->ui32PDumpFlags;
+	sKickKM.sHW2DContextDevVAddr   = psKick->sHW2DContextDevVAddr;
+#if defined(PDUMP)
+	sKickKM.ui32CCBDumpWOff        = psKick->ui32CCBDumpWOff;
+#endif
+#endif
+
+	psRetOUT->eError =
+#if defined (SUPPORT_SID_INTERFACE)
+		SGXSubmit2DKM(hDevCookieInt, &sKickKM);
+#else
+		SGXSubmit2DKM(hDevCookieInt, psKick);
+#endif
+
+	return 0;
+}
+#endif 
+#endif 
+
+
+static IMG_INT
+SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
+				 PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN,
+				 PVRSRV_BRIDGE_RETURN *psRetOUT,
+				 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_HANDLE hDevMemContextInt = 0;
+	PVRSRV_SGXDEV_INFO *psDevInfo;
+	SGX_MISC_INFO        sMiscInfo;
+ 	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	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;
+	}
+
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+	
+	if (psSGXGetMiscInfoIN->psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMREAD)
+	{
+		psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								&hDevMemContextInt,
+								psSGXGetMiscInfoIN->psMiscInfo->hDevMemContext,
+								PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+		if(psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+#endif
+	
+	psDeviceNode = hDevCookieInt;
+	PVR_ASSERT(psDeviceNode != IMG_NULL);
+	if (psDeviceNode == IMG_NULL)
+	{
+		return -EFAULT;
+	}
+
+	psDevInfo = psDeviceNode->pvDevice;
+
+	
+	psRetOUT->eError = CopyFromUserWrapper(psPerProc,
+			                               ui32BridgeID,
+			                               &sMiscInfo,
+			                               psSGXGetMiscInfoIN->psMiscInfo,
+			                               sizeof(SGX_MISC_INFO));
+	if (psRetOUT->eError != PVRSRV_OK)
+	{
+		return -EFAULT;
+	}
+
+	{
+		psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, hDevMemContextInt);
+
+		if (psRetOUT->eError != PVRSRV_OK)
+		{
+			return 0;
+		}
+	}
+
+	
+	psRetOUT->eError = CopyToUserWrapper(psPerProc,
+		                             ui32BridgeID,
+		                             psSGXGetMiscInfoIN->psMiscInfo,
+		                             &sMiscInfo,
+		                             sizeof(SGX_MISC_INFO));
+	if (psRetOUT->eError != PVRSRV_OK)
+	{
+		return -EFAULT;
+	}
+	return 0;
+}
+
+
+static IMG_INT
+SGXReadHWPerfCBBW(IMG_UINT32							ui32BridgeID,
+				  PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB	*psSGXReadHWPerfCBIN,
+				  PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB	*psSGXReadHWPerfCBOUT,
+				  PVRSRV_PER_PROCESS_DATA				*psPerProc)
+{
+	IMG_HANDLE					hDevCookieInt;
+	PVRSRV_SGX_HWPERF_CB_ENTRY	*psAllocated;
+	IMG_HANDLE					hAllocatedHandle;
+	IMG_UINT32					ui32AllocatedSize;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_READ_HWPERF_CB);
+
+	psSGXReadHWPerfCBOUT->eError =PVRSRVLookupHandle(psPerProc->psHandleBase,
+							&hDevCookieInt,
+							psSGXReadHWPerfCBIN->hDevCookie,
+							PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psSGXReadHWPerfCBOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	ui32AllocatedSize = psSGXReadHWPerfCBIN->ui32ArraySize *
+							sizeof(psSGXReadHWPerfCBIN->psHWPerfCBData[0]);
+	ASSIGN_AND_EXIT_ON_ERROR(psSGXReadHWPerfCBOUT->eError,
+	                    OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+	                    ui32AllocatedSize,
+	                    (IMG_VOID **)&psAllocated,
+	                    &hAllocatedHandle,
+						"Array of Hardware Performance Circular Buffer Data"));
+
+	psSGXReadHWPerfCBOUT->eError = SGXReadHWPerfCBKM(hDevCookieInt,
+													 psSGXReadHWPerfCBIN->ui32ArraySize,
+													 psAllocated,
+													 &psSGXReadHWPerfCBOUT->ui32DataCount,
+													 &psSGXReadHWPerfCBOUT->ui32ClockSpeed,
+													 &psSGXReadHWPerfCBOUT->ui32HostTimeStamp);
+	if (psSGXReadHWPerfCBOUT->eError == PVRSRV_OK)
+	{
+		psSGXReadHWPerfCBOUT->eError = CopyToUserWrapper(psPerProc,
+		                                                 ui32BridgeID,
+		                                                 psSGXReadHWPerfCBIN->psHWPerfCBData,
+		                                                 psAllocated,
+		                                                 ui32AllocatedSize);
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+			  ui32AllocatedSize,
+			  psAllocated,
+			  hAllocatedHandle);
+	
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
+				  PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN,
+				  PVRSRV_BRIDGE_OUT_SGXDEVINITPART2 *psSGXDevInitPart2OUT,
+				  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_ERROR eError = PVRSRV_OK;
+#else
+	PVRSRV_ERROR eError;
+#endif
+	IMG_BOOL bDissociateFailed = IMG_FALSE;
+	IMG_BOOL bLookupFailed = IMG_FALSE;
+	IMG_BOOL bReleaseFailed = IMG_FALSE;
+	IMG_HANDLE hDummy;
+	IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+	SGX_BRIDGE_INIT_INFO_KM asInitInfoKM = {0};
+#endif
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2);
+
+	
+	psSGXDevInitPart2OUT->ui32KMBuildOptions = SGX_BUILD_OPTIONS;
+
+	if(!psPerProc->bInitProcess)
+	{
+		psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_PROCESS_NOT_INITIALISED;
+		return 0;
+	}
+
+	psSGXDevInitPart2OUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSGXDevInitPart2IN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psSGXDevInitPart2OUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								&hDummy,
+								psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
+								PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								&hDummy,
+								psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
+								PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+
+#if defined(FIX_HW_BRN_29702)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+
+#if defined(FIX_HW_BRN_29823)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+
+
+#if defined(FIX_HW_BRN_31542)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+	
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+	defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDummy,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+
+	for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		IMG_SID hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+#else
+		IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+		if (hHandle == 0)
+#else
+		if (hHandle == IMG_NULL)
+#endif
+		{
+			continue;
+		}
+
+		eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+							   &hDummy,
+							   hHandle,
+							   PVRSRV_HANDLE_TYPE_MEM_INFO);
+		if (eError != PVRSRV_OK)
+		{
+			bLookupFailed = IMG_TRUE;
+		}
+	}
+
+	if (bLookupFailed)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle lookup failed"));
+		psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
+		return 0;
+	}
+
+	
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelCCBMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelCCBCtlMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelCCBEventKickerMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+
+
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelSGXHostCtlMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelSGXTA3DCtlMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelSGXPTLAWriteBackMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+#endif
+
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelSGXMiscMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelHWProfilingMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelHWPerfCBMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+#endif
+
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+										  &asInitInfoKM.hKernelTASigBufferMemInfo,
+#else
+										  &psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
+#endif
+										  psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
+										  PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+										  &asInitInfoKM.hKernel3DSigBufferMemInfo,
+#else
+										  &psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
+#endif
+										  psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
+										  PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+
+#if defined(FIX_HW_BRN_29702)
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelCFIMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bLookupFailed = IMG_TRUE;
+	}
+#endif
+
+#if defined(FIX_HW_BRN_29823)
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelDummyTermStreamMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+#endif
+
+
+#if defined(FIX_HW_BRN_31542)
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelClearClipWAVDMStreamMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelClearClipWAIndexStreamMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelClearClipWAPDSMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelClearClipWAUSEMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelClearClipWAParamMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelClearClipWAPMPTMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelClearClipWATPCMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelClearClipWAPSGRgnHdrMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+	defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo,
+						   psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+#endif
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+	eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+						   &asInitInfoKM.hKernelEDMStatusBufferMemInfo,
+#else
+						   &psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
+#endif
+						   psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
+						   PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if (eError != PVRSRV_OK)
+	{
+		bReleaseFailed = IMG_TRUE;
+	}
+#endif
+
+	for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		IMG_SID hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+		IMG_HANDLE *phHandleKM = &asInitInfoKM.asInitMemHandles[i];
+
+		if (hHandle == 0)
+#else
+		IMG_HANDLE *phHandle = &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+
+		if (*phHandle == IMG_NULL)
+#endif
+			continue;
+
+		eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+							   phHandleKM,
+							   hHandle,
+#else
+							   phHandle,
+							   *phHandle,
+#endif
+							   PVRSRV_HANDLE_TYPE_MEM_INFO);
+		if (eError != PVRSRV_OK)
+		{
+			bReleaseFailed = IMG_TRUE;
+		}
+	}
+
+	if (bReleaseFailed)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle release failed"));
+		psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
+		
+		PVR_DBG_BREAK;
+		return 0;
+	}
+
+	
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBCtlMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBEventKickerMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXHostCtlMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXTA3DCtlMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXPTLAWriteBackMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#endif
+
+	
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXMiscMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelHWProfilingMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelHWPerfCBMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelTASigBufferMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernel3DSigBufferMemInfo);
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+
+#if defined(FIX_HW_BRN_29702)
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCFIMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(FIX_HW_BRN_29823)
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelDummyTermStreamMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(FIX_HW_BRN_31542)
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAVDMStreamMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAIndexStreamMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAPDSMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAUSEMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAParamMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAPMPTMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWATPCMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAPSGRgnHdrMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+	
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+	defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+#if defined (SUPPORT_SID_INTERFACE)
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelEDMStatusBufferMemInfo);
+	if (eError != PVRSRV_OK)
+	{
+		bDissociateFailed = IMG_TRUE;
+	}
+#else
+	eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo);
+	bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+	for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		IMG_HANDLE hHandle = asInitInfoKM.asInitMemHandles[i];
+#else
+		IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+#endif
+
+		if (hHandle == IMG_NULL)
+			continue;
+
+		eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle);
+		if (eError != PVRSRV_OK)
+		{
+			bDissociateFailed = IMG_TRUE;
+		}
+	}
+
+	
+	if(bDissociateFailed)
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBMemInfo);
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBCtlMemInfo);
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXHostCtlMemInfo);
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXTA3DCtlMemInfo);
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXPTLAWriteBackMemInfo);
+#endif
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXMiscMemInfo);
+#else
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo);
+#endif
+		PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
+#endif
+
+		for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+		{
+#if defined (SUPPORT_SID_INTERFACE)
+			IMG_HANDLE hHandle = asInitInfoKM.asInitMemHandles[i];
+
+			if (hHandle == 0)
+#else
+			IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+
+			if (hHandle == IMG_NULL)
+#endif
+				continue;
+
+			PVRSRVFreeDeviceMemKM(hDevCookieInt, (PVRSRV_KERNEL_MEM_INFO *)hHandle);
+
+		}
+
+		PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A dissociate failed"));
+
+		psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
+
+		
+		PVR_DBG_BREAK;
+		return 0;
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	asInitInfoKM.sScripts               = psSGXDevInitPart2IN->sInitInfo.sScripts;
+	asInitInfoKM.ui32ClientBuildOptions = psSGXDevInitPart2IN->sInitInfo.ui32ClientBuildOptions;
+	asInitInfoKM.sSGXStructSizes        = psSGXDevInitPart2IN->sInitInfo.sSGXStructSizes;
+	asInitInfoKM.ui32CacheControl       = psSGXDevInitPart2IN->sInitInfo.ui32CacheControl;
+	asInitInfoKM.ui32EDMTaskReg0        = psSGXDevInitPart2IN->sInitInfo.ui32EDMTaskReg0;
+	asInitInfoKM.ui32EDMTaskReg1        = psSGXDevInitPart2IN->sInitInfo.ui32EDMTaskReg1;
+	asInitInfoKM.ui32ClkGateStatusReg   = psSGXDevInitPart2IN->sInitInfo.ui32ClkGateStatusReg;
+	asInitInfoKM.ui32ClkGateStatusMask  = psSGXDevInitPart2IN->sInitInfo.ui32ClkGateStatusMask;
+
+	OSMemCopy(&asInitInfoKM.asInitDevData ,
+			  &psSGXDevInitPart2IN->sInitInfo.asInitDevData,
+			  sizeof(asInitInfoKM.asInitDevData));
+	OSMemCopy(&asInitInfoKM.aui32HostKickAddr,
+			  &psSGXDevInitPart2IN->sInitInfo.aui32HostKickAddr,
+			  sizeof(asInitInfoKM.aui32HostKickAddr));
+
+	psSGXDevInitPart2OUT->eError =
+		DevInitSGXPart2KM(psPerProc,
+						  hDevCookieInt,
+						  &asInitInfoKM);
+#else
+	psSGXDevInitPart2OUT->eError =
+		DevInitSGXPart2KM(psPerProc,
+						  hDevCookieInt,
+						  &psSGXDevInitPart2IN->sInitInfo);
+#endif
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXRegisterHWRenderContextBW(IMG_UINT32 ui32BridgeID,
+							 PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextIN,
+							 PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextOUT,
+							 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_HANDLE hHWRenderContextInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc, 1);
+
+	psSGXRegHWRenderContextOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSGXRegHWRenderContextIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psSGXRegHWRenderContextOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	hHWRenderContextInt =
+		SGXRegisterHWRenderContextKM(hDevCookieInt,
+                                     psSGXRegHWRenderContextIN->pHWRenderContextCpuVAddr,
+                                     psSGXRegHWRenderContextIN->ui32HWRenderContextSize,
+                                     psSGXRegHWRenderContextIN->ui32OffsetToPDDevPAddr,
+                                     psSGXRegHWRenderContextIN->hDevMemContext,
+                                     &psSGXRegHWRenderContextOUT->sHWRenderContextDevVAddr,
+                                     psPerProc);
+
+	if (hHWRenderContextInt == IMG_NULL)
+	{
+		psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
+		return 0;
+	}
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psSGXRegHWRenderContextOUT->hHWRenderContext,
+					  hHWRenderContextInt,
+					  PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc);
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXUnregisterHWRenderContextBW(IMG_UINT32 ui32BridgeID,
+							   PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT *psSGXUnregHWRenderContextIN,
+							   PVRSRV_BRIDGE_RETURN *psRetOUT,
+							   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	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,
+													  psSGXUnregHWRenderContextIN->bForceCleanup);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVReleaseHandle(psPerProc->psHandleBase,
+							psSGXUnregHWRenderContextIN->hHWRenderContext,
+							PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
+
+	return 0;
+}
+
+
+static IMG_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);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc, 1);
+
+	psSGXRegHWTransferContextOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSGXRegHWTransferContextIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psSGXRegHWTransferContextOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	hHWTransferContextInt =
+		SGXRegisterHWTransferContextKM(hDevCookieInt,
+									   psSGXRegHWTransferContextIN->pHWTransferContextCpuVAddr,
+                                       psSGXRegHWTransferContextIN->ui32HWTransferContextSize,
+                                       psSGXRegHWTransferContextIN->ui32OffsetToPDDevPAddr,
+                                       psSGXRegHWTransferContextIN->hDevMemContext,
+                                       &psSGXRegHWTransferContextOUT->sHWTransferContextDevVAddr,
+									   psPerProc);
+
+	if (hHWTransferContextInt == IMG_NULL)
+	{
+		psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
+		return 0;
+	}
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psSGXRegHWTransferContextOUT->hHWTransferContext,
+					  hHWTransferContextInt,
+					  PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc);
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXUnregisterHWTransferContextBW(IMG_UINT32 ui32BridgeID,
+							   PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT *psSGXUnregHWTransferContextIN,
+							   PVRSRV_BRIDGE_RETURN *psRetOUT,
+							   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_HANDLE hHWTransferContextInt = 0;
+#else
+	IMG_HANDLE hHWTransferContextInt;
+#endif
+
+	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,
+														psSGXUnregHWTransferContextIN->bForceCleanup);
+	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 IMG_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;
+	IMG_HANDLE hHW2DContextInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc, 1);
+
+	psSGXRegHW2DContextOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSGXRegHW2DContextIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psSGXRegHW2DContextOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	hHW2DContextInt =
+		SGXRegisterHW2DContextKM(hDevCookieInt,
+								 psSGXRegHW2DContextIN->pHW2DContextCpuVAddr,
+                                 psSGXRegHW2DContextIN->ui32HW2DContextSize,
+                                 psSGXRegHW2DContextIN->ui32OffsetToPDDevPAddr,
+								 psSGXRegHW2DContextIN->hDevMemContext,
+                                 &psSGXRegHW2DContextOUT->sHW2DContextDevVAddr,
+								 psPerProc);
+
+	if (hHW2DContextInt == IMG_NULL)
+	{
+		psSGXRegHW2DContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
+		return 0;
+	}
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psSGXRegHW2DContextOUT->hHW2DContext,
+					  hHW2DContextInt,
+					  PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc);
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXUnregisterHW2DContextBW(IMG_UINT32 ui32BridgeID,
+							   PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT *psSGXUnregHW2DContextIN,
+							   PVRSRV_BRIDGE_RETURN *psRetOUT,
+							   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hHW2DContextInt;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hHW2DContextInt,
+						   psSGXUnregHW2DContextIN->hHW2DContext,
+						   PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError = SGXUnregisterHW2DContextKM(hHW2DContextInt,
+												  psSGXUnregHW2DContextIN->bForceCleanup);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVReleaseHandle(psPerProc->psHandleBase,
+							psSGXUnregHW2DContextIN->hHW2DContext,
+							PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT);
+
+	return 0;
+}
+#endif 
+
+static IMG_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;
+	}
+
+	psRetOUT->eError = SGXFlushHWRenderTargetKM(hDevCookieInt, psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr, IMG_FALSE);
+
+	return 0;
+}
+
+
+static IMG_INT
+SGX2DQueryBlitsCompleteBW(IMG_UINT32 ui32BridgeID,
+						  PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN,
+						  PVRSRV_BRIDGE_RETURN *psRetOUT,
+						  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_VOID *pvSyncInfo;
+	PVRSRV_SGXDEV_INFO *psDevInfo;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   ps2DQueryBltsCompleteIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &pvSyncInfo,
+						   ps2DQueryBltsCompleteIN->hKernSyncInfo,
+						   PVRSRV_HANDLE_TYPE_SYNC_INFO);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
+
+	psRetOUT->eError =
+		SGX2DQueryBlitsCompleteKM(psDevInfo,
+								  (PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo,
+								  ps2DQueryBltsCompleteIN->bWaitForComplete);
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXFindSharedPBDescBW(IMG_UINT32 ui32BridgeID,
+					  PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescIN,
+					  PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOUT,
+					  PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = IMG_NULL;
+	IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount = 0;
+	IMG_UINT32 i;
+	IMG_HANDLE hSharedPBDesc = IMG_NULL;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc, PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS + 4);
+
+	psSGXFindSharedPBDescOUT->hSharedPBDesc = IMG_NULL;
+
+	psSGXFindSharedPBDescOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hDevCookieInt,
+						   psSGXFindSharedPBDescIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
+		goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
+
+	psSGXFindSharedPBDescOUT->eError =
+		SGXFindSharedPBDescKM(psPerProc, hDevCookieInt,
+							  psSGXFindSharedPBDescIN->bLockOnFailure,
+							  psSGXFindSharedPBDescIN->ui32TotalPBSize,
+							  &hSharedPBDesc,
+							  &psSharedPBDescKernelMemInfo,
+							  &psHWPBDescKernelMemInfo,
+							  &psBlockKernelMemInfo,
+							  &psHWBlockKernelMemInfo,
+							  &ppsSharedPBDescSubKernelMemInfos,
+							  &ui32SharedPBDescSubKernelMemInfosCount);
+	if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
+		goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
+
+	PVR_ASSERT(ui32SharedPBDescSubKernelMemInfosCount
+			   <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
+
+	psSGXFindSharedPBDescOUT->ui32SharedPBDescSubKernelMemInfoHandlesCount =
+		ui32SharedPBDescSubKernelMemInfosCount;
+
+	if(hSharedPBDesc == IMG_NULL)
+	{
+		psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle = 0;
+		
+		goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
+	}
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+					  &psSGXFindSharedPBDescOUT->hSharedPBDesc,
+					  hSharedPBDesc,
+					  PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
+					  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+	
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+					  &psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle,
+					  psSharedPBDescKernelMemInfo,
+					  PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+					  PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+					  psSGXFindSharedPBDescOUT->hSharedPBDesc);
+
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+					  &psSGXFindSharedPBDescOUT->hHWPBDescKernelMemInfoHandle,
+					  psHWPBDescKernelMemInfo,
+					  PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+					  PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+					  psSGXFindSharedPBDescOUT->hSharedPBDesc);
+
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+				  &psSGXFindSharedPBDescOUT->hBlockKernelMemInfoHandle,
+				  psBlockKernelMemInfo,
+				  PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+				  PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+				  psSGXFindSharedPBDescOUT->hSharedPBDesc);
+
+	PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+				  &psSGXFindSharedPBDescOUT->hHWBlockKernelMemInfoHandle,
+				  psHWBlockKernelMemInfo,
+				  PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+				  PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+				  psSGXFindSharedPBDescOUT->hSharedPBDesc);
+
+
+	for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
+	{
+		PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOut =
+			psSGXFindSharedPBDescOUT;
+
+			PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+							  &psSGXFindSharedPBDescOut->ahSharedPBDescSubKernelMemInfoHandles[i],
+							  ppsSharedPBDescSubKernelMemInfos[i],
+							  PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+							  PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+							  psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle);
+	}
+
+PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT:
+	if (ppsSharedPBDescSubKernelMemInfos != IMG_NULL)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
+				  ppsSharedPBDescSubKernelMemInfos,
+				  IMG_NULL);
+	}
+
+	if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
+	{
+		if(hSharedPBDesc != IMG_NULL)
+		{
+			SGXUnrefSharedPBDescKM(hSharedPBDesc);
+		}
+	}
+	else
+	{
+		COMMIT_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc);
+	}
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXUnrefSharedPBDescBW(IMG_UINT32 ui32BridgeID,
+					   PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN,
+					   PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescOUT,
+					   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hSharedPBDesc;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC);
+
+	psSGXUnrefSharedPBDescOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   &hSharedPBDesc,
+						   psSGXUnrefSharedPBDescIN->hSharedPBDesc,
+						   PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
+	if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psSGXUnrefSharedPBDescOUT->eError =
+		SGXUnrefSharedPBDescKM(hSharedPBDesc);
+
+	if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psSGXUnrefSharedPBDescOUT->eError =
+		PVRSRVReleaseHandle(psPerProc->psHandleBase,
+						   psSGXUnrefSharedPBDescIN->hSharedPBDesc,
+						   PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
+
+	return 0;
+}
+
+
+static IMG_INT
+SGXAddSharedPBDescBW(IMG_UINT32 ui32BridgeID,
+					 PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN,
+					 PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT,
+					 PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
+	IMG_UINT32 ui32KernelMemInfoHandlesCount =
+		psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount;
+	IMG_INT ret = 0;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID *phKernelMemInfoHandles = 0;
+#else
+	IMG_HANDLE *phKernelMemInfoHandles = IMG_NULL;
+#endif
+	PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos = IMG_NULL;
+	IMG_UINT32 i;
+	PVRSRV_ERROR eError;
+	IMG_HANDLE hSharedPBDesc = IMG_NULL;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc, 1);
+
+	psSGXAddSharedPBDescOUT->hSharedPBDesc = IMG_NULL;
+
+	PVR_ASSERT(ui32KernelMemInfoHandlesCount
+			   <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								&hDevCookieInt,
+								psSGXAddSharedPBDescIN->hDevCookie,
+								PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(eError != PVRSRV_OK)
+	{
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								(IMG_VOID **)&psSharedPBDescKernelMemInfo,
+								psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo,
+								PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+	if(eError != PVRSRV_OK)
+	{
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								(IMG_VOID **)&psHWPBDescKernelMemInfo,
+								psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo,
+								PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(eError != PVRSRV_OK)
+	{
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								(IMG_VOID **)&psBlockKernelMemInfo,
+								psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
+								PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+	if(eError != PVRSRV_OK)
+	{
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+								(IMG_VOID **)&psHWBlockKernelMemInfo,
+								psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
+								PVRSRV_HANDLE_TYPE_MEM_INFO);
+	if(eError != PVRSRV_OK)
+	{
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+
+	if(!OSAccessOK(PVR_VERIFY_READ,
+				   psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
+				   ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE)))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:"
+				 " Invalid phKernelMemInfos pointer", __FUNCTION__));
+		ret = -EFAULT;
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+	eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE),
+				  (IMG_VOID **)&phKernelMemInfoHandles,
+				  0,
+				  "Array of Handles");
+	if (eError != PVRSRV_OK)
+	{
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+	if(CopyFromUserWrapper(psPerProc,
+			               ui32BridgeID,
+			               phKernelMemInfoHandles,
+						   psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
+						   ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE))
+	   != PVRSRV_OK)
+	{
+		ret = -EFAULT;
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+	eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *),
+				  (IMG_VOID **)&ppsKernelMemInfos,
+				  0,
+				  "Array of pointers to Kernel Memory Info");
+	if (eError != PVRSRV_OK)
+	{
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+	for(i=0; i<ui32KernelMemInfoHandlesCount; i++)
+	{
+		eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+									(IMG_VOID **)&ppsKernelMemInfos[i],
+									phKernelMemInfoHandles[i],
+									PVRSRV_HANDLE_TYPE_MEM_INFO);
+		if(eError != PVRSRV_OK)
+		{
+			goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+		}
+	}
+
+	
+	 
+	eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+								psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo,
+								PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	 
+	eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+								psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo,
+								PVRSRV_HANDLE_TYPE_MEM_INFO);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	 
+	eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+								psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
+								PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	 
+	eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+								psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
+								PVRSRV_HANDLE_TYPE_MEM_INFO);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	for(i=0; i<ui32KernelMemInfoHandlesCount; i++)
+	{
+		 
+		eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+									phKernelMemInfoHandles[i],
+									PVRSRV_HANDLE_TYPE_MEM_INFO);
+		PVR_ASSERT(eError == PVRSRV_OK);
+	}
+
+	eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt,
+								  psSharedPBDescKernelMemInfo,
+								  psHWPBDescKernelMemInfo,
+								  psBlockKernelMemInfo,
+								  psHWBlockKernelMemInfo,
+								  psSGXAddSharedPBDescIN->ui32TotalPBSize,
+								  &hSharedPBDesc,
+								  ppsKernelMemInfos,
+								  ui32KernelMemInfoHandlesCount,
+								  psSGXAddSharedPBDescIN->sHWPBDescDevVAddr);
+
+
+	if (eError != PVRSRV_OK)
+	{
+		goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+	}
+
+	PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+				  &psSGXAddSharedPBDescOUT->hSharedPBDesc,
+				  hSharedPBDesc,
+				  PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
+				  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT:
+
+	if(phKernelMemInfoHandles)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE),
+				  (IMG_VOID *)phKernelMemInfoHandles,
+				  0);
+	}
+	if(ppsKernelMemInfos)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *),
+				  (IMG_VOID *)ppsKernelMemInfos,
+				  0);
+	}
+
+	if(ret == 0 && eError == PVRSRV_OK)
+	{
+		COMMIT_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc);
+	}
+
+	psSGXAddSharedPBDescOUT->eError = eError;
+
+	return ret;
+}
+
+static IMG_INT
+SGXGetInfoForSrvinitBW(IMG_UINT32 ui32BridgeID,
+					   PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN,
+					   PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT,
+					   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_HANDLE hDevCookieInt;
+	IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+#endif
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT);
+
+	NEW_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS);
+
+	if(!psPerProc->bInitProcess)
+	{
+		psSGXInfoForSrvinitOUT->eError = PVRSRV_ERROR_PROCESS_NOT_INITIALISED;
+		return 0;
+	}
+
+	psSGXInfoForSrvinitOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+						   psSGXInfoForSrvinitIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+	if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psSGXInfoForSrvinitOUT->eError =
+		SGXGetInfoForSrvinitKM(hDevCookieInt,
+#if defined (SUPPORT_SID_INTERFACE)
+							   &asHeapInfo[0],
+							   &psSGXInfoForSrvinitOUT->sInitInfo.sPDDevPAddr);
+#else
+							   &psSGXInfoForSrvinitOUT->sInitInfo);
+#endif
+
+	if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	for(i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
+	{
+		PVRSRV_HEAP_INFO *psHeapInfo;
+
+		psHeapInfo = &psSGXInfoForSrvinitOUT->sInitInfo.asHeapInfo[i];
+
+#if defined (SUPPORT_SID_INTERFACE)
+		if ((asHeapInfo[i].ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID) &&
+			(asHeapInfo[i].hDevMemHeap != IMG_NULL))
+		{
+			
+			PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+							  &psHeapInfo->hDevMemHeap,
+							  asHeapInfo[i].hDevMemHeap,
+							  PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+							  PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+		}
+		else
+		{
+			psHeapInfo->hDevMemHeap = 0;
+		}
+
+		psHeapInfo->ui32HeapID       = asHeapInfo[i].ui32HeapID;
+		psHeapInfo->sDevVAddrBase    = asHeapInfo[i].sDevVAddrBase;
+		psHeapInfo->ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
+		psHeapInfo->ui32Attribs      = asHeapInfo[i].ui32Attribs;
+		psHeapInfo->ui32XTileStride  = asHeapInfo[i].ui32XTileStride;
+#else
+		if (psHeapInfo->ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID)
+		{
+			IMG_HANDLE hDevMemHeapExt;
+
+			if (psHeapInfo->hDevMemHeap != IMG_NULL)
+			{
+				
+				PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+								  &hDevMemHeapExt,
+								  psHeapInfo->hDevMemHeap,
+								  PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+								  PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+				psHeapInfo->hDevMemHeap = hDevMemHeapExt;
+			}
+		}
+#endif
+	}
+
+	COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc);
+
+	return 0;
+}
+
+#if defined(PDUMP)
+static IMG_VOID
+DumpBufferArray(PVRSRV_PER_PROCESS_DATA   *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+				PSGX_KICKTA_DUMP_BUFFER_KM psBufferArray,
+#else
+				PSGX_KICKTA_DUMP_BUFFER	psBufferArray,
+#endif
+				IMG_UINT32                 ui32BufferArrayLength,
+				IMG_BOOL                   bDumpPolls)
+{
+	IMG_UINT32	i;
+
+	for (i=0; i<ui32BufferArrayLength; i++)
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		PSGX_KICKTA_DUMP_BUFFER_KM psBuffer;
+#else
+		PSGX_KICKTA_DUMP_BUFFER	psBuffer;
+#endif
+		PVRSRV_KERNEL_MEM_INFO    *psCtrlMemInfoKM;
+		IMG_CHAR * pszName;
+		IMG_HANDLE hUniqueTag;
+		IMG_UINT32	ui32Offset;
+
+		psBuffer = &psBufferArray[i];
+		pszName = psBuffer->pszName;
+		if (!pszName)
+		{
+			pszName = "Nameless buffer";
+		}
+
+		hUniqueTag = MAKEUNIQUETAG((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo);
+
+	#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+		psCtrlMemInfoKM	= ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hCtrlKernelMemInfo);
+		ui32Offset =  psBuffer->sCtrlDevVAddr.uiAddr - psCtrlMemInfoKM->sDevVAddr.uiAddr;
+	#else
+		psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo)->psKernelSyncInfo->psSyncDataMemInfoKM;
+		ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
+	#endif
+
+		if (psBuffer->ui32Start <= psBuffer->ui32End)
+		{
+			if (bDumpPolls)
+			{
+				PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
+				PDUMPCBP(psCtrlMemInfoKM,
+						 ui32Offset,
+						 psBuffer->ui32Start,
+						 psBuffer->ui32SpaceUsed,
+						 psBuffer->ui32BufferSize,
+						 0,
+						 MAKEUNIQUETAG(psCtrlMemInfoKM));
+			}
+
+			PDUMPCOMMENTWITHFLAGS(0, "%s\r\n", pszName);
+			PDUMPMEMUM(psPerProc,
+					 IMG_NULL,
+					 psBuffer->pvLinAddr,
+					 (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
+					 psBuffer->ui32Start,
+					 psBuffer->ui32End - psBuffer->ui32Start,
+					 0,
+					 hUniqueTag);
+		}
+		else
+		{
+			
+
+			if (bDumpPolls)
+			{
+				PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
+				PDUMPCBP(psCtrlMemInfoKM,
+						 ui32Offset,
+						 psBuffer->ui32Start,
+						 psBuffer->ui32BackEndLength,
+						 psBuffer->ui32BufferSize,
+						 0,
+						 MAKEUNIQUETAG(psCtrlMemInfoKM));
+			}
+			PDUMPCOMMENTWITHFLAGS(0, "%s (part 1)\r\n", pszName);
+			PDUMPMEMUM(psPerProc,
+					 IMG_NULL,
+					 psBuffer->pvLinAddr,
+					 (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
+					 psBuffer->ui32Start,
+					 psBuffer->ui32BackEndLength,
+					 0,
+					 hUniqueTag);
+
+			if (bDumpPolls)
+			{
+				PDUMPMEMPOL(psCtrlMemInfoKM,
+							ui32Offset,
+							0,
+							0xFFFFFFFF,
+							PDUMP_POLL_OPERATOR_NOTEQUAL,
+							0,
+							MAKEUNIQUETAG(psCtrlMemInfoKM));
+
+				PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
+				PDUMPCBP(psCtrlMemInfoKM,
+						 ui32Offset,
+						 0,
+						 psBuffer->ui32End,
+						 psBuffer->ui32BufferSize,
+						 0,
+						 MAKEUNIQUETAG(psCtrlMemInfoKM));
+			}
+			PDUMPCOMMENTWITHFLAGS(0, "%s (part 2)\r\n", pszName);
+			PDUMPMEMUM(psPerProc,
+					 IMG_NULL,
+					 psBuffer->pvLinAddr,
+					 (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
+					 0,
+					 psBuffer->ui32End,
+					 0,
+					 hUniqueTag);
+		}
+	}
+}
+static IMG_INT
+SGXPDumpBufferArrayBW(IMG_UINT32 ui32BridgeID,
+				   PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN,
+				   IMG_VOID *psBridgeOut,
+				   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+	SGX_KICKTA_DUMP_BUFFER *psUMPtr;
+	SGX_KICKTA_DUMP_BUFFER_KM *psKickTADumpBufferKM, *psKMPtr;
+#else
+	SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer;
+#endif
+	IMG_UINT32 ui32BufferArrayLength =
+		psPDumpBufferArrayIN->ui32BufferArrayLength;
+	IMG_UINT32 ui32BufferArraySize =
+		ui32BufferArrayLength * sizeof(SGX_KICKTA_DUMP_BUFFER);
+	PVRSRV_ERROR eError = PVRSRV_ERROR_TOO_FEW_BUFFERS;
+
+#if defined (__QNXNTO__)
+    const IMG_UINT32 MAX_BUFFER_NAME_SIZE = 30;
+    IMG_PCHAR pszNamesBuffer, pszName;
+    IMG_UINT32 ui32NameBufferArraySize;
+#endif
+
+	PVR_UNREFERENCED_PARAMETER(psBridgeOut);
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY);
+
+#if defined (SUPPORT_SID_INTERFACE)
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  ui32BufferArraySize,
+				  (IMG_PVOID *)&psKickTADumpBufferKM, 0,
+				  "Array of Kick Tile Accelerator Dump Buffer") != PVRSRV_OK)
+#else
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  ui32BufferArraySize,
+				  (IMG_PVOID *)&psKickTADumpBuffer, 0,
+				  "Array of Kick Tile Accelerator Dump Buffer") != PVRSRV_OK)
+#endif				  
+	{
+		return -ENOMEM;
+	}
+
+#if !defined (SUPPORT_SID_INTERFACE)
+	if(CopyFromUserWrapper(psPerProc,
+			               ui32BridgeID,
+						   psKickTADumpBuffer,
+						   psPDumpBufferArrayIN->psBufferArray,
+						   ui32BufferArraySize) != PVRSRV_OK)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
+		
+		return -EFAULT;
+	}
+#endif
+
+#if defined (__QNXNTO__)
+    ui32NameBufferArraySize = ui32BufferArrayLength * MAX_BUFFER_NAME_SIZE;
+    if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32NameBufferArraySize,
+            (IMG_PVOID *)&pszNamesBuffer, 0,
+            "Kick Tile Accelerator Dump Buffer names") != PVRSRV_OK)
+    {
+        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
+        return -ENOMEM;
+    }
+
+    pszName = pszNamesBuffer;
+    for (i=0; i<ui32BufferArrayLength; i++)
+    {
+        if (CopyFromUserWrapper(psPerProc, ui32BridgeID, 
+                pszName, psKickTADumpBuffer[i].pszName,
+                MAX_BUFFER_NAME_SIZE) != PVRSRV_OK)
+        {
+            PVR_DPF((PVR_DBG_WARNING, "Failed to read pdump buffer name"));
+            psKickTADumpBuffer[i].pszName = 0;
+        }
+        else 
+        {
+            pszName[MAX_BUFFER_NAME_SIZE-1] = 0;
+            psKickTADumpBuffer[i].pszName = pszName;
+        }
+        pszName += MAX_BUFFER_NAME_SIZE;
+    }
+#endif
+
+	for(i = 0; i < ui32BufferArrayLength; i++)
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		IMG_VOID *pvMemInfo = IMG_NULL;
+		psUMPtr = &psPDumpBufferArrayIN->psBufferArray[i];
+		psKMPtr = &psKickTADumpBufferKM[i];
+#else
+		IMG_VOID *pvMemInfo;
+#endif
+
+		eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+									&pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+									psUMPtr->hKernelMemInfo,
+#else
+									psKickTADumpBuffer[i].hKernelMemInfo,
+#endif
+									PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
+					 "PVRSRVLookupHandle failed (%d)", eError));
+			break;
+		}
+#if defined (SUPPORT_SID_INTERFACE)
+		psKMPtr->hKernelMemInfo = pvMemInfo;
+#else
+		psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo;
+#endif
+
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+		eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+									&pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+									psUMPtr->hCtrlKernelMemInfo,
+#else
+									psKickTADumpBuffer[i].hCtrlKernelMemInfo,
+#endif
+									PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
+					 "PVRSRVLookupHandle failed (%d)", eError));
+			break;
+		}
+#if defined (SUPPORT_SID_INTERFACE)
+		psKMPtr->hCtrlKernelMemInfo = pvMemInfo;
+		psKMPtr->sCtrlDevVAddr = psUMPtr->sCtrlDevVAddr;
+#else
+		psKickTADumpBuffer[i].hCtrlKernelMemInfo = pvMemInfo;
+#endif
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+		psKMPtr->ui32SpaceUsed     = psUMPtr->ui32SpaceUsed;
+		psKMPtr->ui32Start         = psUMPtr->ui32Start;
+		psKMPtr->ui32End           = psUMPtr->ui32End;
+		psKMPtr->ui32BufferSize    = psUMPtr->ui32BufferSize;
+		psKMPtr->ui32BackEndLength = psUMPtr->ui32BackEndLength;
+		psKMPtr->uiAllocIndex      = psUMPtr->uiAllocIndex;
+		psKMPtr->pvLinAddr         = psUMPtr->pvLinAddr;
+		psKMPtr->pszName           = psUMPtr->pszName;
+#endif
+	}
+
+	if(eError == PVRSRV_OK)
+	{
+		DumpBufferArray(psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+						psKickTADumpBufferKM,
+#else
+						psKickTADumpBuffer,
+#endif
+						ui32BufferArrayLength,
+						psPDumpBufferArrayIN->bDumpPolls);
+	}
+
+#if defined (SUPPORT_SID_INTERFACE)
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBufferKM, 0);
+#else
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
+#endif
+	
+
+#if defined (__QNXNTO__)
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32NameBufferArraySize, pszNamesBuffer, 0);
+#endif
+
+	return 0;
+}
+
+static IMG_INT
+SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID,
+				   PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS *psPDump3DSignatureRegistersIN,
+				   PVRSRV_BRIDGE_RETURN *psRetOUT,
+				   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_UINT32 ui32RegisterArraySize =  psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
+	IMG_UINT32 *pui32Registers = IMG_NULL;
+	PVRSRV_SGXDEV_INFO	*psDevInfo;
+#if defined(SGX_FEATURE_MP)	&& defined(FIX_HW_BRN_27270)
+	IMG_UINT32	ui32RegVal = 0;
+#endif
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_HANDLE hDevMemContextInt = 0;
+	IMG_UINT32 ui32MMUContextID;
+	IMG_INT ret = -EFAULT;
+
+	PVR_UNREFERENCED_PARAMETER(psRetOUT);
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS);
+
+	if (ui32RegisterArraySize == 0)
+	{
+		goto ExitNoError;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   (IMG_VOID**)&psDeviceNode,
+						   psPDump3DSignatureRegistersIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
+		goto Exit;
+	}
+
+	psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+#if defined(SGX_FEATURE_MP)	&& defined(FIX_HW_BRN_27270)
+	
+	ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
+#if defined(PDUMP)
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
+						psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+#endif
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  ui32RegisterArraySize,
+				  (IMG_PVOID *)&pui32Registers, 0,
+				  "Array of Registers") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: OSAllocMem failed"));
+		goto Exit;
+	}
+
+	if(CopyFromUserWrapper(psPerProc,
+			        	ui32BridgeID,
+					pui32Registers,
+					psPDump3DSignatureRegistersIN->pui32Registers,
+					ui32RegisterArraySize) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: CopyFromUserWrapper failed"));
+		goto Exit;
+	}
+
+	PDump3DSignatureRegisters(&psDeviceNode->sDevId,
+					psPDump3DSignatureRegistersIN->ui32DumpFrameNum,
+					psPDump3DSignatureRegistersIN->bLastFrame,
+					pui32Registers,
+					psPDump3DSignatureRegistersIN->ui32NumRegisters);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(	psPerProc->psHandleBase,
+							&hDevMemContextInt,
+							psPDump3DSignatureRegistersIN->hDevMemContext,
+							PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	
+	PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL)
+	ui32MMUContextID = psDeviceNode->pfnMMUGetContextID((IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext);
+
+	PDumpSignatureBuffer(&psDeviceNode->sDevId,
+						 "out.tasig", "TA", 0,
+						 psDevInfo->psKernelTASigBufferMemInfo->sDevVAddr,
+						 (IMG_UINT32)psDevInfo->psKernelTASigBufferMemInfo->uAllocSize,
+						 ui32MMUContextID,
+						 0 );
+	PDumpSignatureBuffer(&psDeviceNode->sDevId,
+						 "out.3dsig", "3D", 0,
+						 psDevInfo->psKernel3DSigBufferMemInfo->sDevVAddr,
+						 (IMG_UINT32)psDevInfo->psKernel3DSigBufferMemInfo->uAllocSize,
+						 ui32MMUContextID,
+						 0 );
+
+ExitNoError:
+	psRetOUT->eError = PVRSRV_OK;
+	ret = 0;
+Exit:
+	if (pui32Registers != IMG_NULL)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
+	}
+
+#if defined(SGX_FEATURE_MP)	&& defined(FIX_HW_BRN_27270)
+	if (psDevInfo != IMG_NULL)
+	{
+		OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
+#if defined(PDUMP)
+		PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal,
+							psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+	}
+#endif
+
+	return ret;
+}
+
+static IMG_INT
+SGXPDumpCounterRegistersBW(IMG_UINT32 ui32BridgeID,
+				   PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS *psPDumpCounterRegistersIN,
+				   IMG_VOID *psBridgeOut,
+				   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_UINT32 ui32RegisterArraySize =  psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
+	IMG_UINT32 *pui32Registers = IMG_NULL;
+	PVRSRV_DEVICE_NODE *psDeviceNode ;
+	IMG_INT ret = -EFAULT;
+
+	PVR_UNREFERENCED_PARAMETER(psBridgeOut);
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS);
+
+	if (ui32RegisterArraySize == 0)
+	{
+		goto ExitNoError;
+	}
+
+	if(PVRSRVLookupHandle(psPerProc->psHandleBase,
+						  (IMG_VOID**)&psDeviceNode,
+						  psPDumpCounterRegistersIN->hDevCookie,
+						  PVRSRV_HANDLE_TYPE_DEV_NODE) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXPDumpCounterRegistersBW: hDevCookie lookup failed"));
+		ret = -ENOMEM;
+		goto Exit;
+	}
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  ui32RegisterArraySize,
+				  (IMG_PVOID *)&pui32Registers, 0,
+				  "Array of Registers") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: OSAllocMem failed"));
+		ret = -ENOMEM;
+		goto Exit;
+	}
+
+	if(CopyFromUserWrapper(psPerProc,
+			        	ui32BridgeID,
+					pui32Registers,
+					psPDumpCounterRegistersIN->pui32Registers,
+					ui32RegisterArraySize) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: CopyFromUserWrapper failed"));
+		goto Exit;
+	}
+
+	PDumpCounterRegisters(&psDeviceNode->sDevId,
+					psPDumpCounterRegistersIN->ui32DumpFrameNum,
+					psPDumpCounterRegistersIN->bLastFrame,
+					pui32Registers,
+					psPDumpCounterRegistersIN->ui32NumRegisters);
+
+ExitNoError:
+	ret = 0;
+Exit:
+	if (pui32Registers != IMG_NULL)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
+	}
+
+	return ret;
+}
+
+static IMG_INT
+SGXPDumpTASignatureRegistersBW(IMG_UINT32 ui32BridgeID,
+				   PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS *psPDumpTASignatureRegistersIN,
+				   PVRSRV_BRIDGE_RETURN *psRetOUT,
+				   PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	IMG_UINT32 ui32RegisterArraySize =  psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
+	IMG_UINT32 *pui32Registers = IMG_NULL;
+#if defined(SGX_FEATURE_MP)	&& defined(FIX_HW_BRN_27270)
+	PVRSRV_SGXDEV_INFO	*psDevInfo = IMG_NULL;
+	IMG_UINT32	ui32RegVal = 0;
+#endif
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_INT ret = -EFAULT;
+
+	PVR_UNREFERENCED_PARAMETER(psRetOUT);
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS);
+
+	if (ui32RegisterArraySize == 0)
+	{
+		goto ExitNoError;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
+						   psPDumpTASignatureRegistersIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
+		goto Exit;
+	}
+
+#if defined(SGX_FEATURE_MP)	&& defined(FIX_HW_BRN_27270)
+
+	psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+	
+	ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
+#if defined(PDUMP)
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
+						psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+#endif
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  ui32RegisterArraySize,
+				  (IMG_PVOID *)&pui32Registers, 0,
+				  "Array of Registers") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: OSAllocMem failed"));
+		ret = -ENOMEM;
+		goto Exit;
+	}
+
+	if(CopyFromUserWrapper(psPerProc,
+			        	ui32BridgeID,
+					pui32Registers,
+					psPDumpTASignatureRegistersIN->pui32Registers,
+					ui32RegisterArraySize) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: CopyFromUserWrapper failed"));
+		goto Exit;
+	}
+
+	PDumpTASignatureRegisters(&psDeviceNode->sDevId,
+					psPDumpTASignatureRegistersIN->ui32DumpFrameNum,
+					psPDumpTASignatureRegistersIN->ui32TAKickCount,
+					psPDumpTASignatureRegistersIN->bLastFrame,
+					pui32Registers,
+					psPDumpTASignatureRegistersIN->ui32NumRegisters);
+
+ExitNoError:
+	psRetOUT->eError = PVRSRV_OK;
+	ret = 0;
+Exit:
+	if (pui32Registers != IMG_NULL)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
+	}
+
+#if defined(SGX_FEATURE_MP)	&& defined(FIX_HW_BRN_27270)
+	if (psDevInfo != IMG_NULL)
+	{
+		OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
+#if defined(PDUMP)
+		PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal,
+							psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+	}
+#endif
+
+	return ret;
+}
+static IMG_INT
+SGXPDumpHWPerfCBBW(IMG_UINT32						ui32BridgeID,
+				   PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB	*psPDumpHWPerfCBIN,
+				   PVRSRV_BRIDGE_RETURN 			*psRetOUT,
+				   PVRSRV_PER_PROCESS_DATA 			*psPerProc)
+{
+#if defined(SUPPORT_SGX_HWPERF)
+#if defined(__linux__)
+	PVRSRV_SGXDEV_INFO	*psDevInfo;
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_HANDLE hDevMemContextInt = 0;
+	IMG_UINT32 ui32MMUContextID = 0;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
+						   psPDumpHWPerfCBIN->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psDevInfo = psDeviceNode->pvDevice;
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(	psPerProc->psHandleBase,
+							&hDevMemContextInt,
+							psPDumpHWPerfCBIN->hDevMemContext,
+							PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	
+	PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL)
+	ui32MMUContextID = psDeviceNode->pfnMMUGetContextID(hDevMemContextInt);
+
+	PDumpHWPerfCBKM(&psDeviceNode->sDevId,
+					&psPDumpHWPerfCBIN->szFileName[0],
+					psPDumpHWPerfCBIN->ui32FileOffset,
+					psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr,
+					psDevInfo->psKernelHWPerfCBMemInfo->uAllocSize,
+					ui32MMUContextID,
+					psPDumpHWPerfCBIN->ui32PDumpFlags);
+
+	return 0;
+#else
+	PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+	PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN);
+	PVR_UNREFERENCED_PARAMETER(psRetOUT);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+	return 0;
+#endif 
+#else
+	PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+	PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN);
+	PVR_UNREFERENCED_PARAMETER(psRetOUT);
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+	return -EFAULT;
+#endif 
+}
+
+
+static IMG_INT
+SGXPDumpSaveMemBW(IMG_UINT32						ui32BridgeID,
+				  PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM	*psPDumpSaveMem,
+				  PVRSRV_BRIDGE_RETURN 				*psRetOUT,
+				  PVRSRV_PER_PROCESS_DATA 			*psPerProc)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_HANDLE hDevMemContextInt = 0;
+	IMG_UINT32 ui32MMUContextID;
+
+	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM);
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(psPerProc->psHandleBase,
+						   (IMG_VOID**)&psDeviceNode,
+						   psPDumpSaveMem->hDevCookie,
+						   PVRSRV_HANDLE_TYPE_DEV_NODE);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	psRetOUT->eError =
+		PVRSRVLookupHandle(	psPerProc->psHandleBase,
+							&hDevMemContextInt,
+							psPDumpSaveMem->hDevMemContext,
+							PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+	if(psRetOUT->eError != PVRSRV_OK)
+	{
+		return 0;
+	}
+
+	
+	PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL)
+	ui32MMUContextID = psDeviceNode->pfnMMUGetContextID(hDevMemContextInt);
+
+	PDumpSaveMemKM(&psDeviceNode->sDevId,
+				   &psPDumpSaveMem->szFileName[0],
+				   psPDumpSaveMem->ui32FileOffset,
+				   psPDumpSaveMem->sDevVAddr,
+				   psPDumpSaveMem->ui32Size,
+				   ui32MMUContextID,
+				   psPDumpSaveMem->ui32PDumpFlags);
+	return 0;
+}
+
+#endif 
+
+
+ 
+IMG_VOID SetSGXDispatchTableEntry(IMG_VOID)
+{
+
+	PVR_IO_NSTD(SGX_GETCLIENTINFO, SGXGetClientInfoBW,
+			sizeof(PVRSRV_BRIDGE_IN_GETCLIENTINFO),
+			sizeof(PVRSRV_BRIDGE_OUT_GETCLIENTINFO));
+	PVR_IO_NSTD(SGX_RELEASECLIENTINFO, SGXReleaseClientInfoBW,
+			sizeof(PVRSRV_BRIDGE_IN_RELEASECLIENTINFO),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SGX_GETINTERNALDEVINFO, SGXGetInternalDevInfoBW,
+			sizeof(PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO),
+			sizeof(PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO));
+
+	PVR_IO_NSTD(SGX_DOKICK, SGXDoKickBW,
+			sizeof(PVRSRV_BRIDGE_IN_DOKICK),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SGX_GETPHYSPAGEADDR, DummyBW,
+			sizeof(PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR),
+			sizeof(PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR));
+	PVR_IO_INV(SGX_READREGISTRYDWORD);
+	PVR_IO_NSTD(SGX_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW,
+			sizeof(PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+
+#if defined(TRANSFER_QUEUE)
+	PVR_IO_NSTD(SGX_SUBMITTRANSFER, SGXSubmitTransferBW,
+			sizeof(PVRSRV_BRIDGE_IN_SUBMITTRANSFER),
+			sizeof(PVRSRV_BRIDGE_RETURN));
+#endif
+	PVR_IO_NSTD(SGX_GETMISCINFO, SGXGetMiscInfoBW,
+		sizeof(PVRSRV_BRIDGE_IN_SGXGETMISCINFO),
+		sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SGXINFO_FOR_SRVINIT, SGXGetInfoForSrvinitBW,
+		sizeof(PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT),
+		sizeof(PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT));
+	PVR_IO_NSTD(SGX_DEVINITPART2, SGXDevInitPart2BW,
+		sizeof(PVRSRV_BRIDGE_IN_SGXDEVINITPART2),
+		sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SGX_FINDSHAREDPBDESC, SGXFindSharedPBDescBW,
+		sizeof(PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC),
+		sizeof(PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC));
+	PVR_IO_NSTD(SGX_UNREFSHAREDPBDESC, SGXUnrefSharedPBDescBW,
+		sizeof(PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC),
+		sizeof(PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC));
+	PVR_IO_NSTD(SGX_ADDSHAREDPBDESC, SGXAddSharedPBDescBW,
+		sizeof(PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC),
+		sizeof(PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC));
+	PVR_IO_RW(SGX_REGISTER_HW_RENDER_CONTEXT, SGXRegisterHWRenderContextBW);
+	PVR_IO_W(SGX_FLUSH_HW_RENDER_TARGET, SGXFlushHWRenderTargetBW);
+	PVR_IO_W(SGX_UNREGISTER_HW_RENDER_CONTEXT, SGXUnregisterHWRenderContextBW);
+#if defined(SGX_FEATURE_2D_HARDWARE)
+	PVR_IO_NSTD(SGX_SUBMIT2D, SGXSubmit2DBW,
+		sizeof(PVRSRV_BRIDGE_IN_SUBMIT2D),
+		sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SGX_REGISTER_HW_2D_CONTEXT, SGXRegisterHW2DContextBW,
+		sizeof(PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT),
+		sizeof(PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT));
+	PVR_IO_NSTD(SGX_UNREGISTER_HW_2D_CONTEXT, SGXUnregisterHW2DContextBW,
+		sizeof(PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT),
+		sizeof(PVRSRV_BRIDGE_RETURN));
+#endif
+	PVR_IO_RW(SGX_REGISTER_HW_TRANSFER_CONTEXT, SGXRegisterHWTransferContextBW);
+	PVR_IO_W(SGX_UNREGISTER_HW_TRANSFER_CONTEXT, SGXUnregisterHWTransferContextBW);
+	PVR_IO_W(SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW);
+	PVR_IO_RW(SGX_READ_HWPERF_CB, SGXReadHWPerfCBBW);
+
+	PVR_IO_NSTD(SGX_SET_RENDER_CONTEXT_PRIORITY, SGXSetRenderContextPriorityBW,
+		    sizeof(PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY),
+		    sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SGX_SET_TRANSFER_CONTEXT_PRIORITY, SGXSetTransferContextPriorityBW,
+		    sizeof(PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY),
+		    sizeof(PVRSRV_BRIDGE_RETURN));
+
+#if defined(PDUMP)
+	PVR_IO_NSTD(SGX_PDUMP_BUFFER_ARRAY, SGXPDumpBufferArrayBW,
+		    sizeof(PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY), 0);
+	PVR_IO_NSTD(SGX_PDUMP_3D_SIGNATURE_REGISTERS, SGXPDump3DSignatureRegistersBW,
+		    sizeof(PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS),
+		    sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SGX_PDUMP_COUNTER_REGISTERS, SGXPDumpCounterRegistersBW,
+		    sizeof(PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS), 0);
+	PVR_IO_NSTD(SGX_PDUMP_TA_SIGNATURE_REGISTERS, SGXPDumpTASignatureRegistersBW,
+		    sizeof(PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS),
+		    sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SGX_PDUMP_HWPERFCB, SGXPDumpHWPerfCBBW,
+		    sizeof(PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB),
+		    sizeof(PVRSRV_BRIDGE_RETURN));
+	PVR_IO_NSTD(SGX_PDUMP_SAVEMEM, SGXPDumpSaveMemBW,
+		    sizeof(PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM),
+		    sizeof(PVRSRV_BRIDGE_RETURN));
+#endif
+}
+ 
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h b/drivers/staging/cdv/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h
new file mode 100644
index 0000000..204450c
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h
@@ -0,0 +1,42 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __BRIDGED_SGX_BRIDGE_H__
+#define __BRIDGED_SGX_BRIDGE_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+IMG_VOID SetSGXDispatchTableEntry(IMG_VOID);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/.gitignore b/drivers/staging/cdv/pvr/services4/srvkm/common/.gitignore
new file mode 100644
index 0000000..2f89523
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/.gitignore
@@ -0,0 +1,5 @@
+bin_pc_i686*
+tmp_pc_i686*
+host_pc_i686*
+*.o
+*.o.cmd
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/buffer_manager.c b/drivers/staging/cdv/pvr/services4/srvkm/common/buffer_manager.c
new file mode 100644
index 0000000..3f8e527
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/buffer_manager.c
@@ -0,0 +1,2531 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+
+#include "sysconfig.h"
+#include "hash.h"
+#include "ra.h"
+#include "pdump_km.h"
+#include "lists.h"
+
+static IMG_BOOL
+ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags);
+static IMG_VOID
+BM_FreeMemory (IMG_VOID *pH, IMG_UINTPTR_T base, BM_MAPPING *psMapping);
+static IMG_BOOL
+BM_ImportMemory(IMG_VOID *pH, IMG_SIZE_T uSize,
+					IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping,
+					IMG_UINT32 uFlags, IMG_UINTPTR_T *pBase);
+
+static IMG_BOOL
+DevMemoryAlloc (BM_CONTEXT *pBMContext,
+				BM_MAPPING *pMapping,
+				IMG_SIZE_T *pActualSize,
+				IMG_UINT32 uFlags,
+				IMG_UINT32 dev_vaddr_alignment,
+				IMG_DEV_VIRTADDR *pDevVAddr);
+static IMG_VOID
+DevMemoryFree (BM_MAPPING *pMapping);
+
+static IMG_BOOL
+AllocMemory (BM_CONTEXT				*pBMContext,
+				BM_HEAP				*psBMHeap,
+				IMG_DEV_VIRTADDR	*psDevVAddr,
+				IMG_SIZE_T			uSize,
+				IMG_UINT32			uFlags,
+				IMG_UINT32			uDevVAddrAlignment,
+				BM_BUF				*pBuf)
+{
+	BM_MAPPING			*pMapping;
+	IMG_UINTPTR_T		uOffset;
+	RA_ARENA			*pArena = IMG_NULL;
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "AllocMemory (uSize=0x%x, uFlags=0x%x, align=0x%x)",
+			  uSize, uFlags, uDevVAddrAlignment));
+
+	
+
+
+	if(uFlags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
+	{
+		if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
+		{
+			
+			PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: combination of DevVAddr management and RAM backing mode unsupported"));
+			return IMG_FALSE;
+		}
+
+		
+
+		
+		if(psBMHeap->ui32Attribs
+		   &	(PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+		   |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+		{
+			
+			pArena = psBMHeap->pImportArena;
+			PVR_ASSERT(psBMHeap->sDevArena.psDeviceMemoryHeapInfo->ui32Attribs & PVRSRV_MEM_RAM_BACKED_ALLOCATION);
+		}
+		else
+		{
+			PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: backing store type doesn't match heap"));
+			return IMG_FALSE;
+		}
+
+		
+		if (!RA_Alloc(pArena,
+					  uSize,
+					  IMG_NULL,
+					  (IMG_VOID*) &pMapping,
+					  uFlags,
+					  uDevVAddrAlignment,
+					  0,
+					  (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr)))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%x) FAILED", uSize));
+			return IMG_FALSE;
+		}
+
+		uOffset = pBuf->DevVAddr.uiAddr - pMapping->DevVAddr.uiAddr;
+		if(pMapping->CpuVAddr)
+		{
+			pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + uOffset);
+		}
+		else
+		{
+			pBuf->CpuVAddr = IMG_NULL;
+		}
+
+		if(uSize == pMapping->uSize)
+		{
+			pBuf->hOSMemHandle = pMapping->hOSMemHandle;
+		}
+		else
+		{
+			if(OSGetSubMemHandle(pMapping->hOSMemHandle,
+								 uOffset,
+								 uSize,
+								 psBMHeap->ui32Attribs,
+								 &pBuf->hOSMemHandle)!=PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSGetSubMemHandle FAILED"));
+				return IMG_FALSE;
+			}
+		}
+
+		
+		pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uOffset;
+
+		if(uFlags & PVRSRV_MEM_ZERO)
+		{
+			if(!ZeroBuf(pBuf, pMapping, uSize, psBMHeap->ui32Attribs | uFlags))
+			{
+				return IMG_FALSE;
+			}
+		}
+	}
+	else
+	{
+		if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
+		{
+			
+			PVR_ASSERT(psDevVAddr != IMG_NULL);
+
+			if (psDevVAddr == IMG_NULL)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "AllocMemory: invalid parameter - psDevVAddr"));
+				return IMG_FALSE;
+			}
+
+			
+			pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
+													uSize,
+													IMG_NULL,
+													PVRSRV_MEM_USER_SUPPLIED_DEVVADDR,
+													uDevVAddrAlignment,
+													psDevVAddr);
+
+			
+			pBuf->DevVAddr = *psDevVAddr;
+		}
+		else
+		{
+			
+
+			
+			pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
+													uSize,
+													IMG_NULL,
+													0,
+													uDevVAddrAlignment,
+													&pBuf->DevVAddr);
+		}
+
+		
+		if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+							sizeof (struct _BM_MAPPING_),
+							(IMG_PVOID *)&pMapping, IMG_NULL,
+							"Buffer Manager Mapping") != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%x) FAILED", sizeof(*pMapping)));
+			return IMG_FALSE;
+		}
+
+		
+		pBuf->CpuVAddr = IMG_NULL;
+		pBuf->hOSMemHandle = 0;
+		pBuf->CpuPAddr.uiAddr = 0;
+
+		
+		pMapping->CpuVAddr = IMG_NULL;
+		pMapping->CpuPAddr.uiAddr = 0;
+		pMapping->DevVAddr = pBuf->DevVAddr;
+		pMapping->psSysAddr = IMG_NULL;
+		pMapping->uSize = uSize;
+		pMapping->hOSMemHandle = 0;
+	}
+
+	
+	pMapping->pArena = pArena;
+
+	
+	pMapping->pBMHeap = psBMHeap;
+	pBuf->pMapping = pMapping;
+
+	
+	PVR_DPF ((PVR_DBG_MESSAGE,
+				"AllocMemory: pMapping=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
+				(IMG_UINTPTR_T)pMapping,
+				pMapping->DevVAddr.uiAddr,
+				(IMG_UINTPTR_T)pMapping->CpuVAddr,
+				pMapping->CpuPAddr.uiAddr,
+				pMapping->uSize));
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+				"AllocMemory: pBuf=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
+				(IMG_UINTPTR_T)pBuf,
+				pBuf->DevVAddr.uiAddr,
+				(IMG_UINTPTR_T)pBuf->CpuVAddr,
+				pBuf->CpuPAddr.uiAddr,
+				uSize));
+
+	
+	PVR_ASSERT(((pBuf->DevVAddr.uiAddr) & (uDevVAddrAlignment - 1)) == 0);
+
+	return IMG_TRUE;
+}
+
+
+static IMG_BOOL
+WrapMemory (BM_HEAP *psBMHeap,
+			IMG_SIZE_T uSize,
+			IMG_SIZE_T ui32BaseOffset,
+			IMG_BOOL bPhysContig,
+			IMG_SYS_PHYADDR *psAddr,
+			IMG_VOID *pvCPUVAddr,
+			IMG_UINT32 uFlags,
+			BM_BUF *pBuf)
+{
+	IMG_DEV_VIRTADDR DevVAddr = {0};
+	BM_MAPPING *pMapping;
+	IMG_BOOL bResult;
+	IMG_SIZE_T const ui32PageSize = HOST_PAGESIZE();
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, bPhysContig=0x%x, pvCPUVAddr = 0x%08x, flags=0x%x)",
+			  (IMG_UINTPTR_T)psBMHeap, uSize, ui32BaseOffset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
+
+	PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0);
+	
+	PVR_ASSERT(((IMG_UINTPTR_T)pvCPUVAddr & (ui32PageSize - 1)) == 0);
+
+	uSize += ui32BaseOffset;
+	uSize = HOST_PAGEALIGN (uSize);
+
+	
+	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof(*pMapping),
+						(IMG_PVOID *)&pMapping, IMG_NULL,
+						"Mocked-up mapping") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED",sizeof(*pMapping)));
+		return IMG_FALSE;
+	}
+
+	OSMemSet(pMapping, 0, sizeof (*pMapping));
+
+	pMapping->uSize = uSize;
+	pMapping->pBMHeap = psBMHeap;
+
+	if(pvCPUVAddr)
+	{
+		pMapping->CpuVAddr = pvCPUVAddr;
+
+		if (bPhysContig)
+		{
+			pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr;
+			pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
+
+			if(OSRegisterMem(pMapping->CpuPAddr,
+							pMapping->CpuVAddr,
+							pMapping->uSize,
+							uFlags,
+							&pMapping->hOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,	"WrapMemory: OSRegisterMem Phys=0x%08X, Size=%d) failed",
+					pMapping->CpuPAddr.uiAddr, pMapping->uSize));
+				goto fail_cleanup;
+			}
+		}
+		else
+		{
+			pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr;
+			pMapping->psSysAddr = psAddr;
+
+			if(OSRegisterDiscontigMem(pMapping->psSysAddr,
+							pMapping->CpuVAddr,
+							pMapping->uSize,
+							uFlags,
+							&pMapping->hOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,	"WrapMemory: OSRegisterDiscontigMem Size=%d) failed",
+					pMapping->uSize));
+				goto fail_cleanup;
+			}
+		}
+	}
+	else
+	{
+		if (bPhysContig)
+		{
+			pMapping->eCpuMemoryOrigin = hm_wrapped;
+			pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
+
+			if(OSReservePhys(pMapping->CpuPAddr,
+							 pMapping->uSize,
+							 uFlags,
+							 &pMapping->CpuVAddr,
+							 &pMapping->hOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,	"WrapMemory: OSReservePhys Phys=0x%08X, Size=%d) failed",
+					pMapping->CpuPAddr.uiAddr, pMapping->uSize));
+				goto fail_cleanup;
+			}
+		}
+		else
+		{
+			pMapping->eCpuMemoryOrigin = hm_wrapped_scatter;
+			pMapping->psSysAddr = psAddr;
+
+			if(OSReserveDiscontigPhys(pMapping->psSysAddr,
+							 pMapping->uSize,
+							 uFlags,
+							 &pMapping->CpuVAddr,
+							 &pMapping->hOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,	"WrapMemory: OSReserveDiscontigPhys Size=%d) failed",
+					pMapping->uSize));
+				goto fail_cleanup;
+			}
+		}
+	}
+
+	
+	bResult = DevMemoryAlloc(psBMHeap->pBMContext,
+							 pMapping,
+							 IMG_NULL,
+							 uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
+							 IMG_CAST_TO_DEVVADDR_UINT(ui32PageSize),
+							 &DevVAddr);
+	if (!bResult)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"WrapMemory: DevMemoryAlloc(0x%x) failed",
+				pMapping->uSize));
+		goto fail_cleanup;
+	}
+
+	
+	pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + ui32BaseOffset;
+	if(!ui32BaseOffset)
+	{
+		pBuf->hOSMemHandle = pMapping->hOSMemHandle;
+	}
+	else
+	{
+		if(OSGetSubMemHandle(pMapping->hOSMemHandle,
+							 ui32BaseOffset,
+							 (pMapping->uSize-ui32BaseOffset),
+							 uFlags,
+							 &pBuf->hOSMemHandle)!=PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed"));
+			goto fail_cleanup;
+		}
+	}
+	if(pMapping->CpuVAddr)
+	{
+		pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + ui32BaseOffset);
+	}
+	pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + IMG_CAST_TO_DEVVADDR_UINT(ui32BaseOffset);
+
+	if(uFlags & PVRSRV_MEM_ZERO)
+	{
+		if(!ZeroBuf(pBuf, pMapping, uSize, uFlags))
+		{
+			return IMG_FALSE;
+		}
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr));
+	PVR_DPF ((PVR_DBG_MESSAGE,
+				"WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
+				pMapping->DevVAddr.uiAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize));
+	PVR_DPF ((PVR_DBG_MESSAGE,
+				"WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
+				pBuf->DevVAddr.uiAddr, pBuf->CpuPAddr.uiAddr, uSize));
+
+	pBuf->pMapping = pMapping;
+	return IMG_TRUE;
+
+fail_cleanup:
+	if(ui32BaseOffset && pBuf->hOSMemHandle)
+	{
+		OSReleaseSubMemHandle(pBuf->hOSMemHandle, uFlags);
+	}
+
+	if(pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
+	{
+		switch(pMapping->eCpuMemoryOrigin)
+		{
+			case hm_wrapped:
+				OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
+				break;
+			case hm_wrapped_virtaddr:
+				OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
+				break;
+			case hm_wrapped_scatter:
+				OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
+				break;
+			case hm_wrapped_scatter_virtaddr:
+				OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
+				break;
+			default:
+				break;
+		}
+
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+	
+
+	return IMG_FALSE;
+}
+
+
+static IMG_BOOL
+ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags)
+{
+	IMG_VOID *pvCpuVAddr;
+
+	if(pBuf->CpuVAddr)
+	{
+		OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes);
+	}
+	else if(pMapping->eCpuMemoryOrigin == hm_contiguous
+			|| pMapping->eCpuMemoryOrigin == hm_wrapped)
+	{
+		pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr,
+									ui32Bytes,
+									PVRSRV_HAP_KERNEL_ONLY
+									| (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
+									IMG_NULL);
+		if(!pvCpuVAddr)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed"));
+			return IMG_FALSE;
+		}
+		OSMemSet(pvCpuVAddr, 0, ui32Bytes);
+		OSUnMapPhysToLin(pvCpuVAddr,
+						 ui32Bytes,
+						 PVRSRV_HAP_KERNEL_ONLY
+						 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
+						 IMG_NULL);
+	}
+	else
+	{
+		IMG_SIZE_T ui32BytesRemaining = ui32Bytes;
+		IMG_SIZE_T ui32CurrentOffset = 0;
+		IMG_CPU_PHYADDR CpuPAddr;
+
+		
+		PVR_ASSERT(pBuf->hOSMemHandle);
+
+		while(ui32BytesRemaining > 0)
+		{
+			IMG_SIZE_T ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE());
+			CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset);
+			
+			if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1))
+			{
+				ui32BlockBytes =
+					MIN(ui32BytesRemaining, (IMG_UINT32)(HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr));
+			}
+
+			pvCpuVAddr = OSMapPhysToLin(CpuPAddr,
+										ui32BlockBytes,
+										PVRSRV_HAP_KERNEL_ONLY
+										| (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
+										IMG_NULL);
+			if(!pvCpuVAddr)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED"));
+				return IMG_FALSE;
+			}
+			OSMemSet(pvCpuVAddr, 0, ui32BlockBytes);
+			OSUnMapPhysToLin(pvCpuVAddr,
+							 ui32BlockBytes,
+							 PVRSRV_HAP_KERNEL_ONLY
+							 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
+							 IMG_NULL);
+
+			ui32BytesRemaining -= ui32BlockBytes;
+			ui32CurrentOffset += ui32BlockBytes;
+		}
+	}
+
+	return IMG_TRUE;
+}
+
+static IMG_VOID
+FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags, IMG_BOOL bFromAllocator)
+{
+	BM_MAPPING *pMapping;
+	/* PVRSRV_DEVICE_NODE *psDeviceNode; */
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			"FreeBuf: pBuf=0x%x: DevVAddr=%08X CpuVAddr=0x%x CpuPAddr=%08X",
+			(IMG_UINTPTR_T)pBuf, pBuf->DevVAddr.uiAddr,
+			(IMG_UINTPTR_T)pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr));
+
+	
+	pMapping = pBuf->pMapping;
+
+	/* XXX even below cache invalidate op is noop on SGX545, be better
+	 * to check why under high GPU/mem load, below object reference could
+	 * go madness.
+	 */
+#if 0
+	psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
+	if (psDeviceNode->pfnCacheInvalidate)
+	{
+		psDeviceNode->pfnCacheInvalidate(psDeviceNode);
+	}
+#endif
+
+	if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
+	{
+		
+		if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+		{
+			
+			if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
+			{
+				
+				PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported"));
+			}
+			else
+			{
+				
+				OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+				pBuf->pMapping = IMG_NULL; 
+			}
+		}
+	}
+	else
+	{
+		
+		if(pBuf->hOSMemHandle != pMapping->hOSMemHandle)
+		{
+            
+			if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+			{
+				
+				OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags);
+			}
+		}
+		if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
+		{
+			
+            
+			if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+			{
+				
+
+
+				PVR_ASSERT(pBuf->ui32ExportCount == 0)
+				RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE);
+			}
+		}
+		else
+		{
+			if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+			{
+				switch (pMapping->eCpuMemoryOrigin)
+				{
+					case hm_wrapped:
+						OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
+						break;
+					case hm_wrapped_virtaddr:
+						OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
+						break;
+					case hm_wrapped_scatter:
+						OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
+						break;
+					case hm_wrapped_scatter_virtaddr:
+						OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
+						break;
+					default:
+						break;
+				}
+			}
+			if (bFromAllocator)
+				DevMemoryFree (pMapping);
+
+			if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+			{
+				
+				OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+				pBuf->pMapping = IMG_NULL; 
+			}
+		}
+	}
+
+
+	if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL);
+		
+	}
+}
+
+static PVRSRV_ERROR BM_DestroyContext_AnyCb(BM_HEAP *psBMHeap)
+{
+	if(psBMHeap->ui32Attribs
+	& 	(PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+		|PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+	{
+		if (psBMHeap->pImportArena)
+		{
+			IMG_BOOL bTestDelete = RA_TestDelete(psBMHeap->pImportArena);
+			if (!bTestDelete)
+			{
+				PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext_AnyCb: RA_TestDelete failed"));
+				return PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP;
+			}
+		}
+	}
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+BM_DestroyContext(IMG_HANDLE	hBMContext,
+				  IMG_BOOL		*pbDestroyed)
+{
+	PVRSRV_ERROR eError;
+	BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "BM_DestroyContext"));
+
+	if (pbDestroyed != IMG_NULL)
+	{
+		*pbDestroyed = IMG_FALSE;
+	}
+
+	
+
+	if (pBMContext == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Invalid handle"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	pBMContext->ui32RefCount--;
+
+	if (pBMContext->ui32RefCount > 0)
+	{
+		
+		return PVRSRV_OK;
+	}
+
+	
+
+
+	eError = List_BM_HEAP_PVRSRV_ERROR_Any(pBMContext->psBMHeap, &BM_DestroyContext_AnyCb);
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: List_BM_HEAP_PVRSRV_ERROR_Any failed"));
+#if 0
+		
+		
+		
+		
+		PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Cleaning up with ResManFreeSpecial"));
+		if(ResManFreeSpecial() != PVRSRV_OK)
+		{
+			PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeSpecial failed %d",eError));
+		}
+		
+#endif
+		return eError;
+	}
+	else
+	{
+		
+		eError = ResManFreeResByPtr(pBMContext->hResItem, CLEANUP_WITH_POLL);
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeResByPtr failed %d",eError));
+			return eError;
+		}
+
+		
+		if (pbDestroyed != IMG_NULL)
+		{
+			*pbDestroyed = IMG_TRUE;
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR BM_DestroyContextCallBack_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
+
+	
+	if(psBMHeap->ui32Attribs
+	& 	(PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+		|PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+	{
+		if (psBMHeap->pImportArena)
+		{
+			RA_Delete (psBMHeap->pImportArena);
+		}
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_DestroyContext: backing store type unsupported"));
+		return PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE;
+	}
+
+	
+	psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap);
+
+	
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
+	
+
+	return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID   pvParam,
+											  IMG_UINT32  ui32Param,
+											  IMG_BOOL    bDummy)
+{
+	BM_CONTEXT *pBMContext = pvParam;
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	
+
+	psDeviceNode = pBMContext->psDeviceNode;
+
+	
+
+	eError = List_BM_HEAP_PVRSRV_ERROR_Any_va(pBMContext->psBMHeap,
+										&BM_DestroyContextCallBack_AnyVaCb,
+										psDeviceNode);
+	if (eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+	
+
+	if (pBMContext->psMMUContext)
+	{
+		psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext);
+	}
+
+	
+
+	if (pBMContext->pBufferHash)
+	{
+		HASH_Delete(pBMContext->pBufferHash);
+	}
+
+	if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext)
+	{
+		
+		psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL;
+	}
+	else
+	{
+	    if (pBMContext->ppsThis != IMG_NULL)
+	    {
+		    
+		    List_BM_CONTEXT_Remove(pBMContext);
+		}
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_CONTEXT), pBMContext, IMG_NULL);
+	
+
+	return PVRSRV_OK;
+}
+
+
+static IMG_HANDLE BM_CreateContext_IncRefCount_AnyVaCb(BM_CONTEXT *pBMContext, va_list va)
+{
+	PRESMAN_CONTEXT	hResManContext;
+	hResManContext = va_arg(va, PRESMAN_CONTEXT);
+	if(ResManFindResourceByPtr(hResManContext, pBMContext->hResItem) == PVRSRV_OK)
+	{
+		
+		pBMContext->ui32RefCount++;
+		return pBMContext;
+	}
+	return IMG_NULL;
+}
+
+static IMG_VOID BM_CreateContext_InsertHeap_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	BM_CONTEXT *pBMContext;
+	psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
+	pBMContext = va_arg(va, BM_CONTEXT*);
+	switch(psBMHeap->sDevArena.DevMemHeapType)
+	{
+		case DEVICE_MEMORY_HEAP_SHARED:
+		case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+		{
+			
+			psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap);
+			break;
+		}
+	}
+}
+
+IMG_HANDLE
+BM_CreateContext(PVRSRV_DEVICE_NODE			*psDeviceNode,
+				 IMG_DEV_PHYADDR			*psPDDevPAddr,
+				 PVRSRV_PER_PROCESS_DATA	*psPerProc,
+				 IMG_BOOL					*pbCreated)
+{
+	BM_CONTEXT			*pBMContext;
+	DEVICE_MEMORY_INFO	*psDevMemoryInfo;
+	IMG_BOOL			bKernelContext;
+	PRESMAN_CONTEXT		hResManContext;
+
+	PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateContext"));
+
+	if (psPerProc == IMG_NULL)
+	{
+		bKernelContext = IMG_TRUE;
+		hResManContext = psDeviceNode->hResManContext;
+	}
+	else
+	{
+		bKernelContext = IMG_FALSE;
+		hResManContext = psPerProc->hResManContext;
+	}
+
+	if (pbCreated != IMG_NULL)
+	{
+		*pbCreated = IMG_FALSE;
+	}
+
+	
+	psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+
+	if (bKernelContext == IMG_FALSE)
+	{
+		IMG_HANDLE res = (IMG_HANDLE) List_BM_CONTEXT_Any_va(psDevMemoryInfo->pBMContext,
+															&BM_CreateContext_IncRefCount_AnyVaCb,
+															hResManContext);
+		if (res)
+		{
+			return res;
+		}
+	}
+
+	
+	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					 sizeof (struct _BM_CONTEXT_),
+					 (IMG_PVOID *)&pBMContext, IMG_NULL,
+					 "Buffer Manager Context") != PVRSRV_OK)
+	{
+		PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed"));
+		return IMG_NULL;
+	}
+	OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT));
+
+	
+	pBMContext->psDeviceNode = psDeviceNode;
+
+	
+	
+	pBMContext->pBufferHash = HASH_Create(32);
+	if (pBMContext->pBufferHash==IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed"));
+		goto cleanup;
+	}
+
+	if((IMG_NULL == psDeviceNode->pfnMMUInitialise) || (psDeviceNode->pfnMMUInitialise(psDeviceNode,
+											&pBMContext->psMMUContext,
+											psPDDevPAddr) != PVRSRV_OK))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed"));
+		goto cleanup;
+	}
+
+	if(bKernelContext)
+	{
+		
+		PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL);
+		psDevMemoryInfo->pBMKernelContext = pBMContext;
+	}
+	else
+	{
+		
+
+
+
+
+		PVR_ASSERT(psDevMemoryInfo->pBMKernelContext);
+
+		if (psDevMemoryInfo->pBMKernelContext == IMG_NULL)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: psDevMemoryInfo->pBMKernelContext invalid"));
+			goto cleanup;
+		}
+
+		PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap);
+
+		
+
+
+
+		pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap;
+
+		
+
+
+		List_BM_HEAP_ForEach_va(pBMContext->psBMSharedHeap,
+								&BM_CreateContext_InsertHeap_ForEachVaCb,
+								psDeviceNode,
+								pBMContext);
+
+		
+		List_BM_CONTEXT_Insert(&psDevMemoryInfo->pBMContext, pBMContext);
+	}
+
+	
+	pBMContext->ui32RefCount++;
+
+	
+	pBMContext->hResItem = ResManRegisterRes(hResManContext,
+											RESMAN_TYPE_DEVICEMEM_CONTEXT,
+											pBMContext,
+											0,
+											&BM_DestroyContextCallBack);
+	if (pBMContext->hResItem == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: ResManRegisterRes failed"));
+		goto cleanup;
+	}
+
+	if (pbCreated != IMG_NULL)
+	{
+		*pbCreated = IMG_TRUE;
+	}
+	return (IMG_HANDLE)pBMContext;
+
+cleanup:
+	(IMG_VOID)BM_DestroyContextCallBack(pBMContext, 0, CLEANUP_WITH_POLL);
+
+	return IMG_NULL;
+}
+
+
+static IMG_VOID *BM_CreateHeap_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+	DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo;
+	psDevMemHeapInfo = va_arg(va, DEVICE_MEMORY_HEAP_INFO*);
+	if (psBMHeap->sDevArena.ui32HeapID ==  psDevMemHeapInfo->ui32HeapID)
+	{
+		
+		return psBMHeap;
+	}
+	else
+	{
+		return IMG_NULL;
+	}
+}
+
+IMG_HANDLE
+BM_CreateHeap (IMG_HANDLE hBMContext,
+			   DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo)
+{
+	BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	BM_HEAP *psBMHeap;
+
+	PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap"));
+
+	if(!pBMContext)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: BM_CONTEXT null"));
+		return IMG_NULL;
+	}
+
+	psDeviceNode = pBMContext->psDeviceNode;
+
+	
+ 
+	PVR_ASSERT((psDevMemHeapInfo->ui32HeapSize & (psDevMemHeapInfo->ui32DataPageSize - 1)) == 0);
+	PVR_ASSERT(psDevMemHeapInfo->ui32HeapSize > 0);
+
+	
+
+
+
+
+	if(pBMContext->ui32RefCount > 0)
+	{
+		psBMHeap = (BM_HEAP*)List_BM_HEAP_Any_va(pBMContext->psBMHeap,
+												 &BM_CreateHeap_AnyVaCb,
+												 psDevMemHeapInfo);
+
+		if (psBMHeap)
+		{
+			return psBMHeap;
+		}
+	}
+
+
+	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof (BM_HEAP),
+						(IMG_PVOID *)&psBMHeap, IMG_NULL,
+						"Buffer Manager Heap") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed"));
+		return IMG_NULL;
+	}
+
+	OSMemSet (psBMHeap, 0, sizeof (BM_HEAP));
+
+	psBMHeap->sDevArena.ui32HeapID = psDevMemHeapInfo->ui32HeapID;
+	psBMHeap->sDevArena.pszName = psDevMemHeapInfo->pszName;
+	psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase;
+	psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize;
+	psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType;
+	psBMHeap->sDevArena.ui32DataPageSize = psDevMemHeapInfo->ui32DataPageSize;
+	psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo;
+	psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs;
+
+	
+	psBMHeap->pBMContext = pBMContext;
+
+	psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext,
+													&psBMHeap->sDevArena,
+													&psBMHeap->pVMArena,
+													&psBMHeap->psMMUAttrib);
+	if (!psBMHeap->pMMUHeap)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed"));
+		goto ErrorExit;
+	}
+
+	
+	psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName,
+										0, 0, IMG_NULL,
+										MAX(HOST_PAGESIZE(), psBMHeap->sDevArena.ui32DataPageSize),
+										&BM_ImportMemory,
+										&BM_FreeMemory,
+										IMG_NULL,
+										psBMHeap);
+	if(psBMHeap->pImportArena == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: RA_Create failed"));
+		goto ErrorExit;
+	}
+
+	if(psBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
+	{
+		
+
+
+
+		psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena;
+		if(psBMHeap->pLocalDevMemArena == IMG_NULL)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null"));
+			goto ErrorExit;
+		}
+	}
+
+	
+	List_BM_HEAP_Insert(&pBMContext->psBMHeap, psBMHeap);
+
+	return (IMG_HANDLE)psBMHeap;
+
+	
+ErrorExit:
+
+	
+	if (psBMHeap->pMMUHeap != IMG_NULL)
+	{
+		psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
+		
+	}
+
+	
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
+	
+
+	return IMG_NULL;
+}
+
+IMG_VOID
+BM_DestroyHeap (IMG_HANDLE hDevMemHeap)
+{
+	BM_HEAP* psBMHeap = (BM_HEAP*)hDevMemHeap;
+	PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
+
+	PVR_DPF((PVR_DBG_MESSAGE, "BM_DestroyHeap"));
+
+	if(psBMHeap)
+	{
+		
+		if(psBMHeap->ui32Attribs
+		&	(PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+			|PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+		{
+			if (psBMHeap->pImportArena)
+			{
+				RA_Delete (psBMHeap->pImportArena);
+			}
+		}
+		else
+		{
+			PVR_DPF((PVR_DBG_ERROR, "BM_DestroyHeap: backing store type unsupported"));
+			return;
+		}
+
+		
+		psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
+
+		
+		List_BM_HEAP_Remove(psBMHeap);
+		
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
+		
+	}
+	else
+	{
+		PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle"));
+	}
+}
+
+
+IMG_BOOL
+BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+
+	PVR_DPF((PVR_DBG_MESSAGE, "BM_Reinitialise"));
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+
+
+	return IMG_TRUE;
+}
+
+IMG_BOOL
+BM_Alloc (  IMG_HANDLE			hDevMemHeap,
+			IMG_DEV_VIRTADDR	*psDevVAddr,
+			IMG_SIZE_T			uSize,
+			IMG_UINT32			*pui32Flags,
+			IMG_UINT32			uDevVAddrAlignment,
+			BM_HANDLE			*phBuf)
+{
+	BM_BUF *pBuf;
+	BM_CONTEXT *pBMContext;
+	BM_HEAP *psBMHeap;
+	SYS_DATA *psSysData;
+	IMG_UINT32 uFlags;
+
+	if (pui32Flags == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: invalid parameter"));
+		PVR_DBG_BREAK;
+		return IMG_FALSE;
+	}
+
+	uFlags = *pui32Flags;
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+		  "BM_Alloc (uSize=0x%x, uFlags=0x%x, uDevVAddrAlignment=0x%x)",
+			uSize, uFlags, uDevVAddrAlignment));
+
+	SysAcquireData(&psSysData);
+
+	psBMHeap = (BM_HEAP*)hDevMemHeap;
+	pBMContext = psBMHeap->pBMContext;
+
+	if(uDevVAddrAlignment == 0)
+	{
+		uDevVAddrAlignment = 1;
+	}
+
+	
+	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				   sizeof (BM_BUF),
+				   (IMG_PVOID *)&pBuf, IMG_NULL,
+				   "Buffer Manager buffer") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED"));
+		return IMG_FALSE;
+	}
+	OSMemSet(pBuf, 0, sizeof (BM_BUF));
+
+	
+	if (AllocMemory(pBMContext,
+					psBMHeap,
+					psDevVAddr,
+					uSize,
+					uFlags,
+					uDevVAddrAlignment,
+					pBuf) != IMG_TRUE)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
+		
+		PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: AllocMemory FAILED"));
+		return IMG_FALSE;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+		  "BM_Alloc (uSize=0x%x, uFlags=0x%x)",
+		  uSize, uFlags));
+
+	
+	pBuf->ui32RefCount = 1;
+	*phBuf = (BM_HANDLE)pBuf;
+	*pui32Flags = uFlags | psBMHeap->ui32Attribs;
+
+	
+	if(uFlags & PVRSRV_HAP_CACHETYPE_MASK)
+	{
+		*pui32Flags &= ~PVRSRV_HAP_CACHETYPE_MASK;
+		*pui32Flags |= (uFlags & PVRSRV_HAP_CACHETYPE_MASK);
+	}
+
+	return IMG_TRUE;
+}
+
+
+
+#if defined(PVR_LMA)
+static IMG_BOOL
+ValidSysPAddrArrayForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR *psSysPAddr, IMG_UINT32 ui32PageCount, IMG_SIZE_T ui32PageSize)
+{
+	IMG_UINT32 i;
+
+	for (i = 0; i < ui32PageCount; i++)
+	{
+		IMG_SYS_PHYADDR sStartSysPAddr = psSysPAddr[i];
+		IMG_SYS_PHYADDR sEndSysPAddr;
+
+		if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
+		{
+			return IMG_FALSE;
+		}
+
+		sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32PageSize;
+
+		if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
+		{
+			return IMG_FALSE;
+		}
+	}
+
+	return IMG_TRUE;
+}
+
+static IMG_BOOL
+ValidSysPAddrRangeForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR sStartSysPAddr, IMG_SIZE_T ui32Range)
+{
+	IMG_SYS_PHYADDR sEndSysPAddr;
+
+	if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
+	{
+		return IMG_FALSE;
+	}
+
+	sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32Range;
+
+	if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
+	{
+		return IMG_FALSE;
+	}
+
+	return IMG_TRUE;
+}
+
+#define	WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) HOST_PAGEALIGN((ui32ByteSize) + (ui32PageOffset))
+
+#define	WRAP_PAGE_COUNT(ui32ByteSize, ui32PageOffset, ui32HostPageSize)	(WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) / (ui32HostPageSize))
+
+#endif
+
+
+IMG_BOOL
+BM_Wrap (	IMG_HANDLE hDevMemHeap,
+			IMG_SIZE_T ui32Size,
+			IMG_SIZE_T ui32Offset,
+			IMG_BOOL bPhysContig,
+			IMG_SYS_PHYADDR *psSysAddr,
+			IMG_VOID *pvCPUVAddr,
+			IMG_UINT32 *pui32Flags,
+			BM_HANDLE *phBuf)
+{
+	BM_BUF *pBuf;
+	BM_CONTEXT *psBMContext;
+	BM_HEAP *psBMHeap;
+	SYS_DATA *psSysData;
+	IMG_SYS_PHYADDR sHashAddress;
+	IMG_UINT32 uFlags;
+
+	psBMHeap = (BM_HEAP*)hDevMemHeap;
+	psBMContext = psBMHeap->pBMContext;
+
+	uFlags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK);
+
+	if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0))
+	{
+		uFlags &= ~PVRSRV_HAP_CACHETYPE_MASK;
+		uFlags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+		  "BM_Wrap (uSize=0x%x, uOffset=0x%x, bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
+			ui32Size, ui32Offset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
+
+	SysAcquireData(&psSysData);
+
+#if defined(PVR_LMA)
+	if (bPhysContig)
+	{
+		if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(ui32Size, ui32Offset)))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device"));
+			return IMG_FALSE;
+		}
+	}
+	else
+	{
+		IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
+
+		if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(ui32Size, ui32Offset, ui32HostPageSize), ui32HostPageSize))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device"));
+			return IMG_FALSE;
+		}
+	}
+#endif
+	
+	sHashAddress = psSysAddr[0];
+
+	
+	sHashAddress.uiAddr += ui32Offset;
+
+	
+	pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, sHashAddress.uiAddr);
+
+	if(pBuf)
+	{
+		IMG_SIZE_T ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset);
+
+		
+		if(pBuf->pMapping->uSize == ui32MappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
+														pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr))
+		{
+			PVR_DPF((PVR_DBG_MESSAGE,
+					"BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)",
+					ui32Size, ui32Offset, sHashAddress.uiAddr));
+
+			pBuf->ui32RefCount++;
+			*phBuf = (BM_HANDLE)pBuf;
+			if(pui32Flags)
+				*pui32Flags = uFlags;
+
+			return IMG_TRUE;
+		}
+		else
+		{
+		  
+			HASH_Remove(psBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddress.uiAddr);
+		}	
+	}
+
+	
+	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof (BM_BUF),
+						(IMG_PVOID *)&pBuf, IMG_NULL,
+						"Buffer Manager buffer") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"));
+		return IMG_FALSE;
+	}
+	OSMemSet(pBuf, 0, sizeof (BM_BUF));
+
+	
+	if (WrapMemory (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, uFlags, pBuf) != IMG_TRUE)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED"));
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
+		
+		return IMG_FALSE;
+	}
+
+	
+	if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
+	{
+		
+		PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr);
+
+		if (!HASH_Insert (psBMContext->pBufferHash, sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf))
+		{
+			FreeBuf (pBuf, uFlags, IMG_TRUE);
+			PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED"));
+			return IMG_FALSE;
+		}
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			"BM_Wrap (uSize=0x%x, uFlags=0x%x, devVAddr=%08X)",
+			ui32Size, uFlags, pBuf->DevVAddr.uiAddr));
+
+	
+	pBuf->ui32RefCount = 1;
+	*phBuf = (BM_HANDLE)pBuf;
+	if(pui32Flags)
+	{
+		
+		*pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS;
+	}
+
+	return IMG_TRUE;
+}
+
+IMG_VOID
+BM_Export (BM_HANDLE hBuf)
+{
+	BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+	pBuf->ui32ExportCount++;
+}
+
+IMG_VOID
+BM_FreeExport(BM_HANDLE hBuf,
+		IMG_UINT32 ui32Flags)
+{
+	BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+	pBuf->ui32ExportCount--;
+	FreeBuf (pBuf, ui32Flags, IMG_FALSE);
+}
+
+IMG_VOID
+BM_Free (BM_HANDLE hBuf,
+		IMG_UINT32 ui32Flags)
+{
+	BM_BUF *pBuf = (BM_BUF *)hBuf;
+	SYS_DATA *psSysData;
+	IMG_SYS_PHYADDR sHashAddr;
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "BM_Free (h=0x%x)", (IMG_UINTPTR_T)hBuf));
+	PVR_ASSERT (pBuf!=IMG_NULL);
+
+	if (pBuf == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_Free: invalid parameter"));
+		return;
+	}
+
+	SysAcquireData(&psSysData);
+
+	pBuf->ui32RefCount--;
+
+	if(pBuf->ui32RefCount == 0)
+	{
+		if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
+		{
+			sHashAddr = SysCpuPAddrToSysPAddr(pBuf->CpuPAddr);
+
+			HASH_Remove (pBuf->pMapping->pBMHeap->pBMContext->pBufferHash,	(IMG_UINTPTR_T)sHashAddr.uiAddr);
+		}
+		FreeBuf (pBuf, ui32Flags, IMG_TRUE);
+	}
+}
+
+
+IMG_CPU_VIRTADDR
+BM_HandleToCpuVaddr (BM_HANDLE hBuf)
+{
+	BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+	PVR_ASSERT (pBuf != IMG_NULL);
+	if (pBuf == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_HandleToCpuVaddr: invalid parameter"));
+		return IMG_NULL;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+				"BM_HandleToCpuVaddr(h=0x%x)=0x%x",
+				(IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->CpuVAddr));
+	return pBuf->CpuVAddr;
+}
+
+
+IMG_DEV_VIRTADDR
+BM_HandleToDevVaddr (BM_HANDLE hBuf)
+{
+	BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+	PVR_ASSERT (pBuf != IMG_NULL);
+	if (pBuf == IMG_NULL)
+	{
+		IMG_DEV_VIRTADDR	DevVAddr = {0};
+		PVR_DPF((PVR_DBG_ERROR, "BM_HandleToDevVaddr: invalid parameter"));
+		return DevVAddr;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToDevVaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->DevVAddr.uiAddr));
+	return pBuf->DevVAddr;
+}
+
+
+IMG_SYS_PHYADDR
+BM_HandleToSysPaddr (BM_HANDLE hBuf)
+{
+	BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+	PVR_ASSERT (pBuf != IMG_NULL);
+
+	if (pBuf == IMG_NULL)
+	{
+		IMG_SYS_PHYADDR	PhysAddr = {0};
+		PVR_DPF((PVR_DBG_ERROR, "BM_HandleToSysPaddr: invalid parameter"));
+		return PhysAddr;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToSysPaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->CpuPAddr.uiAddr));
+	return SysCpuPAddrToSysPAddr (pBuf->CpuPAddr);
+}
+
+IMG_HANDLE
+BM_HandleToOSMemHandle(BM_HANDLE hBuf)
+{
+	BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+	PVR_ASSERT (pBuf != IMG_NULL);
+
+	if (pBuf == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_HandleToOSMemHandle: invalid parameter"));
+		return IMG_NULL;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+				"BM_HandleToOSMemHandle(h=0x%x)=0x%x",
+				(IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->hOSMemHandle));
+	return pBuf->hOSMemHandle;
+}
+
+static IMG_BOOL
+DevMemoryAlloc (BM_CONTEXT *pBMContext,
+				BM_MAPPING *pMapping,
+				IMG_SIZE_T *pActualSize,
+				IMG_UINT32 uFlags,
+				IMG_UINT32 dev_vaddr_alignment,
+				IMG_DEV_VIRTADDR *pDevVAddr)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+#ifdef PDUMP
+	IMG_UINT32 ui32PDumpSize = (IMG_UINT32)pMapping->uSize;
+#endif
+
+	psDeviceNode = pBMContext->psDeviceNode;
+
+	if(uFlags & PVRSRV_MEM_INTERLEAVED)
+	{
+		
+		pMapping->uSize *= 2;
+	}
+
+#ifdef PDUMP
+	if(uFlags & PVRSRV_MEM_DUMMY)
+	{
+		
+		ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
+	}
+#endif
+
+	
+	if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap,
+									pMapping->uSize,
+									pActualSize,
+									0,
+									dev_vaddr_alignment,
+									&(pMapping->DevVAddr)))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc"));
+		return IMG_FALSE;
+	}
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+	EnableHostAccess(pBMContext->psMMUContext);
+#endif
+
+#if defined(PDUMP)
+	
+	PDUMPMALLOCPAGES(&psDeviceNode->sDevId,
+					 pMapping->DevVAddr.uiAddr,
+					 pMapping->CpuVAddr,
+					 pMapping->hOSMemHandle,
+					 ui32PDumpSize,
+					 pMapping->pBMHeap->sDevArena.ui32DataPageSize,
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+					 psDeviceNode->pfnMMUIsHeapShared(pMapping->pBMHeap->pMMUHeap),
+#else
+					 IMG_FALSE, 
+#endif 
+					 (IMG_HANDLE)pMapping);
+#endif
+
+	switch (pMapping->eCpuMemoryOrigin)
+	{
+		case hm_wrapped:
+		case hm_wrapped_virtaddr:
+		case hm_contiguous:
+		{
+			psDeviceNode->pfnMMUMapPages (	pMapping->pBMHeap->pMMUHeap,
+							pMapping->DevVAddr,
+							SysCpuPAddrToSysPAddr (pMapping->CpuPAddr),
+							pMapping->uSize,
+							uFlags,
+							(IMG_HANDLE)pMapping);
+
+			*pDevVAddr = pMapping->DevVAddr;
+			break;
+		}
+		case hm_env:
+		{
+			psDeviceNode->pfnMMUMapShadow (	pMapping->pBMHeap->pMMUHeap,
+							pMapping->DevVAddr,
+							pMapping->uSize,
+							pMapping->CpuVAddr,
+							pMapping->hOSMemHandle,
+							pDevVAddr,
+							uFlags,
+							(IMG_HANDLE)pMapping);
+			break;
+		}
+		case hm_wrapped_scatter:
+		case hm_wrapped_scatter_virtaddr:
+		{
+			psDeviceNode->pfnMMUMapScatter (pMapping->pBMHeap->pMMUHeap,
+							pMapping->DevVAddr,
+							pMapping->psSysAddr,
+							pMapping->uSize,
+							uFlags,
+							(IMG_HANDLE)pMapping);
+
+			*pDevVAddr = pMapping->DevVAddr;
+			break;
+		}
+		default:
+			PVR_DPF((PVR_DBG_ERROR,
+				"Illegal value %d for pMapping->eCpuMemoryOrigin",
+				pMapping->eCpuMemoryOrigin));
+			return IMG_FALSE;
+	}
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+	DisableHostAccess(pBMContext->psMMUContext);
+#endif
+
+	return IMG_TRUE;
+}
+
+static IMG_VOID
+DevMemoryFree (BM_MAPPING *pMapping)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_DEV_PHYADDR     sDevPAddr;
+#ifdef PDUMP
+	IMG_UINT32 ui32PSize;
+#endif
+
+	psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
+	sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr);
+
+	if (sDevPAddr.uiAddr != 0)
+	{
+#ifdef PDUMP
+		
+		if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+		{
+			
+			ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
+		}
+		else
+		{
+			ui32PSize = (IMG_UINT32)pMapping->uSize;
+		}
+	
+		PDUMPFREEPAGES(pMapping->pBMHeap,
+	                    pMapping->DevVAddr,
+	                    ui32PSize,
+	                    pMapping->pBMHeap->sDevArena.ui32DataPageSize,
+	                    (IMG_HANDLE)pMapping,
+	                    (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) ? IMG_TRUE : IMG_FALSE);
+#endif
+	}
+	psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, IMG_CAST_TO_DEVVADDR_UINT(pMapping->uSize));
+}
+
+#ifndef XPROC_WORKAROUND_NUM_SHAREABLES
+#define XPROC_WORKAROUND_NUM_SHAREABLES 4096
+#endif
+
+#define XPROC_WORKAROUND_BAD_SHAREINDEX 0773407734
+
+static IMG_UINT32 gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
+
+ 
+static struct BM_XProcWorkaround {
+	IMG_UINT32 ui32RefCount;
+	IMG_UINT32 ui32AllocFlags;
+	IMG_UINT32 ui32Size;
+	IMG_UINT32 ui32PageSize;
+	RA_ARENA *psArena;
+	IMG_SYS_PHYADDR sSysPAddr;
+	IMG_VOID *pvCpuVAddr;
+	IMG_HANDLE hOSMemHandle;
+} *gXProcWorkaroundShareData;
+
+static IMG_UINT32 gXProcWorkaroundShareSize;
+static IMG_UINT32 gXProcWorkaroundShareCount;
+
+PVRSRV_ERROR BM_XProcWorkaroundShareInit(void)
+{
+	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+		       XPROC_WORKAROUND_NUM_SHAREABLES * sizeof(struct BM_XProcWorkaround),
+		       (IMG_PVOID *)&gXProcWorkaroundShareData, IMG_NULL,
+		       "XProc Workaround") != PVRSRV_OK)
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+
+	gXProcWorkaroundShareSize = XPROC_WORKAROUND_NUM_SHAREABLES;
+	gXProcWorkaroundShareCount = 0;
+	return PVRSRV_OK;
+}
+
+void BM_XProcWorkaroundShareDestroy(void)
+{
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, gXProcWorkaroundShareSize * sizeof(struct BM_XProcWorkaround),
+		  gXProcWorkaroundShareData, IMG_NULL);
+}
+
+void XProcWorkaroundShareCheck(void)
+{
+	if (gXProcWorkaroundShareCount == gXProcWorkaroundShareSize) {
+		struct BM_XProcWorkaround *temp, *p;
+		IMG_UINT32 new_size = gXProcWorkaroundShareSize + gXProcWorkaroundShareSize / 2;
+
+		if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+			       new_size * sizeof(struct BM_XProcWorkaround),
+			       (IMG_PVOID *)&p, IMG_NULL,
+			       "XProc Workaround") != PVRSRV_OK)
+			return;
+		memset(p, 0, new_size * sizeof(struct BM_XProcWorkaround));
+
+		memcpy(p, gXProcWorkaroundShareData, gXProcWorkaroundShareSize * sizeof(struct BM_XProcWorkaround));
+
+		temp = gXProcWorkaroundShareData;
+		gXProcWorkaroundShareData = p;
+
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, gXProcWorkaroundShareSize * sizeof(struct BM_XProcWorkaround),
+				temp, IMG_NULL);
+
+		gXProcWorkaroundShareSize = new_size;
+	}
+}
+
+PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index)
+{
+	
+
+
+	if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "No, it's already set!"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	gXProcWorkaroundShareIndex = ui32Index;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index)
+{
+	
+
+
+	if (gXProcWorkaroundShareIndex == XPROC_WORKAROUND_BAD_SHAREINDEX)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "huh?   how can it be bad??"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+	if (gXProcWorkaroundShareIndex != ui32Index)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "gXProcWorkaroundShareIndex == 0x%08x != 0x%08x == ui32Index", gXProcWorkaroundShareIndex, ui32Index));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index)
+{
+	
+
+
+	if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	for (*pui32Index = 0; *pui32Index < gXProcWorkaroundShareSize; (*pui32Index)++)
+	{
+		if (gXProcWorkaroundShareData[*pui32Index].ui32RefCount == 0)
+		{
+			gXProcWorkaroundShareIndex = *pui32Index;
+			return PVRSRV_OK;
+		}
+	}
+
+	PVR_DPF((PVR_DBG_ERROR, "ran out of shared buffers"));
+	return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+IMG_UINT32 BM_XProcWorkaroundGetRefCount(IMG_UINT32 ui32Index)
+{
+	return gXProcWorkaroundShareData[ui32Index].ui32RefCount;
+}
+
+static PVRSRV_ERROR
+XProcWorkaroundAllocShareable(RA_ARENA *psArena,
+                              IMG_UINT32 ui32AllocFlags,
+                              IMG_UINT32 ui32Size,
+                              IMG_UINT32 ui32PageSize,
+                              IMG_VOID **ppvCpuVAddr,
+                              IMG_HANDLE *phOSMemHandle)
+{
+	if ((ui32AllocFlags & PVRSRV_MEM_XPROC) == 0)
+	{
+		PVR_DPF((PVR_DBG_VERBOSE, "XProcWorkaroundAllocShareable: bad flags"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	if (gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount > 0)
+	{
+		PVR_DPF((PVR_DBG_VERBOSE,
+				 "XProcWorkaroundAllocShareable: re-using previously allocated pages"));
+
+		ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK;
+		ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS;
+
+		if (ui32AllocFlags != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+					 "Can't!  Flags don't match! (I had 0x%08x, you gave 0x%08x)",
+					 gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags,
+					 ui32AllocFlags));
+			return PVRSRV_ERROR_INVALID_PARAMS;
+		}
+
+		if (ui32Size != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+					 "Can't!  Size doesn't match!"));
+			return PVRSRV_ERROR_INVALID_PARAMS;
+		}
+
+		if (ui32PageSize != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+					 "Can't!  Page Size doesn't match!"));
+			return PVRSRV_ERROR_INVALID_PARAMS;
+		}
+
+		*ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
+		*phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
+
+		gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount ++;
+
+		return PVRSRV_OK;
+	}
+	else
+	{
+		if (psArena != IMG_NULL)
+		{
+			IMG_CPU_PHYADDR sCpuPAddr;
+			IMG_SYS_PHYADDR sSysPAddr;
+
+			PVR_DPF((PVR_DBG_VERBOSE,
+					 "XProcWorkaroundAllocShareable: making a NEW allocation from local mem"));
+
+			if (!RA_Alloc (psArena,
+						   ui32Size,
+						   IMG_NULL,
+						   IMG_NULL,
+						   0,
+						   ui32PageSize,
+						   0,
+						   (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
+			{
+				PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: RA_Alloc(0x%x) FAILED", ui32Size));
+				return PVRSRV_ERROR_OUT_OF_MEMORY;
+			}
+
+			sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+			if(OSReservePhys(sCpuPAddr,
+							 ui32Size,
+							 ui32AllocFlags,
+							 (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr,
+                             &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,	"XProcWorkaroundAllocShareable: OSReservePhys failed"));
+				return PVRSRV_ERROR_OUT_OF_MEMORY;
+			}
+			gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].sSysPAddr = sSysPAddr;
+		}
+		else
+		{
+			PVR_DPF((PVR_DBG_VERBOSE, "XProcWorkaroundAllocShareable: making a NEW allocation from OS"));
+
+			ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK;
+			ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS;
+
+            
+			if (OSAllocPages(ui32AllocFlags,
+					 ui32Size,
+					 ui32PageSize,
+					 (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr,
+					 &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: OSAllocPages(0x%x) failed",
+							ui32PageSize));
+				return PVRSRV_ERROR_OUT_OF_MEMORY;
+			}
+		}
+
+		gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].psArena = psArena;
+		gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags = ui32AllocFlags;
+		gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size = ui32Size;
+		gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize = ui32PageSize;
+
+		*ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
+		*phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
+
+		gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount ++;
+
+		gXProcWorkaroundShareCount++;
+
+		XProcWorkaroundShareCheck();
+
+		return PVRSRV_OK;
+	}
+}
+
+static PVRSRV_ERROR XProcWorkaroundHandleToSI(IMG_HANDLE hOSMemHandle, IMG_UINT32 *pui32SI)
+{
+	
+	IMG_UINT32 ui32SI;
+	IMG_BOOL bFound;
+	IMG_BOOL bErrorDups;
+
+	bFound = IMG_FALSE;
+	bErrorDups = IMG_FALSE;
+
+	for (ui32SI = 0; ui32SI < gXProcWorkaroundShareSize; ui32SI++)
+	{
+		if (gXProcWorkaroundShareData[ui32SI].ui32RefCount>0 && gXProcWorkaroundShareData[ui32SI].hOSMemHandle == hOSMemHandle)
+		{
+			if (bFound)
+			{
+				bErrorDups = IMG_TRUE;
+			}
+			else
+			{
+				*pui32SI = ui32SI;
+				bFound = IMG_TRUE;
+			}
+		}
+	}
+
+	if (bErrorDups || !bFound)
+	{
+		return PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE;
+	}
+
+	return PVRSRV_OK;
+}
+
+static IMG_VOID XProcWorkaroundFreeShareable(IMG_HANDLE hOSMemHandle)
+{
+	IMG_UINT32 ui32SI = (IMG_UINT32)((IMG_UINTPTR_T)hOSMemHandle & 0xffffU);
+	PVRSRV_ERROR eError;
+
+	eError = XProcWorkaroundHandleToSI(hOSMemHandle, &ui32SI);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "bad handle"));
+		return;
+	}
+
+	gXProcWorkaroundShareData[ui32SI].ui32RefCount --;
+
+	PVR_DPF((PVR_DBG_VERBOSE, "Reduced refcount of SI[%d] from %d to %d",
+			 ui32SI, gXProcWorkaroundShareData[ui32SI].ui32RefCount+1, gXProcWorkaroundShareData[ui32SI].ui32RefCount));
+
+	if (gXProcWorkaroundShareData[ui32SI].ui32RefCount == 0)
+	{
+		if (gXProcWorkaroundShareData[ui32SI].psArena != IMG_NULL)
+		{
+			IMG_SYS_PHYADDR sSysPAddr;
+
+			if (gXProcWorkaroundShareData[ui32SI].pvCpuVAddr != IMG_NULL)
+			{
+				OSUnReservePhys(gXProcWorkaroundShareData[ui32SI].pvCpuVAddr,
+								gXProcWorkaroundShareData[ui32SI].ui32Size,
+								gXProcWorkaroundShareData[ui32SI].ui32AllocFlags,
+								gXProcWorkaroundShareData[ui32SI].hOSMemHandle);
+			}
+			sSysPAddr = gXProcWorkaroundShareData[ui32SI].sSysPAddr;
+			RA_Free (gXProcWorkaroundShareData[ui32SI].psArena,
+					 sSysPAddr.uiAddr,
+					 IMG_FALSE);
+		}
+		else
+		{
+			PVR_DPF((PVR_DBG_VERBOSE, "freeing OS memory"));
+			OSFreePages(gXProcWorkaroundShareData[ui32SI].ui32AllocFlags,
+						gXProcWorkaroundShareData[ui32SI].ui32PageSize,
+						gXProcWorkaroundShareData[ui32SI].pvCpuVAddr,
+						gXProcWorkaroundShareData[ui32SI].hOSMemHandle);
+		}
+		gXProcWorkaroundShareCount--;
+	}
+}
+
+
+static IMG_BOOL
+BM_ImportMemory (IMG_VOID *pH,
+			  IMG_SIZE_T uRequestSize,
+			  IMG_SIZE_T *pActualSize,
+			  BM_MAPPING **ppsMapping,
+			  IMG_UINT32 uFlags,
+			  IMG_UINTPTR_T *pBase)
+{
+	BM_MAPPING *pMapping;
+	BM_HEAP *pBMHeap = pH;
+	BM_CONTEXT *pBMContext = pBMHeap->pBMContext;
+	IMG_BOOL bResult;
+	IMG_SIZE_T uSize;
+	IMG_SIZE_T uPSize;
+	IMG_SIZE_T uDevVAddrAlignment = 0; 
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "BM_ImportMemory (pBMContext=0x%x, uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)",
+			  (IMG_UINTPTR_T)pBMContext, uRequestSize, uFlags, uDevVAddrAlignment));
+
+	PVR_ASSERT (ppsMapping != IMG_NULL);
+	PVR_ASSERT (pBMContext != IMG_NULL);
+
+	if (ppsMapping == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter"));
+		goto fail_exit;
+	}
+
+	uSize = HOST_PAGEALIGN (uRequestSize);
+	PVR_ASSERT (uSize >= uRequestSize);
+
+	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof (BM_MAPPING),
+						(IMG_PVOID *)&pMapping, IMG_NULL,
+						"Buffer Manager Mapping") != PVRSRV_OK)
+	{
+		PVR_DPF ((PVR_DBG_ERROR, "BM_ImportMemory: failed BM_MAPPING alloc"));
+		goto fail_exit;
+	}
+
+	pMapping->hOSMemHandle = 0;
+	pMapping->CpuVAddr = 0;
+	pMapping->DevVAddr.uiAddr = 0;
+	pMapping->CpuPAddr.uiAddr = 0;
+	pMapping->uSize = uSize;
+	pMapping->pBMHeap = pBMHeap;
+	pMapping->ui32Flags = uFlags;
+
+	
+	if (pActualSize)
+	{
+		*pActualSize = uSize;
+	}
+
+	
+	if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+	{
+		uPSize = pBMHeap->sDevArena.ui32DataPageSize;
+	}
+	else
+	{
+		uPSize = pMapping->uSize;
+	}
+
+	if (uFlags & PVRSRV_MEM_XPROC)
+	{
+		IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs | PVRSRV_MEM_XPROC;
+        IMG_BOOL bBadBackingStoreType;
+
+        bBadBackingStoreType = IMG_TRUE; 
+
+		if ((ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) != 0)
+        {
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+		uDevVAddrAlignment = MAX(pBMHeap->sDevArena.ui32DataPageSize, HOST_PAGESIZE());
+
+
+		if (uPSize % uDevVAddrAlignment != 0)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated"));
+			goto fail_mapping_alloc;
+		}
+		uDevVAddrAlignment = 0; 
+
+		
+		if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+		{
+			ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+			ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+		}
+
+		
+		if (XProcWorkaroundAllocShareable(IMG_NULL,
+                                          ui32Attribs,
+							   (IMG_UINT32)uPSize,
+                                          pBMHeap->sDevArena.ui32DataPageSize,
+                                          (IMG_VOID **)&pMapping->CpuVAddr,
+                                          &pMapping->hOSMemHandle) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+					"BM_ImportMemory: XProcWorkaroundAllocShareable(0x%x) failed",
+					uPSize));
+			goto fail_mapping_alloc;
+		}
+
+		
+		
+
+		pMapping->eCpuMemoryOrigin = hm_env;
+        bBadBackingStoreType = IMG_FALSE;
+        }
+
+		if ((ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) != 0)
+        {
+			uDevVAddrAlignment = pBMHeap->sDevArena.ui32DataPageSize;
+
+            if (uPSize % uDevVAddrAlignment != 0)
+            {
+                PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated"));
+                goto fail_mapping_alloc;
+            }
+            uDevVAddrAlignment = 0; 
+
+            
+            if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+            {
+                ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+                ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+            }
+
+            
+            if (XProcWorkaroundAllocShareable(pBMHeap->pLocalDevMemArena,
+                                              ui32Attribs,
+                                              (IMG_UINT32)uPSize,
+                                              pBMHeap->sDevArena.ui32DataPageSize,
+                                              (IMG_VOID **)&pMapping->CpuVAddr,
+                                              &pMapping->hOSMemHandle) != PVRSRV_OK)
+            {
+                PVR_DPF((PVR_DBG_ERROR,
+                         "BM_ImportMemory: XProcWorkaroundAllocShareable(0x%x) failed",
+                         uPSize));
+                goto fail_mapping_alloc;
+            }
+
+            
+            
+
+            pMapping->eCpuMemoryOrigin = hm_env;
+            bBadBackingStoreType = IMG_FALSE;
+        }
+
+        if (bBadBackingStoreType)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "Cannot use this memory sharing workaround with this type of backing store"));
+			goto fail_mapping_alloc;
+		}
+	}
+	else
+
+	
+
+	if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
+	{
+		IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
+
+		
+		if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+		{
+			ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+			ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+		}
+
+		
+		if (OSAllocPages(ui32Attribs,
+						 uPSize,
+						 pBMHeap->sDevArena.ui32DataPageSize,
+						 (IMG_VOID **)&pMapping->CpuVAddr,
+						 &pMapping->hOSMemHandle) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+					"BM_ImportMemory: OSAllocPages(0x%x) failed",
+					uPSize));
+			goto fail_mapping_alloc;
+		}
+
+		
+		pMapping->eCpuMemoryOrigin = hm_env;
+	}
+	else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
+	{
+		IMG_SYS_PHYADDR sSysPAddr;
+		IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
+
+		
+		PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL);
+
+		
+		if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+		{
+			ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+			ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+		}
+
+		if (!RA_Alloc (pBMHeap->pLocalDevMemArena,
+					   uPSize,
+					   IMG_NULL,
+					   IMG_NULL,
+					   0,
+					   pBMHeap->sDevArena.ui32DataPageSize,
+					   0,
+					   (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize));
+			goto fail_mapping_alloc;
+		}
+
+		
+		pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+		if(OSReservePhys(pMapping->CpuPAddr,
+						 uPSize,
+						 ui32Attribs,
+						 &pMapping->CpuVAddr,
+						 &pMapping->hOSMemHandle) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,	"BM_ImportMemory: OSReservePhys failed"));
+			goto fail_dev_mem_alloc;
+		}
+
+		
+		pMapping->eCpuMemoryOrigin = hm_contiguous;
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR,	"BM_ImportMemory: Invalid backing store type"));
+		goto fail_mapping_alloc;
+	}
+
+	
+	bResult = DevMemoryAlloc (pBMContext,
+								pMapping,
+								IMG_NULL,
+								uFlags,
+								(IMG_UINT32)uDevVAddrAlignment,
+								&pMapping->DevVAddr);
+	if (!bResult)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"BM_ImportMemory: DevMemoryAlloc(0x%x) failed",
+				pMapping->uSize));
+		goto fail_dev_mem_alloc;
+	}
+
+	
+	
+	PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1);
+
+	*pBase = pMapping->DevVAddr.uiAddr;
+	*ppsMapping = pMapping;
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE"));
+	return IMG_TRUE;
+
+fail_dev_mem_alloc:
+	if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
+	{
+		
+		if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED)
+		{
+			pMapping->uSize /= 2;
+		}
+
+		if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+		{
+			uPSize = pBMHeap->sDevArena.ui32DataPageSize;
+		}
+		else
+		{
+			uPSize = pMapping->uSize;
+		}
+
+		if (uFlags & PVRSRV_MEM_XPROC)
+		{
+			XProcWorkaroundFreeShareable(pMapping->hOSMemHandle);
+		}
+		else
+        if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
+		{
+			OSFreePages(pBMHeap->ui32Attribs,
+						  uPSize,
+						  (IMG_VOID *)pMapping->CpuVAddr,
+						  pMapping->hOSMemHandle);
+		}
+		else
+		{
+			IMG_SYS_PHYADDR sSysPAddr;
+
+			if(pMapping->CpuVAddr)
+			{
+				OSUnReservePhys(pMapping->CpuVAddr,
+								uPSize,
+								pBMHeap->ui32Attribs,
+								pMapping->hOSMemHandle);
+			}
+			sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr);
+			RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+		}
+	}
+fail_mapping_alloc:
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+	
+fail_exit:
+	return IMG_FALSE;
+}
+
+
+static IMG_VOID
+BM_FreeMemory (IMG_VOID *h, IMG_UINTPTR_T _base, BM_MAPPING *psMapping)
+{
+	BM_HEAP *pBMHeap = h;
+	IMG_SIZE_T uPSize;
+
+	PVR_UNREFERENCED_PARAMETER (_base);
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "BM_FreeMemory (h=0x%x, base=0x%x, psMapping=0x%x)",
+			  (IMG_UINTPTR_T)h, _base, (IMG_UINTPTR_T)psMapping));
+
+	PVR_ASSERT (psMapping != IMG_NULL);
+
+	if (psMapping == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter"));
+		return;
+	}
+
+	DevMemoryFree (psMapping);
+
+	
+	if((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0)
+	{
+		psMapping->uSize /= 2;
+	}
+
+	if(psMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+	{
+		uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize;
+	}
+	else
+	{
+		uPSize = psMapping->uSize;
+	}
+
+	if (psMapping->ui32Flags & PVRSRV_MEM_XPROC)
+	{
+		XProcWorkaroundFreeShareable(psMapping->hOSMemHandle);
+	}
+	else
+    if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
+	{
+		OSFreePages(pBMHeap->ui32Attribs,
+						uPSize,
+						(IMG_VOID *) psMapping->CpuVAddr,
+						psMapping->hOSMemHandle);
+	}
+	else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
+	{
+		IMG_SYS_PHYADDR sSysPAddr;
+
+		OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle);
+
+		sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr);
+
+		RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR,	"BM_FreeMemory: Invalid backing store type"));
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), psMapping, IMG_NULL);
+	
+
+	PVR_DPF((PVR_DBG_MESSAGE,
+			"..BM_FreeMemory (h=0x%x, base=0x%x)",
+			(IMG_UINTPTR_T)h, _base));
+}
+
+IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+								IMG_DEV_VIRTADDR sDevVPageAddr,
+								IMG_DEV_PHYADDR *psDevPAddr)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	PVR_DPF((PVR_DBG_MESSAGE, "BM_GetPhysPageAddr"));
+
+	PVR_ASSERT (psMemInfo && psDevPAddr)
+
+	
+	PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
+
+	 
+	psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode;
+
+	*psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap,
+												sDevVPageAddr);
+}
+
+
+MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap)
+{
+	BM_HEAP *pBMHeap = (BM_HEAP*)hDevMemHeap;
+
+	PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUContext"));
+
+	return pBMHeap->pBMContext->psMMUContext;
+}
+
+MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext)
+{
+	BM_CONTEXT *pBMContext = (BM_CONTEXT*)hDevMemContext;
+
+	PVR_DPF ((PVR_DBG_VERBOSE, "BM_GetMMUContextFromMemContext"));
+
+	return pBMContext->psMMUContext;
+}
+
+IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap)
+{
+	PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUHeap"));
+
+	return (IMG_HANDLE)((BM_HEAP*)hDevMemHeap)->pMMUHeap;
+}
+
+
+PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext)
+{
+	PVR_DPF((PVR_DBG_VERBOSE, "BM_GetDeviceNode"));
+
+	return ((BM_CONTEXT*)hDevMemContext)->psDeviceNode;
+}
+
+
+IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+	PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMappingHandle"));
+
+	return ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->hOSMemHandle;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/deviceclass.c b/drivers/staging/cdv/pvr/services4/srvkm/common/deviceclass.c
new file mode 100644
index 0000000..13bfa8d
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/deviceclass.c
@@ -0,0 +1,2013 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "kernelbuffer.h"
+#include "kerneldisplay.h"
+#include "pvr_bridge_km.h"
+#include "pdump_km.h"
+#include "deviceid.h"
+
+#include "lists.h"
+
+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
+
+#if defined(SUPPORT_MISR_IN_THREAD)
+void OSVSyncMISR(IMG_HANDLE, IMG_BOOL);
+#endif
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE	hCmdCookie,
+										   IMG_BOOL		bScheduleMISR);
+#endif
+typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE;
+
+typedef struct PVRSRV_DC_BUFFER_TAG
+{
+	
+	PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
+
+	struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
+	struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
+} PVRSRV_DC_BUFFER;
+
+typedef struct PVRSRV_DC_SWAPCHAIN_TAG
+{
+	IMG_HANDLE							hExtSwapChain;
+	IMG_UINT32							ui32SwapChainID;
+	IMG_UINT32							ui32RefCount;
+	IMG_UINT32							ui32Flags;
+	PVRSRV_QUEUE_INFO					*psQueue;
+	PVRSRV_DC_BUFFER					asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+	IMG_UINT32							ui32BufferCount;
+	PVRSRV_DC_BUFFER					*psLastFlipBuffer;
+	IMG_UINT32							ui32MinSwapInterval;
+	IMG_UINT32							ui32MaxSwapInterval;
+	struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
+	struct PVRSRV_DC_SWAPCHAIN_TAG		*psNext;
+} PVRSRV_DC_SWAPCHAIN;
+
+
+typedef struct PVRSRV_DC_SWAPCHAIN_REF_TAG
+{
+	struct PVRSRV_DC_SWAPCHAIN_TAG		*psSwapChain;
+	IMG_HANDLE							hResItem;	
+} PVRSRV_DC_SWAPCHAIN_REF;
+
+
+typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG
+{
+	IMG_UINT32 							ui32RefCount;
+	IMG_UINT32							ui32DeviceID;
+	IMG_HANDLE							hExtDevice;
+	PPVRSRV_DC_SRV2DISP_KMJTABLE		psFuncTable;
+	IMG_HANDLE							hDevMemContext;
+	PVRSRV_DC_BUFFER 					sSystemBuffer;
+	struct PVRSRV_DC_SWAPCHAIN_TAG		*psDCSwapChainShared;
+} PVRSRV_DISPLAYCLASS_INFO;
+
+
+typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG
+{
+	PVRSRV_DISPLAYCLASS_INFO			*psDCInfo;
+	PRESMAN_ITEM						hResItem;
+} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO;
+
+
+typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE;
+
+typedef struct PVRSRV_BC_BUFFER_TAG
+{
+	
+	PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
+
+	struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo;
+} PVRSRV_BC_BUFFER;
+
+
+typedef struct PVRSRV_BUFFERCLASS_INFO_TAG
+{
+	IMG_UINT32 							ui32RefCount;
+	IMG_UINT32							ui32DeviceID;
+	IMG_HANDLE							hExtDevice;
+	PPVRSRV_BC_SRV2BUFFER_KMJTABLE		psFuncTable;
+	IMG_HANDLE							hDevMemContext;
+	
+	IMG_UINT32							ui32BufferCount;
+	PVRSRV_BC_BUFFER 					*psBuffer;
+
+} PVRSRV_BUFFERCLASS_INFO;
+
+
+typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG
+{
+	PVRSRV_BUFFERCLASS_INFO				*psBCInfo;
+	IMG_HANDLE							hResItem;
+} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO;
+
+
+static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM)
+{
+	PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+
+	psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+	return psDCPerContextInfo->psDCInfo;
+}
+
+
+static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM)
+{
+	PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+
+	psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+	return psBCPerContextInfo->psBCInfo;
+}
+
+static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+	IMG_UINT *pui32DevCount;
+	IMG_UINT32 **ppui32DevID;
+	PVRSRV_DEVICE_CLASS peDeviceClass;
+
+	pui32DevCount = va_arg(va, IMG_UINT*);
+	ppui32DevID = va_arg(va, IMG_UINT32**);
+	peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS);
+
+	if	((psDeviceNode->sDevId.eDeviceClass == peDeviceClass)
+	&&	(psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT))
+	{
+		(*pui32DevCount)++;
+		if(*ppui32DevID)
+		{
+			*(*ppui32DevID)++ = psDeviceNode->sDevId.ui32DeviceIndex;
+		}
+	}
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass,
+								  IMG_UINT32 *pui32DevCount,
+								  IMG_UINT32 *pui32DevID )
+{
+	
+	IMG_UINT			ui32DevCount = 0;
+	SYS_DATA 			*psSysData;
+
+	SysAcquireData(&psSysData);
+
+	
+	List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+										&PVRSRVEnumerateDCKM_ForEachVaCb,
+										&ui32DevCount,
+										&pui32DevID,
+										DeviceClass);
+
+	if(pui32DevCount)
+	{
+		*pui32DevCount = ui32DevCount;
+	}
+	else if(pui32DevID == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Invalid parameters"));
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static
+PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable,
+									   IMG_UINT32 *pui32DeviceID)
+{
+	PVRSRV_DISPLAYCLASS_INFO 	*psDCInfo = IMG_NULL;
+	PVRSRV_DEVICE_NODE			*psDeviceNode;
+	SYS_DATA					*psSysData;
+
+	
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	SysAcquireData(&psSysData);
+
+	
+
+
+	
+	if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+					 sizeof(*psDCInfo),
+					 (IMG_VOID **)&psDCInfo, IMG_NULL,
+					 "Display Class Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+	OSMemSet (psDCInfo, 0, sizeof(*psDCInfo));
+
+	
+	if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+					 sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
+					 (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL,
+					 "Function table for SRVKM->DISPLAY") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc"));
+		goto ErrorExit;
+	}
+	OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE));
+
+	
+	*psDCInfo->psFuncTable = *psFuncTable;
+
+	
+	if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+					 sizeof(PVRSRV_DEVICE_NODE),
+					 (IMG_VOID **)&psDeviceNode, IMG_NULL,
+					 "Device Node") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc"));
+		goto ErrorExit;
+	}
+	OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
+
+	psDeviceNode->pvDevice = (IMG_VOID*)psDCInfo;
+	psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo);
+	psDeviceNode->ui32RefCount = 1;
+	psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
+	psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY;
+	psDeviceNode->psSysData = psSysData;
+
+	
+	if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
+		goto ErrorExit;
+	}
+	psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+	if (pui32DeviceID)
+	{
+		*pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+	}
+
+	
+	SysRegisterExternalDevice(psDeviceNode);
+
+	
+	List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
+
+	return PVRSRV_OK;
+
+ErrorExit:
+
+	if(psDCInfo->psFuncTable)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
+		psDCInfo->psFuncTable = IMG_NULL;
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
+	
+
+	return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+static PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex)
+{
+	SYS_DATA					*psSysData;
+	PVRSRV_DEVICE_NODE			*psDeviceNode;
+	PVRSRV_DISPLAYCLASS_INFO	*psDCInfo;
+
+	SysAcquireData(&psSysData);
+
+	
+	psDeviceNode = (PVRSRV_DEVICE_NODE*)
+		List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+									   &MatchDeviceKM_AnyVaCb,
+									   ui32DevIndex,
+									   IMG_FALSE,
+									   PVRSRV_DEVICE_CLASS_DISPLAY);
+	if (!psDeviceNode)
+	{
+		
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex));
+		return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+	}
+
+	
+	psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
+
+	
+
+
+	if(psDCInfo->ui32RefCount == 0)
+	{
+		
+
+		List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
+
+		
+		SysRemoveExternalDevice(psDeviceNode);
+
+		
+
+
+		PVR_ASSERT(psDCInfo->ui32RefCount == 0);
+		(IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
+		(IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
+		psDCInfo->psFuncTable = IMG_NULL;
+		(IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
+		
+		(IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
+		
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount));
+		return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static
+PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable,
+									   IMG_UINT32	*pui32DeviceID)
+{
+	PVRSRV_BUFFERCLASS_INFO	*psBCInfo = IMG_NULL;
+	PVRSRV_DEVICE_NODE		*psDeviceNode;
+	SYS_DATA				*psSysData;
+	
+
+
+
+
+
+
+
+
+
+
+
+
+
+	SysAcquireData(&psSysData);
+
+	
+
+
+	
+	if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+					 sizeof(*psBCInfo),
+					 (IMG_VOID **)&psBCInfo, IMG_NULL,
+					 "Buffer Class Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+	OSMemSet (psBCInfo, 0, sizeof(*psBCInfo));
+
+	
+	if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+					 sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE),
+					 (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL,
+					 "Function table for SRVKM->BUFFER") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc"));
+		goto ErrorExit;
+	}
+	OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE));
+
+	
+	*psBCInfo->psFuncTable = *psFuncTable;
+
+	
+	if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+					 sizeof(PVRSRV_DEVICE_NODE),
+					 (IMG_VOID **)&psDeviceNode, IMG_NULL,
+					 "Device Node") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc"));
+		goto ErrorExit;
+	}
+	OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
+
+	psDeviceNode->pvDevice = (IMG_VOID*)psBCInfo;
+	psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo);
+	psDeviceNode->ui32RefCount = 1;
+	psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
+	psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER;
+	psDeviceNode->psSysData = psSysData;
+
+	
+	if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
+		goto ErrorExit;
+	}
+	psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+	if (pui32DeviceID)
+	{
+		*pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+	}
+
+	
+	List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
+
+	return PVRSRV_OK;
+
+ErrorExit:
+
+	if(psBCInfo->psFuncTable)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
+		psBCInfo->psFuncTable = IMG_NULL;
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
+	
+
+	return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+
+static PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex)
+{
+	SYS_DATA					*psSysData;
+	PVRSRV_DEVICE_NODE			*psDevNode;
+	PVRSRV_BUFFERCLASS_INFO		*psBCInfo;
+
+	SysAcquireData(&psSysData);
+
+	
+	psDevNode = (PVRSRV_DEVICE_NODE*)
+		List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+									   &MatchDeviceKM_AnyVaCb,
+									   ui32DevIndex,
+									   IMG_FALSE,
+									   PVRSRV_DEVICE_CLASS_BUFFER);
+
+	if (!psDevNode)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex));
+		return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+	}
+
+	
+	
+	psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice;
+
+	
+
+
+	if(psBCInfo->ui32RefCount == 0)
+	{
+		
+
+		List_PVRSRV_DEVICE_NODE_Remove(psDevNode);
+
+		
+
+
+		(IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
+		
+		
+		(IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
+		psBCInfo->psFuncTable = IMG_NULL;
+		(IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
+		
+		(IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDevNode, IMG_NULL);
+		
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount));
+		return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE	hDeviceKM,
+									IMG_BOOL	bResManCallback)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+
+	PVR_UNREFERENCED_PARAMETER(bResManCallback);
+
+	psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+	
+	eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem, CLEANUP_WITH_POLL);
+
+	return eError;
+}
+
+
+static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID  pvParam,
+										  IMG_UINT32 ui32Param,
+										  IMG_BOOL   bDummy)
+{
+	PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam;
+	psDCInfo = psDCPerContextInfo->psDCInfo;
+
+	if(psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount != 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"CloseDCDeviceCallBack: system buffer (0x%p) still mapped (refcount = %d)",
+				&psDCInfo->sSystemBuffer.sDeviceClassBuffer,
+				psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount));
+
+#if 0
+		
+		return PVRSRV_ERROR_STILL_MAPPED;
+#endif
+	}
+
+	psDCInfo->ui32RefCount--;
+	if(psDCInfo->ui32RefCount == 0)
+	{
+		
+		psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice);
+
+		if (--psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+		{
+			PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+		}
+
+		psDCInfo->hDevMemContext = IMG_NULL;
+		psDCInfo->hExtDevice = IMG_NULL;
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL);
+	
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA	*psPerProc,
+								   IMG_UINT32				ui32DeviceID,
+								   IMG_HANDLE				hDevCookie,
+								   IMG_HANDLE				*phDeviceKM)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+	PVRSRV_DEVICE_NODE	*psDeviceNode;
+	SYS_DATA			*psSysData;
+	PVRSRV_ERROR eError;
+
+	if(!phDeviceKM || !hDevCookie)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	SysAcquireData(&psSysData);
+
+	
+	psDeviceNode = (PVRSRV_DEVICE_NODE*)
+			List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+										   &MatchDeviceKM_AnyVaCb,
+										   ui32DeviceID,
+										   IMG_FALSE,
+										   PVRSRV_DEVICE_CLASS_DISPLAY);
+	if (!psDeviceNode)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID));
+		return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+	}
+	psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
+
+	
+
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  sizeof(*psDCPerContextInfo),
+				  (IMG_VOID **)&psDCPerContextInfo, IMG_NULL,
+				  "Display Class per Context Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+	OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));
+
+	if(psDCInfo->ui32RefCount++ == 0)
+	{
+
+		psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+		
+		psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
+
+		
+		eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
+									(IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext,
+									&psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc"));
+			psDCInfo->ui32RefCount--;
+			return eError;
+		}
+
+		
+		eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID,
+                                                        	&psDCInfo->hExtDevice,
+								(PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM);
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device"));
+			psDCInfo->ui32RefCount--;
+			PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+			return eError;
+		}
+
+		psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
+		psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount = 0;
+	}
+
+	psDCPerContextInfo->psDCInfo = psDCInfo;
+	psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+													 RESMAN_TYPE_DISPLAYCLASS_DEVICE,
+													 psDCPerContextInfo,
+													 0,
+													 &CloseDCDeviceCallBack);
+
+	
+	*phDeviceKM = (IMG_HANDLE)psDCPerContextInfo;
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM,
+									IMG_UINT32 *pui32Count,
+									DISPLAY_FORMAT *psFormat)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+
+	if(!hDeviceKM || !pui32Count || !psFormat)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+	
+	return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat);
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVEnumDCDimsKM (IMG_HANDLE hDeviceKM,
+								 DISPLAY_FORMAT *psFormat,
+								 IMG_UINT32 *pui32Count,
+								 DISPLAY_DIMS *psDim)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+
+	if(!hDeviceKM || !pui32Count || !psFormat)	
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+	
+	return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM,
+										IMG_HANDLE *phBuffer)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	IMG_HANDLE hExtBuffer;
+
+	if(!hDeviceKM || !phBuffer)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+	
+	eError = psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice, &hExtBuffer);
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver"));
+		return eError;
+	}
+
+	
+	psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
+	psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
+	psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
+	psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer;
+
+	psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;
+
+	
+	*phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer);
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetDCInfoKM (IMG_HANDLE hDeviceKM,
+								DISPLAY_INFO *psDisplayInfo)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_ERROR eError;
+
+	if(!hDeviceKM || !psDisplayInfo)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCInfoKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+	
+	eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, psDisplayInfo);
+	if (eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	if (psDisplayInfo->ui32MaxSwapChainBuffers > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
+	{
+		psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChainRef)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
+
+	if(!hSwapChainRef)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psSwapChainRef = hSwapChainRef;
+
+	eError = ResManFreeResByPtr(psSwapChainRef->hResItem, CLEANUP_WITH_POLL);
+
+	return eError;
+}
+
+
+static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain)
+{
+	PVRSRV_ERROR				eError;
+	PVRSRV_DISPLAYCLASS_INFO	*psDCInfo = psSwapChain->psDCInfo;
+	IMG_UINT32 i;
+
+	
+	if( psDCInfo->psDCSwapChainShared )
+	{
+		if( psDCInfo->psDCSwapChainShared == psSwapChain )
+		{
+			psDCInfo->psDCSwapChainShared = psSwapChain->psNext;
+		}
+		else 
+		{
+			PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
+			psCurrentSwapChain = psDCInfo->psDCSwapChainShared; 		
+			while( psCurrentSwapChain->psNext )
+			{
+				if( psCurrentSwapChain->psNext != psSwapChain ) 
+				{
+					psCurrentSwapChain = psCurrentSwapChain->psNext;
+					continue;
+				}
+				psCurrentSwapChain->psNext = psSwapChain->psNext;
+				break;				
+			}
+		}
+	}
+
+	
+	PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue);
+
+	
+	eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice,
+															psSwapChain->hExtSwapChain);
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DestroyDCSwapChainCallBack: Failed to destroy DC swap chain"));
+		return eError;
+	}
+
+	
+	for(i=0; i<psSwapChain->ui32BufferCount; i++)
+	{
+		if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+		{
+			if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+			{
+				PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+			}
+		}
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
+	
+
+	return eError;
+}
+
+
+static PVRSRV_ERROR DestroyDCSwapChainRefCallBack(IMG_PVOID pvParam,
+												  IMG_UINT32 ui32Param,
+												  IMG_BOOL bDummy)
+{
+	PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF *) pvParam;
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	IMG_UINT32 i;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	for (i = 0; i < psSwapChainRef->psSwapChain->ui32BufferCount; i++)
+	{
+		if (psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "DestroyDCSwapChainRefCallBack: swapchain (0x%p) still mapped (ui32MemMapRefCount = %d)",
+					&psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer,
+					psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount));
+#if 0
+			
+			return PVRSRV_ERROR_STILL_MAPPED;
+#endif
+		}
+	}
+
+	if(--psSwapChainRef->psSwapChain->ui32RefCount == 0) 
+	{
+		eError = DestroyDCSwapChain(psSwapChainRef->psSwapChain);
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN_REF), psSwapChainRef, IMG_NULL);
+	return eError;
+}
+
+static PVRSRV_DC_SWAPCHAIN* PVRSRVFindSharedDCSwapChainKM(PVRSRV_DISPLAYCLASS_INFO *psDCInfo,
+														 IMG_UINT32 ui32SwapChainID)
+{
+	PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
+
+	for(psCurrentSwapChain = psDCInfo->psDCSwapChainShared; 
+		psCurrentSwapChain; 
+		psCurrentSwapChain = psCurrentSwapChain->psNext) 
+	{
+		if(psCurrentSwapChain->ui32SwapChainID == ui32SwapChainID)
+			return psCurrentSwapChain;
+	}
+	return IMG_NULL;
+}
+
+static PVRSRV_ERROR PVRSRVCreateDCSwapChainRefKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+												 PVRSRV_DC_SWAPCHAIN 		*psSwapChain, 
+												 PVRSRV_DC_SWAPCHAIN_REF 	**ppsSwapChainRef)
+{
+	PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
+
+	
+	if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+					 sizeof(PVRSRV_DC_SWAPCHAIN_REF),
+					 (IMG_VOID **)&psSwapChainRef, IMG_NULL,
+					 "Display Class Swapchain Reference") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainRefKM: Failed psSwapChainRef alloc"));
+		return  PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+	OSMemSet (psSwapChainRef, 0, sizeof(PVRSRV_DC_SWAPCHAIN_REF));
+
+	
+	psSwapChain->ui32RefCount++;
+
+	
+	psSwapChainRef->psSwapChain = psSwapChain;
+	psSwapChainRef->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+												  RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,
+												  psSwapChainRef,
+												  0,
+												  &DestroyDCSwapChainRefCallBack);
+	*ppsSwapChainRef = psSwapChainRef;
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA	*psPerProc,
+										IMG_HANDLE				hDeviceKM,
+										IMG_UINT32				ui32Flags,
+										DISPLAY_SURF_ATTRIBUTES	*psDstSurfAttrib,
+										DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
+										IMG_UINT32				ui32BufferCount,
+										IMG_UINT32				ui32OEMFlags,
+										IMG_HANDLE				*phSwapChainRef,
+										IMG_UINT32				*pui32SwapChainID)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL;
+	PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
+	PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+	PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
+	PVRSRV_ERROR eError;
+	IMG_UINT32 i;
+	DISPLAY_INFO sDisplayInfo;
+
+
+	if(!hDeviceKM
+	|| !psDstSurfAttrib
+	|| !psSrcSurfAttrib
+	|| !phSwapChainRef
+	|| !pui32SwapChainID)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too many buffers"));
+		return PVRSRV_ERROR_TOOMANYBUFFERS;
+	}
+
+	if (ui32BufferCount < 2)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too few buffers"));
+		return PVRSRV_ERROR_TOO_FEW_BUFFERS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+	if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_QUERY )
+	{
+		
+		psSwapChain = PVRSRVFindSharedDCSwapChainKM(psDCInfo, *pui32SwapChainID );
+		if( psSwapChain  ) 
+		{	
+					   
+			eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, 
+												  psSwapChain, 
+												  &psSwapChainRef);
+			if( eError != PVRSRV_OK ) 
+			{
+				PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
+				return eError;
+			}
+
+			*phSwapChainRef = (IMG_HANDLE)psSwapChainRef;
+			return PVRSRV_OK;
+		}
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: No shared SwapChain found for query"));
+		return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;		
+	}
+
+	
+	if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+					 sizeof(PVRSRV_DC_SWAPCHAIN),
+					 (IMG_VOID **)&psSwapChain, IMG_NULL,
+					 "Display Class Swapchain") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc"));
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto ErrorExit;
+	}
+	OSMemSet (psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN));
+
+	
+	eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue"));
+		goto ErrorExit;
+	}
+
+	
+	psSwapChain->psQueue = psQueue;
+
+	
+	for(i=0; i<ui32BufferCount; i++)
+	{
+		eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
+										psDCInfo->hDevMemContext,
+										&psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain"));
+			goto ErrorExit;
+		}
+
+		psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
+
+		
+		psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
+		psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
+		psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
+
+		
+		psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
+		psSwapChain->asBuffer[i].psSwapChain = psSwapChain;
+
+		
+		apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
+	}
+
+	psSwapChain->ui32BufferCount = ui32BufferCount;
+	psSwapChain->psDCInfo = psDCInfo;
+
+#if defined(PDUMP)
+	PDUMPCOMMENT("Allocate DC swap chain (SwapChainID == %u, BufferCount == %u)",
+			*pui32SwapChainID,
+			ui32BufferCount);
+	PDUMPCOMMENT("  Src surface dimensions == %u x %u",
+			psSrcSurfAttrib->sDims.ui32Width,
+			psSrcSurfAttrib->sDims.ui32Height);
+	PDUMPCOMMENT("  Dst surface dimensions == %u x %u",
+			psDstSurfAttrib->sDims.ui32Width,
+			psDstSurfAttrib->sDims.ui32Height);
+#endif
+
+	eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, &sDisplayInfo);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to get DC info"));
+		return eError;
+	}
+	
+	psSwapChain->ui32MinSwapInterval = sDisplayInfo.ui32MinSwapInterval;
+	psSwapChain->ui32MaxSwapInterval = sDisplayInfo.ui32MaxSwapInterval;
+
+	
+	eError =  psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
+														ui32Flags,
+														psDstSurfAttrib,
+														psSrcSurfAttrib,
+														ui32BufferCount,
+														apsSyncData,
+														ui32OEMFlags,
+														&psSwapChain->hExtSwapChain,
+														&psSwapChain->ui32SwapChainID);
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain"));
+		PDUMPCOMMENT("Swapchain allocation failed.");
+		goto ErrorExit;
+	}
+
+			   
+	eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, 
+										  psSwapChain, 
+										  &psSwapChainRef);
+	if( eError != PVRSRV_OK ) 
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
+		PDUMPCOMMENT("Swapchain allocation failed.");
+		goto ErrorExit;
+	}
+
+	psSwapChain->ui32RefCount = 1;
+	psSwapChain->ui32Flags = ui32Flags;
+
+	
+	if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_SHARED )
+	{
+   		if(! psDCInfo->psDCSwapChainShared ) 
+		{
+			psDCInfo->psDCSwapChainShared = psSwapChain;
+		} 
+		else 
+		{	
+			PVRSRV_DC_SWAPCHAIN *psOldHead = psDCInfo->psDCSwapChainShared;
+			psDCInfo->psDCSwapChainShared = psSwapChain;
+			psSwapChain->psNext = psOldHead;
+		}
+	}
+
+	
+	*pui32SwapChainID = psSwapChain->ui32SwapChainID;
+
+	
+	*phSwapChainRef= (IMG_HANDLE)psSwapChainRef;
+
+	return eError;
+
+ErrorExit:
+
+	for(i=0; i<ui32BufferCount; i++)
+	{
+		if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+		{
+			if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+			{
+				PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+			}
+		}
+	}
+
+	if(psQueue)
+	{
+		PVRSRVDestroyCommandQueueKM(psQueue);
+	}
+
+	if(psSwapChain)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
+		
+	}
+
+	return eError;
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE	hDeviceKM,
+								  IMG_HANDLE	hSwapChainRef,
+								  IMG_RECT		*psRect)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+	if(!hDeviceKM || !hSwapChainRef)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+	psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+	return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
+													psSwapChain->hExtSwapChain,
+													psRect);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE	hDeviceKM,
+								  IMG_HANDLE	hSwapChainRef,
+								  IMG_RECT		*psRect)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+	if(!hDeviceKM || !hSwapChainRef)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+	psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+	return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice,
+													psSwapChain->hExtSwapChain,
+													psRect);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE	hDeviceKM,
+									   IMG_HANDLE	hSwapChainRef,
+									   IMG_UINT32	ui32CKColour)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+	if(!hDeviceKM || !hSwapChainRef)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+	psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+	return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice,
+														psSwapChain->hExtSwapChain,
+														ui32CKColour);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE	hDeviceKM,
+									   IMG_HANDLE	hSwapChainRef,
+									   IMG_UINT32	ui32CKColour)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+	if(!hDeviceKM || !hSwapChainRef)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+	psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+	return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
+														psSwapChain->hExtSwapChain,
+														ui32CKColour);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE	hDeviceKM,
+								  IMG_HANDLE	hSwapChainRef,
+								  IMG_UINT32	*pui32BufferCount,
+								  IMG_HANDLE	*phBuffer)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_DC_SWAPCHAIN *psSwapChain;
+	IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+	PVRSRV_ERROR eError;
+	IMG_UINT32 i;
+
+	if(!hDeviceKM || !hSwapChainRef || !phBuffer)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+	psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+	
+	eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
+													psSwapChain->hExtSwapChain,
+													pui32BufferCount,
+													ahExtBuffer);
+
+	PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
+
+	
+
+
+	for(i=0; i<*pui32BufferCount; i++)
+	{
+		psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i];
+		phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i];
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE	hDeviceKM,
+									IMG_HANDLE	hBuffer,
+									IMG_UINT32	ui32SwapInterval,
+									IMG_HANDLE	hPrivateTag,
+									IMG_UINT32	ui32ClipRectCount,
+									IMG_RECT	*psClipRect)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_DC_BUFFER *psBuffer;
+	PVRSRV_QUEUE_INFO *psQueue;
+	DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
+	IMG_UINT32 i;
+	IMG_BOOL bAddReferenceToLast = IMG_TRUE;
+	IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
+	IMG_UINT32 ui32NumSrcSyncs = 1;
+	PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
+	PVRSRV_COMMAND *psCommand;
+	SYS_DATA *psSysData;
+
+	if(!hDeviceKM || !hBuffer || !psClipRect)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psBuffer = (PVRSRV_DC_BUFFER*)hBuffer;
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+	
+	if(ui32SwapInterval < psBuffer->psSwapChain->ui32MinSwapInterval ||
+		ui32SwapInterval > psBuffer->psSwapChain->ui32MaxSwapInterval)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid swap interval. Requested %u, Allowed range %u-%u",
+				 ui32SwapInterval, psBuffer->psSwapChain->ui32MinSwapInterval, psBuffer->psSwapChain->ui32MaxSwapInterval));
+		return PVRSRV_ERROR_INVALID_SWAPINTERVAL;
+	}
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+
+	if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
+	{
+		psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
+													 psBuffer->psSwapChain->hExtSwapChain,
+													 psBuffer->sDeviceClassBuffer.hExtBuffer, 
+													 hPrivateTag, 
+													 &ui16SwapCommandID,
+													 &bAddReferenceToLast);
+		
+	}
+
+#endif
+
+	
+	psQueue = psBuffer->psSwapChain->psQueue;
+
+	
+	apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
+	
+
+
+	if(bAddReferenceToLast && psBuffer->psSwapChain->psLastFlipBuffer &&
+		psBuffer != psBuffer->psSwapChain->psLastFlipBuffer)
+	{
+		apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
+		
+
+
+		ui32NumSrcSyncs++;
+	}
+
+	
+	eError = PVRSRVInsertCommandKM (psQueue,
+									&psCommand,
+									psDCInfo->ui32DeviceID,
+									ui16SwapCommandID,
+									0,
+									IMG_NULL,
+									ui32NumSrcSyncs,
+									apsSrcSync,
+									sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount));
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue"));
+		goto Exit;
+	}
+
+	
+	psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
+
+	
+	psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
+
+	
+	psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
+
+	
+	psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
+
+	
+	psFlipCmd->hPrivateTag = hPrivateTag;
+
+	
+	psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
+	
+	psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND));	
+	
+	for(i=0; i<ui32ClipRectCount; i++)
+	{
+		psFlipCmd->psClipRect[i] = psClipRect[i];
+	}
+
+	
+	psFlipCmd->ui32SwapInterval = ui32SwapInterval;
+
+	
+	eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command"));
+		goto Exit;
+	}
+
+	
+
+	SysAcquireData(&psSysData);
+    eError = OSScheduleMISR(psSysData);
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to schedule MISR"));
+		goto Exit;
+	}
+
+	
+	psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
+
+Exit:
+
+	if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+	{
+		eError = PVRSRV_ERROR_RETRY;
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE	hDeviceKM,
+									IMG_HANDLE	hSwapChainRef)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_QUEUE_INFO *psQueue;
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	PVRSRV_DC_SWAPCHAIN *psSwapChain;
+	PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
+	DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
+	IMG_UINT32 ui32NumSrcSyncs = 1;
+	PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
+	PVRSRV_COMMAND *psCommand;
+	IMG_BOOL bAddReferenceToLast = IMG_TRUE;
+	IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
+    SYS_DATA *psSysData;
+
+	if(!hDeviceKM || !hSwapChainRef)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+	psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef;
+	psSwapChain = psSwapChainRef->psSwapChain;
+
+	
+	psQueue = psSwapChain->psQueue;
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+
+	if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
+	{
+		psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
+													 psSwapChain->hExtSwapChain,
+													 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer, 
+													 0, 
+													 &ui16SwapCommandID,
+													 &bAddReferenceToLast);
+		
+	}
+
+#endif
+
+	
+	apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
+	
+
+
+	if(bAddReferenceToLast && psSwapChain->psLastFlipBuffer)
+	{
+		
+		if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo)
+		{
+			apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
+			
+
+
+			ui32NumSrcSyncs++;
+		}
+	}
+
+	
+	eError = PVRSRVInsertCommandKM (psQueue,
+									&psCommand,
+									psDCInfo->ui32DeviceID,
+									ui16SwapCommandID,
+									0,
+									IMG_NULL,
+									ui32NumSrcSyncs,
+									apsSrcSync,
+									sizeof(DISPLAYCLASS_FLIP_COMMAND));
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue"));
+		goto Exit;
+	}
+
+	
+	psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
+
+	
+	psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
+
+	
+	psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
+
+	
+	psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
+
+	
+	psFlipCmd->hPrivateTag = IMG_NULL;
+
+	
+	psFlipCmd->ui32ClipRectCount = 0;
+
+	psFlipCmd->ui32SwapInterval = 1;
+
+	
+	eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command"));
+		goto Exit;
+	}
+
+	
+	SysAcquireData(&psSysData);
+    eError = OSScheduleMISR(psSysData);
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to schedule MISR"));
+		goto Exit;
+	}
+
+	
+	psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
+
+	eError = PVRSRV_OK;
+
+Exit:
+
+	if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+	{
+		eError = PVRSRV_ERROR_RETRY;
+	}
+
+	return eError;
+}
+
+
+static
+PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER	pfnISRHandler,
+											 IMG_VOID			*pvISRHandlerData,
+											 IMG_UINT32			ui32ISRSourceMask,
+											 IMG_UINT32			ui32DeviceID)
+{
+	SYS_DATA 			*psSysData;
+	PVRSRV_DEVICE_NODE	*psDevNode;
+
+	PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask);
+
+	SysAcquireData(&psSysData);
+
+	
+	psDevNode = (PVRSRV_DEVICE_NODE*)
+				List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+												&MatchDeviceKM_AnyVaCb,
+												ui32DeviceID,
+												IMG_TRUE);
+
+	if (psDevNode == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode"));
+		PVR_DBG_BREAK;
+		return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+	}
+
+	
+	psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData;
+
+	
+	psDevNode->pfnDeviceISR	= pfnISRHandler;
+
+	return PVRSRV_OK;
+}
+
+static
+IMG_VOID PVRSRVSetDCState_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+	IMG_UINT32 ui32State;
+	ui32State = va_arg(va, IMG_UINT32);
+
+	if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
+	{
+		psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice;
+		if (psDCInfo->psFuncTable->pfnSetDCState && psDCInfo->hExtDevice)
+		{
+			psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->hExtDevice, ui32State);
+		}
+	}
+}
+
+
+IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State)
+{
+	SYS_DATA					*psSysData;
+
+	SysAcquireData(&psSysData);
+
+	List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+										&PVRSRVSetDCState_ForEachVaCb,
+										ui32State);
+}
+
+
+IMG_EXPORT
+IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable)
+{
+	psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE);
+	psJTable->pfnPVRSRVRegisterDCDevice = &PVRSRVRegisterDCDeviceKM;
+	psJTable->pfnPVRSRVRemoveDCDevice = &PVRSRVRemoveDCDeviceKM;
+	psJTable->pfnPVRSRVOEMFunction = &SysOEMFunction;
+	psJTable->pfnPVRSRVRegisterCmdProcList = &PVRSRVRegisterCmdProcListKM;
+	psJTable->pfnPVRSRVRemoveCmdProcList = &PVRSRVRemoveCmdProcListKM;
+#if defined(SUPPORT_MISR_IN_THREAD)
+        psJTable->pfnPVRSRVCmdComplete = &OSVSyncMISR;
+#else
+        psJTable->pfnPVRSRVCmdComplete = &PVRSRVCommandCompleteKM;
+#endif
+	psJTable->pfnPVRSRVRegisterSystemISRHandler = &PVRSRVRegisterSystemISRHandler;
+	psJTable->pfnPVRSRVRegisterPowerDevice = &PVRSRVRegisterPowerDevice;
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+	psJTable->pfnPVRSRVFreeCmdCompletePacket = &PVRSRVFreeCommandCompletePacketKM;
+#endif
+
+	return IMG_TRUE;
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE	hDeviceKM,
+									IMG_BOOL	bResManCallback)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+
+	PVR_UNREFERENCED_PARAMETER(bResManCallback);
+
+	psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+	
+	eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem, CLEANUP_WITH_POLL);
+
+	return eError;
+}
+
+
+static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID  pvParam,
+										  IMG_UINT32 ui32Param,
+										  IMG_BOOL   bDummy)
+{
+	PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+	PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+	IMG_UINT32 i;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam;
+
+	psBCInfo = psBCPerContextInfo->psBCInfo;
+
+	for (i = 0; i < psBCInfo->ui32BufferCount; i++)
+	{
+		if (psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "CloseBCDeviceCallBack: buffer %d (0x%p) still mapped (ui32MemMapRefCount = %d)",
+					i,
+					&psBCInfo->psBuffer[i].sDeviceClassBuffer,
+					psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount));
+			return PVRSRV_ERROR_STILL_MAPPED;
+		}
+	}
+
+	psBCInfo->ui32RefCount--;
+	if(psBCInfo->ui32RefCount == 0)
+	{
+		
+		psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->ui32DeviceID, psBCInfo->hExtDevice);
+
+		
+		for(i=0; i<psBCInfo->ui32BufferCount; i++)
+		{
+			if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+			{
+				if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+				{
+					PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+				}
+			}
+		}
+
+		
+		if(psBCInfo->psBuffer)
+		{
+			OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER) * psBCInfo->ui32BufferCount, psBCInfo->psBuffer, IMG_NULL);
+			psBCInfo->psBuffer = IMG_NULL;
+		}
+	}
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL);
+	
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA	*psPerProc,
+								   IMG_UINT32				ui32DeviceID,
+								   IMG_HANDLE				hDevCookie,
+								   IMG_HANDLE				*phDeviceKM)
+{
+	PVRSRV_BUFFERCLASS_INFO	*psBCInfo;
+	PVRSRV_BUFFERCLASS_PERCONTEXT_INFO	*psBCPerContextInfo;
+	PVRSRV_DEVICE_NODE		*psDeviceNode;
+	SYS_DATA 				*psSysData;
+	IMG_UINT32 				i;
+	PVRSRV_ERROR			eError;
+
+	if(!phDeviceKM || !hDevCookie)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	SysAcquireData(&psSysData);
+
+	
+	psDeviceNode = (PVRSRV_DEVICE_NODE*)
+			List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+										   &MatchDeviceKM_AnyVaCb,
+										   ui32DeviceID,
+										   IMG_FALSE,
+										   PVRSRV_DEVICE_CLASS_BUFFER);
+	if (!psDeviceNode)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID));
+		return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+	}
+	psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice;
+
+	
+
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  sizeof(*psBCPerContextInfo),
+				  (IMG_VOID **)&psBCPerContextInfo, IMG_NULL,
+				  "Buffer Class per Context Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+	OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));
+
+	if(psBCInfo->ui32RefCount++ == 0)
+	{
+		BUFFER_INFO sBufferInfo;
+
+		psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+		
+		psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
+
+		
+		eError = psBCInfo->psFuncTable->pfnOpenBCDevice(ui32DeviceID, &psBCInfo->hExtDevice);
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device"));
+			return eError;
+		}
+
+		
+		eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo);
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info"));
+			return eError;
+		}
+
+		
+		psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
+		
+
+		
+		eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+							  sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount,
+							  (IMG_VOID **)&psBCInfo->psBuffer,
+						 	  IMG_NULL,
+							  "Array of Buffer Class Buffer");
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers"));
+			return eError;
+		}
+		OSMemSet (psBCInfo->psBuffer,
+					0,
+					sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount);
+
+		for(i=0; i<psBCInfo->ui32BufferCount; i++)
+		{
+			
+			eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
+										psBCInfo->hDevMemContext,
+										&psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+			if(eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc"));
+				goto ErrorExit;
+			}
+
+			psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
+			
+			
+
+
+			eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice,
+															i,
+															psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData,
+															&psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer);
+			if(eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers"));
+				goto ErrorExit;
+			}
+
+			
+			psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr;
+			psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext;
+			psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice;
+			psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount = 0;
+		}
+	}
+
+	psBCPerContextInfo->psBCInfo = psBCInfo;
+	psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+													 RESMAN_TYPE_BUFFERCLASS_DEVICE,
+													 psBCPerContextInfo,
+													 0,
+													 &CloseBCDeviceCallBack);
+
+	
+	*phDeviceKM = (IMG_HANDLE)psBCPerContextInfo;
+
+	return PVRSRV_OK;
+
+ErrorExit:
+
+	
+	for(i=0; i<psBCInfo->ui32BufferCount; i++)
+	{
+		if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+		{
+			if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+			{
+				PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+			}
+		}
+	}
+
+	
+	if(psBCInfo->psBuffer)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL);
+		psBCInfo->psBuffer = IMG_NULL;
+	}
+
+	return eError;
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetBCInfoKM (IMG_HANDLE hDeviceKM,
+								BUFFER_INFO *psBufferInfo)
+{
+	PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+	PVRSRV_ERROR 			eError;
+
+	if(!hDeviceKM || !psBufferInfo)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
+
+	eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, psBufferInfo);
+
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM : Failed to get BC Info"));
+		return eError;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetBCBufferKM (IMG_HANDLE hDeviceKM,
+								  IMG_UINT32 ui32BufferIndex,
+								  IMG_HANDLE *phBuffer)
+{
+	PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+
+	if(!hDeviceKM || !phBuffer)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
+
+	if(ui32BufferIndex < psBCInfo->ui32BufferCount)
+	{
+		*phBuffer = (IMG_HANDLE)&psBCInfo->psBuffer[ui32BufferIndex];
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)", ui32BufferIndex,psBCInfo->ui32BufferCount));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable)
+{
+	psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE);
+
+	psJTable->pfnPVRSRVRegisterBCDevice = &PVRSRVRegisterBCDeviceKM;
+	psJTable->pfnPVRSRVScheduleDevices = &PVRSRVScheduleDevicesKM;
+	psJTable->pfnPVRSRVRemoveBCDevice = &PVRSRVRemoveBCDeviceKM;
+
+	return IMG_TRUE;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/deviceid.h b/drivers/staging/cdv/pvr/services4/srvkm/common/deviceid.h
new file mode 100644
index 0000000..9a7bdb3
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/deviceid.h
@@ -0,0 +1,36 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __DEVICEID_H__
+#define __DEVICEID_H__
+
+#include "services.h"
+#include "syscommon.h"
+
+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/devicemem.c b/drivers/staging/cdv/pvr/services4/srvkm/common/devicemem.c
new file mode 100644
index 0000000..cb8dccb
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/devicemem.c
@@ -0,0 +1,1797 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "pdump_km.h"
+#include "pvr_bridge_km.h"
+#include "osfunc.h"
+
+static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE		hDevCookie,
+									IMG_HANDLE		hDevMemHeap,
+									IMG_UINT32		ui32Flags,
+									IMG_SIZE_T		ui32Size,
+									IMG_SIZE_T		ui32Alignment,
+									PVRSRV_KERNEL_MEM_INFO	**ppsMemInfo);
+
+typedef struct _RESMAN_MAP_DEVICE_MEM_DATA_
+{
+	
+	PVRSRV_KERNEL_MEM_INFO	*psMemInfo;
+	
+	PVRSRV_KERNEL_MEM_INFO	*psSrcMemInfo;
+} RESMAN_MAP_DEVICE_MEM_DATA;
+
+typedef struct _PVRSRV_DC_MAPINFO_
+{
+	PVRSRV_KERNEL_MEM_INFO	*psMemInfo;
+	PVRSRV_DEVICE_NODE		*psDeviceNode;
+	IMG_UINT32				ui32RangeIndex;
+	IMG_UINT32				ui32TilingStride;
+	PVRSRV_DEVICECLASS_BUFFER	*psDeviceClassBuffer;
+} PVRSRV_DC_MAPINFO;
+
+static IMG_UINT32 g_ui32SyncUID = 0;
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+													PVRSRV_HEAP_INFO_KM *psHeapInfo)
+#else
+													PVRSRV_HEAP_INFO *psHeapInfo)
+#endif
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_UINT32 ui32HeapCount;
+	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+	IMG_UINT32 i;
+
+	if (hDevCookie == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid"));
+		PVR_DBG_BREAK;
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+	
+	ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+	psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+
+	
+	PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
+
+	
+	for(i=0; i<ui32HeapCount; i++)
+	{
+		
+		psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+		psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
+		psHeapInfo[i].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+		psHeapInfo[i].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+		psHeapInfo[i].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+	}
+
+	for(; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
+	{
+		OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo));
+		psHeapInfo[i].ui32HeapID = (IMG_UINT32)PVRSRV_UNDEFINED_HEAP_ID;
+	}
+
+	return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE					hDevCookie,
+														 PVRSRV_PER_PROCESS_DATA	*psPerProc,
+														 IMG_HANDLE 				*phDevMemContext,
+														 IMG_UINT32 				*pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+														 PVRSRV_HEAP_INFO_KM		*psHeapInfo,
+#else
+														 PVRSRV_HEAP_INFO			*psHeapInfo,
+#endif
+														 IMG_BOOL					*pbCreated,
+														 IMG_BOOL 					*pbShared)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
+	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+	IMG_HANDLE hDevMemContext;
+	IMG_HANDLE hDevMemHeap;
+	IMG_DEV_PHYADDR sPDDevPAddr;
+	IMG_UINT32 i;
+
+#if !defined(PVR_SECURE_HANDLES) && !defined (SUPPORT_SID_INTERFACE)
+	PVR_UNREFERENCED_PARAMETER(pbShared);
+#endif
+
+	if (hDevCookie == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVCreateDeviceMemContextKM: hDevCookie invalid"));
+		PVR_DBG_BREAK;
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+	
+
+	ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+	psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+
+	
+
+	PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
+
+	
+
+	hDevMemContext = BM_CreateContext(psDeviceNode,
+									  &sPDDevPAddr,
+									  psPerProc,
+									  pbCreated);
+	if (hDevMemContext == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	
+	for(i=0; i<ui32HeapCount; i++)
+	{
+		switch(psDeviceMemoryHeap[i].DevMemHeapType)
+		{
+			case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+			{
+				
+				psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+				psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
+				psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+				psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+				psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+				pbShared[ui32ClientHeapCount] = IMG_TRUE;
+#endif
+				ui32ClientHeapCount++;
+				break;
+			}
+			case DEVICE_MEMORY_HEAP_PERCONTEXT:
+			{
+				if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+				{
+					hDevMemHeap = BM_CreateHeap(hDevMemContext,
+												&psDeviceMemoryHeap[i]);
+					if (hDevMemHeap == IMG_NULL)
+					{
+						BM_DestroyContext(hDevMemContext, IMG_NULL);
+						return PVRSRV_ERROR_OUT_OF_MEMORY;
+					}
+				}
+				else
+				{
+					hDevMemHeap = IMG_NULL;
+				}
+
+				
+				psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+				psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
+				psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+				psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+				psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+				pbShared[ui32ClientHeapCount] = IMG_FALSE;
+#endif
+
+				ui32ClientHeapCount++;
+				break;
+			}
+		}
+	}
+
+	
+	*pui32ClientHeapCount = ui32ClientHeapCount;
+	*phDevMemContext = hDevMemContext;
+
+	return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
+														  IMG_HANDLE hDevMemContext,
+														  IMG_BOOL *pbDestroyed)
+{
+	PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+	return BM_DestroyContext(hDevMemContext, pbDestroyed);
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE					hDevCookie,
+														 IMG_HANDLE 				hDevMemContext,
+														 IMG_UINT32 				*pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+														 PVRSRV_HEAP_INFO_KM		*psHeapInfo,
+#else
+														 PVRSRV_HEAP_INFO			*psHeapInfo,
+#endif
+														 IMG_BOOL 					*pbShared)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
+	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+	IMG_HANDLE hDevMemHeap;
+	IMG_UINT32 i;
+
+#if !defined(PVR_SECURE_HANDLES) && !defined (SUPPORT_SID_INTERFACE)
+	PVR_UNREFERENCED_PARAMETER(pbShared);
+#endif
+
+	if (hDevCookie == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapInfoKM: hDevCookie invalid"));
+		PVR_DBG_BREAK;
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+	
+
+	ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+	psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+
+	
+
+	PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
+
+	
+	for(i=0; i<ui32HeapCount; i++)
+	{
+		switch(psDeviceMemoryHeap[i].DevMemHeapType)
+		{
+			case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+			{
+				
+				psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+				psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
+				psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+				psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+				psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+				pbShared[ui32ClientHeapCount] = IMG_TRUE;
+#endif
+				ui32ClientHeapCount++;
+				break;
+			}
+			case DEVICE_MEMORY_HEAP_PERCONTEXT:
+			{
+				if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+				{
+					hDevMemHeap = BM_CreateHeap(hDevMemContext,
+												&psDeviceMemoryHeap[i]);
+				
+					if (hDevMemHeap == IMG_NULL)
+					{
+						return PVRSRV_ERROR_OUT_OF_MEMORY;
+					}
+				}
+				else
+				{
+					hDevMemHeap = IMG_NULL;
+				}
+
+				
+				psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+				psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
+				psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+				psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+				psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+				pbShared[ui32ClientHeapCount] = IMG_FALSE;
+#endif
+
+				ui32ClientHeapCount++;
+				break;
+			}
+		}
+	}
+
+	
+	*pui32ClientHeapCount = ui32ClientHeapCount;
+
+	return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE		hDevCookie,
+									IMG_HANDLE		hDevMemHeap,
+									IMG_UINT32		ui32Flags,
+									IMG_SIZE_T		ui32Size,
+									IMG_SIZE_T		ui32Alignment,
+									PVRSRV_KERNEL_MEM_INFO	**ppsMemInfo)
+{
+ 	PVRSRV_KERNEL_MEM_INFO	*psMemInfo;
+	BM_HANDLE 		hBuffer;
+	
+	PVRSRV_MEMBLK	*psMemBlock;
+	IMG_BOOL		bBMError;
+
+	PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+	*ppsMemInfo = IMG_NULL;
+
+	if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+					sizeof(PVRSRV_KERNEL_MEM_INFO),
+					(IMG_VOID **)&psMemInfo, IMG_NULL,
+					"Kernel Memory Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: Failed to alloc memory for block"));
+		return (PVRSRV_ERROR_OUT_OF_MEMORY);
+	}
+
+	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+
+	psMemBlock = &(psMemInfo->sMemBlk);
+
+	
+	psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION;
+
+	bBMError = BM_Alloc (hDevMemHeap,
+							IMG_NULL,
+							ui32Size,
+							&psMemInfo->ui32Flags,
+							IMG_CAST_TO_DEVVADDR_UINT(ui32Alignment),
+							&hBuffer);
+
+	if (!bBMError)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: BM_Alloc Failed"));
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+		
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	
+	psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+	psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+
+	
+	psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+	
+
+	psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
+
+	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+
+	psMemInfo->uAllocSize = ui32Size;
+
+	
+	psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+	
+	*ppsMemInfo = psMemInfo;
+
+	
+	return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR FreeDeviceMem2(PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_BOOL bFromAllocator)
+{
+	BM_HANDLE		hBuffer;
+
+	if (!psMemInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	hBuffer = psMemInfo->sMemBlk.hBuffer;
+
+	
+	if (bFromAllocator)
+		BM_Free(hBuffer, psMemInfo->ui32Flags);
+	else
+		BM_FreeExport(hBuffer, psMemInfo->ui32Flags);
+
+	
+	if ((psMemInfo->pvSysBackupBuffer) && bFromAllocator)
+	{
+		
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
+		psMemInfo->pvSysBackupBuffer = IMG_NULL;
+	}
+
+	if (psMemInfo->ui32RefCount == 0)
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+	
+
+	return(PVRSRV_OK);
+}
+
+static PVRSRV_ERROR FreeDeviceMem(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+	BM_HANDLE		hBuffer;
+
+	if (!psMemInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	hBuffer = psMemInfo->sMemBlk.hBuffer;
+
+	
+	BM_Free(hBuffer, psMemInfo->ui32Flags);
+
+	if(psMemInfo->pvSysBackupBuffer)
+	{
+		
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
+		psMemInfo->pvSysBackupBuffer = IMG_NULL;
+	}
+
+	OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+	
+
+	return(PVRSRV_OK);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE					hDevCookie,
+												IMG_HANDLE					hDevMemContext,
+												PVRSRV_KERNEL_SYNC_INFO		**ppsKernelSyncInfo)
+{
+	IMG_HANDLE hSyncDevMemHeap;
+	DEVICE_MEMORY_INFO *psDevMemoryInfo;
+	BM_CONTEXT *pBMContext;
+	PVRSRV_ERROR eError;
+	PVRSRV_KERNEL_SYNC_INFO	*psKernelSyncInfo;
+	PVRSRV_SYNC_DATA *psSyncData;
+
+	eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+						sizeof(PVRSRV_KERNEL_SYNC_INFO),
+						(IMG_VOID **)&psKernelSyncInfo, IMG_NULL,
+						"Kernel Synchronization Info");
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	psKernelSyncInfo->ui32RefCount = 0;
+
+	
+	pBMContext = (BM_CONTEXT*)hDevMemContext;
+	psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo;
+
+	
+	hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap;
+
+	
+
+
+	eError = AllocDeviceMem(hDevCookie,
+							hSyncDevMemHeap,
+							PVRSRV_MEM_CACHE_CONSISTENT,
+							sizeof(PVRSRV_SYNC_DATA),
+							sizeof(IMG_UINT32),
+							&psKernelSyncInfo->psSyncDataMemInfoKM);
+
+	if (eError != PVRSRV_OK)
+	{
+
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
+		
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	
+	psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
+	psSyncData = psKernelSyncInfo->psSyncData;
+
+	psSyncData->ui32WriteOpsPending = 0;
+	psSyncData->ui32WriteOpsComplete = 0;
+	psSyncData->ui32ReadOpsPending = 0;
+	psSyncData->ui32ReadOpsComplete = 0;
+	psSyncData->ui32LastOpDumpVal = 0;
+	psSyncData->ui32LastReadOpDumpVal = 0;
+
+#if defined(PDUMP)
+	PDUMPCOMMENT("Allocating kernel sync object");
+	PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM,
+			psKernelSyncInfo->psSyncDataMemInfoKM,
+			0,
+			(IMG_UINT32)psKernelSyncInfo->psSyncDataMemInfoKM->uAllocSize,
+			PDUMP_FLAGS_CONTINUOUS,
+			MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
+#endif
+
+	psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
+	psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
+	psKernelSyncInfo->ui32UID = g_ui32SyncUID++;
+
+	
+	psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL;
+
+	
+	*ppsKernelSyncInfo = psKernelSyncInfo;
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO	*psKernelSyncInfo)
+{
+	PVRSRV_ERROR eError;
+
+	if (psKernelSyncInfo->ui32RefCount != 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "oops: sync info ref count not zero at destruction"));
+		
+		return PVRSRV_ERROR_OUT_OF_MEMORY; 
+	}
+
+	eError = FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
+	(IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
+	
+
+	return eError;
+}
+
+static IMG_VOID freeWrapped(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+	IMG_HANDLE hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem;
+
+	
+	if(psMemInfo->sMemBlk.psIntSysPAddr)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
+		psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
+	}
+
+	if(hOSWrapMem)
+	{
+		OSReleasePhysPageAddr(hOSWrapMem);
+	}
+}
+
+
+#if defined (PVRSRV_FLUSH_KERNEL_OPS_LAST_ONLY)
+static
+PVRSRV_ERROR _PollUntilAtLeast(volatile IMG_UINT32* pui32WatchedValue,
+                               IMG_UINT32 ui32MinimumValue,
+                               IMG_UINT32 ui32Waitus,
+                               IMG_UINT32 ui32Tries)
+{
+	PVRSRV_ERROR eError;
+	IMG_INT32 iDiff;
+
+	for(;;)
+	{
+		SYS_DATA *psSysData = SysAcquireDataNoCheck();
+		iDiff = *pui32WatchedValue - ui32MinimumValue;
+
+		if (iDiff >= 0)
+		{
+			eError = PVRSRV_OK;
+			break;
+		}
+
+		if(!ui32Tries)
+		{
+			eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+			break;
+		}
+
+		ui32Tries--;
+
+		
+		if (psSysData->psGlobalEventObject)
+		{
+			IMG_HANDLE hOSEventKM;
+			if(psSysData->psGlobalEventObject)
+			{
+				eError = OSEventObjectOpenKM(psSysData->psGlobalEventObject, &hOSEventKM);
+				if (eError |= PVRSRV_OK)
+				{
+					PVR_DPF((PVR_DBG_ERROR,
+								"_PollUntilAtLeast: OSEventObjectOpen failed"));
+					goto Exit;
+				}
+				eError = OSEventObjectWaitKM(hOSEventKM);
+				if (eError != PVRSRV_OK)
+				{
+					PVR_DPF((PVR_DBG_ERROR,
+								"_PollUntilAtLeast: PVRSRVEventObjectWait failed"));
+					goto Exit;
+				}
+				eError = OSEventObjectCloseKM(psSysData->psGlobalEventObject, hOSEventKM);
+				if (eError != PVRSRV_OK)
+				{
+					PVR_DPF((PVR_DBG_ERROR,
+								"_PollUntilAtLeast: OSEventObjectClose failed"));
+				}
+			}
+		}
+	}
+Exit:
+	return eError;
+}
+
+static PVRSRV_ERROR FlushKernelOps(PVRSRV_SYNC_DATA *psSyncData)
+{
+	PVRSRV_ERROR eError;
+
+	if(!psSyncData)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FlushKernelOps: invalid psSyncData"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+
+
+
+
+
+
+
+
+	eError = _PollUntilAtLeast(&psSyncData->ui32ReadOpsComplete,
+                               psSyncData->ui32ReadOpsPending,
+                               MAX_HW_TIME_US/WAIT_TRY_COUNT,
+                               WAIT_TRY_COUNT);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FlushClientOps: Read ops pending timeout"));
+		PVR_DBG_BREAK; 
+		return eError;
+	}
+
+	eError = _PollUntilAtLeast(&psSyncData->ui32WriteOpsComplete,
+                               psSyncData->ui32WriteOpsPending,
+                               MAX_HW_TIME_US/WAIT_TRY_COUNT,
+                               WAIT_TRY_COUNT);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FlushClientOps: Write ops pending timeout"));
+		PVR_DBG_BREAK; 
+	}
+
+	return eError;
+}
+#endif 
+
+static PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+										  IMG_UINT32	ui32Param,
+										  IMG_BOOL	bFromAllocator)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+	
+	psMemInfo->ui32RefCount--;
+
+	if (psMemInfo->ui32RefCount == 0)
+	{
+		if(psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED)
+		{
+#if defined (SUPPORT_SID_INTERFACE)
+			IMG_SID hMemInfo = 0;
+#else
+			IMG_HANDLE hMemInfo = IMG_NULL;
+#endif
+
+
+			eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE,
+					&hMemInfo,
+					psMemInfo,
+					PVRSRV_HANDLE_TYPE_MEM_INFO);
+			if(eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: can't find exported meminfo in the global handle list"));
+				return eError;
+			}
+
+
+			eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+					hMemInfo,
+					PVRSRV_HANDLE_TYPE_MEM_INFO);
+			if(eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: PVRSRVReleaseHandle failed for exported meminfo"));
+				return eError;
+			}
+		}
+
+#if defined (PVRSRV_FLUSH_KERNEL_OPS_LAST_ONLY)
+		if (psMemInfo->psKernelSyncInfo)
+		{
+			if (psMemInfo->sShareMemWorkaround.bInUse)
+			{
+				
+				if (BM_XProcWorkaroundGetRefCount(psMemInfo->sShareMemWorkaround.ui32ShareIndex)
+						== 1)
+				{
+					FlushKernelOps(psMemInfo->psKernelSyncInfo->psSyncData);
+				}
+			}
+			else
+			{
+				
+
+
+
+
+
+
+
+				FlushKernelOps(psMemInfo->psKernelSyncInfo->psSyncData);
+			}
+		}
+#endif
+
+		switch(psMemInfo->memType)
+		{
+			
+			case PVRSRV_MEMTYPE_WRAPPED:
+				freeWrapped(psMemInfo);
+			case PVRSRV_MEMTYPE_DEVICE:
+				if (psMemInfo->psKernelSyncInfo)
+				{
+					psMemInfo->psKernelSyncInfo->ui32RefCount--;
+
+					if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
+					{
+						eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
+					}
+				}
+			case PVRSRV_MEMTYPE_DEVICECLASS:
+				break;
+			default:
+				PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: Unknown memType"));
+				eError = PVRSRV_ERROR_INVALID_MEMINFO;
+		}
+	}
+
+	
+	if (eError == PVRSRV_OK)
+	{
+		eError = FreeDeviceMem2(psMemInfo, bFromAllocator);
+	}
+
+	return eError;
+}
+
+static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID  pvParam,
+										  IMG_UINT32 ui32Param,
+										  IMG_BOOL   bDummy)
+{
+	PVRSRV_KERNEL_MEM_INFO	*psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
+	
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE				hDevCookie,
+												PVRSRV_KERNEL_MEM_INFO	*psMemInfo)
+{
+	PVRSRV_ERROR eError;
+
+	PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+	if (!psMemInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	if (psMemInfo->sMemBlk.hResItem != IMG_NULL)
+	{
+		eError = ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+	}
+	else
+	{
+		
+		eError = FreeDeviceMemCallBack(psMemInfo, 0, CLEANUP_WITH_POLL);
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE					hDevCookie,
+												 PVRSRV_PER_PROCESS_DATA	*psPerProc,
+												 IMG_HANDLE					hDevMemHeap,
+												 IMG_UINT32					ui32Flags,
+												 IMG_SIZE_T					ui32Size,
+												 IMG_SIZE_T					ui32Alignment,
+												 PVRSRV_KERNEL_MEM_INFO		**ppsMemInfo)
+{
+	PVRSRV_KERNEL_MEM_INFO	*psMemInfo;
+	PVRSRV_ERROR 			eError;
+	BM_HEAP					*psBMHeap;
+	IMG_HANDLE				hDevMemContext;
+
+	if (!hDevMemHeap ||
+		(ui32Size == 0))
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	if (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+	{
+		 
+		if (((ui32Size % HOST_PAGESIZE()) != 0) ||
+			((ui32Alignment % HOST_PAGESIZE()) != 0))
+		{
+			return PVRSRV_ERROR_INVALID_PARAMS;
+		}
+	}
+
+	eError = AllocDeviceMem(hDevCookie,
+							hDevMemHeap,
+							ui32Flags,
+							ui32Size,
+							ui32Alignment,
+							&psMemInfo);
+
+	if (eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
+	{
+		psMemInfo->psKernelSyncInfo = IMG_NULL;
+	}
+	else
+	{
+		
+
+
+		psBMHeap = (BM_HEAP*)hDevMemHeap;
+		hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
+		eError = PVRSRVAllocSyncInfoKM(hDevCookie,
+									   hDevMemContext,
+									   &psMemInfo->psKernelSyncInfo);
+		if(eError != PVRSRV_OK)
+		{
+			goto free_mainalloc;
+		}
+		psMemInfo->psKernelSyncInfo->ui32RefCount++;
+	}
+
+	
+	*ppsMemInfo = psMemInfo;
+
+	if (ui32Flags & PVRSRV_MEM_NO_RESMAN)
+	{
+		psMemInfo->sMemBlk.hResItem = IMG_NULL;
+	}
+	else
+	{
+		
+		psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+														RESMAN_TYPE_DEVICEMEM_ALLOCATION,
+														psMemInfo,
+														0,
+														&FreeDeviceMemCallBack);
+		if (psMemInfo->sMemBlk.hResItem == IMG_NULL)
+		{
+			
+			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+			goto free_mainalloc;
+		}
+	}
+
+	
+	psMemInfo->ui32RefCount++;
+
+	psMemInfo->memType = PVRSRV_MEMTYPE_DEVICE;
+
+	
+	return (PVRSRV_OK);
+
+free_mainalloc:
+	FreeDeviceMem(psMemInfo);
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE              hDevCookie,
+													  PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+	PVRSRV_ERROR		eError;
+	PVRSRV_DEVICE_NODE	*psDeviceNode = hDevCookie;
+
+	PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+	if (!psMemInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem, psDeviceNode->hResManContext);
+
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
+												   IMG_SIZE_T *pui32Total,
+												   IMG_SIZE_T *pui32Free,
+												   IMG_SIZE_T *pui32LargestBlock)
+{
+	
+
+	PVR_UNREFERENCED_PARAMETER(ui32Flags);
+	PVR_UNREFERENCED_PARAMETER(pui32Total);
+	PVR_UNREFERENCED_PARAMETER(pui32Free);
+	PVR_UNREFERENCED_PARAMETER(pui32LargestBlock);
+
+	return PVRSRV_OK;
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM (PVRSRV_KERNEL_MEM_INFO	*psMemInfo)
+{
+	if (!psMemInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+
+
+static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID  pvParam,
+											IMG_UINT32 ui32Param,
+											IMG_BOOL   bDummy)
+{
+	PVRSRV_KERNEL_MEM_INFO	*psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
+	
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE				hDevCookie,
+												PVRSRV_PER_PROCESS_DATA	*psPerProc,
+												IMG_HANDLE				hDevMemContext,
+												IMG_SIZE_T 				uByteSize,
+												IMG_SIZE_T				uPageOffset,
+												IMG_BOOL				bPhysContig,
+												IMG_SYS_PHYADDR	 		*psExtSysPAddr,
+												IMG_VOID 				*pvLinAddr,
+												IMG_UINT32				ui32Flags,
+												PVRSRV_KERNEL_MEM_INFO	**ppsMemInfo)
+{
+	PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
+	DEVICE_MEMORY_INFO  *psDevMemoryInfo;
+	IMG_SIZE_T			ui32HostPageSize = HOST_PAGESIZE();
+	IMG_HANDLE			hDevMemHeap = IMG_NULL;
+	PVRSRV_DEVICE_NODE* psDeviceNode;
+	BM_HANDLE 			hBuffer;
+	PVRSRV_MEMBLK		*psMemBlock;
+	IMG_BOOL			bBMError;
+	BM_HEAP				*psBMHeap;
+	PVRSRV_ERROR		eError;
+	IMG_VOID 			*pvPageAlignedCPUVAddr;
+	IMG_SYS_PHYADDR	 	*psIntSysPAddr = IMG_NULL;
+	IMG_HANDLE			hOSWrapMem = IMG_NULL;
+	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+	IMG_UINT32		i;
+	IMG_SIZE_T          uPageCount = 0;
+
+
+	psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie;
+	PVR_ASSERT(psDeviceNode != IMG_NULL);
+
+	if (psDeviceNode == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	if(pvLinAddr)
+	{
+		
+		uPageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1);
+
+		
+		uPageCount = HOST_PAGEALIGN(uByteSize + uPageOffset) / ui32HostPageSize;
+		pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - uPageOffset);
+
+		
+		if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						uPageCount * sizeof(IMG_SYS_PHYADDR),
+						(IMG_VOID **)&psIntSysPAddr, IMG_NULL,
+						"Array of Page Addresses") != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
+			return PVRSRV_ERROR_OUT_OF_MEMORY;
+		}
+
+		eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
+										uPageCount * ui32HostPageSize,
+										psIntSysPAddr,
+										&hOSWrapMem);
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
+			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+			goto ErrorExitPhase1;
+		}
+
+		
+		psExtSysPAddr = psIntSysPAddr;
+
+		
+
+		bPhysContig = IMG_FALSE;
+	}
+	else
+	{
+		
+	}
+
+	
+	psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->psDeviceNode->sDevMemoryInfo;
+	psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+	for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
+	{
+		if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
+		{
+			if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
+			{
+				
+				if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+				{
+					hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
+				}
+				else
+				{
+					hDevMemHeap = IMG_NULL;
+				}
+			}
+			else
+			{
+				hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
+			}
+			break;
+		}
+	}
+
+	if(hDevMemHeap == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: unable to find mapping heap"));
+		eError = PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP;
+		goto ErrorExitPhase2;
+	}
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					sizeof(PVRSRV_KERNEL_MEM_INFO),
+					(IMG_VOID **)&psMemInfo, IMG_NULL,
+					"Kernel Memory Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto ErrorExitPhase2;
+	}
+
+	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+	psMemInfo->ui32Flags = ui32Flags;
+
+	psMemBlock = &(psMemInfo->sMemBlk);
+
+	bBMError = BM_Wrap(hDevMemHeap,
+					   uByteSize,
+					   uPageOffset,
+					   bPhysContig,
+					   psExtSysPAddr,
+					   IMG_NULL,
+					   &psMemInfo->ui32Flags,
+					   &hBuffer);
+	if (!bBMError)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed"));
+		eError = PVRSRV_ERROR_BAD_MAPPING;
+		goto ErrorExitPhase3;
+	}
+
+	
+	psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+	psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+	psMemBlock->hOSWrapMem = hOSWrapMem;
+	psMemBlock->psIntSysPAddr = psIntSysPAddr;
+
+	
+	psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+	
+	psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
+	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+	psMemInfo->uAllocSize = uByteSize;
+
+	
+
+	psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+	
+
+
+	psBMHeap = (BM_HEAP*)hDevMemHeap;
+	hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
+	eError = PVRSRVAllocSyncInfoKM(hDevCookie,
+									hDevMemContext,
+									&psMemInfo->psKernelSyncInfo);
+	if(eError != PVRSRV_OK)
+	{
+		goto ErrorExitPhase4;
+	}
+
+	psMemInfo->psKernelSyncInfo->ui32RefCount++;
+
+	
+	psMemInfo->ui32RefCount++;
+
+	psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED;
+
+	
+	psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+													RESMAN_TYPE_DEVICEMEM_WRAP,
+													psMemInfo,
+													0,
+													&UnwrapExtMemoryCallBack);
+
+	
+	*ppsMemInfo = psMemInfo;
+
+	return PVRSRV_OK;
+
+	
+
+ErrorExitPhase4:
+	if(psMemInfo)
+	{
+		FreeDeviceMem(psMemInfo);
+		
+
+
+		psMemInfo = IMG_NULL;
+	}
+
+ErrorExitPhase3:
+	if(psMemInfo)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+		
+	}
+
+ErrorExitPhase2:
+	if(psIntSysPAddr)
+	{
+		OSReleasePhysPageAddr(hOSWrapMem);
+	}
+
+ErrorExitPhase1:
+	if(psIntSysPAddr)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL);
+		
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+	if (!psMemInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+
+
+static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID  pvParam,
+											  IMG_UINT32 ui32Param,
+											  IMG_BOOL   bDummy)
+{
+	PVRSRV_ERROR				eError;
+	RESMAN_MAP_DEVICE_MEM_DATA	*psMapData = pvParam;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
+		psMapData->psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
+	}
+
+	if( psMapData->psMemInfo->psKernelSyncInfo )
+	{
+		psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount--;
+		if (psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
+		{
+			eError = PVRSRVFreeSyncInfoKM(psMapData->psMemInfo->psKernelSyncInfo);
+			if(eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free sync info"));
+				return eError;
+			}
+		}
+	}
+
+	eError = FreeDeviceMem(psMapData->psMemInfo);
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo"));
+		return eError;
+	}
+
+	
+	eError = FreeMemCallBackCommon(psMapData->psSrcMemInfo, 0, IMG_FALSE);
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
+	
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+												  PVRSRV_KERNEL_MEM_INFO	*psSrcMemInfo,
+												  IMG_HANDLE				hDstDevMemHeap,
+												  PVRSRV_KERNEL_MEM_INFO	**ppsDstMemInfo)
+{
+	PVRSRV_ERROR				eError;
+	IMG_UINT32					i;
+	IMG_SIZE_T					uPageCount, uPageOffset;
+	IMG_SIZE_T					ui32HostPageSize = HOST_PAGESIZE();
+	IMG_SYS_PHYADDR				*psSysPAddr = IMG_NULL;
+	IMG_DEV_PHYADDR				sDevPAddr;
+	BM_BUF						*psBuf;
+	IMG_DEV_VIRTADDR			sDevVAddr;
+	PVRSRV_KERNEL_MEM_INFO		*psMemInfo = IMG_NULL;
+	BM_HANDLE 					hBuffer;
+	PVRSRV_MEMBLK				*psMemBlock;
+	IMG_BOOL					bBMError;
+	PVRSRV_DEVICE_NODE			*psDeviceNode;
+	IMG_VOID 					*pvPageAlignedCPUVAddr;
+	RESMAN_MAP_DEVICE_MEM_DATA	*psMapData = IMG_NULL;
+
+	
+	if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	*ppsDstMemInfo = IMG_NULL;
+
+	uPageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1);
+	uPageCount = HOST_PAGEALIGN(psSrcMemInfo->uAllocSize + uPageOffset) / ui32HostPageSize;
+	pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - uPageOffset);
+
+	
+
+
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					uPageCount*sizeof(IMG_SYS_PHYADDR),
+					(IMG_VOID **)&psSysPAddr, IMG_NULL,
+					"Array of Page Addresses") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	psBuf = psSrcMemInfo->sMemBlk.hBuffer;
+
+	
+	psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode;
+
+	
+	sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(uPageOffset);
+	for(i=0; i<uPageCount; i++)
+	{
+		BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);
+
+		
+		psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr);
+
+		
+		sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize);
+	}
+
+	
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					sizeof(RESMAN_MAP_DEVICE_MEM_DATA),
+					(IMG_VOID **)&psMapData, IMG_NULL,
+					"Resource Manager Map Data") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data"));
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto ErrorExit;
+	}
+
+	if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+					sizeof(PVRSRV_KERNEL_MEM_INFO),
+					(IMG_VOID **)&psMemInfo, IMG_NULL,
+					"Kernel Memory Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto ErrorExit;
+	}
+
+	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+	psMemInfo->ui32Flags = psSrcMemInfo->ui32Flags;
+
+	psMemBlock = &(psMemInfo->sMemBlk);
+
+	bBMError = BM_Wrap(hDstDevMemHeap,
+					   psSrcMemInfo->uAllocSize,
+					   uPageOffset,
+					   IMG_FALSE,
+					   psSysPAddr,
+					   pvPageAlignedCPUVAddr,
+					   &psMemInfo->ui32Flags,
+					   &hBuffer);
+
+	if (!bBMError)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed"));
+		eError = PVRSRV_ERROR_BAD_MAPPING;
+		goto ErrorExit;
+	}
+
+	
+	psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+	psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+
+	
+	psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+	
+	psMemBlock->psIntSysPAddr = psSysPAddr;
+
+	
+	psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM;
+
+	
+	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+	psMemInfo->uAllocSize = psSrcMemInfo->uAllocSize;
+	psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo;
+
+	
+	if(psMemInfo->psKernelSyncInfo)
+	{
+		psMemInfo->psKernelSyncInfo->ui32RefCount++;
+	}
+
+	
+
+	psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+	
+	psMemInfo->ui32RefCount++;
+
+	
+	psSrcMemInfo->ui32RefCount++;
+
+	
+	BM_Export(psSrcMemInfo->sMemBlk.hBuffer);
+
+	psMemInfo->memType = PVRSRV_MEMTYPE_MAPPED;
+
+	
+	psMapData->psMemInfo = psMemInfo;
+	psMapData->psSrcMemInfo = psSrcMemInfo;
+
+	
+	psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+													RESMAN_TYPE_DEVICEMEM_MAPPING,
+													psMapData,
+													0,
+													&UnmapDeviceMemoryCallBack);
+
+	*ppsDstMemInfo = psMemInfo;
+
+	return PVRSRV_OK;
+
+	
+
+ErrorExit:
+
+	if(psSysPAddr)
+	{
+		
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL);
+		
+	}
+
+	if(psMemInfo)
+	{
+		
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+		
+	}
+
+	if(psMapData)
+	{
+		
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
+		
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+	if (!psMemInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+
+
+static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID  pvParam,
+												   IMG_UINT32 ui32Param,
+												   IMG_BOOL   bDummy)
+{
+	PVRSRV_DC_MAPINFO *psDCMapInfo = pvParam;
+	PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	psMemInfo = psDCMapInfo->psMemInfo;
+
+#if defined(SUPPORT_MEMORY_TILING)
+	if(psDCMapInfo->ui32TilingStride > 0)
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = psDCMapInfo->psDeviceNode;
+
+		if (psDeviceNode->pfnFreeMemTilingRange(psDeviceNode,
+												psDCMapInfo->ui32RangeIndex) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceClassMemoryCallBack: FreeMemTilingRange failed"));
+		}
+	}
+#endif
+
+	(psDCMapInfo->psDeviceClassBuffer->ui32MemMapRefCount)--;
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_MAPINFO), psDCMapInfo, IMG_NULL);
+
+	return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+													   IMG_HANDLE				hDevMemContext,
+													   IMG_HANDLE				hDeviceClassBuffer,
+													   PVRSRV_KERNEL_MEM_INFO	**ppsMemInfo,
+													   IMG_HANDLE				*phOSMapInfo)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_DEVICE_NODE* psDeviceNode;
+	PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
+	PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
+	IMG_SYS_PHYADDR *psSysPAddr;
+	IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr;
+	IMG_BOOL bPhysContig;
+	BM_CONTEXT *psBMContext;
+	DEVICE_MEMORY_INFO *psDevMemoryInfo;
+	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+	IMG_HANDLE hDevMemHeap = IMG_NULL;
+	IMG_SIZE_T uByteSize;
+	IMG_SIZE_T ui32Offset;
+	IMG_SIZE_T ui32PageSize = HOST_PAGESIZE();
+	BM_HANDLE		hBuffer;
+	PVRSRV_MEMBLK	*psMemBlock;
+	IMG_BOOL		bBMError;
+	IMG_UINT32 i;
+	PVRSRV_DC_MAPINFO *psDCMapInfo = IMG_NULL;
+
+	if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					sizeof(PVRSRV_DC_MAPINFO),
+					(IMG_VOID **)&psDCMapInfo, IMG_NULL,
+					"PVRSRV_DC_MAPINFO") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for psDCMapInfo"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+	OSMemSet(psDCMapInfo, 0, sizeof(PVRSRV_DC_MAPINFO));
+
+	psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer;
+
+	
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice,
+												   psDeviceClassBuffer->hExtBuffer,
+												   &psSysPAddr,
+												   &uByteSize,
+												   &pvCPUVAddr,
+												   phOSMapInfo,
+												   &bPhysContig,
+												   &psDCMapInfo->ui32TilingStride);
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address"));
+		goto ErrorExitPhase1;
+	}
+
+	
+	psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext;
+	psDeviceNode = psBMContext->psDeviceNode;
+	psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+	psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+	for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
+	{
+		if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
+		{
+			if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
+			{
+				
+				if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+				{
+					hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
+				}
+				else
+				{
+					hDevMemHeap = IMG_NULL;
+				}
+			}
+			else
+			{
+				hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
+			}
+			break;
+		}
+	}
+
+	if(hDevMemHeap == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap"));
+		eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE;
+		goto ErrorExitPhase1;
+	}
+
+	
+	ui32Offset = ((IMG_UINTPTR_T)pvCPUVAddr) & (ui32PageSize - 1);
+	pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - ui32Offset);
+
+	eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+					sizeof(PVRSRV_KERNEL_MEM_INFO),
+					(IMG_VOID **)&psMemInfo, IMG_NULL,
+					"Kernel Memory Info");
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block"));
+		goto ErrorExitPhase1;
+	}
+
+	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+
+	psMemBlock = &(psMemInfo->sMemBlk);
+
+	bBMError = BM_Wrap(hDevMemHeap,
+					   uByteSize,
+					   ui32Offset,
+					   bPhysContig,
+					   psSysPAddr,
+					   pvPageAlignedCPUVAddr,
+					   &psMemInfo->ui32Flags,
+					   &hBuffer);
+
+	if (!bBMError)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed"));
+		
+		eError = PVRSRV_ERROR_BAD_MAPPING;
+		goto ErrorExitPhase2;
+	}
+
+	
+	psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+	psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+
+	
+	psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+	
+
+	psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
+
+	
+	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+	psMemInfo->uAllocSize = uByteSize;
+	psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;
+
+	
+
+	psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+	
+	psDCMapInfo->psMemInfo = psMemInfo;
+	psDCMapInfo->psDeviceClassBuffer = psDeviceClassBuffer;
+
+#if defined(SUPPORT_MEMORY_TILING)
+	psDCMapInfo->psDeviceNode = psDeviceNode;
+
+	if(psDCMapInfo->ui32TilingStride > 0)
+	{
+		
+		eError = psDeviceNode->pfnAllocMemTilingRange(psDeviceNode,
+														psMemInfo,
+														psDCMapInfo->ui32TilingStride,
+														&psDCMapInfo->ui32RangeIndex);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: AllocMemTilingRange failed"));
+			goto ErrorExitPhase3;
+		}
+	}
+#endif
+
+	
+	psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+													RESMAN_TYPE_DEVICECLASSMEM_MAPPING,
+													psDCMapInfo,
+													0,
+													&UnmapDeviceClassMemoryCallBack);
+
+	(psDeviceClassBuffer->ui32MemMapRefCount)++;
+	psMemInfo->ui32RefCount++;
+
+	psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS;
+
+	
+	*ppsMemInfo = psMemInfo;
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	
+	PDUMPCOMMENT("Dump display surface");
+	PDUMPMEM(IMG_NULL, psMemInfo, ui32Offset, psMemInfo->uAllocSize, PDUMP_FLAGS_CONTINUOUS, ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping);
+#endif
+	return PVRSRV_OK;
+
+#if defined(SUPPORT_MEMORY_TILING)
+ErrorExitPhase3:
+	if(psMemInfo)
+	{
+		FreeDeviceMem(psMemInfo);
+		
+
+
+		psMemInfo = IMG_NULL;
+	}
+#endif
+
+ErrorExitPhase2:
+	if(psMemInfo)
+	{
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+	}
+
+ErrorExitPhase1:
+	if(psDCMapInfo)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psDCMapInfo, IMG_NULL);
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVChangeDeviceMemoryAttributesKM(IMG_HANDLE hKernelMemInfo, IMG_UINT32 ui32Attribs)
+{
+	PVRSRV_KERNEL_MEM_INFO		*psKMMemInfo;
+
+	if (hKernelMemInfo == IMG_NULL)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psKMMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hKernelMemInfo;
+
+	if (ui32Attribs & PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT)
+	{
+		psKMMemInfo->ui32Flags |= PVRSRV_MEM_CACHE_CONSISTENT;
+	}
+	else
+	{
+		psKMMemInfo->ui32Flags &= ~PVRSRV_MEM_CACHE_CONSISTENT;
+	}
+
+	return PVRSRV_OK;
+}
+
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/handle.c b/drivers/staging/cdv/pvr/services4/srvkm/common/handle.c
new file mode 100644
index 0000000..d911b38
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/handle.c
@@ -0,0 +1,1873 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+#include <stddef.h>
+
+#include "services_headers.h"
+#include "handle.h"
+
+#ifdef	DEBUG
+#define	HANDLE_BLOCK_SHIFT	2
+#else
+#define	HANDLE_BLOCK_SHIFT	8
+#endif
+
+#define	DIVIDE_BY_BLOCK_SIZE(i)		(((IMG_UINT32)(i)) >> HANDLE_BLOCK_SHIFT)
+#define	MULTIPLY_BY_BLOCK_SIZE(i)	(((IMG_UINT32)(i)) << HANDLE_BLOCK_SHIFT)
+
+#define HANDLE_BLOCK_SIZE       MULTIPLY_BY_BLOCK_SIZE(1)
+#define	HANDLE_SUB_BLOCK_MASK	(HANDLE_BLOCK_SIZE - 1)
+#define	HANDLE_BLOCK_MASK	(~(HANDLE_SUB_BLOCK_MASK))
+
+#define	HANDLE_HASH_TAB_INIT_SIZE	32
+
+#define	INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount)
+
+#if defined (SUPPORT_SID_INTERFACE)
+#define	INDEX_TO_HANDLE(i) ((IMG_SID)((i) + 1))
+#define	HANDLE_TO_INDEX(h) ((IMG_UINT32)(h) - 1)
+#else
+#define	INDEX_TO_HANDLE(i) ((IMG_HANDLE)((IMG_UINTPTR_T)(i) + 1))
+#define	HANDLE_TO_INDEX(h) ((IMG_UINT32)(IMG_UINTPTR_T)(h) - 1)
+
+#endif
+
+#define	INDEX_TO_BLOCK_INDEX(i)		DIVIDE_BY_BLOCK_SIZE(i)
+#define BLOCK_INDEX_TO_INDEX(i)		MULTIPLY_BY_BLOCK_SIZE(i)
+#define INDEX_TO_SUB_BLOCK_INDEX(i)	((i) & HANDLE_SUB_BLOCK_MASK)
+
+#define INDEX_TO_INDEX_STRUCT_PTR(psArray, i) (&((psArray)[INDEX_TO_BLOCK_INDEX(i)]))
+#define	BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i) INDEX_TO_INDEX_STRUCT_PTR((psBase)->psHandleArray, i)
+
+#define	INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->ui32FreeHandBlockCount)
+
+#define INDEX_TO_HANDLE_STRUCT_PTR(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->psHandle + INDEX_TO_SUB_BLOCK_INDEX(i))
+
+#define	HANDLE_TO_HANDLE_STRUCT_PTR(psBase, h) (INDEX_TO_HANDLE_STRUCT_PTR(psBase, HANDLE_TO_INDEX(h)))
+
+#define	HANDLE_PTR_TO_INDEX(psHandle) ((psHandle)->ui32Index)
+#define	HANDLE_PTR_TO_HANDLE(psHandle) INDEX_TO_HANDLE(HANDLE_PTR_TO_INDEX(psHandle))
+
+#define	ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(a) (HANDLE_BLOCK_MASK & (a))
+#define	ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(a) ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE((a) + HANDLE_BLOCK_SIZE - 1)
+
+#define	DEFAULT_MAX_HANDLE		0x7fffffffu
+#define	DEFAULT_MAX_INDEX_PLUS_ONE	ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(DEFAULT_MAX_HANDLE)
+
+#define	HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0)
+
+#define HANDLE_ARRAY_SIZE(handleCount) DIVIDE_BY_BLOCK_SIZE(ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(handleCount))
+
+#define	SET_FLAG(v, f) ((IMG_VOID)((v) |= (f)))
+#define	CLEAR_FLAG(v, f) ((IMG_VOID)((v) &= ~(f)))
+#define	TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0))
+
+#define	TEST_ALLOC_FLAG(psHandle, f) TEST_FLAG((psHandle)->eFlag, f)
+
+#define	SET_INTERNAL_FLAG(psHandle, f) SET_FLAG((psHandle)->eInternalFlag, f)
+#define	CLEAR_INTERNAL_FLAG(psHandle, f) CLEAR_FLAG((psHandle)->eInternalFlag, f)
+#define	TEST_INTERNAL_FLAG(psHandle, f) TEST_FLAG((psHandle)->eInternalFlag, f)
+
+#define	BATCHED_HANDLE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
+
+#define	SET_BATCHED_HANDLE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
+
+#define	SET_UNBATCHED_HANDLE(psHandle) CLEAR_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
+
+#define	BATCHED_HANDLE_PARTIALLY_FREE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
+
+#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
+
+#define	HANDLE_STRUCT_IS_FREE(psHandle) ((psHandle)->eType == PVRSRV_HANDLE_TYPE_NONE && (psHandle)->eInternalFlag == INTERNAL_HANDLE_FLAG_NONE)
+
+#ifdef	MIN
+#undef MIN
+#endif
+
+#define	MIN(x, y) (((x) < (y)) ? (x) : (y))
+
+struct sHandleList
+{
+	IMG_UINT32 ui32Prev;
+	IMG_UINT32 ui32Next;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID hParent;
+#else
+	IMG_HANDLE hParent;
+#endif
+};
+
+enum ePVRSRVInternalHandleFlag
+{
+	INTERNAL_HANDLE_FLAG_NONE = 0x00,
+	INTERNAL_HANDLE_FLAG_BATCHED = 0x01,
+	INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02,
+};
+
+struct sHandle
+{
+	
+	PVRSRV_HANDLE_TYPE eType;
+
+	
+	IMG_VOID *pvData;
+
+	
+	IMG_UINT32 ui32NextIndexPlusOne;
+
+	
+	enum ePVRSRVInternalHandleFlag eInternalFlag;
+
+	
+	PVRSRV_HANDLE_ALLOC_FLAG eFlag;
+
+	
+	IMG_UINT32 ui32Index;
+
+	
+	struct sHandleList sChildren;
+
+	
+	struct sHandleList sSiblings;
+};
+
+struct sHandleIndex
+{
+	
+	struct sHandle *psHandle;
+
+	
+	IMG_HANDLE hBlockAlloc;
+
+	
+	IMG_UINT32 ui32FreeHandBlockCount;
+};
+
+struct _PVRSRV_HANDLE_BASE_
+{
+	
+	IMG_HANDLE hBaseBlockAlloc;
+
+	
+	IMG_HANDLE hArrayBlockAlloc;
+
+	
+	struct sHandleIndex *psHandleArray;
+
+	
+	HASH_TABLE *psHashTab;
+
+	
+	IMG_UINT32 ui32FreeHandCount;
+
+	
+	IMG_UINT32 ui32FirstFreeIndex;
+
+	
+	IMG_UINT32 ui32MaxIndexPlusOne;
+
+	
+	IMG_UINT32 ui32TotalHandCount;
+
+	
+	IMG_UINT32 ui32LastFreeIndexPlusOne;
+
+	
+	IMG_UINT32 ui32HandBatchSize;
+
+	
+	IMG_UINT32 ui32TotalHandCountPreBatch;
+
+	
+	IMG_UINT32 ui32FirstBatchIndexPlusOne;
+
+	
+	IMG_UINT32 ui32BatchHandAllocFailures;
+
+	
+	IMG_BOOL bPurgingEnabled;
+};
+
+enum eHandKey {
+	HAND_KEY_DATA = 0,
+	HAND_KEY_TYPE,
+	HAND_KEY_PARENT,
+	HAND_KEY_LEN			
+};
+
+PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL;
+
+typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN];
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListInit)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_SID hParent)
+#else
+IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_HANDLE hParent)
+#endif
+{
+	psList->ui32Next = ui32Index;
+	psList->ui32Prev = ui32Index;
+	psList->hParent = hParent;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitParentList)
+#endif
+static INLINE
+IMG_VOID InitParentList(struct sHandle *psHandle)
+{
+	IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psHandle);
+
+	HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(ui32Parent));
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitChildEntry)
+#endif
+static INLINE
+IMG_VOID InitChildEntry(struct sHandle *psHandle)
+{
+	HandleListInit(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, IMG_NULL);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListIsEmpty)
+#endif
+static INLINE
+IMG_BOOL HandleListIsEmpty(IMG_UINT32 ui32Index, struct sHandleList *psList)
+{
+	IMG_BOOL bIsEmpty;
+
+	bIsEmpty = (IMG_BOOL)(psList->ui32Next == ui32Index);
+
+#ifdef	DEBUG
+	{
+		IMG_BOOL bIsEmpty2;
+
+		bIsEmpty2 = (IMG_BOOL)(psList->ui32Prev == ui32Index);
+		PVR_ASSERT(bIsEmpty == bIsEmpty2)
+	}
+#endif
+
+	return bIsEmpty;
+}
+
+#ifdef DEBUG
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoChildren)
+#endif
+static INLINE
+IMG_BOOL NoChildren(struct sHandle *psHandle)
+{
+	PVR_ASSERT(psHandle->sChildren.hParent == HANDLE_PTR_TO_HANDLE(psHandle))
+
+	return HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sChildren);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoParent)
+#endif
+static INLINE
+IMG_BOOL NoParent(struct sHandle *psHandle)
+{
+	if (HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings))
+	{
+		PVR_ASSERT(psHandle->sSiblings.hParent == IMG_NULL)
+
+		return IMG_TRUE;
+	}
+	else
+	{
+		PVR_ASSERT(psHandle->sSiblings.hParent != IMG_NULL)
+	}
+	return IMG_FALSE;
+}
+#endif 
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentHandle)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_SID ParentHandle(struct sHandle *psHandle)
+#else
+IMG_HANDLE ParentHandle(struct sHandle *psHandle)
+#endif
+{
+	return psHandle->sSiblings.hParent;
+}
+
+#define	LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, i, p, po, eo) \
+		((struct sHandleList *)((IMG_CHAR *)(INDEX_TO_HANDLE_STRUCT_PTR(psBase, i)) + (((i) == (p)) ? (po) : (eo))))
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListInsertBefore)
+#endif
+static INLINE
+IMG_VOID HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32InsIndex, struct sHandleList *psIns, IMG_SIZE_T uiParentOffset, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_UINT32 ui32ParentIndex)
+{
+	 
+	struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset);
+
+	PVR_ASSERT(psEntry->hParent == IMG_NULL)
+	PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next)
+	PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(ui32ParentIndex))
+
+	psEntry->ui32Prev = psIns->ui32Prev;
+	psIns->ui32Prev = ui32EntryIndex;
+	psEntry->ui32Next = ui32InsIndex;
+	psPrevIns->ui32Next = ui32EntryIndex;
+
+	psEntry->hParent = INDEX_TO_HANDLE(ui32ParentIndex);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(AdoptChild)
+#endif
+static INLINE
+IMG_VOID AdoptChild(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, struct sHandle *psChild)
+{
+	IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psParent->sChildren.hParent);
+
+	PVR_ASSERT(ui32Parent == HANDLE_PTR_TO_INDEX(psParent))
+
+	HandleListInsertBefore(psBase, ui32Parent, &psParent->sChildren, offsetof(struct sHandle, sChildren), HANDLE_PTR_TO_INDEX(psChild), &psChild->sSiblings, offsetof(struct sHandle, sSiblings), ui32Parent);
+
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListRemove)
+#endif
+static INLINE
+IMG_VOID HandleListRemove(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_SIZE_T uiParentOffset)
+{
+	if (!HandleListIsEmpty(ui32EntryIndex, psEntry))
+	{
+		 
+		struct sHandleList *psPrev = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Prev, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
+		struct sHandleList *psNext = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Next, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
+
+		
+		PVR_ASSERT(psEntry->hParent != IMG_NULL)
+
+		psPrev->ui32Next = psEntry->ui32Next;
+		psNext->ui32Prev = psEntry->ui32Prev;
+
+		HandleListInit(ui32EntryIndex, psEntry, IMG_NULL);
+	}
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(UnlinkFromParent)
+#endif
+static INLINE
+IMG_VOID UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
+{
+	HandleListRemove(psBase, HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, offsetof(struct sHandle, sSiblings), offsetof(struct sHandle, sChildren));
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListIterate)
+#endif
+static INLINE
+PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase, struct sHandleList *psHead, IMG_SIZE_T uiParentOffset, IMG_SIZE_T uiEntryOffset, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
+{
+	IMG_UINT32 ui32Index;
+	IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psHead->hParent);
+
+	PVR_ASSERT(psHead->hParent != IMG_NULL)
+
+	
+	for(ui32Index = psHead->ui32Next; ui32Index != ui32Parent; )
+	{
+		struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
+		 
+		struct sHandleList *psEntry = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32Index, ui32Parent, uiParentOffset, uiEntryOffset);
+		PVRSRV_ERROR eError;
+
+		PVR_ASSERT(psEntry->hParent == psHead->hParent)
+		
+		ui32Index = psEntry->ui32Next;
+
+		eError = (*pfnIterFunc)(psBase, psHandle);
+		if (eError != PVRSRV_OK)
+		{
+			return eError;
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(IterateOverChildren)
+#endif
+static INLINE
+PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
+{
+	 return HandleListIterate(psBase, &psParent->sChildren, offsetof(struct sHandle, sChildren), offsetof(struct sHandle, sSiblings), pfnIterFunc);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(GetHandleStructure)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+	IMG_UINT32 ui32Index = HANDLE_TO_INDEX(hHandle);
+	struct sHandle *psHandle;
+
+	
+	if (!INDEX_IS_VALID(psBase, ui32Index))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount));
+#if defined (SUPPORT_SID_INTERFACE)
+		PVR_DBG_BREAK
+#endif
+		return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+	}
+
+	psHandle =  INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
+	if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle not allocated (index: %u)", ui32Index));
+#if defined (SUPPORT_SID_INTERFACE)
+		PVR_DBG_BREAK
+#endif
+		return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED;
+	}
+
+	
+	if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandle->eType)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle type mismatch (%d != %d)", eType, psHandle->eType));
+#if defined (SUPPORT_SID_INTERFACE)
+		PVR_DBG_BREAK
+#endif
+		return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH;
+	}
+
+	
+	*ppsHandle = psHandle;
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentIfPrivate)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_SID ParentIfPrivate(struct sHandle *psHandle)
+#else
+IMG_HANDLE ParentIfPrivate(struct sHandle *psHandle)
+#endif
+{
+	return TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
+			ParentHandle(psHandle) : IMG_NULL;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitKey)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent)
+#else
+IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
+#endif
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	aKey[HAND_KEY_DATA] = (IMG_UINTPTR_T)pvData;
+	aKey[HAND_KEY_TYPE] = (IMG_UINTPTR_T)eType;
+	aKey[HAND_KEY_PARENT] = (IMG_UINTPTR_T)hParent;
+}
+
+static
+PVRSRV_ERROR ReallocHandleArray(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32NewCount)
+{
+	struct sHandleIndex *psOldArray = psBase->psHandleArray;
+	IMG_HANDLE hOldArrayBlockAlloc = psBase->hArrayBlockAlloc;
+	IMG_UINT32 ui32OldCount = psBase->ui32TotalHandCount;
+	struct sHandleIndex *psNewArray = IMG_NULL;
+	IMG_HANDLE hNewArrayBlockAlloc = IMG_NULL;
+	PVRSRV_ERROR eError;
+	PVRSRV_ERROR eReturn = PVRSRV_OK;
+	IMG_UINT32 ui32Index;
+
+	if (ui32NewCount == ui32OldCount)
+	{
+		return PVRSRV_OK;
+	}
+
+	if (ui32NewCount != 0 && !psBase->bPurgingEnabled &&
+		 ui32NewCount < ui32OldCount)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	if (((ui32OldCount % HANDLE_BLOCK_SIZE) != 0) ||
+		((ui32NewCount % HANDLE_BLOCK_SIZE) != 0))
+	{
+		PVR_ASSERT((ui32OldCount % HANDLE_BLOCK_SIZE) == 0)
+		PVR_ASSERT((ui32NewCount % HANDLE_BLOCK_SIZE) == 0)
+
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	if (ui32NewCount != 0)
+	{
+		
+		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+			HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
+			(IMG_VOID **)&psNewArray,
+			&hNewArrayBlockAlloc,
+			"Memory Area");
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate new handle array (%d)", eError));
+			eReturn = eError;
+			goto error;
+		}
+
+		if (ui32OldCount != 0)
+		{
+			OSMemCopy(psNewArray, psOldArray, HANDLE_ARRAY_SIZE(MIN(ui32NewCount, ui32OldCount)) * sizeof(struct sHandleIndex));
+		}
+	}
+
+	
+	for(ui32Index = ui32NewCount; ui32Index < ui32OldCount; ui32Index += HANDLE_BLOCK_SIZE)
+	{
+		struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psOldArray, ui32Index);
+
+		eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+				sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
+				psIndex->psHandle,
+				psIndex->hBlockAlloc);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
+		}
+	}
+
+	
+	for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
+	{
+		 
+		struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
+
+		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
+				(IMG_VOID **)&psIndex->psHandle,
+				&psIndex->hBlockAlloc,
+				"Memory Area");
+		if (eError != PVRSRV_OK)
+		{
+			psIndex->psHandle = IMG_NULL;
+			PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate handle structures (%d)", eError));
+			eReturn = eError;
+		}
+		else
+		{
+			IMG_UINT32 ui32SubIndex;
+
+			psIndex->ui32FreeHandBlockCount = HANDLE_BLOCK_SIZE;
+
+			for(ui32SubIndex = 0; ui32SubIndex < HANDLE_BLOCK_SIZE; ui32SubIndex++)
+			{
+				struct sHandle *psHandle = psIndex->psHandle + ui32SubIndex;
+
+
+				psHandle->ui32Index = ui32SubIndex + ui32Index;
+				psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
+				psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
+				psHandle->ui32NextIndexPlusOne  = 0;
+			}
+		}
+	}
+	if (eReturn != PVRSRV_OK)
+	{
+		goto error;
+	}
+
+#ifdef	DEBUG_MAX_HANDLE_COUNT
+	
+	if (ui32NewCount > DEBUG_MAX_HANDLE_COUNT)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Max handle count (%u) reached", DEBUG_MAX_HANDLE_COUNT));
+		eReturn = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto error;
+	}
+#endif
+
+	if (psOldArray != IMG_NULL)
+	{
+		
+		eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+			HANDLE_ARRAY_SIZE(ui32OldCount) * sizeof(struct sHandleIndex),
+			psOldArray,
+			hOldArrayBlockAlloc);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free old handle array (%d)", eError));
+		}
+	}
+
+	psBase->psHandleArray = psNewArray;
+	psBase->hArrayBlockAlloc = hNewArrayBlockAlloc;
+	psBase->ui32TotalHandCount = ui32NewCount;
+
+	if (ui32NewCount > ui32OldCount)
+	{
+		
+		PVR_ASSERT(psBase->ui32FreeHandCount + (ui32NewCount - ui32OldCount) > psBase->ui32FreeHandCount)
+
+		 
+		psBase->ui32FreeHandCount += (ui32NewCount - ui32OldCount);
+
+		
+		if (psBase->ui32FirstFreeIndex == 0)
+		{
+			PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0)
+
+			psBase->ui32FirstFreeIndex = ui32OldCount;
+		}
+		else
+		{
+			if (!psBase->bPurgingEnabled)
+			{
+				PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0)
+				PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0)
+
+				INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32OldCount + 1;
+			}
+		}
+
+		if (!psBase->bPurgingEnabled)
+		{
+			psBase->ui32LastFreeIndexPlusOne = ui32NewCount;
+		}
+	}
+	else
+	{
+		PVR_ASSERT(ui32NewCount == 0 || psBase->bPurgingEnabled)
+		PVR_ASSERT(ui32NewCount == 0 || psBase->ui32FirstFreeIndex <= ui32NewCount)
+		PVR_ASSERT(psBase->ui32FreeHandCount - (ui32OldCount - ui32NewCount) < psBase->ui32FreeHandCount)
+
+		 
+		psBase->ui32FreeHandCount -= (ui32OldCount - ui32NewCount);
+
+		if (ui32NewCount == 0)
+		{
+			psBase->ui32FirstFreeIndex = 0;
+			psBase->ui32LastFreeIndexPlusOne = 0;
+		}
+	}
+
+	PVR_ASSERT(psBase->ui32FirstFreeIndex <= psBase->ui32TotalHandCount)
+
+	return PVRSRV_OK;
+
+error:
+	PVR_ASSERT(eReturn != PVRSRV_OK)
+
+	if (psNewArray != IMG_NULL)
+	{
+		
+		for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
+		{
+			struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
+			if (psIndex->psHandle != IMG_NULL)
+			{
+				eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
+						psIndex->psHandle,
+						psIndex->hBlockAlloc);
+				if (eError != PVRSRV_OK)
+				{
+					PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
+				}
+			}
+		}
+
+		
+		eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+			HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
+			psNewArray,
+			hNewArrayBlockAlloc);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free new handle array (%d)", eError));
+		}
+	}
+
+	return eReturn;
+}
+
+static PVRSRV_ERROR FreeHandleArray(PVRSRV_HANDLE_BASE *psBase)
+{
+	return ReallocHandleArray(psBase, 0);
+}
+
+static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
+{
+	HAND_KEY aKey;
+	IMG_UINT32 ui32Index = HANDLE_PTR_TO_INDEX(psHandle);
+	PVRSRV_ERROR eError;
+
+	
+	InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle));
+
+	if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+	{
+#if defined (SUPPORT_SID_INTERFACE)
+		IMG_SID hHandle;
+		hHandle = (IMG_SID) HASH_Remove_Extended(psBase->psHashTab, aKey);
+#else
+		IMG_HANDLE hHandle;
+		hHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, aKey);
+
+#endif
+
+		PVR_ASSERT(hHandle != IMG_NULL)
+		PVR_ASSERT(hHandle == INDEX_TO_HANDLE(ui32Index))
+		PVR_UNREFERENCED_PARAMETER(hHandle);
+	}
+
+	
+	UnlinkFromParent(psBase, psHandle);
+
+	
+	eError = IterateOverChildren(psBase, psHandle, FreeHandle);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%d)", eError));
+		return eError;
+	}
+
+	
+	psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
+
+	if (BATCHED_HANDLE(psHandle) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+	{
+		 
+        SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle);
+		
+		return PVRSRV_OK;
+	}
+
+	
+	if (!psBase->bPurgingEnabled)
+	{
+		if (psBase->ui32FreeHandCount == 0)
+		{
+			PVR_ASSERT(psBase->ui32FirstFreeIndex == 0)
+			PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0)
+
+			psBase->ui32FirstFreeIndex =  ui32Index;
+		}
+		else
+		{
+			
+			PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0)
+			PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0)
+			INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne =  ui32Index + 1;
+		}
+
+		PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0)
+
+		
+		psBase->ui32LastFreeIndexPlusOne = ui32Index + 1;
+	}
+
+	psBase->ui32FreeHandCount++;
+	INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)++;
+
+	PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)<= HANDLE_BLOCK_SIZE)
+
+#ifdef DEBUG
+	{
+		IMG_UINT32 ui32BlockedIndex;
+		IMG_UINT32 ui32FreeHandCount = 0;
+
+		for (ui32BlockedIndex = 0; ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
+		{
+			ui32FreeHandCount += INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32BlockedIndex);
+		}
+
+		PVR_ASSERT(ui32FreeHandCount == psBase->ui32FreeHandCount)
+	}
+#endif
+
+	return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR FreeAllHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+	IMG_UINT32 i;
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
+	{
+		return eError;
+	}
+
+	for (i = 0; i < psBase->ui32TotalHandCount; i++)
+	{
+		struct sHandle *psHandle;
+
+		psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, i);
+
+		if (psHandle->eType != PVRSRV_HANDLE_TYPE_NONE)
+		{
+			eError = FreeHandle(psBase, psHandle);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "FreeAllHandles: FreeHandle failed (%d)", eError));
+				break;
+			}
+
+			
+			if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
+			{
+				break;
+			}
+		}
+	}
+
+	return eError;
+}
+
+static PVRSRV_ERROR FreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
+{
+	PVRSRV_ERROR eError;
+
+	if (HANDLES_BATCHED(psBase))
+	{
+		PVR_DPF((PVR_DBG_WARNING, "FreeHandleBase: Uncommitted/Unreleased handle batch"));
+		PVRSRVReleaseHandleBatch(psBase);
+	}
+
+	
+	eError = FreeAllHandles(psBase);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handles (%d)", eError));
+		return eError;
+	}
+
+	
+	eError = FreeHandleArray(psBase);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle array (%d)", eError));
+		return eError;
+	}
+
+	if (psBase->psHashTab != IMG_NULL)
+	{
+		
+		HASH_Delete(psBase->psHashTab);
+	}
+
+	eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+		sizeof(*psBase),
+		psBase,
+		psBase->hBaseBlockAlloc);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle base (%d)", eError));
+		return eError;
+	}
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(FindHandle)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_SID FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent)
+#else
+IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
+#endif
+{
+	HAND_KEY aKey;
+
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+	InitKey(aKey, psBase, pvData, eType, hParent);
+
+#if defined (SUPPORT_SID_INTERFACE)
+	return (IMG_SID) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
+#else
+	return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
+#endif
+}
+
+static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Delta)
+{
+	PVRSRV_ERROR eError;
+	IMG_UINT32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(ui32Delta);
+	IMG_UINT32 ui32NewTotalHandCount = psBase->ui32TotalHandCount + ui32DeltaAdjusted;
+;
+
+	PVR_ASSERT(ui32Delta != 0)
+
+	
+	if (ui32NewTotalHandCount > psBase->ui32MaxIndexPlusOne || ui32NewTotalHandCount <= psBase->ui32TotalHandCount)
+	{
+		ui32NewTotalHandCount = psBase->ui32MaxIndexPlusOne;
+
+		ui32DeltaAdjusted = ui32NewTotalHandCount - psBase->ui32TotalHandCount;
+
+		if (ui32DeltaAdjusted < ui32Delta)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: Maximum handle limit reached (%d)", psBase->ui32MaxIndexPlusOne));
+			return PVRSRV_ERROR_OUT_OF_MEMORY;
+		}
+	}
+
+	PVR_ASSERT(ui32DeltaAdjusted >= ui32Delta)
+
+	
+	eError = ReallocHandleArray(psBase, ui32NewTotalHandCount);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: ReallocHandleArray failed (%d)", eError));
+		return eError;
+	}
+
+	return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR EnsureFreeHandles(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Free)
+{
+	PVRSRV_ERROR eError;
+
+	if (ui32Free > psBase->ui32FreeHandCount)
+	{
+		IMG_UINT32 ui32FreeHandDelta = ui32Free - psBase->ui32FreeHandCount;
+		eError = IncreaseHandleArraySize(psBase, ui32FreeHandDelta);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "EnsureFreeHandles: Couldn't allocate %u handles to ensure %u free handles (IncreaseHandleArraySize failed with error %d)", ui32FreeHandDelta, ui32Free, eError));
+
+			return eError;
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent)
+#else
+static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
+#endif
+{
+	IMG_UINT32 ui32NewIndex = DEFAULT_MAX_INDEX_PLUS_ONE;
+	struct sHandle *psNewHandle = IMG_NULL;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID hHandle;
+#else
+	IMG_HANDLE hHandle;
+#endif
+	HAND_KEY aKey;
+	PVRSRV_ERROR eError;
+
+	
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+	PVR_ASSERT(psBase != IMG_NULL)
+	PVR_ASSERT(psBase->psHashTab != IMG_NULL)
+
+	if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+	{
+		
+		PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == IMG_NULL)
+	}
+
+	if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase))
+	{
+		 PVR_DPF((PVR_DBG_WARNING, "AllocHandle: Handle batch size (%u) was too small, allocating additional space", psBase->ui32HandBatchSize)); 
+	}
+
+	
+	eError = EnsureFreeHandles(psBase, 1);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "AllocHandle: EnsureFreeHandles failed (%d)", eError));
+		return eError;
+	}
+	PVR_ASSERT(psBase->ui32FreeHandCount != 0)
+
+	if (!psBase->bPurgingEnabled)
+	{
+		
+		ui32NewIndex = psBase->ui32FirstFreeIndex;
+
+		
+		psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
+	}
+	else
+	{
+		IMG_UINT32 ui32BlockedIndex;
+
+		
+		
+		PVR_ASSERT((psBase->ui32FirstFreeIndex % HANDLE_BLOCK_SIZE) == 0)
+
+		for (ui32BlockedIndex = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(psBase->ui32FirstFreeIndex); ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
+		{
+			struct sHandleIndex *psIndex = BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, ui32BlockedIndex);
+
+			if (psIndex->ui32FreeHandBlockCount == 0)
+			{
+				continue;
+			}
+
+			for (ui32NewIndex = ui32BlockedIndex; ui32NewIndex < ui32BlockedIndex + HANDLE_BLOCK_SIZE; ui32NewIndex++)
+			{
+				psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
+				if (HANDLE_STRUCT_IS_FREE(psNewHandle))
+				{
+					break;
+				}
+			}
+		}
+		psBase->ui32FirstFreeIndex = 0;
+		PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount)
+	}
+	PVR_ASSERT(psNewHandle != IMG_NULL)
+
+	
+	hHandle = INDEX_TO_HANDLE(ui32NewIndex);
+
+	
+	if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+	{
+		
+		InitKey(aKey, psBase, pvData, eType, hParent);
+
+		
+		if (!HASH_Insert_Extended(psBase->psHashTab, aKey, (IMG_UINTPTR_T)hHandle))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't add handle to hash table"));
+
+			return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE;
+		}
+	}
+
+	psBase->ui32FreeHandCount--;
+
+	PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) <= HANDLE_BLOCK_SIZE)
+	PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) > 0)
+
+	INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex)--;
+
+	
+	if (!psBase->bPurgingEnabled)
+	{
+		
+		if (psBase->ui32FreeHandCount == 0)
+		{
+			PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex)
+			PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1))
+
+			psBase->ui32LastFreeIndexPlusOne = 0;
+			psBase->ui32FirstFreeIndex = 0;
+		}
+		else
+		{
+			
+			psBase->ui32FirstFreeIndex = (psNewHandle->ui32NextIndexPlusOne == 0) ?
+				ui32NewIndex + 1 :
+				psNewHandle->ui32NextIndexPlusOne - 1;
+		}
+	}
+
+	
+	PVR_ASSERT(psNewHandle->ui32Index == ui32NewIndex)
+
+	 
+	psNewHandle->eType = eType;
+	psNewHandle->pvData = pvData;
+	psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
+	psNewHandle->eFlag = eFlag;
+
+	InitParentList(psNewHandle);
+#if defined(DEBUG)
+	PVR_ASSERT(NoChildren(psNewHandle))
+#endif
+
+	InitChildEntry(psNewHandle);
+#if defined(DEBUG)
+	PVR_ASSERT(NoParent(psNewHandle))
+#endif
+
+	if (HANDLES_BATCHED(psBase))
+	{
+		
+		psNewHandle->ui32NextIndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
+
+		psBase->ui32FirstBatchIndexPlusOne = ui32NewIndex + 1;
+
+		 
+		SET_BATCHED_HANDLE(psNewHandle);
+	}
+	else
+	{
+		psNewHandle->ui32NextIndexPlusOne = 0;
+	}
+
+	
+	*phHandle = hHandle;
+
+	return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
+#else
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
+#endif
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID hHandle;
+#else
+	IMG_HANDLE hHandle;
+#endif
+	PVRSRV_ERROR eError;
+
+#if defined (SUPPORT_SID_INTERFACE)
+	*phHandle = 0;
+#else
+	*phHandle = IMG_NULL;
+#endif
+
+	if (HANDLES_BATCHED(psBase))
+	{
+		
+		psBase->ui32BatchHandAllocFailures++;
+	}
+
+	
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+	if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+	{
+		
+		hHandle = FindHandle(psBase, pvData, eType, IMG_NULL);
+#if defined (SUPPORT_SID_INTERFACE)
+		if (hHandle != 0)
+#else
+		if (hHandle != IMG_NULL)
+#endif
+		{
+			struct sHandle *psHandle;
+
+			eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Lookup of existing handle failed"));
+				return eError;
+			}
+
+			
+			if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED))
+			{
+				*phHandle = hHandle;
+				eError = PVRSRV_OK;
+				goto exit_ok;
+			}
+			
+#if defined (SUPPORT_SID_INTERFACE)
+			PVR_DBG_BREAK
+#endif
+			return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
+		}
+	}
+
+	eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL);
+	
+exit_ok:
+	if (HANDLES_BATCHED(psBase) && (eError == PVRSRV_OK))
+	{
+		psBase->ui32BatchHandAllocFailures--;
+	}
+
+	return eError;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent)
+#else
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
+#endif
+{
+	struct sHandle *psPHand;
+	struct sHandle *psCHand;
+	PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID hParentKey;
+	IMG_SID hHandle;
+
+	*phHandle = 0;
+#else
+	IMG_HANDLE hParentKey;
+	IMG_HANDLE hHandle;
+
+	*phHandle = IMG_NULL;
+#endif
+
+	if (HANDLES_BATCHED(psBase))
+	{
+		
+		psBase->ui32BatchHandAllocFailures++;
+	}
+
+	
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+	hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
+			hParent : IMG_NULL;
+
+	
+	eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE);
+	if (eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+	{
+		
+		hHandle = FindHandle(psBase, pvData, eType, hParentKey);
+#if defined (SUPPORT_SID_INTERFACE)
+		if (hHandle != 0)
+#else
+		if (hHandle != IMG_NULL)
+#endif
+		{
+			struct sHandle *psCHandle;
+			PVRSRV_ERROR eErr;
+
+			eErr = GetHandleStructure(psBase, &psCHandle, hHandle, eType);
+			if (eErr != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed"));
+				return eErr;
+			}
+
+			PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent)
+
+			
+			if (TEST_FLAG(psCHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent)
+			{
+				*phHandle = hHandle;
+				goto exit_ok;
+			}
+#if defined (SUPPORT_SID_INTERFACE)
+			PVR_DBG_BREAK
+#endif
+			return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
+		}
+	}
+
+	eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey);
+	if (eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	
+	psPHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hParent);
+
+	psCHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle);
+
+	AdoptChild(psBase, psPHand, psCHand);
+
+	*phHandle = hHandle;
+
+exit_ok:
+	if (HANDLES_BATCHED(psBase))
+	{
+		psBase->ui32BatchHandAllocFailures--;
+	}
+
+	return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID hHandle;
+#else
+	IMG_HANDLE hHandle;
+#endif
+
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+	
+#if defined (SUPPORT_SID_INTERFACE)
+	hHandle = (IMG_SID) FindHandle(psBase, pvData, eType, IMG_NULL);
+#else
+	hHandle = (IMG_HANDLE) FindHandle(psBase, pvData, eType, IMG_NULL);
+#endif
+	if (hHandle == IMG_NULL)
+	{
+		return PVRSRV_ERROR_HANDLE_NOT_FOUND;
+	}
+
+	*phHandle = hHandle;
+
+	return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_SID hHandle)
+#else
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
+#endif
+{
+	struct sHandle *psHandle;
+	PVRSRV_ERROR eError;
+
+	eError = GetHandleStructure(psBase, &psHandle, hHandle, PVRSRV_HANDLE_TYPE_NONE);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: Error looking up handle (%d)", eError));
+#if defined (SUPPORT_SID_INTERFACE)
+		PVR_DBG_BREAK
+#endif
+		return eError;
+	}
+
+	*ppvData = psHandle->pvData;
+	*peType = psHandle->eType;
+
+	return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+	struct sHandle *psHandle;
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+#if defined (SUPPORT_SID_INTERFACE)
+	PVR_ASSERT(hHandle != 0)
+#endif
+
+	eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Error looking up handle (%d)", eError));
+#if defined (SUPPORT_SID_INTERFACE)
+		PVR_DBG_BREAK
+#endif
+		return eError;
+	}
+
+	*ppvData = psHandle->pvData;
+
+	return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType, IMG_SID hAncestor)
+#else
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
+#endif
+{
+	struct sHandle *psPHand;
+	struct sHandle *psCHand;
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+#if defined (SUPPORT_SID_INTERFACE)
+	PVR_ASSERT(hHandle != 0)
+#endif
+
+	eError = GetHandleStructure(psBase, &psCHand, hHandle, eType);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Error looking up subhandle (%d)", eError));
+		return eError;
+	}
+
+	
+	for (psPHand = psCHand; ParentHandle(psPHand) != hAncestor; )
+	{
+		eError = GetHandleStructure(psBase, &psPHand, ParentHandle(psPHand), PVRSRV_HANDLE_TYPE_NONE);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor"));
+			return PVRSRV_ERROR_INVALID_SUBHANDLE;
+		}
+	}
+
+	*ppvData = psCHand->pvData;
+
+	return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phParent, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+	struct sHandle *psHandle;
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+	eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Error looking up subhandle (%d)", eError));
+		return eError;
+	}
+
+	*phParent = ParentHandle(psHandle);
+
+	return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+	struct sHandle *psHandle;
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+	eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupAndReleaseHandle: Error looking up handle (%d)", eError));
+#if defined (SUPPORT_SID_INTERFACE)
+		PVR_DBG_BREAK
+#endif
+		return eError;
+	}
+
+	*ppvData = psHandle->pvData;
+
+	eError = FreeHandle(psBase, psHandle);
+
+	return eError;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+	struct sHandle *psHandle;
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+	eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Error looking up handle (%d)", eError));
+		return eError;
+	}
+
+	eError = FreeHandle(psBase, psHandle);
+
+	return eError;
+}
+
+PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize)
+{
+	PVRSRV_ERROR eError;
+
+	if (HANDLES_BATCHED(psBase))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: There is a handle batch already in use (size %u)", psBase->ui32HandBatchSize));
+		return  PVRSRV_ERROR_HANDLE_BATCH_IN_USE;
+	}
+
+	if (ui32BatchSize == 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: Invalid batch size (%u)", ui32BatchSize));
+		return  PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	eError = EnsureFreeHandles(psBase, ui32BatchSize);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: EnsureFreeHandles failed (error %d)", eError));
+		return eError;
+	}
+
+	psBase->ui32HandBatchSize = ui32BatchSize;
+
+	
+	psBase->ui32TotalHandCountPreBatch = psBase->ui32TotalHandCount;
+
+	PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0)
+
+	PVR_ASSERT(psBase->ui32FirstBatchIndexPlusOne == 0)
+
+	PVR_ASSERT(HANDLES_BATCHED(psBase))
+
+	return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, IMG_BOOL bCommit)
+{
+
+	IMG_UINT32 ui32IndexPlusOne;
+	IMG_BOOL bCommitBatch = bCommit;
+
+	if (!HANDLES_BATCHED(psBase))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: There is no handle batch"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+
+	}
+
+	if (psBase->ui32BatchHandAllocFailures != 0)
+	{
+		if (bCommit)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Attempting to commit batch with handle allocation failures."));
+		}
+		bCommitBatch = IMG_FALSE;
+	}
+	
+	PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0 || !bCommit)
+
+	ui32IndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
+	while(ui32IndexPlusOne != 0)
+	{
+		struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32IndexPlusOne - 1);
+		IMG_UINT32 ui32NextIndexPlusOne = psHandle->ui32NextIndexPlusOne;
+		PVR_ASSERT(BATCHED_HANDLE(psHandle))
+
+		psHandle->ui32NextIndexPlusOne = 0;
+
+		if (!bCommitBatch || BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+		{
+			PVRSRV_ERROR eError;
+
+			
+			if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+			{
+				 
+				SET_UNBATCHED_HANDLE(psHandle);  
+			}
+
+			eError = FreeHandle(psBase, psHandle);
+			if (eError != PVRSRV_OK)
+			{
+				 PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Error freeing handle (%d)", eError));
+			}
+			PVR_ASSERT(eError == PVRSRV_OK)
+		}
+		else
+		{
+			 
+			SET_UNBATCHED_HANDLE(psHandle);
+		}
+
+		ui32IndexPlusOne = ui32NextIndexPlusOne;
+	}
+
+#ifdef DEBUG
+	if (psBase->ui32TotalHandCountPreBatch != psBase->ui32TotalHandCount)
+	{
+		IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - psBase->ui32TotalHandCountPreBatch;
+
+		PVR_ASSERT(psBase->ui32TotalHandCount > psBase->ui32TotalHandCountPreBatch)
+
+		PVR_DPF((PVR_DBG_WARNING, "PVRSRVHandleBatchCommitOrRelease: The batch size was too small.  Batch size was %u, but needs to be %u", psBase->ui32HandBatchSize,  psBase->ui32HandBatchSize + ui32Delta));
+
+	}
+#endif
+
+	psBase->ui32HandBatchSize = 0;
+	psBase->ui32FirstBatchIndexPlusOne = 0;
+	psBase->ui32TotalHandCountPreBatch = 0;
+	psBase->ui32BatchHandAllocFailures = 0;
+
+	if (psBase->ui32BatchHandAllocFailures != 0 && bCommit)
+	{
+		PVR_ASSERT(!bCommitBatch)
+
+		return PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE;
+	}
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+	return PVRSRVHandleBatchCommitOrRelease(psBase, IMG_TRUE);
+}
+
+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+	(IMG_VOID) PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE);
+}
+
+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
+{
+	IMG_UINT32 ui32MaxHandleRounded;
+
+	if (HANDLES_BATCHED(psBase))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set whilst in batch mode"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	if (ui32MaxHandle  == 0 || ui32MaxHandle > DEFAULT_MAX_HANDLE)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit must be between %u and %u, inclusive", 0, DEFAULT_MAX_HANDLE));
+
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	if (psBase->ui32TotalHandCount != 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set because handles have already been allocated"));
+
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	ui32MaxHandleRounded = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(ui32MaxHandle);
+
+	
+	if (ui32MaxHandleRounded != 0 && ui32MaxHandleRounded < psBase->ui32MaxIndexPlusOne)
+	{
+		psBase->ui32MaxIndexPlusOne = ui32MaxHandleRounded;
+	}
+
+	PVR_ASSERT(psBase->ui32MaxIndexPlusOne != 0)
+	PVR_ASSERT(psBase->ui32MaxIndexPlusOne <= DEFAULT_MAX_INDEX_PLUS_ONE)
+	PVR_ASSERT((psBase->ui32MaxIndexPlusOne % HANDLE_BLOCK_SIZE) == 0)
+
+	return PVRSRV_OK;
+}
+
+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
+{
+	return psBase->ui32MaxIndexPlusOne;
+}
+
+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
+{
+	if (psBase->bPurgingEnabled)
+	{
+		PVR_DPF((PVR_DBG_WARNING, "PVRSRVEnableHandlePurging: Purging already enabled"));
+		return PVRSRV_OK;
+	}
+
+	
+	if (psBase->ui32TotalHandCount != 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVEnableHandlePurging: Handles have already been allocated"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psBase->bPurgingEnabled = IMG_TRUE;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+	IMG_UINT32 ui32BlockIndex;
+	IMG_UINT32 ui32NewHandCount;
+
+	if (!psBase->bPurgingEnabled)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not enabled for this handle base"));
+		return PVRSRV_ERROR_NOT_SUPPORTED;
+	}
+
+	if (HANDLES_BATCHED(psBase))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not allowed whilst in batch mode"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	PVR_ASSERT((psBase->ui32TotalHandCount % HANDLE_BLOCK_SIZE) == 0)
+
+	for (ui32BlockIndex = INDEX_TO_BLOCK_INDEX(psBase->ui32TotalHandCount); ui32BlockIndex != 0; ui32BlockIndex--)
+	{
+		if (psBase->psHandleArray[ui32BlockIndex - 1].ui32FreeHandBlockCount != HANDLE_BLOCK_SIZE)
+		{
+			break;
+		}
+	}
+	ui32NewHandCount = BLOCK_INDEX_TO_INDEX(ui32BlockIndex);
+
+	
+	if (ui32NewHandCount <= (psBase->ui32TotalHandCount/2))
+	{
+		PVRSRV_ERROR eError;
+
+		
+
+		eError = ReallocHandleArray(psBase, ui32NewHandCount);
+		if (eError != PVRSRV_OK)
+		{
+			return eError;
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
+{
+	PVRSRV_HANDLE_BASE *psBase;
+	IMG_HANDLE hBlockAlloc;
+	PVRSRV_ERROR eError;
+
+	eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+		sizeof(*psBase),
+		(IMG_PVOID *)&psBase,
+		&hBlockAlloc,
+		"Handle Base");
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base (%d)", eError));
+		return eError;
+	}
+	OSMemSet(psBase, 0, sizeof(*psBase));
+
+	
+	psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, sizeof(HAND_KEY), HASH_Func_Default, HASH_Key_Comp_Default);
+	if (psBase->psHashTab == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't create data pointer hash table\n"));
+		(IMG_VOID)PVRSRVFreeHandleBase(psBase);
+		return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
+	}
+
+	psBase->hBaseBlockAlloc = hBlockAlloc;
+
+	psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE;
+
+	*ppsBase = psBase;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
+{
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(psBase != gpsKernelHandleBase)
+
+	eError = FreeHandleBase(psBase);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeHandleBase: FreeHandleBase failed (%d)", eError));
+	}
+
+	return eError;
+}
+
+PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID)
+{
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(gpsKernelHandleBase == IMG_NULL)
+
+	eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%d)", eError));
+		goto error;
+	}
+
+	eError = PVRSRVEnableHandlePurging(gpsKernelHandleBase);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%d)", eError));
+		goto error;
+	}
+
+	return PVRSRV_OK;
+error:
+	(IMG_VOID) PVRSRVHandleDeInit();
+	return eError;
+}
+
+PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	if (gpsKernelHandleBase != IMG_NULL)
+	{
+		eError = FreeHandleBase(gpsKernelHandleBase);
+		if (eError == PVRSRV_OK)
+		{
+			gpsKernelHandleBase = IMG_NULL;
+		}
+		else
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleDeInit: FreeHandleBase failed (%d)", eError));
+		}
+	}
+
+	return eError;
+}
+#else
+#endif	
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/hash.c b/drivers/staging/cdv/pvr/services4/srvkm/common/hash.c
new file mode 100644
index 0000000..e5dd781
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/hash.c
@@ -0,0 +1,506 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "pvr_debug.h"
+#include "img_defs.h"
+#include "services.h"
+#include "servicesint.h"
+#include "hash.h"
+#include "osfunc.h"
+
+#define PRIVATE_MAX(a,b) ((a)>(b)?(a):(b))
+
+#define	KEY_TO_INDEX(pHash, key, uSize) \
+	((pHash)->pfnHashFunc((pHash)->uKeySize, (key), (uSize)) % (uSize))
+
+#define	KEY_COMPARE(pHash, pKey1, pKey2) \
+	((pHash)->pfnKeyComp((pHash)->uKeySize, (pKey1), (pKey2)))
+
+struct _BUCKET_
+{
+	
+	struct _BUCKET_ *pNext;
+
+	
+	IMG_UINTPTR_T v;
+
+	
+	IMG_UINTPTR_T k[];		 
+};
+typedef struct _BUCKET_ BUCKET;
+
+struct _HASH_TABLE_
+{
+	
+	BUCKET **ppBucketTable;
+
+	
+	IMG_UINT32 uSize;
+
+	
+	IMG_UINT32 uCount;
+
+	
+	IMG_UINT32 uMinimumSize;
+
+	
+	IMG_UINT32 uKeySize;
+
+	
+	HASH_FUNC *pfnHashFunc;
+
+	
+	HASH_KEY_COMP *pfnKeyComp;
+};
+
+IMG_UINT32
+HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen)
+{
+	IMG_UINTPTR_T *p = (IMG_UINTPTR_T *)pKey;
+	IMG_UINT32 uKeyLen = (IMG_UINT32)(uKeySize / sizeof(IMG_UINTPTR_T));
+	IMG_UINT32 ui;
+	IMG_UINT32 uHashKey = 0;
+
+	PVR_UNREFERENCED_PARAMETER(uHashTabLen);
+
+	PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0);
+
+	for (ui = 0; ui < uKeyLen; ui++)
+	{
+		IMG_UINT32 uHashPart = (IMG_UINT32)*p++;
+
+		uHashPart += (uHashPart << 12);
+		uHashPart ^= (uHashPart >> 22);
+		uHashPart += (uHashPart << 4);
+		uHashPart ^= (uHashPart >> 9);
+		uHashPart += (uHashPart << 10);
+		uHashPart ^= (uHashPart >> 2);
+		uHashPart += (uHashPart << 7);
+		uHashPart ^= (uHashPart >> 12);
+
+		uHashKey += uHashPart;
+	}
+
+	return uHashKey;
+}
+
+IMG_BOOL
+HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2)
+{
+	IMG_UINTPTR_T *p1 = (IMG_UINTPTR_T *)pKey1;
+	IMG_UINTPTR_T *p2 = (IMG_UINTPTR_T *)pKey2;
+	IMG_UINT32 uKeyLen = (IMG_UINT32)(uKeySize / sizeof(IMG_UINTPTR_T));
+	IMG_UINT32 ui;
+
+	PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0);
+
+	for (ui = 0; ui < uKeyLen; ui++)
+	{
+		if (*p1++ != *p2++)
+			return IMG_FALSE;
+	}
+
+	return IMG_TRUE;
+}
+
+static PVRSRV_ERROR
+_ChainInsert (HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize)
+{
+	IMG_UINT32 uIndex;
+
+	PVR_ASSERT (pBucket != IMG_NULL);
+	PVR_ASSERT (ppBucketTable != IMG_NULL);
+	PVR_ASSERT (uSize != 0);
+
+	if ((pBucket == IMG_NULL) || (ppBucketTable == IMG_NULL) || (uSize == 0))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "_ChainInsert: invalid parameter"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize);	 
+	pBucket->pNext = ppBucketTable[uIndex];
+	ppBucketTable[uIndex] = pBucket;
+
+	return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+_Rehash (HASH_TABLE *pHash,
+	 BUCKET **ppOldTable, IMG_UINT32 uOldSize,
+         BUCKET **ppNewTable, IMG_UINT32 uNewSize)
+{
+	IMG_UINT32 uIndex;
+	for (uIndex=0; uIndex< uOldSize; uIndex++)
+    {
+		BUCKET *pBucket;
+		pBucket = ppOldTable[uIndex];
+		while (pBucket != IMG_NULL)
+		{
+			PVRSRV_ERROR eError;
+			BUCKET *pNextBucket = pBucket->pNext;
+			eError = _ChainInsert (pHash, pBucket, ppNewTable, uNewSize);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "_Rehash: call to _ChainInsert failed"));
+				return eError;
+			}
+			pBucket = pNextBucket;
+		}
+    }
+	return PVRSRV_OK;
+}
+
+static IMG_BOOL
+_Resize (HASH_TABLE *pHash, IMG_UINT32 uNewSize)
+{
+	if (uNewSize != pHash->uSize)
+    {
+		BUCKET **ppNewTable;
+		IMG_UINT32 uIndex;
+
+		PVR_DPF ((PVR_DBG_MESSAGE,
+                  "HASH_Resize: oldsize=0x%x  newsize=0x%x  count=0x%x",
+				pHash->uSize, uNewSize, pHash->uCount));
+
+		OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+                      sizeof (BUCKET *) * uNewSize,
+                      (IMG_PVOID*)&ppNewTable, IMG_NULL,
+					  "Hash Table Buckets");
+		if (ppNewTable == IMG_NULL)
+			return IMG_FALSE;
+
+        for (uIndex=0; uIndex<uNewSize; uIndex++)
+            ppNewTable[uIndex] = IMG_NULL;
+
+        if (_Rehash (pHash, pHash->ppBucketTable, pHash->uSize, ppNewTable, uNewSize) != PVRSRV_OK)
+		{
+			OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET*) * uNewSize, ppNewTable, IMG_NULL);
+			return IMG_FALSE;
+		}
+
+        OSFreeMem (PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
+        
+        pHash->ppBucketTable = ppNewTable;
+        pHash->uSize = uNewSize;
+    }
+    return IMG_TRUE;
+}
+
+
+HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp)
+{
+	HASH_TABLE *pHash;
+	IMG_UINT32 uIndex;
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Create_Extended: InitialSize=0x%x", uInitialLen));
+
+	if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+					sizeof(HASH_TABLE),
+					(IMG_VOID **)&pHash, IMG_NULL,
+					"Hash Table") != PVRSRV_OK)
+	{
+		return IMG_NULL;
+	}
+
+	pHash->uCount = 0;
+	pHash->uSize = uInitialLen;
+	pHash->uMinimumSize = uInitialLen;
+	pHash->uKeySize = (IMG_UINT32)uKeySize;
+	pHash->pfnHashFunc = pfnHashFunc;
+	pHash->pfnKeyComp = pfnKeyComp;
+
+	OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+                  sizeof (BUCKET *) * pHash->uSize,
+                  (IMG_PVOID*)&pHash->ppBucketTable, IMG_NULL,
+				  "Hash Table Buckets");
+
+	if (pHash->ppBucketTable == IMG_NULL)
+    {
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
+		
+		return IMG_NULL;
+    }
+
+	for (uIndex=0; uIndex<pHash->uSize; uIndex++)
+		pHash->ppBucketTable[uIndex] = IMG_NULL;
+	return pHash;
+}
+
+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen)
+{
+	return HASH_Create_Extended(uInitialLen, sizeof(IMG_UINTPTR_T),
+		&HASH_Func_Default, &HASH_Key_Comp_Default);
+}
+
+IMG_VOID
+HASH_Delete (HASH_TABLE *pHash)
+{
+	if (pHash != IMG_NULL)
+    {
+		PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Delete"));
+
+		PVR_ASSERT (pHash->uCount==0);
+		if(pHash->uCount != 0)
+		{
+			PVR_DPF ((PVR_DBG_ERROR, "HASH_Delete: leak detected in hash table!"));
+			PVR_DPF ((PVR_DBG_ERROR, "Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
+		}
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
+		pHash->ppBucketTable = IMG_NULL;
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
+		
+    }
+}
+
+IMG_BOOL
+HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v)
+{
+	BUCKET *pBucket;
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+              "HASH_Insert_Extended: Hash=0x%08x, pKey=0x%08x, v=0x%x",
+              (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
+
+	PVR_ASSERT (pHash != IMG_NULL);
+
+	if (pHash == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "HASH_Insert_Extended: invalid parameter"));
+		return IMG_FALSE;
+	}
+
+	if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+					sizeof(BUCKET) + pHash->uKeySize,
+					(IMG_VOID **)&pBucket, IMG_NULL,
+					"Hash Table entry") != PVRSRV_OK)
+	{
+		return IMG_FALSE;
+	}
+
+	pBucket->v = v;
+	 
+	OSMemCopy(pBucket->k, pKey, pHash->uKeySize);
+	if (_ChainInsert (pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != PVRSRV_OK)
+	{
+		OSFreeMem(PVRSRV_PAGEABLE_SELECT,
+				  sizeof(BUCKET) + pHash->uKeySize,
+				  pBucket, IMG_NULL);
+		return IMG_FALSE;
+	}
+
+	pHash->uCount++;
+
+	
+	if (pHash->uCount << 1 > pHash->uSize)
+    {
+        
+
+        _Resize (pHash, pHash->uSize << 1);
+    }
+
+
+	return IMG_TRUE;
+}
+
+IMG_BOOL
+HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v)
+{
+	PVR_DPF ((PVR_DBG_MESSAGE,
+              "HASH_Insert: Hash=0x%x, k=0x%x, v=0x%x",
+              (IMG_UINTPTR_T)pHash, k, v));
+
+	return HASH_Insert_Extended(pHash, &k, v);
+}
+
+IMG_UINTPTR_T
+HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey)
+{
+	BUCKET **ppBucket;
+	IMG_UINT32 uIndex;
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x",
+			(IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+
+	PVR_ASSERT (pHash != IMG_NULL);
+
+	if (pHash == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "HASH_Remove_Extended: Null hash table"));
+		return 0;
+	}
+
+	uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
+
+	for (ppBucket = &(pHash->ppBucketTable[uIndex]); ppBucket && *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
+	{
+		 
+		if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
+		{
+			BUCKET *pBucket = *ppBucket;
+			IMG_UINTPTR_T v = pBucket->v;
+			(*ppBucket) = pBucket->pNext;
+
+			OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET) + pHash->uKeySize, pBucket, IMG_NULL);
+			
+
+			pHash->uCount--;
+
+			
+			if (pHash->uSize > (pHash->uCount << 2) &&
+                pHash->uSize > pHash->uMinimumSize)
+            {
+                
+
+				_Resize (pHash,
+                         PRIVATE_MAX (pHash->uSize >> 1,
+                                      pHash->uMinimumSize));
+            }
+
+			PVR_DPF ((PVR_DBG_MESSAGE,
+                      "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x%x",
+                      (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
+			return v;
+		}
+	}
+	PVR_DPF ((PVR_DBG_MESSAGE,
+              "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x0 !!!!",
+              (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+	return 0;
+}
+
+IMG_UINTPTR_T
+HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k)
+{
+	PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove: Hash=0x%x, k=0x%x",
+			(IMG_UINTPTR_T)pHash, k));
+
+	return HASH_Remove_Extended(pHash, &k);
+}
+
+IMG_UINTPTR_T
+HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey)
+{
+	BUCKET **ppBucket;
+	IMG_UINT32 uIndex;
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve_Extended: Hash=0x%x, pKey=0x%x",
+			(IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+
+	PVR_ASSERT (pHash != IMG_NULL);
+
+	if (pHash == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "HASH_Retrieve_Extended: Null hash table"));
+		return 0;
+	}
+
+	uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
+
+	for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
+	{
+		 
+		if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
+		{
+			BUCKET *pBucket = *ppBucket;
+			IMG_UINTPTR_T v = pBucket->v;
+
+			PVR_DPF ((PVR_DBG_MESSAGE,
+                      "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x%x",
+                      (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
+			return v;
+		}
+	}
+	PVR_DPF ((PVR_DBG_MESSAGE,
+              "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x0 !!!!",
+              (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+	return 0;
+}
+
+IMG_UINTPTR_T
+HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k)
+{
+	PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=0x%x, k=0x%x",
+			(IMG_UINTPTR_T)pHash, k));
+	return HASH_Retrieve_Extended(pHash, &k);
+}
+
+PVRSRV_ERROR
+HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback)
+{
+	IMG_UINT32 uIndex;
+	for (uIndex=0; uIndex < pHash->uSize; uIndex++)
+	{
+		BUCKET *pBucket;
+		pBucket = pHash->ppBucketTable[uIndex];
+		while (pBucket != IMG_NULL)
+		{
+			PVRSRV_ERROR eError;
+			BUCKET *pNextBucket = pBucket->pNext;
+			
+			eError = pfnCallback((IMG_UINTPTR_T) ((IMG_VOID *) *(pBucket->k)), (IMG_UINTPTR_T) pBucket->v);
+
+			
+			if (eError != PVRSRV_OK)
+				return eError;
+
+			pBucket = pNextBucket;
+		}
+	}
+	return PVRSRV_OK;
+}
+
+#ifdef HASH_TRACE
+IMG_VOID
+HASH_Dump (HASH_TABLE *pHash)
+{
+	IMG_UINT32 uIndex;
+	IMG_UINT32 uMaxLength=0;
+	IMG_UINT32 uEmptyCount=0;
+
+	PVR_ASSERT (pHash != IMG_NULL);
+	for (uIndex=0; uIndex<pHash->uSize; uIndex++)
+	{
+		BUCKET *pBucket;
+		IMG_UINT32 uLength = 0;
+		if (pHash->ppBucketTable[uIndex] == IMG_NULL)
+		{
+			uEmptyCount++;
+		}
+		for (pBucket=pHash->ppBucketTable[uIndex];
+				pBucket != IMG_NULL;
+				pBucket = pBucket->pNext)
+		{
+			uLength++;
+		}
+		uMaxLength = PRIVATE_MAX (uMaxLength, uLength);
+	}
+
+	PVR_TRACE(("hash table: uMinimumSize=%d  size=%d  count=%d",
+			pHash->uMinimumSize, pHash->uSize, pHash->uCount));
+	PVR_TRACE(("  empty=%d  max=%d", uEmptyCount, uMaxLength));
+}
+#endif
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/lists.c b/drivers/staging/cdv/pvr/services4/srvkm/common/lists.c
new file mode 100644
index 0000000..1081781
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/lists.c
@@ -0,0 +1,99 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "lists.h"
+#include "services_headers.h"
+
+IMPLEMENT_LIST_ANY_VA(BM_HEAP)
+IMPLEMENT_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_FOR_EACH_VA(BM_HEAP)
+IMPLEMENT_LIST_REMOVE(BM_HEAP)
+IMPLEMENT_LIST_INSERT(BM_HEAP)
+
+IMPLEMENT_LIST_ANY_VA(BM_CONTEXT)
+IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL)
+IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_FOR_EACH(BM_CONTEXT)
+IMPLEMENT_LIST_REMOVE(BM_CONTEXT)
+IMPLEMENT_LIST_INSERT(BM_CONTEXT)
+
+IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_ANY_VA(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_FOR_EACH(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_INSERT(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_REMOVE(PVRSRV_DEVICE_NODE)
+
+IMPLEMENT_LIST_ANY_VA(PVRSRV_POWER_DEV)
+IMPLEMENT_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_INSERT(PVRSRV_POWER_DEV)
+IMPLEMENT_LIST_REMOVE(PVRSRV_POWER_DEV)
+
+
+IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va)
+{
+	IMG_UINT32 ui32DevIndex;
+	IMG_BOOL bIgnoreClass;
+	PVRSRV_DEVICE_CLASS eDevClass;
+
+	ui32DevIndex = va_arg(va, IMG_UINT32);
+	bIgnoreClass = va_arg(va, IMG_BOOL);
+	if (!bIgnoreClass)
+	{
+		eDevClass = va_arg(va, PVRSRV_DEVICE_CLASS);
+	}
+	else
+	{
+		
+
+		eDevClass = PVRSRV_DEVICE_CLASS_FORCE_I32;
+	}
+
+	if ((bIgnoreClass || psDeviceNode->sDevId.eDeviceClass == eDevClass) &&
+		psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex)
+	{
+		return psDeviceNode;
+	}
+	return IMG_NULL;
+}
+
+IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va)
+{
+	IMG_UINT32 ui32DeviceIndex;
+
+	ui32DeviceIndex = va_arg(va, IMG_UINT32);
+
+	if (psPowerDev->ui32DeviceIndex == ui32DeviceIndex)
+	{
+		return psPowerDev;
+	}
+	else
+	{
+		return IMG_NULL;
+	}
+}
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/mem.c b/drivers/staging/cdv/pvr/services4/srvkm/common/mem.c
new file mode 100644
index 0000000..5b5d1ac
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/mem.c
@@ -0,0 +1,153 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "pvr_bridge_km.h"
+
+
+static PVRSRV_ERROR
+FreeSharedSysMemCallBack(IMG_PVOID  pvParam,
+						 IMG_UINT32 ui32Param,
+						 IMG_BOOL   bDummy)
+{
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = pvParam;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	OSFreePages(psKernelMemInfo->ui32Flags,
+				psKernelMemInfo->uAllocSize,
+				psKernelMemInfo->pvLinAddrKM,
+				psKernelMemInfo->sMemBlk.hOSMemHandle);
+
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+			  sizeof(PVRSRV_KERNEL_MEM_INFO),
+			  psKernelMemInfo,
+			  IMG_NULL);
+	
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+							 IMG_UINT32					ui32Flags,
+							 IMG_SIZE_T 				uSize,
+							 PVRSRV_KERNEL_MEM_INFO 	**ppsKernelMemInfo)
+{
+	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  sizeof(PVRSRV_KERNEL_MEM_INFO),
+				  (IMG_VOID **)&psKernelMemInfo, IMG_NULL,
+				  "Kernel Memory Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for meminfo"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo));
+
+	ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK;
+	ui32Flags |= PVRSRV_HAP_MULTI_PROCESS;
+	psKernelMemInfo->ui32Flags = ui32Flags;
+	psKernelMemInfo->uAllocSize = uSize;
+
+	if(OSAllocPages(psKernelMemInfo->ui32Flags,
+					psKernelMemInfo->uAllocSize,
+					(IMG_UINT32)HOST_PAGESIZE(),
+					&psKernelMemInfo->pvLinAddrKM,
+					&psKernelMemInfo->sMemBlk.hOSMemHandle)
+		!= PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for block"));
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+				  sizeof(PVRSRV_KERNEL_MEM_INFO),
+				  psKernelMemInfo,
+				  0);
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	
+	psKernelMemInfo->sMemBlk.hResItem =
+				ResManRegisterRes(psPerProc->hResManContext,
+								  RESMAN_TYPE_SHARED_MEM_INFO,
+								  psKernelMemInfo,
+								  0,
+								  &FreeSharedSysMemCallBack);
+
+	*ppsKernelMemInfo = psKernelMemInfo;
+
+	return PVRSRV_OK; 
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+	PVRSRV_ERROR eError;
+
+	if(psKernelMemInfo->sMemBlk.hResItem)
+	{
+		eError = ResManFreeResByPtr(psKernelMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+	}
+	else
+	{
+		eError = FreeSharedSysMemCallBack(psKernelMemInfo, 0, CLEANUP_WITH_POLL);
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	if(!psKernelMemInfo)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	if(psKernelMemInfo->sMemBlk.hResItem)
+	{
+		eError = ResManDissociateRes(psKernelMemInfo->sMemBlk.hResItem, IMG_NULL);
+
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVDissociateMemFromResmanKM: ResManDissociateRes failed"));
+			PVR_DBG_BREAK;
+			return eError;
+		}
+
+		psKernelMemInfo->sMemBlk.hResItem = IMG_NULL;
+	}
+
+	return eError;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/mem_debug.c b/drivers/staging/cdv/pvr/services4/srvkm/common/mem_debug.c
new file mode 100644
index 0000000..e721fb3
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/mem_debug.c
@@ -0,0 +1,250 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef MEM_DEBUG_C
+#define MEM_DEBUG_C
+
+#if defined(PVRSRV_DEBUG_OS_MEMORY)
+
+#include "img_types.h"
+#include "services_headers.h"
+
+#if defined (__cplusplus)
+extern "C"
+{
+#endif
+
+#define STOP_ON_ERROR 0
+
+	
+
+	
+
+
+
+
+
+	IMG_BOOL MemCheck(const IMG_PVOID pvAddr, const IMG_UINT8 ui8Pattern, IMG_SIZE_T uSize)
+	{
+		IMG_UINT8 *pui8Addr;
+		for (pui8Addr = (IMG_UINT8*)pvAddr; uSize > 0; uSize--, pui8Addr++)
+		{
+			if (*pui8Addr != ui8Pattern)
+			{
+				return IMG_FALSE;
+			}
+		}
+		return IMG_TRUE;
+	}
+
+	
+
+	IMG_VOID OSCheckMemDebug(IMG_PVOID pvCpuVAddr, IMG_SIZE_T uSize, const IMG_CHAR *pszFileName, const IMG_UINT32 uLine)
+	{
+		OSMEM_DEBUG_INFO const *psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32)pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
+
+		
+		if (pvCpuVAddr == IMG_NULL)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : null pointer"
+					 " - referenced %s:%d - allocated %s:%d",
+					 pvCpuVAddr,
+					 pszFileName, uLine,
+					 psInfo->sFileName, psInfo->uLineNo));
+			while (STOP_ON_ERROR);
+		}
+
+		
+		if (((IMG_UINT32)pvCpuVAddr&3) != 0)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : invalid alignment"
+					 " - referenced %s:%d - allocated %s:%d",
+					 pvCpuVAddr,
+					 pszFileName, uLine,
+					 psInfo->sFileName, psInfo->uLineNo));
+			while (STOP_ON_ERROR);
+		}
+
+		
+		if (!MemCheck((IMG_PVOID)psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore)))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region before overwritten"
+					 " - referenced %s:%d - allocated %s:%d",
+					 pvCpuVAddr,
+					 pszFileName, uLine,
+					 psInfo->sFileName, psInfo->uLineNo));
+			while (STOP_ON_ERROR);
+		}
+
+		
+		if (uSize != psInfo->uSize)
+		{
+			PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : supplied size was different to stored size (0x%X != 0x%X)"
+					 " - referenced %s:%d - allocated %s:%d",
+					 pvCpuVAddr, uSize, psInfo->uSize,
+					 pszFileName, uLine,
+					 psInfo->sFileName, psInfo->uLineNo));
+			while (STOP_ON_ERROR);
+		}
+
+		
+		if ((0x01234567 ^ psInfo->uSizeParityCheck) != psInfo->uSize)
+		{
+			PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : stored size parity error (0x%X != 0x%X)"
+					 " - referenced %s:%d - allocated %s:%d",
+					 pvCpuVAddr, psInfo->uSize, 0x01234567 ^ psInfo->uSizeParityCheck,
+					 pszFileName, uLine,
+					 psInfo->sFileName, psInfo->uLineNo));
+			while (STOP_ON_ERROR);
+		}
+		else
+		{
+			
+			uSize = psInfo->uSize;
+		}
+
+		
+		if (uSize)
+		{
+			if (!MemCheck((IMG_VOID*)((IMG_UINT32)pvCpuVAddr + uSize), 0xB2, TEST_BUFFER_PADDING_AFTER))
+			{
+				PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region after overwritten"
+						 " - referenced from %s:%d - allocated from %s:%d",
+						 pvCpuVAddr,
+						 pszFileName, uLine,
+						 psInfo->sFileName, psInfo->uLineNo));
+			}
+		}
+
+		
+		if (psInfo->eValid != isAllocated)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : not allocated (freed? %d)"
+					 " - referenced %s:%d - freed %s:%d",
+					 pvCpuVAddr, psInfo->eValid == isFree,
+					 pszFileName, uLine,
+					 psInfo->sFileName, psInfo->uLineNo));
+			while (STOP_ON_ERROR);
+		}
+	}
+
+	IMG_VOID debug_strcpy(IMG_CHAR *pDest, const IMG_CHAR *pSrc)
+	{
+		IMG_SIZE_T i = 0;
+
+		for (; i < 128; i++) 
+		{
+			*pDest = *pSrc;
+			if (*pSrc == '\0') break;
+			pDest++;
+			pSrc++;
+		}
+	}
+
+	PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+										  IMG_UINT32 ui32Size,
+										  IMG_PVOID *ppvCpuVAddr,
+										  IMG_HANDLE *phBlockAlloc,
+										  IMG_CHAR *pszFilename,
+										  IMG_UINT32 ui32Line)
+	{
+		OSMEM_DEBUG_INFO *psInfo;
+
+		PVRSRV_ERROR eError;
+
+		eError = OSAllocMem_Debug_Linux_Memory_Allocations(ui32Flags,
+				 ui32Size + TEST_BUFFER_PADDING,
+				 ppvCpuVAddr,
+				 phBlockAlloc,
+				 pszFilename,
+				 ui32Line);
+
+		if (eError != PVRSRV_OK)
+		{
+			return eError;
+		}
+
+		
+		OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + TEST_BUFFER_PADDING_STATUS, 0xBB, ui32Size);
+		OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + ui32Size + TEST_BUFFER_PADDING_STATUS, 0xB2, TEST_BUFFER_PADDING_AFTER);
+
+		
+		psInfo = (OSMEM_DEBUG_INFO *)(*ppvCpuVAddr);
+
+		OSMemSet(psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore));
+		debug_strcpy(psInfo->sFileName, pszFilename);
+		psInfo->uLineNo = ui32Line;
+		psInfo->eValid = isAllocated;
+		psInfo->uSize = ui32Size;
+		psInfo->uSizeParityCheck = 0x01234567 ^ ui32Size;
+
+		
+		*ppvCpuVAddr = (IMG_PVOID) ((IMG_UINT32)*ppvCpuVAddr)+TEST_BUFFER_PADDING_STATUS;
+
+#ifdef PVRSRV_LOG_MEMORY_ALLOCS
+		
+		PVR_TRACE(("Allocated pointer (after debug info): 0x%X from %s:%d", *ppvCpuVAddr, pszFilename, ui32Line));
+#endif
+
+		return PVRSRV_OK;
+	}
+
+	PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+										 IMG_UINT32 ui32Size,
+										 IMG_PVOID pvCpuVAddr,
+										 IMG_HANDLE hBlockAlloc,
+										 IMG_CHAR *pszFilename,
+										 IMG_UINT32 ui32Line)
+	{
+		OSMEM_DEBUG_INFO *psInfo;
+
+		
+		OSCheckMemDebug(pvCpuVAddr, ui32Size, pszFilename, ui32Line);
+
+		
+		OSMemSet(pvCpuVAddr, 0xBF, ui32Size + TEST_BUFFER_PADDING_AFTER);  
+
+		
+		psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32) pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
+
+		
+		psInfo->uSize = 0;
+		psInfo->uSizeParityCheck = 0;
+		psInfo->eValid = isFree;
+		psInfo->uLineNo = ui32Line;
+		debug_strcpy(psInfo->sFileName, pszFilename);
+
+		return OSFreeMem_Debug_Linux_Memory_Allocations(ui32Flags, ui32Size + TEST_BUFFER_PADDING, psInfo, hBlockAlloc, pszFilename, ui32Line);
+	}
+
+#if defined (__cplusplus)
+
+}
+#endif
+
+#endif 
+
+#endif        
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/metrics.c b/drivers/staging/cdv/pvr/services4/srvkm/common/metrics.c
new file mode 100644
index 0000000..640eb04
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/metrics.c
@@ -0,0 +1,160 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "metrics.h"
+
+#if defined(SUPPORT_VGX)
+#include "vgxapi_km.h"
+#endif
+
+#if defined(SUPPORT_SGX)
+#include "sgxapi_km.h"
+#endif
+
+#if defined(DEBUG) || defined(TIMING)
+
+static volatile IMG_UINT32 *pui32TimerRegister = 0;
+
+#define PVRSRV_TIMER_TOTAL_IN_TICKS(X)	asTimers[X].ui32Total
+#define PVRSRV_TIMER_TOTAL_IN_MS(X)		((1000*asTimers[X].ui32Total)/ui32TicksPerMS)
+#define PVRSRV_TIMER_COUNT(X)			asTimers[X].ui32Count
+
+
+Temporal_Data asTimers[PVRSRV_NUM_TIMERS]; 
+
+
+IMG_UINT32 PVRSRVTimeNow(IMG_VOID)
+{
+	if (!pui32TimerRegister)
+	{
+		static IMG_BOOL bFirstTime = IMG_TRUE;
+
+		if (bFirstTime)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVTimeNow: No timer register set up"));
+
+			bFirstTime = IMG_FALSE;
+		}
+
+		return 0;
+	}
+
+#if defined(__sh__)
+
+	return (0xffffffff-*pui32TimerRegister);
+
+#else 
+
+	return 0;
+
+#endif 
+}
+
+
+static IMG_UINT32 PVRSRVGetCPUFreq(IMG_VOID)
+{
+	IMG_UINT32 ui32Time1, ui32Time2;
+
+	ui32Time1 = PVRSRVTimeNow();
+
+	OSWaitus(1000000);
+
+	ui32Time2 = PVRSRVTimeNow();
+
+	PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetCPUFreq: timer frequency = %d Hz", ui32Time2 - ui32Time1));
+
+	return (ui32Time2 - ui32Time1);
+}
+
+
+IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo)
+{
+	IMG_UINT32 ui32Loop;
+
+	PVR_UNREFERENCED_PARAMETER(pvDevInfo);
+
+	for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++)
+	{
+		asTimers[ui32Loop].ui32Total = 0;
+		asTimers[ui32Loop].ui32Count = 0;
+	}
+
+
+	#if defined(__sh__)
+
+		
+		
+		
+		
+		*TCR_2 = TIMER_DIVISOR;
+
+		
+		*TCOR_2 = *TCNT_2 = (IMG_UINT)0xffffffff;
+
+		
+		*TST_REG |= (IMG_UINT8)0x04;
+
+		pui32TimerRegister = (IMG_UINT32 *)TCNT_2;
+
+	#else 
+
+		pui32TimerRegister = 0;
+
+	#endif 
+
+}
+
+
+IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID)
+{
+	IMG_UINT32 ui32TicksPerMS, ui32Loop;
+
+	ui32TicksPerMS = PVRSRVGetCPUFreq();
+
+	if (!ui32TicksPerMS)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOutputMetricTotals: Failed to get CPU Freq"));
+		return;
+	}
+
+	for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++)
+	{
+		if (asTimers[ui32Loop].ui32Count & 0x80000000L)
+		{
+			PVR_DPF((PVR_DBG_WARNING,"PVRSRVOutputMetricTotals: Timer %u is still ON", ui32Loop));
+		}
+	}
+#if 0
+	
+	PVR_DPF((PVR_DBG_ERROR," Timer(%u): Total = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_TICKS(PVRSRV_TIMER_EXAMPLE_1)));
+	PVR_DPF((PVR_DBG_ERROR," Timer(%u): Time = %ums",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_MS(PVRSRV_TIMER_EXAMPLE_1)));
+	PVR_DPF((PVR_DBG_ERROR," Timer(%u): Count = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_COUNT(PVRSRV_TIMER_EXAMPLE_1)));
+#endif
+}
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/osfunc_common.c b/drivers/staging/cdv/pvr/services4/srvkm/common/osfunc_common.c
new file mode 100644
index 0000000..e0a46da
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/osfunc_common.c
@@ -0,0 +1,31 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "img_types.h"
+#include "services_headers.h"
+#include "osfunc.h"
+
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/pdump_common.c b/drivers/staging/cdv/pvr/services4/srvkm/common/pdump_common.c
new file mode 100644
index 0000000..fbec2a1
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/pdump_common.c
@@ -0,0 +1,2371 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if defined(PDUMP)
+#include <stdarg.h>
+
+#include "services_headers.h"
+#include "perproc.h"
+
+#include "pdump_km.h"
+#include "pdump_int.h"
+
+#if !defined(PDUMP_TEMP_BUFFER_SIZE)
+#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U)
+#endif
+
+#if 1
+#define PDUMP_DBG(a)   PDumpOSDebugPrintf (a)
+#else
+#define PDUMP_DBG(a)
+#endif
+
+
+#define	PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x)))
+#define	VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID *, p, x)
+#define	VPTR_INC(p, x) ((p) = VPTR_PLUS(p, x))
+#define MAX_PDUMP_MMU_CONTEXTS	(32)
+static IMG_VOID *gpvTempBuffer = IMG_NULL;
+static IMG_HANDLE ghTempBufferBlockAlloc;
+static IMG_UINT16 gui16MMUContextUsage = 0;
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+IMG_UINT32 g_ui32EveryLineCounter = 1U;
+#endif
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(_PDumpIsPersistent)
+#endif
+static INLINE
+IMG_BOOL _PDumpIsPersistent(IMG_VOID)
+{
+	PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+
+	if(psPerProc == IMG_NULL)
+	{
+		
+		return IMG_FALSE;
+	}
+	return psPerProc->bPDumpPersistent;
+}
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+
+static INLINE
+IMG_BOOL _PDumpIsProcessActive(IMG_VOID)
+{
+	PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+	if(psPerProc == IMG_NULL)
+	{
+		
+		return IMG_TRUE;
+	}
+	return psPerProc->bPDumpActive;
+}
+
+#endif 
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+static INLINE
+IMG_UINT32 _PDumpGetPID(IMG_VOID)
+{
+	PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+	if(psPerProc == IMG_NULL)
+	{
+		
+		return 0;
+	}
+	return psPerProc->ui32PID;
+}
+#endif 
+
+static IMG_VOID *GetTempBuffer(IMG_VOID)
+{
+	
+	if (gpvTempBuffer == IMG_NULL)
+	{
+		PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					  PDUMP_TEMP_BUFFER_SIZE,
+					  &gpvTempBuffer,
+					  &ghTempBufferBlockAlloc,
+					  "PDUMP Temporary Buffer");
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed: %d", eError));
+		}
+	}
+
+	return gpvTempBuffer;
+}
+
+static IMG_VOID FreeTempBuffer(IMG_VOID)
+{
+
+	if (gpvTempBuffer != IMG_NULL)
+	{
+		PVRSRV_ERROR eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+					  PDUMP_TEMP_BUFFER_SIZE,
+					  gpvTempBuffer,
+					  ghTempBufferBlockAlloc);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "FreeTempBuffer: OSFreeMem failed: %d", eError));
+		}
+		else
+		{
+			gpvTempBuffer = IMG_NULL;
+		}
+	}
+}
+
+IMG_VOID PDumpInitCommon(IMG_VOID)
+{
+	
+	(IMG_VOID) GetTempBuffer();
+
+	
+	PDumpInit();
+}
+
+IMG_VOID PDumpDeInitCommon(IMG_VOID)
+{
+	
+	FreeTempBuffer();
+
+	
+	PDumpDeInit();
+}
+
+IMG_BOOL PDumpIsSuspended(IMG_VOID)
+{
+	return PDumpOSIsSuspended();
+}
+
+IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID)
+{
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	if( _PDumpIsProcessActive() )
+	{
+		return PDumpOSIsCaptureFrameKM();
+	}
+	return IMG_FALSE;
+#else
+	return PDumpOSIsCaptureFrameKM();
+#endif
+}
+
+PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame)
+{
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	if( _PDumpIsProcessActive() )
+	{
+		return PDumpOSSetFrameKM(ui32Frame);
+	}
+	return PVRSRV_OK;
+#else
+	return PDumpOSSetFrameKM(ui32Frame);
+#endif
+}
+
+PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+								IMG_UINT32 ui32Reg,
+								IMG_UINT32 ui32Data,
+								IMG_UINT32 ui32Flags)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING()
+	PDUMP_DBG(("PDumpRegWithFlagsKM"));
+
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X\r\n",
+								pszPDumpRegName, ui32Reg, ui32Data);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName,
+						IMG_UINT32 ui32Reg,
+						IMG_UINT32 ui32Data)
+{
+	return PDumpRegWithFlagsKM(pszPDumpRegName, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS);
+}
+
+PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+									IMG_UINT32 ui32RegAddr, 
+									IMG_UINT32 ui32RegValue, 
+									IMG_UINT32 ui32Mask,
+									IMG_UINT32 ui32Flags,
+									PDUMP_POLL_OPERATOR	eOperator)
+{
+	
+	#define POLL_DELAY			1000U
+	#define POLL_COUNT_LONG		(2000000000U / POLL_DELAY)
+	#define POLL_COUNT_SHORT	(1000000U / POLL_DELAY)
+
+	PVRSRV_ERROR eErr;
+	IMG_UINT32	ui32PollCount;
+
+	PDUMP_GET_SCRIPT_STRING();
+	PDUMP_DBG(("PDumpRegPolWithFlagsKM"));
+	if ( _PDumpIsPersistent() )
+	{
+		
+		return PVRSRV_OK;
+	}
+
+#if 0
+	if (((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
+		(ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_TA_FINISHED_MASK) != 0) ||
+	    ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
+		(ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK) != 0) ||
+	    ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
+		(ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK) != 0))
+	{
+		ui32PollCount = POLL_COUNT_LONG;
+	}
+	else
+#endif
+	{
+		ui32PollCount = POLL_COUNT_LONG;
+	}
+
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n",
+							pszPDumpRegName, ui32RegAddr, ui32RegValue,
+							ui32Mask, eOperator, ui32PollCount, POLL_DELAY);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, PDUMP_POLL_OPERATOR	eOperator)
+{
+	return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS, eOperator);
+}
+
+PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER	*psDevID,
+                           IMG_UINT32         ui32DevVAddr,
+                           IMG_CPU_VIRTADDR   pvLinAddr,
+                           IMG_HANDLE         hOSMemHandle,
+                           IMG_UINT32         ui32NumBytes,
+                           IMG_UINT32         ui32PageSize,
+                           IMG_BOOL			  bShared,
+                           IMG_HANDLE         hUniqueTag)
+{
+	PVRSRV_ERROR eErr;
+	IMG_PUINT8		pui8LinAddr;
+    IMG_UINT32      ui32Offset;
+	IMG_UINT32		ui32NumPages;
+	IMG_DEV_PHYADDR	sDevPAddr;
+	IMG_UINT32		ui32Page;
+	IMG_UINT32		ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+
+	PDUMP_GET_SCRIPT_STRING();
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	
+	ui32Flags |= ( _PDumpIsPersistent() || bShared ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#else
+	PVR_UNREFERENCED_PARAMETER(bShared);
+	ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+
+	
+#if !defined(LINUX)
+	PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & HOST_PAGEMASK) == 0);
+#endif
+
+	PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & HOST_PAGEMASK) == 0);
+	PVR_ASSERT(((IMG_UINT32) ui32NumBytes & HOST_PAGEMASK) == 0);
+
+	
+
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:VA_%08X 0x%08X %u\r\n",
+			psDevID->pszPDumpDevName, ui32DevVAddr, ui32NumBytes, ui32PageSize);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	
+
+	pui8LinAddr = (IMG_PUINT8) pvLinAddr;
+	ui32Offset = 0;
+	ui32NumPages = ui32NumBytes / ui32PageSize;
+	while (ui32NumPages)
+	{ 
+		ui32NumPages--;
+
+		
+
+
+
+
+
+
+		
+		
+ 		
+		PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
+				hOSMemHandle,
+				ui32Offset,
+				pui8LinAddr,
+				ui32PageSize,
+				&sDevPAddr);
+		ui32Page = (IMG_UINT32)(sDevPAddr.uiAddr / ui32PageSize);
+		
+		pui8LinAddr	+= ui32PageSize;
+		ui32Offset += ui32PageSize;
+
+		eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X %u %u 0x%08X\r\n",
+												psDevID->pszPDumpDevName,
+												(IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+												ui32Page * ui32PageSize,
+												ui32PageSize,
+												ui32PageSize,
+												ui32Page * ui32PageSize);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+		PDumpOSWriteString2(hScript, ui32Flags);
+	}
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER	*psDevId,
+								   IMG_HANDLE hOSMemHandle,
+								   IMG_UINT32 ui32Offset,
+                              	   IMG_CPU_VIRTADDR pvLinAddr,
+								   IMG_UINT32 ui32PTSize,
+								   IMG_UINT32 ui32Flags,
+								   IMG_HANDLE hUniqueTag)
+{
+	PVRSRV_ERROR eErr;
+	IMG_DEV_PHYADDR	sDevPAddr;
+
+	PDUMP_GET_SCRIPT_STRING();
+
+	PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0);
+	ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
+	ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+	
+	
+
+	eErr = PDumpOSBufprintf(hScript,
+							ui32MaxLen,
+							"-- MALLOC :%s:PAGE_TABLE 0x%08X %u\r\n",
+							psDevId->pszPDumpDevName,
+							ui32PTSize,
+							ui32PTSize);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	
+
+	
+	
+	
+	
+
+	PDumpOSCPUVAddrToDevPAddr(psDevId->eDeviceType,
+			hOSMemHandle, 
+			ui32Offset,
+			(IMG_PUINT8) pvLinAddr,
+			ui32PTSize,
+			&sDevPAddr);
+
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X 0x%X %u 0x%08X\r\n",
+											psDevId->pszPDumpDevName,
+											(IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+											sDevPAddr.uiAddr,
+											ui32PTSize,
+											ui32PTSize,
+											sDevPAddr.uiAddr);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpFreePages	(BM_HEAP 			*psBMHeap,
+                         IMG_DEV_VIRTADDR  sDevVAddr,
+                         IMG_UINT32        ui32NumBytes,
+                         IMG_UINT32        ui32PageSize,
+                         IMG_HANDLE        hUniqueTag,
+						 IMG_BOOL		   bInterleaved)
+{
+	PVRSRV_ERROR eErr;
+	IMG_UINT32 ui32NumPages, ui32PageCounter;
+	IMG_DEV_PHYADDR	sDevPAddr;
+	IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	PDUMP_GET_SCRIPT_STRING();
+
+	PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0);
+	PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0);
+
+	psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
+	ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+	
+
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:VA_%08X\r\n", 
+							psDeviceNode->sDevId.pszPDumpDevName, sDevVAddr.uiAddr);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
+		
+		if( psDeviceNode->pfnMMUIsHeapShared(psBMHeap->pMMUHeap) )
+		{
+			ui32Flags |= PDUMP_FLAGS_PERSISTENT;
+		}
+	}
+#endif
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	
+
+	ui32NumPages = ui32NumBytes / ui32PageSize;
+	for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++)
+	{
+		if (!bInterleaved || (ui32PageCounter % 2) == 0)
+		{
+			sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr);
+
+			PVR_ASSERT(sDevPAddr.uiAddr != 0)
+
+			eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
+									psDeviceNode->sDevId.pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr);
+			if(eErr != PVRSRV_OK)
+			{
+				return eErr;
+			}
+			PDumpOSWriteString2(hScript, ui32Flags);
+		}
+		else
+		{
+			
+		}
+
+		sDevVAddr.uiAddr += ui32PageSize;
+	}
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpFreePageTable	(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+								 IMG_HANDLE hOSMemHandle,
+								 IMG_CPU_VIRTADDR   pvLinAddr,
+								 IMG_UINT32         ui32PTSize,
+								 IMG_UINT32			ui32Flags,
+								 IMG_HANDLE         hUniqueTag)
+{
+	PVRSRV_ERROR eErr;
+	IMG_DEV_PHYADDR	sDevPAddr;
+
+	PDUMP_GET_SCRIPT_STRING();
+
+	PVR_UNREFERENCED_PARAMETER(ui32PTSize);
+	ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
+	ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+	
+	PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0);	
+
+	
+
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:PAGE_TABLE\r\n", psDevID->pszPDumpDevName);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	
+
+	
+	
+	
+	
+
+	PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
+							  hOSMemHandle, 
+			0,
+			(IMG_PUINT8) pvLinAddr,
+			ui32PTSize,
+			&sDevPAddr);
+
+	{
+		eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
+								psDevID->pszPDumpDevName,
+								(IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+								sDevPAddr.uiAddr);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+		PDumpOSWriteString2(hScript, ui32Flags);
+	}
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
+							IMG_UINT32 ui32Reg,
+							 IMG_UINT32 ui32Data,
+							 IMG_UINT32	ui32Flags,
+							 IMG_HANDLE hUniqueTag)
+{
+	PVRSRV_ERROR eErr;
+	IMG_CHAR *pszRegString;
+	PDUMP_GET_SCRIPT_STRING()
+	
+	if(psMMUAttrib->pszPDRegRegion != IMG_NULL)
+	{	
+		pszRegString = psMMUAttrib->pszPDRegRegion;
+	}
+	else
+	{
+		pszRegString = psMMUAttrib->sDevId.pszPDumpRegName;
+	}
+
+	
+
+#if defined(SGX_FEATURE_36BIT_MMU)
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
+			 "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
+			 psMMUAttrib->sDevId.pszPDumpDevName,
+			 psMMUAttrib->sDevId.pszPDumpDevName,
+			 (IMG_UINT32)hUniqueTag,
+			 (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :%s:$1 :%s:$1 0x4\r\n", 
+			psMMUAttrib->sDevId.pszPDumpDevName,
+			psMMUAttrib->sDevId.pszPDumpDevName);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
+			 "WRW :%s:0x%08X: %s:$1\r\n",
+			 pszRegString,
+			 ui32Reg,
+			 psMMUAttrib->sDevId.pszPDumpDevName);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+#else
+	eErr = PDumpOSBufprintf(hScript,
+				ui32MaxLen,
+				"WRW :%s:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+				pszRegString,
+				ui32Reg,
+				psMMUAttrib->sDevId.pszPDumpDevName,
+				(IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+				(ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift,
+				ui32Data & ~psMMUAttrib->ui32PDEMask);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+#endif
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpPDReg	(PDUMP_MMU_ATTRIB *psMMUAttrib, 
+					 IMG_UINT32 ui32Reg,
+					 IMG_UINT32 ui32Data,
+					 IMG_HANDLE hUniqueTag)
+{
+	return PDumpPDRegWithFlags(psMMUAttrib, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag);
+}
+
+PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO		*psMemInfo,
+						   IMG_UINT32			ui32Offset,
+						   IMG_UINT32			ui32Value,
+						   IMG_UINT32			ui32Mask,
+						   PDUMP_POLL_OPERATOR	eOperator,
+						   IMG_UINT32			ui32Flags,
+						   IMG_HANDLE			hUniqueTag)
+{
+	#define MEMPOLL_DELAY		(1000)
+	#define MEMPOLL_COUNT		(2000000000 / MEMPOLL_DELAY)
+
+	PVRSRV_ERROR eErr;
+	IMG_UINT32			ui32PageOffset;
+	IMG_UINT8			*pui8LinAddr;
+	IMG_DEV_PHYADDR		sDevPAddr;
+	IMG_DEV_VIRTADDR	sDevVPageAddr;
+	PDUMP_MMU_ATTRIB	*psMMUAttrib;
+
+	PDUMP_GET_SCRIPT_STRING();
+
+	if (PDumpOSIsSuspended())
+	{
+		return PVRSRV_OK;
+	}
+
+	if ( _PDumpIsPersistent() )
+	{
+		
+		return PVRSRV_OK;
+	}
+
+	
+	PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->uAllocSize);
+
+	psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+
+	
+
+	eErr = PDumpOSBufprintf(hScript,
+			 ui32MaxLen,
+			 "-- POL :%s:VA_%08X 0x%08X 0x%08X %d %d %d\r\n",
+			 psMMUAttrib->sDevId.pszPDumpDevName,
+			 psMemInfo->sDevVAddr.uiAddr + ui32Offset,
+			 ui32Value,
+			 ui32Mask,
+			 eOperator,
+			 MEMPOLL_COUNT,
+			 MEMPOLL_DELAY);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+
+	pui8LinAddr = psMemInfo->pvLinAddrKM;
+
+	
+	pui8LinAddr += ui32Offset;
+
+	
+
+
+	PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
+			ui32Offset,
+			pui8LinAddr,
+			psMMUAttrib->ui32DataPageMask,
+			&ui32PageOffset);
+
+	
+	sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
+
+	PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
+
+	
+	BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+
+	
+	sDevPAddr.uiAddr += ui32PageOffset;
+
+	eErr = PDumpOSBufprintf(hScript,
+			 ui32MaxLen,
+			 "POL :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %d %d %d\r\n",
+			 psMMUAttrib->sDevId.pszPDumpDevName,
+			 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+			 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
+			 sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
+			 ui32Value,
+			 ui32Mask,
+			 eOperator,
+			 MEMPOLL_COUNT,
+			 MEMPOLL_DELAY);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr,
+						PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+						IMG_UINT32 ui32Offset,
+						IMG_UINT32 ui32Bytes,
+						IMG_UINT32 ui32Flags,
+						IMG_HANDLE hUniqueTag)
+{
+	PVRSRV_ERROR eErr;
+	IMG_UINT32 ui32NumPages;
+	IMG_UINT32 ui32PageByteOffset;
+	IMG_UINT32 ui32BlockBytes;
+	IMG_UINT8* pui8LinAddr;
+	IMG_UINT8* pui8DataLinAddr = IMG_NULL;
+	IMG_DEV_VIRTADDR sDevVPageAddr;
+	IMG_DEV_VIRTADDR sDevVAddr;
+	IMG_DEV_PHYADDR sDevPAddr;
+	IMG_UINT32 ui32ParamOutPos;
+	PDUMP_MMU_ATTRIB *psMMUAttrib;
+	IMG_UINT32 ui32DataPageSize;
+
+	PDUMP_GET_SCRIPT_AND_FILE_STRING();
+	
+	 
+	if (ui32Bytes == 0 || PDumpOSIsSuspended())
+	{
+		return PVRSRV_OK;
+	}
+
+	psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+	
+	
+
+	PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->uAllocSize);
+
+	if (!PDumpOSJTInitialised())
+	{
+		return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+	}
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	
+	{
+		BM_HEAP *pHeap = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap;
+		PVRSRV_DEVICE_NODE *psDeviceNode = pHeap->pBMContext->psDeviceNode;
+		
+		if( psDeviceNode->pfnMMUIsHeapShared(pHeap->pMMUHeap) )
+		{
+			ui32Flags |= PDUMP_FLAGS_PERSISTENT;
+		}
+	}
+#endif
+
+	
+	if(pvAltLinAddr)
+	{
+		pui8DataLinAddr = pvAltLinAddr;
+	}
+	else if(psMemInfo->pvLinAddrKM)
+	{
+		pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset;
+	}
+	pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM;
+	sDevVAddr = psMemInfo->sDevVAddr;
+
+	
+	sDevVAddr.uiAddr += ui32Offset;
+	pui8LinAddr += ui32Offset;
+
+	PVR_ASSERT(pui8DataLinAddr);
+
+	PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
+
+	ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
+
+	
+
+	if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
+						pui8DataLinAddr,
+						ui32Bytes,
+						ui32Flags))
+	{
+		return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+	}
+
+	if (PDumpOSGetParamFileNum() == 0)
+	{
+		eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
+	}
+	else
+	{
+		eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
+	}
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	
+
+	eErr = PDumpOSBufprintf(hScript,
+			 ui32MaxLenScript,
+			 "-- LDB :%s:VA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+			 psMMUAttrib->sDevId.pszPDumpDevName,
+			 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+			 psMemInfo->sDevVAddr.uiAddr,
+			 ui32Offset,
+			 ui32Bytes,
+			 ui32ParamOutPos,
+			 pszFileName);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	
+
+
+	PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
+			ui32Offset,
+			pui8LinAddr,
+			psMMUAttrib->ui32DataPageMask,
+			&ui32PageByteOffset);
+	ui32DataPageSize = psMMUAttrib->ui32DataPageMask + 1;
+	ui32NumPages = (ui32PageByteOffset + ui32Bytes + psMMUAttrib->ui32DataPageMask) / ui32DataPageSize;
+
+	while(ui32NumPages)
+	{
+		ui32NumPages--;
+	
+		
+		sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
+
+		if (ui32DataPageSize <= PDUMP_TEMP_BUFFER_SIZE)
+		{
+			
+			PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
+		}
+
+		
+		BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+
+		
+		sDevPAddr.uiAddr += ui32PageByteOffset;
+
+		
+		if (ui32PageByteOffset + ui32Bytes > ui32DataPageSize)
+		{
+			
+			ui32BlockBytes = ui32DataPageSize - ui32PageByteOffset;
+		}
+		else
+		{
+			
+			ui32BlockBytes = ui32Bytes;
+		}
+
+		eErr = PDumpOSBufprintf(hScript,
+					 ui32MaxLenScript,
+					 "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+					 psMMUAttrib->sDevId.pszPDumpDevName,
+					 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+					 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
+					 sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
+					 ui32BlockBytes,
+					 ui32ParamOutPos,
+					 pszFileName);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+		PDumpOSWriteString2(hScript, ui32Flags);
+
+		
+
+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+		
+		ui32PageByteOffset = (ui32PageByteOffset + ui32BlockBytes) % ui32DataPageSize;
+#else
+		
+		ui32PageByteOffset = 0;
+#endif
+		
+		ui32Bytes -= ui32BlockBytes;	 
+		
+		sDevVAddr.uiAddr += ui32BlockBytes;
+		
+		pui8LinAddr += ui32BlockBytes;
+		
+		ui32ParamOutPos += ui32BlockBytes;
+	}
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+								 IMG_HANDLE hOSMemHandle,
+								 IMG_CPU_VIRTADDR pvLinAddr,
+								 IMG_UINT32 ui32Bytes,
+								 IMG_UINT32 ui32Flags,
+								 IMG_BOOL bInitialisePages,
+								 IMG_HANDLE hUniqueTag1,
+								 IMG_HANDLE hUniqueTag2)
+{
+	PDUMP_MMU_ATTRIB sMMUAttrib;
+	
+	
+	sMMUAttrib = *psMMUAttrib;
+	sMMUAttrib.ui32PTSize = (IMG_UINT32)HOST_PAGESIZE();
+	return PDumpMemPTEntriesKM(	&sMMUAttrib,
+								hOSMemHandle,
+								pvLinAddr,
+								ui32Bytes,
+								ui32Flags,
+								bInitialisePages,
+								hUniqueTag1,
+								hUniqueTag2);
+}
+
+PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+								 IMG_HANDLE hOSMemHandle,
+								 IMG_CPU_VIRTADDR pvLinAddr,
+								 IMG_UINT32 ui32Bytes,
+								 IMG_UINT32 ui32Flags,
+								 IMG_BOOL bInitialisePages,
+								 IMG_HANDLE hUniqueTag1,
+								 IMG_HANDLE hUniqueTag2)
+{
+	PVRSRV_ERROR eErr;
+	IMG_UINT32 ui32NumPages;
+	IMG_UINT32 ui32PageOffset;
+	IMG_UINT32 ui32BlockBytes;
+	IMG_UINT8* pui8LinAddr;
+	IMG_DEV_PHYADDR sDevPAddr;
+	IMG_CPU_PHYADDR sCpuPAddr;
+	IMG_UINT32 ui32Offset;
+	IMG_UINT32 ui32ParamOutPos;
+	IMG_UINT32 ui32PageMask; 
+
+	PDUMP_GET_SCRIPT_AND_FILE_STRING();
+	ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+	if (PDumpOSIsSuspended())
+	{
+		return PVRSRV_OK;
+	}
+
+	if (!PDumpOSJTInitialised())
+	{
+		return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+	}
+
+	if (!pvLinAddr)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
+
+	ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
+
+	if (bInitialisePages)
+	{
+		
+
+
+		if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
+							pvLinAddr,
+							ui32Bytes,
+							ui32Flags | PDUMP_FLAGS_CONTINUOUS))
+		{
+			return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+		}
+
+		if (PDumpOSGetParamFileNum() == 0)
+		{
+			eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
+		}
+		else
+		{
+			eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
+		}
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+	}
+
+	
+
+
+
+
+	ui32PageMask = psMMUAttrib->ui32PTSize - 1;
+
+	
+
+	
+ 	ui32PageOffset	= (IMG_UINT32)((IMG_UINTPTR_T)pvLinAddr & (psMMUAttrib->ui32PTSize - 1));
+ 	ui32NumPages	= (ui32PageOffset + ui32Bytes + psMMUAttrib->ui32PTSize - 1) / psMMUAttrib->ui32PTSize;
+	pui8LinAddr		= (IMG_UINT8*) pvLinAddr;
+
+	while (ui32NumPages)
+	{
+		ui32NumPages--;
+		
+
+
+
+
+
+		sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
+		sDevPAddr = SysCpuPAddrToDevPAddr(psMMUAttrib->sDevId.eDeviceType, sCpuPAddr);
+
+		
+		if (ui32PageOffset + ui32Bytes > psMMUAttrib->ui32PTSize)
+		{
+			
+			ui32BlockBytes = psMMUAttrib->ui32PTSize - ui32PageOffset;
+		}
+		else
+		{
+			
+			ui32BlockBytes = ui32Bytes;
+		}
+
+		
+
+		
+		if (bInitialisePages)
+		{
+			eErr = PDumpOSBufprintf(hScript,
+					 ui32MaxLenScript,
+					 "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+					 psMMUAttrib->sDevId.pszPDumpDevName,
+					 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+					 sDevPAddr.uiAddr & ~ui32PageMask,
+					 sDevPAddr.uiAddr & ui32PageMask,
+					 ui32BlockBytes,
+					 ui32ParamOutPos,
+					 pszFileName);
+			if(eErr != PVRSRV_OK)
+			{
+				return eErr;
+			}
+			PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+		}
+		else
+		{
+			for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32))
+			{
+				IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset));  
+
+				if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0)
+				{
+					
+#if defined(SGX_FEATURE_36BIT_MMU)
+					eErr = PDumpOSBufprintf(hScript,
+							ui32MaxLenScript,
+							 "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
+							 psMMUAttrib->sDevId.pszPDumpDevName,
+							 psMMUAttrib->sDevId.pszPDumpDevName,
+							 (IMG_UINT32)hUniqueTag2,
+							 (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift);
+					if(eErr != PVRSRV_OK)
+					{
+						return eErr;
+					}
+					PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+					eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n",
+								psMMUAttrib->sDevId.pszPDumpDevName,
+								psMMUAttrib->sDevId.pszPDumpDevName);
+					if(eErr != PVRSRV_OK)
+					{
+						return eErr;
+					}
+					PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+					eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :%s:$1 :%s:$1 0x%08X\r\n",
+								psMMUAttrib->sDevId.pszPDumpDevName,
+								psMMUAttrib->sDevId.pszPDumpDevName,
+								ui32PTE & ~psMMUAttrib->ui32PDEMask);
+					if(eErr != PVRSRV_OK)
+					{
+						return eErr;
+					}
+					PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+					eErr = PDumpOSBufprintf(hScript,
+							ui32MaxLenScript,
+							 "WRW :%s:PA_%08X%08X:0x%08X :%s:$1\r\n",
+							 psMMUAttrib->sDevId.pszPDumpDevName,
+							 (IMG_UINT32)hUniqueTag1,
+							 (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
+							 (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
+							 psMMUAttrib->sDevId.pszPDumpDevName);
+					if(eErr != PVRSRV_OK)
+					{
+						return eErr;
+					}
+					PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+#else
+					eErr = PDumpOSBufprintf(hScript,
+							ui32MaxLenScript,
+							 "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+							 psMMUAttrib->sDevId.pszPDumpDevName,
+							 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+							 (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
+							 (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
+							 psMMUAttrib->sDevId.pszPDumpDevName,
+							 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
+							 (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift,
+							 ui32PTE & ~psMMUAttrib->ui32PDEMask);
+					if(eErr != PVRSRV_OK)
+					{
+						return eErr;
+					}
+					PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+#endif
+				}
+				else
+				{
+#if !defined(FIX_HW_BRN_31620)
+					PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL);
+#endif
+					eErr = PDumpOSBufprintf(hScript,
+							ui32MaxLenScript,
+							 "WRW :%s:PA_%08X%08X:0x%08X 0x%08X%08X\r\n",
+							 psMMUAttrib->sDevId.pszPDumpDevName,
+							 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+							 (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
+							 (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
+							 (ui32PTE << psMMUAttrib->ui32PTEAlignShift),
+							 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2);
+					if(eErr != PVRSRV_OK)
+					{
+						return eErr;
+					}
+					PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+				}
+			}
+		}
+
+		
+
+		
+		ui32PageOffset = 0;
+		
+		ui32Bytes -= ui32BlockBytes;
+		
+		pui8LinAddr += ui32BlockBytes;
+		
+		ui32ParamOutPos += ui32BlockBytes;
+	}
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+							   IMG_UINT32 ui32Offset,
+							   IMG_DEV_PHYADDR sPDDevPAddr,
+							   IMG_HANDLE hUniqueTag1,
+							   IMG_HANDLE hUniqueTag2)
+{
+	PVRSRV_ERROR eErr;
+	IMG_UINT32 ui32PageByteOffset;
+	IMG_DEV_VIRTADDR sDevVAddr;
+	IMG_DEV_VIRTADDR sDevVPageAddr;
+	IMG_DEV_PHYADDR sDevPAddr;
+	IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+	IMG_UINT32 ui32ParamOutPos;
+	PDUMP_MMU_ATTRIB *psMMUAttrib;
+	IMG_UINT32 ui32PageMask; 
+
+	PDUMP_GET_SCRIPT_AND_FILE_STRING();
+
+	if (!PDumpOSJTInitialised())
+	{
+		return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+	}
+
+	psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+	ui32PageMask = psMMUAttrib->ui32PTSize - 1;
+
+	ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
+
+	
+	if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
+						(IMG_UINT8 *)&sPDDevPAddr,
+						sizeof(IMG_DEV_PHYADDR),
+						ui32Flags))
+	{
+		return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+	}
+
+	if (PDumpOSGetParamFileNum() == 0)
+	{
+		eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
+	}
+	else
+	{
+		eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
+	}
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	
+	eErr = PDumpOSBufprintf(hScript,
+			ui32MaxLenScript,
+			"-- LDB :%s:PA_0x%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+			psMMUAttrib->sDevId.pszPDumpDevName,
+			(IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+			sPDDevPAddr.uiAddr & ~ui32PageMask,
+			sPDDevPAddr.uiAddr & ui32PageMask,
+			sizeof(IMG_DEV_PHYADDR),
+			ui32ParamOutPos,
+			pszFileName);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	
+	sDevVAddr = psMemInfo->sDevVAddr;
+	ui32PageByteOffset = sDevVAddr.uiAddr & ui32PageMask;
+
+	sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
+	PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
+
+	BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+	sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset;
+
+	if ((sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask) != 0UL)
+	{
+#if defined(SGX_FEATURE_36BIT_MMU)
+		eErr = PDumpOSBufprintf(hScript,
+				ui32MaxLenScript,
+				 "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
+				 psMMUAttrib->sDevId.pszPDumpDevName,
+				 psMMUAttrib->sDevId.pszPDumpDevName,
+				 (IMG_UINT32)hUniqueTag2,
+				 sPDDevPAddr.uiAddr);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+		PDumpOSWriteString2(hScript, ui32Flags);
+
+		eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "AND  :%s:$2 :%s:$1 0xFFFFFFFF\r\n",
+					psMMUAttrib->sDevId.pszPDumpDevName,
+					psMMUAttrib->sDevId.pszPDumpDevName);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+		PDumpOSWriteString2(hScript, ui32Flags);
+
+		eErr = PDumpOSBufprintf(hScript,
+				ui32MaxLenScript,
+				 "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
+				 psMMUAttrib->sDevId.pszPDumpDevName,
+				 (IMG_UINT32)hUniqueTag1,
+				 (sDevPAddr.uiAddr) & ~(psMMUAttrib->ui32DataPageMask),
+				 (sDevPAddr.uiAddr) & (psMMUAttrib->ui32DataPageMask),
+				 psMMUAttrib->sDevId.pszPDumpDevName);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+		PDumpOSWriteString2(hScript, ui32Flags);
+
+		eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$2 :%s:$1 0x20\r\n",
+				psMMUAttrib->sDevId.pszPDumpDevName,
+				psMMUAttrib->sDevId.pszPDumpDevName);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+		PDumpOSWriteString2(hScript, ui32Flags);
+
+		eErr = PDumpOSBufprintf(hScript,
+				ui32MaxLenScript,
+				 "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
+				 psMMUAttrib->sDevId.pszPDumpDevName,
+				 (IMG_UINT32)hUniqueTag1,
+				 (sDevPAddr.uiAddr + 4) & ~(psMMUAttrib->ui32DataPageMask),
+				 (sDevPAddr.uiAddr + 4) & (psMMUAttrib->ui32DataPageMask),
+				 psMMUAttrib->sDevId.pszPDumpDevName);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+		PDumpOSWriteString2(hScript, ui32Flags);
+#else
+		eErr = PDumpOSBufprintf(hScript,
+				 ui32MaxLenScript,
+				 "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+				 psMMUAttrib->sDevId.pszPDumpDevName,
+				 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+				 sDevPAddr.uiAddr & ~ui32PageMask,
+				 sDevPAddr.uiAddr & ui32PageMask,
+				 psMMUAttrib->sDevId.pszPDumpDevName,
+				 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
+				 sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask,
+				 sPDDevPAddr.uiAddr & ~psMMUAttrib->ui32PDEMask);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+#endif
+	}
+	else
+	{
+		PVR_ASSERT(!(sDevPAddr.uiAddr & psMMUAttrib->ui32PTEValid));
+		eErr = PDumpOSBufprintf(hScript,
+				 ui32MaxLenScript,
+				 "WRW :%s:PA_%08X%08X:0x%08X 0x%08X\r\n",
+				 psMMUAttrib->sDevId.pszPDumpDevName,
+				 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+				 sDevPAddr.uiAddr & ~ui32PageMask,
+				 sDevPAddr.uiAddr & ui32PageMask,
+				 sPDDevPAddr.uiAddr);
+		if(eErr != PVRSRV_OK)
+		{
+			return eErr;
+		}
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+
+	return PVRSRV_OK;
+}
+
+
+
+
+PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
+{
+	PVRSRV_ERROR eErr;
+	IMG_CHAR pszCommentPrefix[] = "-- "; 
+#if defined(PDUMP_DEBUG_OUTFILES)
+	IMG_CHAR pszTemp[256];
+#endif
+	IMG_UINT32 ui32LenCommentPrefix;
+	PDUMP_GET_SCRIPT_STRING();
+	PDUMP_DBG(("PDumpCommentKM"));
+#if defined(PDUMP_DEBUG_OUTFILES)
+	
+	ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+	
+	PDumpOSVerifyLineEnding(pszComment, ui32MaxLen);
+
+	
+	ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix));
+
+	
+	
+	if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2),
+			  (IMG_UINT8*)pszCommentPrefix,
+			  ui32LenCommentPrefix,
+			  ui32Flags))
+	{
+#if defined(PDUMP_DEBUG_OUTFILES)
+		if(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+		{
+			PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (continuous set)",
+					 g_ui32EveryLineCounter, pszComment));
+			return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+		}
+		else if(ui32Flags & PDUMP_FLAGS_PERSISTENT)
+		{
+			PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (persistent set)",
+					 g_ui32EveryLineCounter, pszComment));
+			return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+		}
+		else
+		{
+			PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s",
+					 g_ui32EveryLineCounter, pszComment));
+			return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+		}
+#else
+		PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %s",
+					 pszComment));
+		return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+#endif
+	}
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+	
+	eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s",
+		_PDumpGetPID(),
+		g_ui32EveryLineCounter,
+		pszComment);
+
+	
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
+		pszTemp);
+#else
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
+		pszComment);
+#endif
+	if( (eErr != PVRSRV_OK) &&
+		(eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_va_list ap;
+	PDUMP_GET_MSG_STRING();
+
+	
+	PDUMP_va_start(ap, pszFormat);
+	eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
+	PDUMP_va_end(ap);
+
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	return PDumpCommentKM(pszMsg, ui32Flags);
+}
+
+PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_va_list ap;
+	PDUMP_GET_MSG_STRING();
+
+	
+	PDUMP_va_start(ap, pszFormat);
+	eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
+	PDUMP_va_end(ap);
+
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	return PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS);
+}
+
+PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags)
+{
+	PVRSRV_ERROR eErr;
+	IMG_UINT32	ui32MsgLen;
+	PDUMP_GET_MSG_STRING();
+
+	
+	eErr = PDumpOSSprintf(pszMsg, ui32MaxLen, "%s", pszString);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	
+	PDumpOSVerifyLineEnding(pszMsg, ui32MaxLen);
+	ui32MsgLen = PDumpOSBuflen(pszMsg, ui32MaxLen);
+
+	if	(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_DRIVERINFO),
+						  (IMG_UINT8*)pszMsg,
+						  ui32MsgLen,
+						  ui32Flags))
+	{
+		if	(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+		{
+			return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+		}
+		else
+		{
+			return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+		}
+	}
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpBitmapKM(	PVRSRV_DEVICE_NODE *psDeviceNode,
+							IMG_CHAR *pszFileName,
+							IMG_UINT32 ui32FileOffset,
+							IMG_UINT32 ui32Width,
+							IMG_UINT32 ui32Height,
+							IMG_UINT32 ui32StrideInBytes,
+							IMG_DEV_VIRTADDR sDevBaseAddr,
+							IMG_HANDLE hDevMemContext,
+							IMG_UINT32 ui32Size,
+							PDUMP_PIXEL_FORMAT ePixelFormat,
+							PDUMP_MEM_FORMAT eMemFormat,
+							IMG_UINT32 ui32PDumpFlags)
+{
+	PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId;
+	IMG_UINT32 ui32MMUContextID;
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING();
+
+	if ( _PDumpIsPersistent() )
+	{
+		return PVRSRV_OK;
+	}
+
+	PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n");
+
+	
+	ui32MMUContextID = psDeviceNode->pfnMMUGetContextID( hDevMemContext );
+
+	eErr = PDumpOSBufprintf(hScript,
+				ui32MaxLen,
+				"SII %s %s.bin :%s:v%x:0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n",
+				pszFileName,
+				pszFileName,
+				psDevId->pszPDumpDevName,
+				ui32MMUContextID,
+				sDevBaseAddr.uiAddr,
+				ui32Size,
+				ui32FileOffset,
+				ePixelFormat,
+				ui32Width,
+				ui32Height,
+				ui32StrideInBytes,
+				eMemFormat);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	PDumpOSWriteString2( hScript, ui32PDumpFlags);
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpReadRegKM		(	IMG_CHAR *pszPDumpRegName,
+									IMG_CHAR *pszFileName,
+									IMG_UINT32 ui32FileOffset,
+									IMG_UINT32 ui32Address,
+									IMG_UINT32 ui32Size,
+									IMG_UINT32 ui32PDumpFlags)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING();
+
+	PVR_UNREFERENCED_PARAMETER(ui32Size);
+
+	eErr = PDumpOSBufprintf(hScript,
+			ui32MaxLen,
+			"SAB :%s:0x%08X 0x%08X %s\r\n",
+			pszPDumpRegName,
+			ui32Address,
+			ui32FileOffset,
+			pszFileName);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	PDumpOSWriteString2( hScript, ui32PDumpFlags);
+
+	return PVRSRV_OK;
+}
+
+IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame)
+{
+	IMG_BOOL	bFrameDumped;
+
+	
+
+	(IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1);
+	bFrameDumped = PDumpIsCaptureFrameKM();
+	(IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame);
+
+	return bFrameDumped;
+}
+
+static PVRSRV_ERROR PDumpSignatureRegister	(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+									 IMG_CHAR	*pszFileName,
+									 IMG_UINT32		ui32Address,
+									 IMG_UINT32		ui32Size,
+									 IMG_UINT32		*pui32FileOffset,
+									 IMG_UINT32		ui32Flags)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING();
+
+	eErr = PDumpOSBufprintf(hScript,
+			ui32MaxLen,
+			"SAB :%s:0x%08X 0x%08X %s\r\n",
+			psDevId->pszPDumpRegName,
+			ui32Address,
+			*pui32FileOffset,
+			pszFileName);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	PDumpOSWriteString2(hScript, ui32Flags);
+	*pui32FileOffset += ui32Size;
+	return PVRSRV_OK;
+}
+
+static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+									IMG_CHAR *pszFileName,
+									IMG_UINT32 *pui32Registers,
+									IMG_UINT32  ui32NumRegisters,
+									IMG_UINT32 *pui32FileOffset,
+									IMG_UINT32	ui32Size,
+									IMG_UINT32	ui32Flags)
+{
+	IMG_UINT32 i;
+	for (i = 0; i < ui32NumRegisters; i++)
+	{
+		PDumpSignatureRegister(psDevId, pszFileName, pui32Registers[i], ui32Size, pui32FileOffset, ui32Flags);
+	}
+}
+
+PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+										IMG_UINT32 ui32DumpFrameNum,
+										IMG_BOOL bLastFrame,
+										IMG_UINT32 *pui32Registers,
+										IMG_UINT32 ui32NumRegisters)
+{
+	PVRSRV_ERROR eErr;
+	IMG_UINT32	ui32FileOffset, ui32Flags;
+
+	PDUMP_GET_FILE_STRING();
+
+	ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
+	ui32FileOffset = 0;
+
+	PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump 3D signature registers\r\n");
+	eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_3d.sig", ui32DumpFrameNum);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	PDumpRegisterRange(psDevId,
+						pszFileName,
+						pui32Registers,
+						ui32NumRegisters,
+						&ui32FileOffset,
+						sizeof(IMG_UINT32),
+						ui32Flags);
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpTASignatureRegisters	(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+			 IMG_UINT32 ui32DumpFrameNum,
+			 IMG_UINT32	ui32TAKickCount,
+			 IMG_BOOL	bLastFrame,
+			 IMG_UINT32 *pui32Registers,
+			 IMG_UINT32 ui32NumRegisters)
+{
+	PVRSRV_ERROR eErr;
+	IMG_UINT32	ui32FileOffset, ui32Flags;
+
+	PDUMP_GET_FILE_STRING();
+
+	ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
+	ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32);
+
+	PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump TA signature registers\r\n");
+	eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_ta.sig", ui32DumpFrameNum);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	PDumpRegisterRange(psDevId,
+						pszFileName, 
+						pui32Registers, 
+						ui32NumRegisters, 
+						&ui32FileOffset, 
+						sizeof(IMG_UINT32), 
+						ui32Flags);
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+								IMG_UINT32 ui32DumpFrameNum,
+								IMG_BOOL	bLastFrame,
+								IMG_UINT32 *pui32Registers,
+								IMG_UINT32 ui32NumRegisters)
+{
+	PVRSRV_ERROR eErr;
+	IMG_UINT32	ui32FileOffset, ui32Flags;
+
+	PDUMP_GET_FILE_STRING();
+
+	ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0UL;
+	ui32FileOffset = 0UL;
+
+	PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump counter registers\r\n");
+	eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u.perf", ui32DumpFrameNum);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	PDumpRegisterRange(psDevId,
+						pszFileName,
+						pui32Registers,
+						ui32NumRegisters,
+						&ui32FileOffset,
+						sizeof(IMG_UINT32),
+						ui32Flags);
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
+							const IMG_UINT32 ui32RegOffset,
+							IMG_UINT32 ui32Flags)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING();
+
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
+							pszPDumpRegName, 
+							ui32RegOffset);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+							 IMG_CHAR			*pszFileName,
+							 IMG_UINT32			ui32FileOffset,
+							 IMG_DEV_VIRTADDR	sDevBaseAddr,
+							 IMG_UINT32 		ui32Size,
+							 IMG_UINT32			ui32MMUContextID,
+							 IMG_UINT32 		ui32PDumpFlags)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING();
+	
+	eErr = PDumpOSBufprintf(hScript,
+							ui32MaxLen,
+							"SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n",
+							psDevId->pszPDumpDevName,
+							ui32MMUContextID,
+							sDevBaseAddr.uiAddr,
+							ui32Size,
+							ui32FileOffset,
+							pszFileName);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+
+	PDumpOSWriteString2(hScript, ui32PDumpFlags);
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+									const IMG_UINT32 ui32RegOffset,
+									IMG_BOOL bLastFrame)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING();
+
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n", 
+							psDevId->pszPDumpRegName,
+							ui32RegOffset);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+								   IMG_CHAR			*pszFileName,
+								   IMG_CHAR			*pszBufferType,
+								   IMG_UINT32		ui32FileOffset,
+								   IMG_DEV_VIRTADDR	sDevBaseAddr,
+								   IMG_UINT32 		ui32Size,
+								   IMG_UINT32		ui32MMUContextID,
+								   IMG_UINT32 		ui32PDumpFlags)
+{
+	PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n",
+						  pszBufferType);
+	PDumpCommentWithFlags(ui32PDumpFlags, "Buffer format (sizes in 32-bit words):\r\n");
+	PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of signatures per sample (1)\r\n");
+	PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of samples (1)\r\n");
+	PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature register offsets (1 * number of signatures)\r\n");
+	PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n");
+	PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n");
+	return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
+						  ui32MMUContextID, ui32PDumpFlags);
+}
+
+
+PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+							  IMG_CHAR			*pszFileName,
+							  IMG_UINT32		ui32FileOffset,
+							  IMG_DEV_VIRTADDR	sDevBaseAddr,
+							  IMG_UINT32 		ui32Size,
+							  IMG_UINT32		ui32MMUContextID,
+							  IMG_UINT32 		ui32PDumpFlags)
+{
+	PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n");
+	return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
+						  ui32MMUContextID, ui32PDumpFlags);
+}
+
+
+PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO		psROffMemInfo,
+			  IMG_UINT32					ui32ROffOffset,
+			  IMG_UINT32					ui32WPosVal,
+			  IMG_UINT32					ui32PacketSize,
+			  IMG_UINT32					ui32BufferSize,
+			  IMG_UINT32					ui32Flags,
+			  IMG_HANDLE					hUniqueTag)
+{
+	PVRSRV_ERROR eErr;
+	IMG_UINT32			ui32PageOffset;
+	IMG_UINT8			*pui8LinAddr;
+	IMG_DEV_VIRTADDR	sDevVAddr;
+	IMG_DEV_PHYADDR		sDevPAddr;
+	IMG_DEV_VIRTADDR 	sDevVPageAddr;
+    
+	PDUMP_MMU_ATTRIB *psMMUAttrib;
+
+	PDUMP_GET_SCRIPT_STRING();
+
+	psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+
+	
+	PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->uAllocSize);
+
+	pui8LinAddr = psROffMemInfo->pvLinAddrKM;
+	sDevVAddr = psROffMemInfo->sDevVAddr;
+
+	
+	pui8LinAddr += ui32ROffOffset;
+	sDevVAddr.uiAddr += ui32ROffOffset;
+
+	
+
+
+	PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle,
+			ui32ROffOffset,
+			pui8LinAddr,
+			psMMUAttrib->ui32DataPageMask,
+			&ui32PageOffset);
+
+	
+	sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset;
+
+	PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
+
+	
+	BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr);
+
+	
+	sDevPAddr.uiAddr += ui32PageOffset;
+
+	eErr = PDumpOSBufprintf(hScript,
+			 ui32MaxLen,
+			 "CBP :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
+			 psMMUAttrib->sDevId.pszPDumpDevName,
+			 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+			 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
+			 sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
+			 ui32WPosVal,
+			 ui32PacketSize,
+			 ui32BufferSize);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING();
+	PDUMP_DBG(("PDumpIDLWithFlags"));
+
+	eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u\r\n", ui32Clocks);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, ui32Flags);
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
+{
+	return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
+}
+
+PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+						IMG_PVOID pvAltLinAddrUM,
+						IMG_PVOID pvLinAddrUM,
+						PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+						IMG_UINT32 ui32Offset,
+						IMG_UINT32 ui32Bytes,
+						IMG_UINT32 ui32Flags,
+						IMG_HANDLE hUniqueTag)
+{
+	IMG_VOID *pvAddrUM;
+	IMG_VOID *pvAddrKM;
+	IMG_UINT32 ui32BytesDumped;
+	IMG_UINT32 ui32CurrentOffset;
+
+	if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL)
+	{
+		
+		return PDumpMemKM(IMG_NULL,
+					   psMemInfo,
+					   ui32Offset,
+					   ui32Bytes,
+					   ui32Flags,
+					   hUniqueTag);
+	}
+
+	pvAddrUM = (pvAltLinAddrUM != IMG_NULL) ? pvAltLinAddrUM : ((pvLinAddrUM != IMG_NULL) ? VPTR_PLUS(pvLinAddrUM, ui32Offset) : IMG_NULL);
+
+	pvAddrKM = GetTempBuffer();
+
+	
+	PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL);
+	if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE)
+	{
+		PDumpCommentWithFlags(ui32Flags, "Dumping 0x%08x bytes of memory, in blocks of 0x%08x bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE);
+	}
+
+	ui32CurrentOffset = ui32Offset;
+	for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;)
+	{
+		PVRSRV_ERROR eError;
+		IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped);
+
+		eError = OSCopyFromUser(psPerProc,
+					   pvAddrKM,
+					   pvAddrUM,
+					   ui32BytesToDump);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError));
+			return eError;
+		}
+
+		eError = PDumpMemKM(pvAddrKM,
+					   psMemInfo,
+					   ui32CurrentOffset,
+					   ui32BytesToDump,
+					   ui32Flags,
+					   hUniqueTag);
+
+		if (eError != PVRSRV_OK)
+		{
+			
+			if (ui32BytesDumped != 0)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError));
+			}
+			return eError;
+		}
+
+		VPTR_INC(pvAddrUM, ui32BytesToDump);
+		ui32CurrentOffset += ui32BytesToDump;
+		ui32BytesDumped += ui32BytesToDump;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID)
+{
+	IMG_UINT32 i;
+
+	
+	for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++)
+	{
+		if((gui16MMUContextUsage & (1U << i)) == 0)
+		{
+			
+			gui16MMUContextUsage |= 1U << i;
+			*pui32MMUContextID = i;
+			return PVRSRV_OK;
+		}
+	}
+
+	PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids"));
+
+	return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
+}
+
+
+static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID)
+{
+	if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS)
+	{
+		
+		gui16MMUContextUsage &= ~(1U << ui32MMUContextID);
+		return PVRSRV_OK;
+	}
+
+	PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid"));
+
+	return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
+}
+
+
+PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+								IMG_CHAR *pszMemSpace,
+								IMG_UINT32 *pui32MMUContextID,
+								IMG_UINT32 ui32MMUType,
+								IMG_HANDLE hUniqueTag1,
+								IMG_HANDLE hOSMemHandle, 
+								IMG_VOID *pvPDCPUAddr)
+{
+	IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr;
+	IMG_CPU_PHYADDR sCpuPAddr;
+	IMG_DEV_PHYADDR sDevPAddr;
+	IMG_UINT32 ui32MMUContextID;
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING();
+
+	eErr = _PdumpAllocMMUContext(&ui32MMUContextID);
+	if(eErr != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eErr));
+		return eErr;
+	}
+
+	
+	
+	sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
+	sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
+	
+	sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1);
+
+	eErr = PDumpOSBufprintf(hScript,
+						ui32MaxLen, 
+						"MMU :%s:v%d %d :%s:PA_%08X%08X\r\n",
+						pszMemSpace,
+						ui32MMUContextID,
+						ui32MMUType,
+						pszMemSpace,
+						(IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+						sDevPAddr.uiAddr);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
+
+	
+	*pui32MMUContextID = ui32MMUContextID;
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+								IMG_CHAR *pszMemSpace,
+								IMG_UINT32 ui32MMUContextID,
+								IMG_UINT32 ui32MMUType)
+{
+	PVRSRV_ERROR eErr;
+	PDUMP_GET_SCRIPT_STRING();
+	PVR_UNREFERENCED_PARAMETER(eDeviceType);
+	PVR_UNREFERENCED_PARAMETER(ui32MMUType);
+
+	
+	PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace);
+	eErr = PDumpOSBufprintf(hScript,
+						ui32MaxLen, 
+						"MMU :%s:v%d\r\n",
+						pszMemSpace,
+						ui32MMUContextID);
+	if(eErr != PVRSRV_OK)
+	{
+		return eErr;
+	}
+	PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
+
+	eErr = _PdumpFreeMMUContext(ui32MMUContextID);
+	if(eErr != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr));
+		return eErr;
+	}
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
+						         IMG_CHAR *pszFileName,
+								 IMG_UINT32 ui32FileOffset, 
+								 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+								 IMG_UINT32 uiAddr, 
+								 IMG_UINT32 ui32Size,
+								 IMG_UINT32 ui32PDumpFlags,
+								 IMG_HANDLE hUniqueTag)
+{
+	IMG_DEV_PHYADDR		sDevPAddr;
+	IMG_DEV_VIRTADDR	sDevVPageAddr;
+	IMG_UINT32			ui32PageOffset;
+
+	PDUMP_GET_SCRIPT_STRING();
+
+	
+
+
+	ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask);
+	
+	
+	sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset;
+	
+	
+	BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+	
+	
+	sDevPAddr.uiAddr += ui32PageOffset;
+
+	PDumpOSBufprintf(hScript,
+			 ui32MaxLen,
+			 "SAB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+			 psMMUAttrib->sDevId.pszPDumpDevName,
+			 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+			 sDevPAddr.uiAddr & ~psMMUAttrib->ui32DataPageMask,
+			 sDevPAddr.uiAddr & psMMUAttrib->ui32DataPageMask,
+			 ui32Size,
+			 ui32FileOffset,
+			 pszFileName);
+
+	PDumpOSWriteString2(hScript, ui32PDumpFlags);
+	
+	return PVRSRV_OK;	
+}
+
+PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR		*pszPDumpRegName,
+							  IMG_UINT32	ui32RegOffset,
+							  IMG_UINT32	ui32WPosVal,
+							  IMG_UINT32	ui32PacketSize,
+							  IMG_UINT32	ui32BufferSize,
+							  IMG_UINT32	ui32Flags)
+{
+	PDUMP_GET_SCRIPT_STRING();
+
+	PDumpOSBufprintf(hScript,
+			 ui32MaxLen,
+			 "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
+			 pszPDumpRegName,
+			 ui32RegOffset,
+			 ui32WPosVal,
+			 ui32PacketSize,
+			 ui32BufferSize);
+	PDumpOSWriteString2(hScript, ui32Flags);
+	
+	return PVRSRV_OK;		
+}
+
+
+ 
+#include "syscommon.h"
+
+IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID)
+{
+	SYS_DATA			*psSysData;
+	PVRSRV_DEVICE_NODE	*psThis;
+	PVR_DPF((PVR_DBG_WARNING, "PDump has connected."));
+	
+	
+	SysAcquireData(&psSysData);
+	
+	psThis = psSysData->psDeviceNodeList;
+	while (psThis)
+	{
+		if (psThis->pfnPDumpInitDevice)
+		{
+			
+			psThis->pfnPDumpInitDevice(psThis);
+		}
+		psThis = psThis->psNext;
+	}
+}
+
+IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
+{
+	IMG_UINT32	ui32BytesWritten = 0;
+	IMG_UINT32	ui32Off = 0;
+	PDBG_STREAM_CONTROL psCtrl = psStream->psCtrl;
+
+	
+	if ((ui32Flags & PDUMP_FLAGS_NEVER) != 0)
+	{
+		return ui32BCount;
+	}
+	
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	
+	if ( (_PDumpIsProcessActive() == IMG_FALSE ) &&
+		 ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) )
+	{
+		return ui32BCount;
+	}
+#endif
+
+	
+	if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) )
+	{
+		while (ui32BCount > 0)
+		{
+			
+
+
+			ui32BytesWritten = PDumpOSDebugDriverWrite(	psStream,
+														PDUMP_WRITE_MODE_PERSISTENT,
+														&pui8Data[ui32Off], ui32BCount, 1, 0);
+
+			if (ui32BytesWritten == 0)
+			{
+				PDumpOSReleaseExecution();
+			}
+
+			if (ui32BytesWritten != 0xFFFFFFFFU)
+			{
+				ui32Off += ui32BytesWritten;
+				ui32BCount -= ui32BytesWritten;
+			}
+			else
+			{
+				PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data"));
+				if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0)
+				{
+					
+					PDumpSuspendKM();
+				}
+				return 0xFFFFFFFFU;
+			}
+		}
+		
+		
+		ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0;
+	}
+
+	while (((IMG_UINT32) ui32BCount > 0) && (ui32BytesWritten != 0xFFFFFFFFU))
+	{
+		if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0)
+		{
+			
+
+			if (((psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
+				 (psCtrl->ui32Start == 0xFFFFFFFFU) &&
+				 (psCtrl->ui32End == 0xFFFFFFFFU) &&
+				  psCtrl->bInitPhaseComplete)
+			{
+				ui32BytesWritten = ui32BCount;
+			}
+			else
+			{
+				ui32BytesWritten = PDumpOSDebugDriverWrite(	psStream, 
+															PDUMP_WRITE_MODE_CONTINUOUS,
+															&pui8Data[ui32Off], ui32BCount, 1, 0);
+			}
+		}
+		else
+		{
+			if (ui32Flags & PDUMP_FLAGS_LASTFRAME)
+			{
+				IMG_UINT32	ui32DbgFlags;
+	
+				ui32DbgFlags = 0;
+				if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER)
+				{
+					ui32DbgFlags |= WRITELF_FLAGS_RESETBUF;
+				}
+	
+				ui32BytesWritten = PDumpOSDebugDriverWrite(	psStream,
+															PDUMP_WRITE_MODE_LASTFRAME,
+															&pui8Data[ui32Off], ui32BCount, 1, ui32DbgFlags);
+			}
+			else
+			{
+				ui32BytesWritten = PDumpOSDebugDriverWrite(	psStream, 
+															PDUMP_WRITE_MODE_BINCM,
+															&pui8Data[ui32Off], ui32BCount, 1, 0);
+			}
+		}
+
+		
+
+
+		if (ui32BytesWritten == 0)
+		{
+			PDumpOSReleaseExecution();
+		}
+
+		if (ui32BytesWritten != 0xFFFFFFFFU)
+		{
+			ui32Off += ui32BytesWritten;
+			ui32BCount -= ui32BytesWritten;
+		}
+
+		
+	}
+
+
+	
+	return ui32BytesWritten;
+}
+
+
+
+#else	
+#endif	
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/perproc.c b/drivers/staging/cdv/pvr/services4/srvkm/common/perproc.c
new file mode 100644
index 0000000..eb73166
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/perproc.c
@@ -0,0 +1,305 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "resman.h"
+#include "handle.h"
+#include "perproc.h"
+#include "osperproc.h"
+#if defined(TTRACE)
+#include "ttrace.h"
+#endif
+
+#define	HASH_TAB_INIT_SIZE 32
+
+static HASH_TABLE *psHashTab = IMG_NULL;
+
+static PVRSRV_ERROR FreePerProcessData(PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_ERROR eError;
+	IMG_UINTPTR_T uiPerProc;
+
+	PVR_ASSERT(psPerProc != IMG_NULL);
+
+	if (psPerProc == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: invalid parameter"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	uiPerProc = HASH_Remove(psHashTab, (IMG_UINTPTR_T)psPerProc->ui32PID);
+	if (uiPerProc == 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't find process in per-process data hash table"));
+		
+		PVR_ASSERT(psPerProc->ui32PID == 0);
+	}
+	else
+	{
+		PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc);
+		PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID);
+	}
+
+	
+	if (psPerProc->psHandleBase != IMG_NULL)
+	{
+		eError = PVRSRVFreeHandleBase(psPerProc->psHandleBase);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free handle base for process (%d)", eError));
+			return eError;
+		}
+	}
+
+	
+	if (psPerProc->hPerProcData != IMG_NULL)
+	{
+		eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, psPerProc->hPerProcData, PVRSRV_HANDLE_TYPE_PERPROC_DATA);
+
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't release per-process data handle (%d)", eError));
+			return eError;
+		}
+	}
+
+	
+	eError = OSPerProcessPrivateDataDeInit(psPerProc->hOsPrivateData);
+	if (eError != PVRSRV_OK)
+	{
+		 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: OSPerProcessPrivateDataDeInit failed (%d)", eError));
+		return eError;
+	}
+
+	eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+		sizeof(*psPerProc),
+		psPerProc,
+		psPerProc->hBlockAlloc);
+	
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError));
+		return eError;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID)
+{
+	PVRSRV_PER_PROCESS_DATA *psPerProc;
+
+	PVR_ASSERT(psHashTab != IMG_NULL);
+
+	
+	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
+	return psPerProc;
+}
+
+
+PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32	ui32PID, IMG_UINT32 ui32Flags)
+{
+	PVRSRV_PER_PROCESS_DATA *psPerProc;
+	IMG_HANDLE hBlockAlloc;
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	if (psHashTab == IMG_NULL)
+	{
+		return PVRSRV_ERROR_INIT_FAILURE;
+	}
+
+	
+	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
+
+	if (psPerProc == IMG_NULL)
+	{
+		
+		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+							sizeof(*psPerProc),
+							(IMG_PVOID *)&psPerProc,
+							&hBlockAlloc,
+							"Per Process Data");
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
+			return eError;
+		}
+		OSMemSet(psPerProc, 0, sizeof(*psPerProc));
+		psPerProc->hBlockAlloc = hBlockAlloc;
+
+		if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
+			eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED;
+			goto failure;
+		}
+
+		psPerProc->ui32PID = ui32PID;
+		psPerProc->ui32RefCount = 0;
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+		if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE)
+		{
+			psPerProc->bPDumpActive = IMG_TRUE;
+		}
+#else
+		PVR_UNREFERENCED_PARAMETER(ui32Flags);
+#endif
+
+		
+		eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
+		if (eError != PVRSRV_OK)
+		{
+			 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
+			goto failure;
+		}
+
+		
+		eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
+								   &psPerProc->hPerProcData,
+								   psPerProc,
+								   PVRSRV_HANDLE_TYPE_PERPROC_DATA,
+								   PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
+			goto failure;
+		}
+
+		
+		eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
+			goto failure;
+		}
+
+		
+		eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
+			goto failure;
+		}
+		
+		
+		eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
+			goto failure;
+		}
+#if defined (TTRACE)
+		PVRSRVTimeTraceBufferCreate(ui32PID);
+#endif
+	}
+	
+	psPerProc->ui32RefCount++;
+	PVR_DPF((PVR_DBG_MESSAGE,
+			"PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
+			ui32PID, psPerProc->ui32RefCount));
+
+	return eError;
+
+failure:
+	(IMG_VOID)FreePerProcessData(psPerProc);
+	return eError;
+}
+
+
+IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32	ui32PID)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_PER_PROCESS_DATA *psPerProc;
+
+	PVR_ASSERT(psHashTab != IMG_NULL);
+
+	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
+	if (psPerProc == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID));
+	}
+	else
+	{
+		psPerProc->ui32RefCount--;
+		if (psPerProc->ui32RefCount == 0)
+		{
+			PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: "
+					"Last close from process 0x%x received", ui32PID));
+
+#if defined (TTRACE)
+			PVRSRVTimeTraceBufferDestroy(ui32PID);
+#endif
+
+			
+			PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE);
+			
+			
+			eError = FreePerProcessData(psPerProc);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data"));
+			}
+		}
+	}
+
+	eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError));
+	}
+}
+
+
+PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID)
+{
+	PVR_ASSERT(psHashTab == IMG_NULL);
+
+	
+	psHashTab = HASH_Create(HASH_TAB_INIT_SIZE);
+	if (psHashTab == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataInit: Couldn't create per-process data hash table"));
+		return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
+	}
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID)
+{
+	
+	if (psHashTab != IMG_NULL)
+	{
+		
+		HASH_Delete(psHashTab);
+		psHashTab = IMG_NULL;
+	}
+
+	return PVRSRV_OK;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/power.c b/drivers/staging/cdv/pvr/services4/srvkm/common/power.c
new file mode 100644
index 0000000..21d7ad4
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/power.c
@@ -0,0 +1,719 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "pdump_km.h"
+
+#include "lists.h"
+
+static IMG_BOOL gbInitServerRunning = IMG_FALSE;
+static IMG_BOOL gbInitServerRan = IMG_FALSE;
+static IMG_BOOL gbInitSuccessful = IMG_FALSE;
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState)
+{
+
+	switch(eInitServerState)
+	{
+		case PVRSRV_INIT_SERVER_RUNNING:
+			gbInitServerRunning	= bState;
+			break;
+		case PVRSRV_INIT_SERVER_RAN:
+			gbInitServerRan	= bState;
+			break;
+		case PVRSRV_INIT_SERVER_SUCCESSFUL:
+			gbInitSuccessful = bState;
+			break;
+		default:
+			PVR_DPF((PVR_DBG_ERROR,
+				"PVRSRVSetInitServerState : Unknown state %x", eInitServerState));
+			return PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE;
+	}
+
+	return PVRSRV_OK;
+}
+
+IMG_EXPORT
+IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState)
+{
+	IMG_BOOL	bReturnVal;
+
+	switch(eInitServerState)
+	{
+		case PVRSRV_INIT_SERVER_RUNNING:
+			bReturnVal = gbInitServerRunning;
+			break;
+		case PVRSRV_INIT_SERVER_RAN:
+			bReturnVal = gbInitServerRan;
+			break;
+		case PVRSRV_INIT_SERVER_SUCCESSFUL:
+			bReturnVal = gbInitSuccessful;
+			break;
+		default:
+			PVR_DPF((PVR_DBG_ERROR,
+				"PVRSRVGetInitServerState : Unknown state %x", eInitServerState));
+			bReturnVal = IMG_FALSE;
+	}
+
+	return bReturnVal;
+}
+
+static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState)
+{
+	return (IMG_BOOL)(eSystemPowerState < PVRSRV_SYS_POWER_STATE_D2);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32	ui32CallerID,
+							 IMG_BOOL	bSystemPowerEvent)
+{
+	PVRSRV_ERROR	eError;
+	SYS_DATA	*psSysData;
+	IMG_UINT32	ui32Timeout = 1000000;
+	IMG_BOOL	bTryLock = (ui32CallerID == ISR_ID);
+
+	SysAcquireData(&psSysData);
+
+	eError = OSPowerLockWrap(bTryLock);
+	if (eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	do
+	{
+		eError = OSLockResource(&psSysData->sPowerStateChangeResource,
+								ui32CallerID);
+		if (eError == PVRSRV_OK)
+		{
+			break;
+		}
+		else if (bTryLock)
+		{
+			
+
+			eError = PVRSRV_ERROR_RETRY;
+			break;
+		}
+
+		OSWaitus(1);
+		ui32Timeout--;
+	} while (ui32Timeout > 0);
+
+	if (eError != PVRSRV_OK)
+	{
+		OSPowerLockUnwrap();
+	}
+
+	 
+	if ((eError == PVRSRV_OK) &&
+		!bSystemPowerEvent &&
+		!_IsSystemStatePowered(psSysData->eCurrentPowerState))
+	{
+		
+		PVRSRVPowerUnlock(ui32CallerID);
+		eError = PVRSRV_ERROR_RETRY;
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+IMG_VOID PVRSRVPowerUnlock(IMG_UINT32	ui32CallerID)
+{
+	OSUnlockResource(&gpsSysData->sPowerStateChangeResource, ui32CallerID);
+	OSPowerLockUnwrap();
+}
+
+
+static PVRSRV_ERROR PVRSRVDevicePrePowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+	PVRSRV_DEV_POWER_STATE	eNewDevicePowerState;
+	PVRSRV_ERROR			eError;
+
+	
+	IMG_BOOL				bAllDevices;
+	IMG_UINT32				ui32DeviceIndex;
+	PVRSRV_DEV_POWER_STATE	eNewPowerState;
+
+	
+	bAllDevices = va_arg(va, IMG_BOOL);
+	ui32DeviceIndex = va_arg(va, IMG_UINT32);
+	eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+
+	if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+	{
+		eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
+							psPowerDevice->eDefaultPowerState : eNewPowerState;
+
+		if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
+		{
+			if (psPowerDevice->pfnPrePower != IMG_NULL)
+			{
+				
+				eError = psPowerDevice->pfnPrePower(psPowerDevice->hDevCookie,
+													eNewDevicePowerState,
+													psPowerDevice->eCurrentPowerState);
+				if (eError != PVRSRV_OK)
+				{
+					return eError;
+				}
+			}
+
+			
+			eError = SysDevicePrePowerState(psPowerDevice->ui32DeviceIndex,
+											eNewDevicePowerState,
+											psPowerDevice->eCurrentPowerState);
+			if (eError != PVRSRV_OK)
+			{
+				return eError;
+			}
+		}
+	}
+
+	return  PVRSRV_OK;
+}
+
+static
+PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL				bAllDevices,
+										 IMG_UINT32				ui32DeviceIndex,
+										 PVRSRV_DEV_POWER_STATE	eNewPowerState)
+{
+	PVRSRV_ERROR		eError;
+	SYS_DATA			*psSysData;
+
+	SysAcquireData(&psSysData);
+
+	
+	eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
+														&PVRSRVDevicePrePowerStateKM_AnyVaCb,
+														bAllDevices,
+														ui32DeviceIndex,
+														eNewPowerState);
+
+	return eError;
+}
+
+static PVRSRV_ERROR PVRSRVDevicePostPowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+	PVRSRV_DEV_POWER_STATE	eNewDevicePowerState;
+	PVRSRV_ERROR			eError;
+
+	
+	IMG_BOOL				bAllDevices;
+	IMG_UINT32				ui32DeviceIndex;
+	PVRSRV_DEV_POWER_STATE	eNewPowerState;
+
+	
+	bAllDevices = va_arg(va, IMG_BOOL);
+	ui32DeviceIndex = va_arg(va, IMG_UINT32);
+	eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+
+	if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+	{
+		eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
+								psPowerDevice->eDefaultPowerState : eNewPowerState;
+
+		if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
+		{
+			
+			eError = SysDevicePostPowerState(psPowerDevice->ui32DeviceIndex,
+											 eNewDevicePowerState,
+											 psPowerDevice->eCurrentPowerState);
+			if (eError != PVRSRV_OK)
+			{
+				return eError;
+			}
+
+			if (psPowerDevice->pfnPostPower != IMG_NULL)
+			{
+				
+				eError = psPowerDevice->pfnPostPower(psPowerDevice->hDevCookie,
+													 eNewDevicePowerState,
+													 psPowerDevice->eCurrentPowerState);
+				if (eError != PVRSRV_OK)
+				{
+					return eError;
+				}
+			}
+
+			psPowerDevice->eCurrentPowerState = eNewDevicePowerState;
+		}
+	}
+	return PVRSRV_OK;
+}
+
+static
+PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL					bAllDevices,
+										  IMG_UINT32				ui32DeviceIndex,
+										  PVRSRV_DEV_POWER_STATE	eNewPowerState)
+{
+	PVRSRV_ERROR		eError;
+	SYS_DATA			*psSysData;
+
+	SysAcquireData(&psSysData);
+
+	
+	eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
+														&PVRSRVDevicePostPowerStateKM_AnyVaCb,
+														bAllDevices,
+														ui32DeviceIndex,
+														eNewPowerState);
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32				ui32DeviceIndex,
+										 PVRSRV_DEV_POWER_STATE	eNewPowerState,
+										 IMG_UINT32				ui32CallerID,
+										 IMG_BOOL				bRetainMutex)
+{
+	PVRSRV_ERROR	eError;
+	SYS_DATA		*psSysData;
+
+	SysAcquireData(&psSysData);
+
+	eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
+	if(eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	#if defined(PDUMP)
+	if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
+	{
+		
+
+
+
+		eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
+		if(eError != PVRSRV_OK)
+		{
+			goto Exit;
+		}
+
+		eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
+
+		if (eError != PVRSRV_OK)
+		{
+			goto Exit;
+		}
+
+		PDUMPSUSPEND();
+	}
+	#endif 
+
+	eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
+	if(eError != PVRSRV_OK)
+	{
+		if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
+		{
+			PDUMPRESUME();
+		}
+		goto Exit;
+	}
+
+	eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
+
+	if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
+	{
+		PDUMPRESUME();
+	}
+
+Exit:
+
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError));
+	}
+
+	if (!bRetainMutex || (eError != PVRSRV_OK))
+	{
+		PVRSRVPowerUnlock(ui32CallerID);
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
+{
+	PVRSRV_ERROR			eError;
+	SYS_DATA				*psSysData;
+	PVRSRV_DEV_POWER_STATE	eNewDevicePowerState;
+
+	SysAcquireData(&psSysData);
+
+	
+	eError = PVRSRVPowerLock(KERNEL_ID, IMG_TRUE);
+	if(eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	if (_IsSystemStatePowered(eNewSysPowerState) !=
+		_IsSystemStatePowered(psSysData->eCurrentPowerState))
+	{
+		if (_IsSystemStatePowered(eNewSysPowerState))
+		{
+			
+			eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
+		}
+		else
+		{
+			eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
+		}
+
+		
+		eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
+		if (eError != PVRSRV_OK)
+		{
+			goto ErrorExit;
+		}
+	}
+
+	if (eNewSysPowerState != psSysData->eCurrentPowerState)
+	{
+		
+		eError = SysSystemPrePowerState(eNewSysPowerState);
+		if (eError != PVRSRV_OK)
+		{
+			goto ErrorExit;
+		}
+	}
+
+	return eError;
+
+ErrorExit:
+
+	PVR_DPF((PVR_DBG_ERROR,
+			"PVRSRVSystemPrePowerStateKM: Transition from %d to %d FAILED 0x%x",
+			psSysData->eCurrentPowerState, eNewSysPowerState, eError));
+
+	
+	psSysData->eFailedPowerState = eNewSysPowerState;
+
+	PVRSRVPowerUnlock(KERNEL_ID);
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
+{
+	PVRSRV_ERROR			eError = PVRSRV_OK;
+	SYS_DATA				*psSysData;
+	PVRSRV_DEV_POWER_STATE	eNewDevicePowerState;
+
+	SysAcquireData(&psSysData);
+
+	if (eNewSysPowerState != psSysData->eCurrentPowerState)
+	{
+		
+		eError = SysSystemPostPowerState(eNewSysPowerState);
+		if (eError != PVRSRV_OK)
+		{
+			goto Exit;
+		}
+	}
+
+	if (_IsSystemStatePowered(eNewSysPowerState) !=
+		_IsSystemStatePowered(psSysData->eCurrentPowerState))
+	{
+		if (_IsSystemStatePowered(eNewSysPowerState))
+		{
+			
+			eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
+		}
+		else
+		{
+			eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
+		}
+
+		
+		eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
+		if (eError != PVRSRV_OK)
+		{
+			goto Exit;
+		}
+	}
+
+	PVR_DPF((PVR_DBG_MESSAGE,
+			"PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK",
+			psSysData->eCurrentPowerState, eNewSysPowerState));
+
+	psSysData->eCurrentPowerState = eNewSysPowerState;
+
+Exit:
+
+	PVRSRVPowerUnlock(KERNEL_ID);
+
+	 
+	if (_IsSystemStatePowered(eNewSysPowerState) &&
+			PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
+	{
+		
+
+
+		PVRSRVScheduleDeviceCallbacks();
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
+{
+	PVRSRV_ERROR	eError;
+	SYS_DATA		*psSysData;
+
+	SysAcquireData(&psSysData);
+
+	eError = PVRSRVSystemPrePowerStateKM(eNewSysPowerState);
+	if(eError != PVRSRV_OK)
+	{
+		goto ErrorExit;
+	}
+
+	eError = PVRSRVSystemPostPowerStateKM(eNewSysPowerState);
+	if(eError != PVRSRV_OK)
+	{
+		goto ErrorExit;
+	}
+
+	
+	psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
+
+	return PVRSRV_OK;
+
+ErrorExit:
+
+	PVR_DPF((PVR_DBG_ERROR,
+			"PVRSRVSetPowerStateKM: Transition from %d to %d FAILED 0x%x",
+			psSysData->eCurrentPowerState, eNewSysPowerState, eError));
+
+	
+	psSysData->eFailedPowerState = eNewSysPowerState;
+
+	return eError;
+}
+
+
+PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32					ui32DeviceIndex,
+									   PFN_PRE_POWER				pfnPrePower,
+									   PFN_POST_POWER				pfnPostPower,
+									   PFN_PRE_CLOCKSPEED_CHANGE	pfnPreClockSpeedChange,
+									   PFN_POST_CLOCKSPEED_CHANGE	pfnPostClockSpeedChange,
+									   IMG_HANDLE					hDevCookie,
+									   PVRSRV_DEV_POWER_STATE		eCurrentPowerState,
+									   PVRSRV_DEV_POWER_STATE		eDefaultPowerState)
+{
+	PVRSRV_ERROR		eError;
+	SYS_DATA			*psSysData;
+	PVRSRV_POWER_DEV	*psPowerDevice;
+
+	if (pfnPrePower == IMG_NULL &&
+		pfnPostPower == IMG_NULL)
+	{
+		return PVRSRVRemovePowerDevice(ui32DeviceIndex);
+	}
+
+	SysAcquireData(&psSysData);
+
+	eError = OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+						 sizeof(PVRSRV_POWER_DEV),
+						 (IMG_VOID **)&psPowerDevice, IMG_NULL,
+						 "Power Device");
+	if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV"));
+		return eError;
+	}
+
+	
+	psPowerDevice->pfnPrePower = pfnPrePower;
+	psPowerDevice->pfnPostPower = pfnPostPower;
+	psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange;
+	psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange;
+	psPowerDevice->hDevCookie = hDevCookie;
+	psPowerDevice->ui32DeviceIndex = ui32DeviceIndex;
+	psPowerDevice->eCurrentPowerState = eCurrentPowerState;
+	psPowerDevice->eDefaultPowerState = eDefaultPowerState;
+
+	
+	List_PVRSRV_POWER_DEV_Insert(&(psSysData->psPowerDeviceList), psPowerDevice);
+
+	return (PVRSRV_OK);
+}
+
+
+PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex)
+{
+	SYS_DATA			*psSysData;
+	PVRSRV_POWER_DEV	*psPowerDev;
+
+	SysAcquireData(&psSysData);
+
+	
+	psPowerDev = (PVRSRV_POWER_DEV*)
+					List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+												 &MatchPowerDeviceIndex_AnyVaCb,
+												 ui32DeviceIndex);
+
+	if (psPowerDev)
+	{
+		List_PVRSRV_POWER_DEV_Remove(psPowerDev);
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psPowerDev, IMG_NULL);
+		
+	}
+
+	return (PVRSRV_OK);
+}
+
+
+IMG_EXPORT
+IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex)
+{
+	SYS_DATA			*psSysData;
+	PVRSRV_POWER_DEV	*psPowerDevice;
+
+	SysAcquireData(&psSysData);
+
+	 
+	if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) ||
+		OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID))
+	{
+		return IMG_FALSE;
+	}
+
+	psPowerDevice = (PVRSRV_POWER_DEV*)
+					List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+												 &MatchPowerDeviceIndex_AnyVaCb,
+												 ui32DeviceIndex);
+	return (psPowerDevice && (psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON))
+			? IMG_TRUE : IMG_FALSE;
+}
+
+
+PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32	ui32DeviceIndex,
+											 IMG_BOOL	bIdleDevice,
+											 IMG_VOID	*pvInfo)
+{
+	PVRSRV_ERROR		eError = PVRSRV_OK;
+	SYS_DATA			*psSysData;
+	PVRSRV_POWER_DEV	*psPowerDevice;
+
+	PVR_UNREFERENCED_PARAMETER(pvInfo);
+
+	SysAcquireData(&psSysData);
+
+	if (bIdleDevice)
+	{
+		
+		eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,	"PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError));
+			return eError;
+		}
+	}
+
+	
+	psPowerDevice = (PVRSRV_POWER_DEV*)
+					List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+												 &MatchPowerDeviceIndex_AnyVaCb,
+												 ui32DeviceIndex);
+
+	if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
+	{
+			eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie,
+														   bIdleDevice,
+														   psPowerDevice->eCurrentPowerState);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+						"PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x",
+						ui32DeviceIndex, eError));
+			}
+	}
+
+	if (bIdleDevice && eError != PVRSRV_OK)
+	{
+		PVRSRVPowerUnlock(KERNEL_ID);
+	}
+
+	return eError;
+}
+
+
+IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32	ui32DeviceIndex,
+										  IMG_BOOL		bIdleDevice,
+										  IMG_VOID		*pvInfo)
+{
+	PVRSRV_ERROR		eError;
+	SYS_DATA			*psSysData;
+	PVRSRV_POWER_DEV	*psPowerDevice;
+
+	PVR_UNREFERENCED_PARAMETER(pvInfo);
+
+	SysAcquireData(&psSysData);
+
+	
+	psPowerDevice = (PVRSRV_POWER_DEV*)
+					List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+												 &MatchPowerDeviceIndex_AnyVaCb,
+												 ui32DeviceIndex);
+
+	if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
+	{
+		eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie,
+														bIdleDevice,
+														psPowerDevice->eCurrentPowerState);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+					"PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x",
+					ui32DeviceIndex, eError));
+		}
+	}
+
+
+	if (bIdleDevice)
+	{
+		
+		PVRSRVPowerUnlock(KERNEL_ID);
+	}
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/pvrsrv.c b/drivers/staging/cdv/pvr/services4/srvkm/common/pvrsrv.c
new file mode 100644
index 0000000..968144f
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/pvrsrv.c
@@ -0,0 +1,1338 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "pvr_bridge_km.h"
+#include "handle.h"
+#include "perproc.h"
+#include "pdump_km.h"
+#include "deviceid.h"
+#include "ra.h"
+#if defined(TTRACE)
+#include "ttrace.h"
+#endif
+
+#include "pvrversion.h"
+
+#include "lists.h"
+
+IMG_UINT32	g_ui32InitFlags;
+
+#define		INIT_DATA_ENABLE_PDUMPINIT	0x1U
+#define		INIT_DATA_ENABLE_TTARCE		0x2U
+
+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID)
+{
+	SYS_DEVICE_ID* psDeviceWalker;
+	SYS_DEVICE_ID* psDeviceEnd;
+
+	psDeviceWalker = &psSysData->sDeviceID[0];
+	psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
+
+	
+	while (psDeviceWalker < psDeviceEnd)
+	{
+		if (!psDeviceWalker->bInUse)
+		{
+			psDeviceWalker->bInUse = IMG_TRUE;
+			*pui32DevID = psDeviceWalker->uiID;
+			return PVRSRV_OK;
+		}
+		psDeviceWalker++;
+	}
+
+	PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!"));
+
+	
+	PVR_ASSERT(psDeviceWalker < psDeviceEnd);
+
+	return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE;
+}
+
+
+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID)
+{
+	SYS_DEVICE_ID* psDeviceWalker;
+	SYS_DEVICE_ID* psDeviceEnd;
+
+	psDeviceWalker = &psSysData->sDeviceID[0];
+	psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
+
+	
+	while (psDeviceWalker < psDeviceEnd)
+	{
+		
+		if	(
+				(psDeviceWalker->uiID == ui32DevID) &&
+				(psDeviceWalker->bInUse)
+			)
+		{
+			psDeviceWalker->bInUse = IMG_FALSE;
+			return PVRSRV_OK;
+		}
+		psDeviceWalker++;
+	}
+
+	PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!"));
+
+	
+	PVR_ASSERT(psDeviceWalker < psDeviceEnd);
+
+	return PVRSRV_ERROR_INVALID_DEVICEID;
+}
+
+
+#ifndef ReadHWReg
+IMG_EXPORT
+IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
+{
+	return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset);
+}
+#endif
+
+
+#ifndef WriteHWReg
+IMG_EXPORT
+IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+	PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x",
+			(IMG_UINTPTR_T)pvLinRegBaseAddr,ui32Offset,ui32Value));
+
+	*(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value;
+}
+#endif
+
+
+#ifndef WriteHWRegs
+IMG_EXPORT
+IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs)
+{
+	while (ui32Count)
+	{
+		WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal);
+		psHWRegs++;
+		ui32Count--;
+	}
+}
+#endif
+
+static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+	IMG_UINT *pui32DevCount;
+	PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList;
+
+	pui32DevCount = va_arg(va, IMG_UINT*);
+	ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**);
+
+	if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
+	{
+		*(*ppsDevIdList) = psDeviceNode->sDevId;
+		(*ppsDevIdList)++;
+		(*pui32DevCount)++;
+	}
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
+											 	   PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
+{
+	SYS_DATA			*psSysData;
+	IMG_UINT32 			i;
+
+	if (!pui32NumDevices || !psDevIdList)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	SysAcquireData(&psSysData);
+
+	
+
+	for (i=0; i<PVRSRV_MAX_DEVICES; i++)
+	{
+		psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
+	}
+
+	
+	*pui32NumDevices = 0;
+
+	
+
+
+
+	List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+									   &PVRSRVEnumerateDevicesKM_ForEachVaCb,
+									   pui32NumDevices,
+									   &psDevIdList);
+
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData)
+{
+	PVRSRV_ERROR	eError;
+
+	eError = BM_XProcWorkaroundShareInit();
+	if (eError != PVRSRV_OK)
+	{
+		goto Error;
+	}
+	
+	eError = ResManInit();
+	if (eError != PVRSRV_OK)
+	{
+		goto Error;
+	}
+
+	eError = PVRSRVPerProcessDataInit();
+	if(eError != PVRSRV_OK)
+	{
+		goto Error;
+	}
+
+	
+	eError = PVRSRVHandleInit();
+	if(eError != PVRSRV_OK)
+	{
+		goto Error;
+	}
+
+	
+	eError = OSCreateResource(&psSysData->sPowerStateChangeResource);
+	if (eError != PVRSRV_OK)
+	{
+		goto Error;
+	}
+
+	
+	psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
+	psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
+
+	
+	if(OSAllocMem( PVRSRV_PAGEABLE_SELECT,
+					 sizeof(PVRSRV_EVENTOBJECT) ,
+					 (IMG_VOID **)&psSysData->psGlobalEventObject, 0,
+					 "Event Object") != PVRSRV_OK)
+	{
+
+		goto Error;
+	}
+
+	if(OSEventObjectCreateKM("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK)
+	{
+		goto Error;
+	}
+
+	
+	psSysData->pfnHighResTimerCreate = OSFuncHighResTimerCreate;
+	psSysData->pfnHighResTimerGetus = OSFuncHighResTimerGetus;
+	psSysData->pfnHighResTimerDestroy = OSFuncHighResTimerDestroy;
+
+#if defined(TTRACE)
+	eError = PVRSRVTimeTraceInit();
+	if (eError != PVRSRV_OK)
+		goto Error;
+	g_ui32InitFlags |= INIT_DATA_ENABLE_TTARCE;
+#endif
+
+	
+	PDUMPINIT();
+	g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
+
+	return eError;
+
+Error:
+	PVRSRVDeInit(psSysData);
+	return eError;
+}
+
+
+
+IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData)
+{
+	PVRSRV_ERROR	eError;
+
+	PVR_UNREFERENCED_PARAMETER(psSysData);
+
+	if (psSysData == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param"));
+		return;
+	}
+#if defined(TTRACE)
+	
+	if ((g_ui32InitFlags & INIT_DATA_ENABLE_TTARCE) > 0)
+	{
+		PVRSRVTimeTraceDeinit();
+	}
+#endif
+	
+	if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
+	{
+		PDUMPDEINIT();
+	}
+	
+	
+	if(psSysData->psGlobalEventObject)
+	{
+		OSEventObjectDestroyKM(psSysData->psGlobalEventObject);
+		OSFreeMem( PVRSRV_PAGEABLE_SELECT,
+						 sizeof(PVRSRV_EVENTOBJECT),
+						 psSysData->psGlobalEventObject,
+						 0);
+		psSysData->psGlobalEventObject = IMG_NULL;
+	}
+
+	eError = PVRSRVHandleDeInit();
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
+	}
+
+	eError = PVRSRVPerProcessDataDeInit();
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed"));
+	}
+
+	ResManDeInit();
+
+	BM_XProcWorkaroundShareDestroy();
+}
+
+
+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;
+
+	
+	if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+					 sizeof(PVRSRV_DEVICE_NODE),
+					 (IMG_VOID **)&psDeviceNode, IMG_NULL,
+					 "Device Node") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
+		return (PVRSRV_ERROR_OUT_OF_MEMORY);
+	}
+	OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
+
+	eError = pfnRegisterDevice(psDeviceNode);
+	if (eError != PVRSRV_OK)
+	{
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+					sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
+		
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
+		return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED);
+	}
+
+	
+
+
+
+
+	psDeviceNode->ui32RefCount = 1;
+	psDeviceNode->psSysData = psSysData;
+	psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit;
+
+	
+	AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
+
+	
+	List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
+
+	
+	*pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex)
+{
+	PVRSRV_DEVICE_NODE	*psDeviceNode;
+	SYS_DATA			*psSysData;
+	PVRSRV_ERROR		eError;
+
+	PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice"));
+
+	SysAcquireData(&psSysData);
+
+	
+	psDeviceNode = (PVRSRV_DEVICE_NODE*)
+					 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+													&MatchDeviceKM_AnyVaCb,
+													ui32DevIndex,
+													IMG_TRUE);
+	if(!psDeviceNode)
+	{
+		
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present"));
+		return PVRSRV_ERROR_INIT_FAILURE;
+	}
+	PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
+
+	
+
+	eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call"));
+		return eError;
+	}
+
+	
+	if(psDeviceNode->pfnInitDevice != IMG_NULL)
+	{
+		eError = psDeviceNode->pfnInitDevice(psDeviceNode);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call"));
+			return eError;
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVRSRV_ERROR eError;
+	eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+										 PVRSRV_DEV_POWER_STATE_DEFAULT,
+										 KERNEL_ID, IMG_FALSE);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
+	}
+	return eError;
+}
+
+static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVRSRV_ERROR eError;
+	eError = PVRSRVDevInitCompatCheck(psDeviceNode);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
+	}
+	return eError;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful)
+{
+	SYS_DATA		*psSysData;
+	PVRSRV_ERROR		eError;
+
+	PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
+
+	SysAcquireData(&psSysData);
+
+	if (bInitSuccessful)
+	{
+		eError = SysFinalise();
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError));
+			return eError;
+		}
+
+		
+		eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
+														&PVRSRVFinaliseSystem_SetPowerState_AnyCb);
+		if (eError != PVRSRV_OK)
+		{
+			return eError;
+		}
+
+		
+		eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
+													&PVRSRVFinaliseSystem_CompatCheck_AnyCb);
+		if (eError != PVRSRV_OK)
+		{
+			return eError;
+		}
+	}
+
+	
+
+
+
+#if !defined(__QNXNTO__)
+	PDUMPENDINITPHASE();
+#endif
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	
+	if (psDeviceNode->pfnInitDeviceCompatCheck)
+		return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode);
+	else
+		return PVRSRV_OK;
+}
+
+static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+	PVRSRV_DEVICE_TYPE eDeviceType;
+	IMG_UINT32 ui32DevIndex;
+
+	eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
+	ui32DevIndex = va_arg(va, IMG_UINT32);
+
+	if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
+		psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
+		(eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
+		 psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
+	{
+		return psDeviceNode;
+	}
+	else
+	{
+		return IMG_NULL;
+	}
+}
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32			ui32DevIndex,
+													 PVRSRV_DEVICE_TYPE	eDeviceType,
+													 IMG_HANDLE			*phDevCookie)
+{
+	PVRSRV_DEVICE_NODE	*psDeviceNode;
+	SYS_DATA			*psSysData;
+
+	PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
+
+	SysAcquireData(&psSysData);
+
+	
+	psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+												&PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
+												eDeviceType,
+												ui32DevIndex);
+
+
+	if (!psDeviceNode)
+	{
+		
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
+		return PVRSRV_ERROR_INIT_FAILURE;
+	}
+
+	PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
+
+	
+	if (phDevCookie)
+	{
+		*phDevCookie = (IMG_HANDLE)psDeviceNode;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex)
+{
+	PVRSRV_DEVICE_NODE	*psDeviceNode;
+	SYS_DATA			*psSysData;
+	PVRSRV_ERROR		eError;
+
+	SysAcquireData(&psSysData);
+
+	psDeviceNode = (PVRSRV_DEVICE_NODE*)
+					 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+													&MatchDeviceKM_AnyVaCb,
+													ui32DevIndex,
+													IMG_TRUE);
+
+	if (!psDeviceNode)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex));
+		return PVRSRV_ERROR_DEVICEID_NOT_FOUND;
+	}
+
+	
+
+	eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex,
+										 PVRSRV_DEV_POWER_STATE_OFF,
+										 KERNEL_ID,
+										 IMG_FALSE);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call"));
+		return eError;
+	}
+
+	
+
+	eError = ResManFreeResByCriteria(psDeviceNode->hResManContext,
+									 RESMAN_CRITERIA_RESTYPE,
+									 RESMAN_TYPE_DEVICEMEM_ALLOCATION,
+									 IMG_NULL, 0);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call"));
+		return eError;
+	}
+
+	
+
+	if(psDeviceNode->pfnDeInitDevice != IMG_NULL)
+	{
+		eError = psDeviceNode->pfnDeInitDevice(psDeviceNode);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call"));
+			return eError;
+		}
+	}
+
+	
+
+	PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE);
+	psDeviceNode->hResManContext = IMG_NULL;
+
+	
+	List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
+
+	
+	(IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
+	OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
+	
+
+	return (PVRSRV_OK);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32*	pui32LinMemAddr,
+										  IMG_UINT32			ui32Value,
+										  IMG_UINT32			ui32Mask,
+										  IMG_UINT32			ui32Timeoutus,
+										  IMG_UINT32			ui32PollPeriodus,
+										  IMG_BOOL				bAllowPreemption)
+{
+#if defined (EMULATOR)
+	{
+		PVR_UNREFERENCED_PARAMETER(bAllowPreemption);
+		#if !defined(__linux__)
+		PVR_UNREFERENCED_PARAMETER(ui32PollPeriodus);
+		#endif	
+		
+		
+		
+		do
+		{
+			if((*pui32LinMemAddr & ui32Mask) == ui32Value)
+			{
+				return PVRSRV_OK;
+			}
+
+			#if defined(__linux__)
+			OSWaitus(ui32PollPeriodus);
+			#else
+			OSReleaseThreadQuanta();
+			#endif	
+
+		} while (ui32Timeoutus); 
+	}
+#else
+	{
+		IMG_UINT32	ui32ActualValue = 0xFFFFFFFFU; 
+
+		if (bAllowPreemption)
+		{
+			PVR_ASSERT(ui32PollPeriodus >= 1000);
+		}
+
+		 
+		LOOP_UNTIL_TIMEOUT(ui32Timeoutus)
+		{
+			ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
+			if(ui32ActualValue == ui32Value)
+			{
+				return PVRSRV_OK;
+			}
+			
+			if (bAllowPreemption)
+			{
+				OSSleepms(ui32PollPeriodus / 1000);
+			}
+			else
+			{
+				OSWaitus(ui32PollPeriodus);
+			}
+		} END_LOOP_UNTIL_TIMEOUT();
+	
+		PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).",
+				ui32Value, ui32ActualValue, ui32Mask));
+	}
+#endif 
+
+	return PVRSRV_ERROR_TIMEOUT;
+}
+
+
+static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+	IMG_CHAR **ppszStr;
+	IMG_UINT32 *pui32StrLen;
+	IMG_UINT32 ui32Mode;
+	PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *);
+
+	ppszStr = va_arg(va, IMG_CHAR**);
+	pui32StrLen = va_arg(va, IMG_UINT32*);
+	ui32Mode = va_arg(va, IMG_UINT32);
+
+	
+	switch(ui32Mode)
+	{
+		case PVRSRV_MISC_INFO_MEMSTATS_PRESENT:
+			pfnGetStats = &RA_GetStats;
+			break;
+		case PVRSRV_MISC_INFO_FREEMEM_PRESENT:
+			pfnGetStats = &RA_GetStatsFreeMem;
+			break;
+		default:
+			return;
+	}
+
+	if(psBMHeap->pImportArena)
+	{
+		pfnGetStats(psBMHeap->pImportArena,
+					ppszStr,
+					pui32StrLen);
+	}
+
+	if(psBMHeap->pVMArena)
+	{
+		pfnGetStats(psBMHeap->pVMArena,
+					ppszStr,
+					pui32StrLen);
+	}
+}
+
+static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va)
+{
+
+	IMG_UINT32 *pui32StrLen;
+	IMG_INT32 *pi32Count;
+	IMG_CHAR **ppszStr;
+	IMG_UINT32 ui32Mode;
+
+	pui32StrLen = va_arg(va, IMG_UINT32*);
+	pi32Count = va_arg(va, IMG_INT32*);
+	ppszStr = va_arg(va, IMG_CHAR**);
+	ui32Mode = va_arg(va, IMG_UINT32);
+
+	CHECK_SPACE(*pui32StrLen);
+	*pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n",
+							(IMG_HANDLE)psBMContext);
+	UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
+
+	List_BM_HEAP_ForEach_va(psBMContext->psBMHeap,
+							&PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
+							ppszStr,
+							pui32StrLen,
+							ui32Mode);
+	return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+	IMG_UINT32 *pui32StrLen;
+	IMG_INT32 *pi32Count;
+	IMG_CHAR **ppszStr;
+	IMG_UINT32 ui32Mode;
+
+	pui32StrLen = va_arg(va, IMG_UINT32*);
+	pi32Count = va_arg(va, IMG_INT32*);
+	ppszStr = va_arg(va, IMG_CHAR**);
+	ui32Mode = va_arg(va, IMG_UINT32);
+
+	CHECK_SPACE(*pui32StrLen);
+	*pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType);
+	UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
+
+	
+	if(psDeviceNode->sDevMemoryInfo.pBMKernelContext)
+	{
+		CHECK_SPACE(*pui32StrLen);
+		*pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n");
+		UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
+
+		List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap,
+								&PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
+								ppszStr,
+								pui32StrLen,
+								ui32Mode);
+	}
+
+	
+	return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext,
+												&PVRSRVGetMiscInfoKM_BMContext_AnyVaCb,
+							 					pui32StrLen,
+												pi32Count,
+												ppszStr,
+												ui32Mode);
+}
+
+
+IMG_EXPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO_KM *psMiscInfo)
+#else
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo)
+#endif
+{
+	SYS_DATA *psSysData;
+
+	if(!psMiscInfo)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psMiscInfo->ui32StatePresent = 0;
+
+	
+	if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT
+										|PVRSRV_MISC_INFO_CLOCKGATE_PRESENT
+										|PVRSRV_MISC_INFO_MEMSTATS_PRESENT
+										|PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT
+										|PVRSRV_MISC_INFO_DDKVERSION_PRESENT
+										|PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT
+										|PVRSRV_MISC_INFO_RESET_PRESENT
+										|PVRSRV_MISC_INFO_FREEMEM_PRESENT))
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	SysAcquireData(&psSysData);
+
+	
+	if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) &&
+		(psSysData->pvSOCTimerRegisterKM != IMG_NULL))
+	{
+		psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT;
+		psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM;
+		psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle;
+	}
+	else
+	{
+		psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL;
+		psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL;
+	}
+
+	
+	if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) &&
+		(psSysData->pvSOCClockGateRegsBase != IMG_NULL))
+	{
+		psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT;
+		psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase;
+		psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize;
+	}
+
+	
+	if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) &&
+		(psMiscInfo->pszMemoryStr != IMG_NULL))
+	{
+		RA_ARENA			**ppArena;
+		IMG_CHAR			*pszStr;
+		IMG_UINT32			ui32StrLen;
+		IMG_INT32			i32Count;
+
+		pszStr = psMiscInfo->pszMemoryStr;
+		ui32StrLen = psMiscInfo->ui32MemoryStrLen;
+
+		psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT;
+
+		
+		ppArena = &psSysData->apsLocalDevMemArena[0];
+		while(*ppArena)
+		{
+			CHECK_SPACE(ui32StrLen);
+			i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n");
+			UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+			RA_GetStats(*ppArena,
+							&pszStr,
+							&ui32StrLen);
+			
+			ppArena++;
+		}
+
+		
+		
+		List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
+													&PVRSRVGetMiscInfoKM_Device_AnyVaCb,
+													&ui32StrLen,
+													&i32Count,
+													&pszStr,
+													PVRSRV_MISC_INFO_MEMSTATS_PRESENT);
+
+		
+		i32Count = OSSNPrintf(pszStr, 100, "\n");
+		UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+	}
+
+	
+	if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0)
+		&& psMiscInfo->pszMemoryStr)
+	{
+		IMG_CHAR			*pszStr;
+		IMG_UINT32			ui32StrLen;
+		IMG_INT32			i32Count;
+		
+		pszStr = psMiscInfo->pszMemoryStr;
+		ui32StrLen = psMiscInfo->ui32MemoryStrLen;
+  
+		psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT;
+
+		
+		List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
+													&PVRSRVGetMiscInfoKM_Device_AnyVaCb,
+													&ui32StrLen,
+													&i32Count,
+													&pszStr,
+													PVRSRV_MISC_INFO_FREEMEM_PRESENT);
+		
+		i32Count = OSSNPrintf(pszStr, 100, "\n");
+		UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+	}
+
+	if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) &&
+		(psSysData->psGlobalEventObject != IMG_NULL))
+	{
+		psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT;
+		psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject;
+	}
+
+	
+
+	if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL)
+		&& ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL)
+		&& (psMiscInfo->pszMemoryStr != IMG_NULL))
+	{
+		IMG_CHAR	*pszStr;
+		IMG_UINT32	ui32StrLen;
+		IMG_UINT32 	ui32LenStrPerNum = 12; 
+		IMG_INT32	i32Count;
+		IMG_INT i;
+		psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT;
+
+		
+		psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ;
+		psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN;
+		psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BRANCH;
+		psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD;
+
+		pszStr = psMiscInfo->pszMemoryStr;
+		ui32StrLen = psMiscInfo->ui32MemoryStrLen;
+
+		for (i=0; i<4; i++)
+		{
+			if (ui32StrLen < ui32LenStrPerNum)
+			{
+				return PVRSRV_ERROR_INVALID_PARAMS;
+			}
+
+			i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]);
+			UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+			if (i != 3)
+			{
+				i32Count = OSSNPrintf(pszStr, 2, ".");
+				UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+			}
+		}
+	}
+
+	if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL)
+	{
+		psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT;
+
+		if(psMiscInfo->sCacheOpCtl.bDeferOp)
+		{
+			
+			psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType;
+		}
+		else
+		{
+#if defined (SUPPORT_SID_INTERFACE)
+			PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = psMiscInfo->sCacheOpCtl.psKernelMemInfo;
+
+			if(!psMiscInfo->sCacheOpCtl.psKernelMemInfo)
+#else
+			PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+			PVRSRV_PER_PROCESS_DATA *psPerProc;
+
+			if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo)
+#endif
+			{
+				PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
+						 "Ignoring non-deferred cache op with no meminfo"));
+				return PVRSRV_ERROR_INVALID_PARAMS;
+			}
+
+			if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE)
+			{
+				PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
+						 "Deferred cache op is pending. It is unlikely you want "
+						 "to combine deferred cache ops with immediate ones"));
+			}
+
+#if defined (SUPPORT_SID_INTERFACE)
+			PVR_DBG_BREAK
+#else
+			
+			psPerProc = PVRSRVFindPerProcessData();
+
+			if(PVRSRVLookupHandle(psPerProc->psHandleBase,
+								  (IMG_PVOID *)&psKernelMemInfo,
+								  psMiscInfo->sCacheOpCtl.u.psKernelMemInfo,
+								  PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
+						 "Can't find kernel meminfo"));
+				return PVRSRV_ERROR_INVALID_PARAMS;
+			}
+#endif
+
+			if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+			{
+				if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
+										   psMiscInfo->sCacheOpCtl.pvBaseVAddr,
+										   psMiscInfo->sCacheOpCtl.ui32Length))
+				{
+					return PVRSRV_ERROR_CACHEOP_FAILED;
+				}
+			}
+			else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+			{
+				if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
+										   psMiscInfo->sCacheOpCtl.pvBaseVAddr,
+										   psMiscInfo->sCacheOpCtl.ui32Length))
+				{
+					return PVRSRV_ERROR_CACHEOP_FAILED;
+				}
+			}
+		}
+	}
+
+#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
+	if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL)
+	{
+		PVR_LOG(("User requested OS reset"));
+		OSPanic();
+	}
+#endif 
+
+	return PVRSRV_OK;
+}
+
+
+IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	SYS_DATA			*psSysData;
+	IMG_BOOL			bStatus = IMG_FALSE;
+	IMG_UINT32			ui32InterruptSource;
+
+	if(!psDeviceNode)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n"));
+		goto out;
+	}
+	psSysData = psDeviceNode->psSysData;
+
+	
+	ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode);
+	if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
+	{
+		if(psDeviceNode->pfnDeviceISR != IMG_NULL)
+		{
+			bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData);
+		}
+
+		SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit);
+	}
+
+out:
+	return bStatus;
+}
+
+static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+
+	IMG_BOOL *pbStatus;
+	IMG_UINT32 *pui32InterruptSource;
+	IMG_UINT32 *pui32ClearInterrupts;
+
+	pbStatus = va_arg(va, IMG_BOOL*);
+	pui32InterruptSource = va_arg(va, IMG_UINT32*);
+	pui32ClearInterrupts = va_arg(va, IMG_UINT32*);
+
+
+	if(psDeviceNode->pfnDeviceISR != IMG_NULL)
+	{
+		if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
+		{
+			if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData))
+			{
+				
+				*pbStatus = IMG_TRUE;
+			}
+			
+			*pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit;
+		}
+	}
+}
+
+IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData)
+{
+	SYS_DATA			*psSysData = pvSysData;
+	IMG_BOOL			bStatus = IMG_FALSE;
+	IMG_UINT32			ui32InterruptSource;
+	IMG_UINT32			ui32ClearInterrupts = 0;
+	if(!psSysData)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n"));
+	}
+	else
+	{
+		
+		ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL);
+
+		
+		if(ui32InterruptSource)
+		{
+			
+			List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+												&PVRSRVSystemLISR_ForEachVaCb,
+												&bStatus,
+												&ui32InterruptSource,
+												&ui32ClearInterrupts);
+
+			SysClearInterrupts(psSysData, ui32ClearInterrupts);
+		}
+	}
+	return bStatus;
+}
+
+
+static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	if(psDeviceNode->pfnDeviceMISR != IMG_NULL)
+	{
+		(*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData);
+	}
+}
+
+IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData)
+{
+	SYS_DATA			*psSysData = pvSysData;
+	if(!psSysData)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n"));
+		return;
+	}
+
+	
+	List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
+									&PVRSRVMISR_ForEachCb);
+
+	
+	if (PVRSRVProcessQueues(IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
+	{
+		PVRSRVProcessQueues(IMG_FALSE);
+	}
+
+	
+	if (psSysData->psGlobalEventObject)
+	{
+		IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
+		if(hOSEventKM)
+		{
+			OSEventObjectSignalKM(hOSEventKM);
+		}
+	}
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32	ui32PID, IMG_UINT32 ui32Flags)
+{
+	return PVRSRVPerProcessDataConnect(ui32PID, ui32Flags);
+}
+
+
+IMG_EXPORT
+IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32	ui32PID)
+{
+	PVRSRVPerProcessDataDisconnect(ui32PID);
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
+														IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
+{
+	IMG_SIZE_T         uiBytesSaved = 0;
+	IMG_PVOID          pvLocalMemCPUVAddr;
+	RA_SEGMENT_DETAILS sSegDetails;
+
+	if (hArena == IMG_NULL)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	sSegDetails.uiSize = 0;
+	sSegDetails.sCpuPhyAddr.uiAddr = 0;
+	sSegDetails.hSegment = 0;
+
+	
+	while (RA_GetNextLiveSegment(hArena, &sSegDetails))
+	{
+		if (pbyBuffer == IMG_NULL)
+		{
+			
+			uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
+		}
+		else
+		{
+			if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
+			{
+				return (PVRSRV_ERROR_OUT_OF_MEMORY);
+			}
+
+			PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize));
+
+			
+			pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
+									sSegDetails.uiSize,
+									PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+									IMG_NULL);
+			if (pvLocalMemCPUVAddr == IMG_NULL)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
+				return (PVRSRV_ERROR_OUT_OF_MEMORY);
+			}
+
+			if (bSave)
+			{
+				
+				OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
+				pbyBuffer += sizeof(sSegDetails.uiSize);
+
+				OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
+				pbyBuffer += sSegDetails.uiSize;
+			}
+			else
+			{
+				IMG_UINT32 uiSize;
+				
+				OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));
+
+				if (uiSize != sSegDetails.uiSize)
+				{
+					PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
+				}
+				else
+				{
+					pbyBuffer += sizeof(sSegDetails.uiSize);
+
+					OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
+					pbyBuffer += sSegDetails.uiSize;
+				}
+			}
+
+
+			uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
+
+			OSUnMapPhysToLin(pvLocalMemCPUVAddr,
+		                     sSegDetails.uiSize,
+		                     PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+		                     IMG_NULL);
+		}
+	}
+
+	if (pbyBuffer == IMG_NULL)
+	{
+		*puiBufSize = uiBytesSaved;
+	}
+
+	return (PVRSRV_OK);
+}
+
+
+IMG_EXPORT
+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
+{ 
+ 
+#include "pvrsrv_errors.h"
+}
+
+static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
+	{
+		
+		(*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
+	}
+}
+
+IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID)
+{
+	SYS_DATA				*psSysData;
+	SysAcquireData(&psSysData);
+
+	
+	List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
+									&PVRSRVCommandCompleteCallbacks_ForEachCb);
+}
+
+IMG_EXPORT
+IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID)
+{
+	PVRSRVScheduleDeviceCallbacks();
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/queue.c b/drivers/staging/cdv/pvr/services4/srvkm/common/queue.c
new file mode 100644
index 0000000..5a1e9b4
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/queue.c
@@ -0,0 +1,1079 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+
+#include "lists.h"
+#include "ttrace.h"
+
+#define DC_NUM_COMMANDS_PER_TYPE		1
+
+typedef struct _DEVICE_COMMAND_DATA_
+{
+	PFN_CMD_PROC			pfnCmdProc;
+	PCOMMAND_COMPLETE_DATA	apsCmdCompleteData[DC_NUM_COMMANDS_PER_TYPE];
+	IMG_UINT32				ui32CCBOffset;
+} DEVICE_COMMAND_DATA;
+
+
+#if defined(__linux__) && defined(__KERNEL__)
+
+#include "proc.h"
+
+void ProcSeqShowQueue(struct seq_file *sfile,void* el)
+{
+	PVRSRV_QUEUE_INFO *psQueue = (PVRSRV_QUEUE_INFO*)el;
+	IMG_INT cmds = 0;
+	IMG_SIZE_T ui32ReadOffset;
+	IMG_SIZE_T ui32WriteOffset;
+	PVRSRV_COMMAND *psCmd;
+
+	if(el == PVR_PROC_SEQ_START_TOKEN)
+	{
+		seq_printf( sfile,
+					"Command Queues\n"
+					"Queue    CmdPtr      Pid Command Size DevInd  DSC  SSC  #Data ...\n");
+		return;
+	}
+
+	ui32ReadOffset = psQueue->ui32ReadOffset;
+	ui32WriteOffset = psQueue->ui32WriteOffset;
+
+	while (ui32ReadOffset != ui32WriteOffset)
+	{
+		psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
+
+		seq_printf(sfile, "%x %x  %5u  %6u  %3u  %5u   %2u   %2u    %3u  \n",
+							(IMG_UINTPTR_T)psQueue,
+							(IMG_UINTPTR_T)psCmd,
+					 		psCmd->ui32ProcessID,
+							psCmd->CommandType,
+							psCmd->uCmdSize,
+							psCmd->ui32DevIndex,
+							psCmd->ui32DstSyncCount,
+							psCmd->ui32SrcSyncCount,
+							psCmd->uDataSize);
+		{
+			IMG_UINT32 i;
+			for (i = 0; i < psCmd->ui32SrcSyncCount; i++)
+			{
+				PVRSRV_SYNC_DATA *psSyncData = psCmd->psSrcSync[i].psKernelSyncInfoKM->psSyncData;
+				seq_printf(sfile, "  Sync %u: ROP/ROC: 0x%x/0x%x WOP/WOC: 0x%x/0x%x ROC-VA: 0x%x WOC-VA: 0x%x\n",
+									i,
+									psCmd->psSrcSync[i].ui32ReadOpsPending,
+									psSyncData->ui32ReadOpsComplete,
+									psCmd->psSrcSync[i].ui32WriteOpsPending,
+									psSyncData->ui32WriteOpsComplete,
+									psCmd->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
+									psCmd->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr);
+			}
+		}
+
+		
+		ui32ReadOffset += psCmd->uCmdSize;
+		ui32ReadOffset &= psQueue->ui32QueueSize - 1;
+		cmds++;
+	}
+
+	if (cmds == 0)
+	{
+		seq_printf(sfile, "%x <empty>\n", (IMG_UINTPTR_T)psQueue);
+	}
+}
+
+void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off)
+{
+	PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
+	SYS_DATA *psSysData;
+
+	PVR_UNREFERENCED_PARAMETER(sfile);
+
+	if(!off)
+	{
+		return PVR_PROC_SEQ_START_TOKEN;
+	}
+
+
+	psSysData = SysAcquireDataNoCheck();
+	if (psSysData != IMG_NULL)
+	{
+		for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM);
+	}
+
+	return psQueue;
+}
+#endif 
+
+#define GET_SPACE_IN_CMDQ(psQueue)										\
+	((((psQueue)->ui32ReadOffset - (psQueue)->ui32WriteOffset)				\
+	+ ((psQueue)->ui32QueueSize - 1)) & ((psQueue)->ui32QueueSize - 1))
+
+#define UPDATE_QUEUE_WOFF(psQueue, ui32Size)							\
+	(psQueue)->ui32WriteOffset = ((psQueue)->ui32WriteOffset + (ui32Size))	\
+	& ((psQueue)->ui32QueueSize - 1);
+
+#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending)					\
+	((ui32OpsComplete) >= (ui32OpsPending))
+
+
+static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData,
+									 IMG_UINT32				i,
+									 IMG_BOOL				bIsSrc)
+{
+	PVRSRV_SYNC_OBJECT	*psSyncObject;
+
+	psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync;
+
+	if (psCmdCompleteData->bInUse)
+	{
+		PVR_LOG(("\t%s %u: ROC DevVAddr:0x%X ROP:0x%x ROC:0x%x, WOC DevVAddr:0x%X WOP:0x%x WOC:0x%x",
+				bIsSrc ? "SRC" : "DEST", i,
+				psSyncObject[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
+				psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsPending,
+				psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete,
+				psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+				psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending,
+				psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete))
+	}
+	else
+	{
+		PVR_LOG(("\t%s %u: (Not in use)", bIsSrc ? "SRC" : "DEST", i))
+	}
+}
+
+
+static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
+	{
+		IMG_UINT32				ui32CmdCounter, ui32SyncCounter;
+		SYS_DATA				*psSysData;
+		DEVICE_COMMAND_DATA		*psDeviceCommandData;
+		PCOMMAND_COMPLETE_DATA	psCmdCompleteData;
+
+		SysAcquireData(&psSysData);
+
+		psDeviceCommandData = psSysData->apsDeviceCommandData[psDeviceNode->sDevId.ui32DeviceIndex];
+
+		if (psDeviceCommandData != IMG_NULL)
+		{
+			for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
+			{
+				psCmdCompleteData = psDeviceCommandData[DC_FLIP_COMMAND].apsCmdCompleteData[ui32CmdCounter];
+
+				PVR_LOG(("Flip Command Complete Data %u for display device %u:",
+						ui32CmdCounter, psDeviceNode->sDevId.ui32DeviceIndex))
+
+				for (ui32SyncCounter = 0;
+					 ui32SyncCounter < psCmdCompleteData->ui32SrcSyncCount;
+					 ui32SyncCounter++)
+				{
+					QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_TRUE);
+				}
+
+				for (ui32SyncCounter = 0;
+					 ui32SyncCounter < psCmdCompleteData->ui32DstSyncCount;
+					 ui32SyncCounter++)
+				{
+					QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_FALSE);
+				}
+			}
+		}
+		else
+		{
+			PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex))
+		}
+	}
+}
+
+
+IMG_VOID QueueDumpDebugInfo(IMG_VOID)
+{
+	SYS_DATA	*psSysData;
+	SysAcquireData(&psSysData);
+	List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, &QueueDumpDebugInfo_ForEachCb);
+}
+
+
+static IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value)
+{
+	IMG_SIZE_T ui32Temp, ui32Result = 1;
+
+	if(!ui32Value)
+		return 0;
+
+	ui32Temp = ui32Value - 1;
+	while(ui32Temp)
+	{
+		ui32Result <<= 1;
+		ui32Temp >>= 1;
+	}
+
+	return ui32Result;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
+													 PVRSRV_QUEUE_INFO **ppsQueueInfo)
+{
+	PVRSRV_QUEUE_INFO	*psQueueInfo;
+	IMG_SIZE_T			ui32Power2QueueSize = NearestPower2(ui32QueueSize);
+	SYS_DATA			*psSysData;
+	PVRSRV_ERROR		eError;
+	IMG_HANDLE			hMemBlock;
+
+	SysAcquireData(&psSysData);
+
+	
+	eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+					 sizeof(PVRSRV_QUEUE_INFO),
+					 (IMG_VOID **)&psQueueInfo, &hMemBlock,
+					 "Queue Info");
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct"));
+		goto ErrorExit;
+	}
+	OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO));
+
+	psQueueInfo->hMemBlock[0] = hMemBlock;
+	psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
+
+	
+	eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+					 ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE,
+					 &psQueueInfo->pvLinQueueKM, &hMemBlock,
+					 "Command Queue");
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer"));
+		goto ErrorExit;
+	}
+
+	psQueueInfo->hMemBlock[1] = hMemBlock;
+	psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
+
+	
+	PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0);
+	PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0);
+
+	psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
+
+	
+	if (psSysData->psQueueList == IMG_NULL)
+	{
+		eError = OSCreateResource(&psSysData->sQProcessResource);
+		if (eError != PVRSRV_OK)
+		{
+			goto ErrorExit;
+		}
+	}
+
+	
+	eError = OSLockResource(&psSysData->sQProcessResource,
+							KERNEL_ID);
+	if (eError != PVRSRV_OK)
+	{
+		goto ErrorExit;
+	}
+
+	psQueueInfo->psNextKM = psSysData->psQueueList;
+	psSysData->psQueueList = psQueueInfo;
+
+	eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
+	if (eError != PVRSRV_OK)
+	{
+		goto ErrorExit;
+	}
+
+	*ppsQueueInfo = psQueueInfo;
+
+	return PVRSRV_OK;
+
+ErrorExit:
+
+	if(psQueueInfo)
+	{
+		if(psQueueInfo->pvLinQueueKM)
+		{
+			OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+						psQueueInfo->ui32QueueSize,
+						psQueueInfo->pvLinQueueKM,
+						psQueueInfo->hMemBlock[1]);
+			psQueueInfo->pvLinQueueKM = IMG_NULL;
+		}
+
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+					sizeof(PVRSRV_QUEUE_INFO),
+					psQueueInfo,
+					psQueueInfo->hMemBlock[0]);
+		
+	}
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo)
+{
+	PVRSRV_QUEUE_INFO	*psQueue;
+	SYS_DATA			*psSysData;
+	PVRSRV_ERROR		eError;
+	IMG_BOOL			bTimeout = IMG_TRUE;
+
+	SysAcquireData(&psSysData);
+
+	psQueue = psSysData->psQueueList;
+
+	 
+	LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+	{
+		if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
+		{
+			bTimeout = IMG_FALSE;
+			break;
+		}
+		OSSleepms(1);
+	} END_LOOP_UNTIL_TIMEOUT();
+
+	if (bTimeout)
+	{
+		
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue"));
+		eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE;
+		goto ErrorExit;
+	}
+
+	
+	eError = OSLockResource(&psSysData->sQProcessResource,
+								KERNEL_ID);
+	if (eError != PVRSRV_OK)
+	{
+		goto ErrorExit;
+	}
+
+	if(psQueue == psQueueInfo)
+	{
+		psSysData->psQueueList = psQueueInfo->psNextKM;
+
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+					NearestPower2(psQueueInfo->ui32QueueSize) + PVRSRV_MAX_CMD_SIZE,
+					psQueueInfo->pvLinQueueKM,
+					psQueueInfo->hMemBlock[1]);
+		psQueueInfo->pvLinQueueKM = IMG_NULL;
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+					sizeof(PVRSRV_QUEUE_INFO),
+					psQueueInfo,
+					psQueueInfo->hMemBlock[0]);
+		 
+		psQueueInfo = IMG_NULL; 
+	}
+	else
+	{
+		while(psQueue)
+		{
+			if(psQueue->psNextKM == psQueueInfo)
+			{
+				psQueue->psNextKM = psQueueInfo->psNextKM;
+
+				OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+							psQueueInfo->ui32QueueSize,
+							psQueueInfo->pvLinQueueKM,
+							psQueueInfo->hMemBlock[1]);
+				psQueueInfo->pvLinQueueKM = IMG_NULL;
+				OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+							sizeof(PVRSRV_QUEUE_INFO),
+							psQueueInfo,
+							psQueueInfo->hMemBlock[0]);
+				 
+				psQueueInfo = IMG_NULL; 
+				break;
+			}
+			psQueue = psQueue->psNextKM;
+		}
+
+		if(!psQueue)
+		{
+			eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
+			if (eError != PVRSRV_OK)
+			{
+				goto ErrorExit;
+			}
+			eError = PVRSRV_ERROR_INVALID_PARAMS;
+			goto ErrorExit;
+		}
+	}
+
+	
+	eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
+	if (eError != PVRSRV_OK)
+	{
+		goto ErrorExit;
+	}
+
+	
+	if (psSysData->psQueueList == IMG_NULL)
+	{
+		eError = OSDestroyResource(&psSysData->sQProcessResource);
+		if (eError != PVRSRV_OK)
+		{
+			goto ErrorExit;
+		}
+	}
+
+ErrorExit:
+
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
+												IMG_SIZE_T ui32ParamSize,
+												IMG_VOID **ppvSpace)
+{
+	IMG_BOOL bTimeout = IMG_TRUE;
+
+	
+	ui32ParamSize =  (ui32ParamSize+3) & 0xFFFFFFFC;
+
+	if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE)
+	{
+		PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE));
+		return PVRSRV_ERROR_CMD_TOO_BIG;
+	}
+
+	 
+	LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+	{
+		if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize)
+		{
+			bTimeout = IMG_FALSE;
+			break;
+		}
+		OSSleepms(1);
+	} END_LOOP_UNTIL_TIMEOUT();
+
+	if (bTimeout == IMG_TRUE)
+	{
+		*ppvSpace = IMG_NULL;
+
+		return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE;
+	}
+	else
+	{
+		*ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset);
+	}
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO	*psQueue,
+												PVRSRV_COMMAND		**ppsCommand,
+												IMG_UINT32			ui32DevIndex,
+												IMG_UINT16			CommandType,
+												IMG_UINT32			ui32DstSyncCount,
+												PVRSRV_KERNEL_SYNC_INFO	*apsDstSync[],
+												IMG_UINT32			ui32SrcSyncCount,
+												PVRSRV_KERNEL_SYNC_INFO	*apsSrcSync[],
+												IMG_SIZE_T			ui32DataByteSize )
+{
+	PVRSRV_ERROR 	eError;
+	PVRSRV_COMMAND	*psCommand;
+	IMG_SIZE_T		ui32CommandSize;
+	IMG_UINT32		i;
+
+	
+	ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL;
+
+	
+	ui32CommandSize = sizeof(PVRSRV_COMMAND)
+					+ ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT))
+					+ ui32DataByteSize;
+
+	
+	eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand);
+	if(eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	psCommand->ui32ProcessID	= OSGetCurrentProcessIDKM();
+
+	
+	psCommand->uCmdSize		= ui32CommandSize; 
+	psCommand->ui32DevIndex 	= ui32DevIndex;
+	psCommand->CommandType 		= CommandType;
+	psCommand->ui32DstSyncCount	= ui32DstSyncCount;
+	psCommand->ui32SrcSyncCount	= ui32SrcSyncCount;
+	
+	
+	psCommand->psDstSync		= (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND));
+
+
+	psCommand->psSrcSync		= (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync)
+								+ (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+
+	psCommand->pvData			= (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync)
+								+ (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+	psCommand->uDataSize		= ui32DataByteSize;
+
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_START, QUEUE_TOKEN_INSERTKM);
+	PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_NONE,
+			QUEUE_TOKEN_COMMAND_TYPE, CommandType);
+
+	
+	for (i=0; i<ui32DstSyncCount; i++)
+	{
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
+						apsDstSync[i], PVRSRV_SYNCOP_SAMPLE);
+
+		psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i];
+		psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
+		psCommand->psDstSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
+
+		PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+				i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
+				psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+				psCommand->psDstSync[i].ui32ReadOpsPending,
+				psCommand->psDstSync[i].ui32WriteOpsPending));
+	}
+
+	
+	for (i=0; i<ui32SrcSyncCount; i++)
+	{
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
+						apsSrcSync[i], PVRSRV_SYNCOP_SAMPLE);
+
+		psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i];
+		psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
+		psCommand->psSrcSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
+
+		PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+				i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
+				psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+				psCommand->psSrcSync[i].ui32ReadOpsPending,
+				psCommand->psSrcSync[i].ui32WriteOpsPending));
+	}
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_END, QUEUE_TOKEN_INSERTKM);
+
+	
+	*ppsCommand = psCommand;
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
+												PVRSRV_COMMAND *psCommand)
+{
+	
+	
+	
+	if (psCommand->ui32DstSyncCount > 0)
+	{
+		psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
+									+ psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND));
+	}
+
+	if (psCommand->ui32SrcSyncCount > 0)
+	{
+		psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
+									+ psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
+									+ (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+	}
+
+	psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
+									+ psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
+									+ (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))
+									+ (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+
+	
+	UPDATE_QUEUE_WOFF(psQueue, psCommand->uCmdSize);
+
+	return PVRSRV_OK;
+}
+
+
+
+static
+PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA			*psSysData,
+								  PVRSRV_COMMAND	*psCommand,
+								  IMG_BOOL			bFlush)
+{
+	PVRSRV_SYNC_OBJECT		*psWalkerObj;
+	PVRSRV_SYNC_OBJECT		*psEndObj;
+	IMG_UINT32				i;
+	COMMAND_COMPLETE_DATA	*psCmdCompleteData;
+	PVRSRV_ERROR			eError = PVRSRV_OK;
+	IMG_UINT32				ui32WriteOpsComplete;
+	IMG_UINT32				ui32ReadOpsComplete;
+	DEVICE_COMMAND_DATA		*psDeviceCommandData;
+	IMG_UINT32				ui32CCBOffset;
+
+	
+	psWalkerObj = psCommand->psDstSync;
+	psEndObj = psWalkerObj + psCommand->ui32DstSyncCount;
+	while (psWalkerObj < psEndObj)
+	{
+		PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
+
+		ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
+		ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
+		
+		if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
+		||	(ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
+		{
+			if (!bFlush ||
+				!SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
+				!SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
+			{
+				return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+			}
+		}
+
+		psWalkerObj++;
+	}
+
+	
+	psWalkerObj = psCommand->psSrcSync;
+	psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount;
+	while (psWalkerObj < psEndObj)
+	{
+		PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
+
+		ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
+		ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
+		
+		if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
+		|| (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
+		{
+			if (!bFlush &&
+				SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) &&
+				SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
+			{
+				PVR_DPF((PVR_DBG_WARNING,
+						"PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
+						(IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending));
+			}
+
+			if (!bFlush ||
+				!SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
+				!SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
+			{
+				return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+			}
+		}
+		psWalkerObj++;
+	}
+
+	
+	if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+					"PVRSRVProcessCommand: invalid DeviceType 0x%x",
+					psCommand->ui32DevIndex));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex];
+	ui32CCBOffset = psDeviceCommandData[psCommand->CommandType].ui32CCBOffset;
+	psCmdCompleteData = psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[ui32CCBOffset];
+	if (psCmdCompleteData->bInUse)
+	{
+		
+		return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+	}
+
+	
+	psCmdCompleteData->bInUse = IMG_TRUE;
+
+	
+	psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount;
+	for (i=0; i<psCommand->ui32DstSyncCount; i++)
+	{
+		psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
+
+		PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)",
+				i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
+				psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+				psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
+				psCmdCompleteData->psDstSync[i].ui32WriteOpsPending,
+				ui32CCBOffset));
+	}
+
+
+	
+	psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
+	for (i=0; i<psCommand->ui32SrcSyncCount; i++)
+	{
+		psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i];
+
+		PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)",
+				i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
+				psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+				psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
+				psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending,
+				ui32CCBOffset));
+	}
+
+	
+
+
+
+
+
+
+
+
+
+	if (psDeviceCommandData[psCommand->CommandType].pfnCmdProc((IMG_HANDLE)psCmdCompleteData,
+															   (IMG_UINT32)psCommand->uDataSize,
+															   psCommand->pvData) == IMG_FALSE)
+	{
+		
+
+
+		psCmdCompleteData->bInUse = IMG_FALSE;
+		eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
+	}
+	
+	
+	psDeviceCommandData[psCommand->CommandType].ui32CCBOffset = (ui32CCBOffset + 1) % DC_NUM_COMMANDS_PER_TYPE;
+
+	return eError;
+}
+
+
+static IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	if (psDeviceNode->bReProcessDeviceCommandComplete &&
+		psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
+	{
+		(*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
+	}
+}
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL	bFlush)
+{
+	PVRSRV_QUEUE_INFO 	*psQueue;
+	SYS_DATA			*psSysData;
+	PVRSRV_COMMAND 		*psCommand;
+	SysAcquireData(&psSysData);
+
+	
+
+	while (OSLockResource(&psSysData->sQProcessResource, ISR_ID) != PVRSRV_OK)
+	{
+		OSSleepms(1);
+	};
+	
+	psQueue = psSysData->psQueueList;
+
+	if(!psQueue)
+	{
+		PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands"));
+	}
+
+	if (bFlush)
+	{
+		PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS);
+	}
+
+	while (psQueue)
+	{
+		while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
+		{
+			psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);
+
+			if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK)
+			{
+				
+				UPDATE_QUEUE_ROFF(psQueue, psCommand->uCmdSize)
+				continue;
+			}
+
+			break;
+		}
+		psQueue = psQueue->psNextKM;
+	}
+
+	if (bFlush)
+	{
+		PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
+	}
+
+	
+	List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
+									&PVRSRVProcessQueues_ForEachCb);
+
+	OSUnlockResource(&psSysData->sQProcessResource, ISR_ID);
+
+	return PVRSRV_OK;
+}
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+IMG_INTERNAL
+IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE	hCmdCookie,
+										   IMG_BOOL		bScheduleMISR)
+{
+	COMMAND_COMPLETE_DATA	*psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
+	SYS_DATA				*psSysData;
+
+	SysAcquireData(&psSysData);
+
+	
+	psCmdCompleteData->bInUse = IMG_FALSE;
+
+	
+	PVRSRVScheduleDeviceCallbacks();
+
+	if(bScheduleMISR)
+	{
+		OSScheduleMISR(psSysData);
+	}
+}
+
+#endif 
+
+
+IMG_EXPORT
+IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE	hCmdCookie,
+								 IMG_BOOL	bScheduleMISR)
+{
+	IMG_UINT32				i;
+	COMMAND_COMPLETE_DATA	*psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
+	SYS_DATA				*psSysData;
+
+	SysAcquireData(&psSysData);
+
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_START,
+			QUEUE_TOKEN_COMMAND_COMPLETE);
+
+	
+	for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++)
+	{
+		psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
+
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST,
+					  psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM,
+					  PVRSRV_SYNCOP_COMPLETE);
+
+		PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+				i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
+				psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+				psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
+				psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
+	}
+
+	
+	for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++)
+	{
+		psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete++;
+
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC,
+					  psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM,
+					  PVRSRV_SYNCOP_COMPLETE);
+
+		PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+				i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
+				psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+				psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
+				psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
+	}
+
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_END,
+			QUEUE_TOKEN_COMMAND_COMPLETE);
+
+	
+	psCmdCompleteData->bInUse = IMG_FALSE;
+
+	
+	PVRSRVScheduleDeviceCallbacks();
+
+	if(bScheduleMISR)
+	{
+		OSScheduleMISR(psSysData);
+	}
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32		ui32DevIndex,
+										 PFN_CMD_PROC	*ppfnCmdProcList,
+										 IMG_UINT32		ui32MaxSyncsPerCmd[][2],
+										 IMG_UINT32		ui32CmdCount)
+{
+	SYS_DATA				*psSysData;
+	PVRSRV_ERROR			eError;
+	IMG_UINT32				ui32CmdCounter, ui32CmdTypeCounter;
+	IMG_SIZE_T				ui32AllocSize;
+	DEVICE_COMMAND_DATA		*psDeviceCommandData;
+	COMMAND_COMPLETE_DATA	*psCmdCompleteData;
+
+	
+	if(ui32DevIndex >= SYS_DEVICE_COUNT)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+					"PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x",
+					ui32DevIndex));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	SysAcquireData(&psSysData);
+
+	
+	ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
+	eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+						ui32AllocSize,
+						(IMG_VOID **)&psDeviceCommandData, IMG_NULL,
+						"Array of Pointers for Command Store");
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data"));
+		goto ErrorExit;
+	}
+
+	psSysData->apsDeviceCommandData[ui32DevIndex] = psDeviceCommandData;
+
+	for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
+	{
+		psDeviceCommandData[ui32CmdTypeCounter].pfnCmdProc = ppfnCmdProcList[ui32CmdTypeCounter];
+		psDeviceCommandData[ui32CmdTypeCounter].ui32CCBOffset = 0;
+		
+		for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
+		{
+			
+
+			ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA) 
+						  + ((ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]
+						  +	ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1])
+						  * sizeof(PVRSRV_SYNC_OBJECT));	 
+
+			eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+								ui32AllocSize,
+								(IMG_VOID **)&psCmdCompleteData,
+								IMG_NULL,
+								"Command Complete Data");
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d", ui32CmdTypeCounter));
+				goto ErrorExit;
+			}
+			
+			psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = psCmdCompleteData;
+			
+			
+			OSMemSet(psCmdCompleteData, 0x00, ui32AllocSize);
+
+			
+			psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*)
+											(((IMG_UINTPTR_T)psCmdCompleteData)
+											+ sizeof(COMMAND_COMPLETE_DATA));
+			psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*)
+											(((IMG_UINTPTR_T)psCmdCompleteData->psDstSync)
+											+ (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]));
+
+			psCmdCompleteData->ui32AllocSize = (IMG_UINT32)ui32AllocSize;
+		}
+	}
+
+	return PVRSRV_OK;
+
+ErrorExit:
+
+	
+	if (PVRSRVRemoveCmdProcListKM(ui32DevIndex, ui32CmdCount) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"PVRSRVRegisterCmdProcListKM: Failed to clean up after error, device 0x%x",
+				ui32DevIndex));
+	}
+	
+	return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
+									   IMG_UINT32 ui32CmdCount)
+{
+	SYS_DATA				*psSysData;
+	IMG_UINT32				ui32CmdTypeCounter, ui32CmdCounter;
+	DEVICE_COMMAND_DATA		*psDeviceCommandData;
+	COMMAND_COMPLETE_DATA	*psCmdCompleteData;
+	IMG_SIZE_T				ui32AllocSize;
+
+	
+	if(ui32DevIndex >= SYS_DEVICE_COUNT)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x",
+				ui32DevIndex));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	SysAcquireData(&psSysData);
+
+	psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex];
+	if(psDeviceCommandData != IMG_NULL)
+	{
+		for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
+		{
+			for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
+			{
+				psCmdCompleteData = psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter];
+				
+				
+				if (psCmdCompleteData != IMG_NULL)
+				{
+					OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize,
+							  psCmdCompleteData, IMG_NULL);
+					psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL;
+				}
+			}
+		}
+
+		
+		ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psDeviceCommandData, IMG_NULL);
+		psSysData->apsDeviceCommandData[ui32DevIndex] = IMG_NULL;
+	}
+
+	return PVRSRV_OK;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/ra.c b/drivers/staging/cdv/pvr/services4/srvkm/common/ra.c
new file mode 100644
index 0000000..e93f05f
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/ra.c
@@ -0,0 +1,1725 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "hash.h"
+#include "ra.h"
+#include "buffer_manager.h"
+#include "osfunc.h"
+
+#ifdef __linux__
+#include <linux/kernel.h>
+#include "proc.h"
+#endif
+
+#ifdef USE_BM_FREESPACE_CHECK
+#include <stdio.h>
+#endif
+
+#define MINIMUM_HASH_SIZE (64)
+
+#if defined(VALIDATE_ARENA_TEST)
+
+typedef enum RESOURCE_DESCRIPTOR_TAG {
+
+	RESOURCE_SPAN_LIVE				= 10,
+	RESOURCE_SPAN_FREE,
+	IMPORTED_RESOURCE_SPAN_START,
+	IMPORTED_RESOURCE_SPAN_LIVE,
+	IMPORTED_RESOURCE_SPAN_FREE,
+	IMPORTED_RESOURCE_SPAN_END,
+
+} RESOURCE_DESCRIPTOR;
+
+typedef enum RESOURCE_TYPE_TAG {
+
+	IMPORTED_RESOURCE_TYPE		= 20,
+	NON_IMPORTED_RESOURCE_TYPE
+
+} RESOURCE_TYPE;
+
+
+static IMG_UINT32 ui32BoundaryTagID = 0;
+
+IMG_UINT32 ValidateArena(RA_ARENA *pArena);
+#endif
+
+struct _BT_
+{
+	enum bt_type
+	{
+		btt_span,				
+		btt_free,				
+		btt_live				
+	} type;
+
+	
+	IMG_UINTPTR_T base;
+	IMG_SIZE_T uSize;
+
+	
+	struct _BT_ *pNextSegment;
+	struct _BT_ *pPrevSegment;
+	
+	struct _BT_ *pNextFree;
+	struct _BT_ *pPrevFree;
+	
+	BM_MAPPING *psMapping;
+
+#if defined(VALIDATE_ARENA_TEST)
+	RESOURCE_DESCRIPTOR eResourceSpan;
+	RESOURCE_TYPE		eResourceType;
+
+	
+	IMG_UINT32			ui32BoundaryTagID;
+#endif
+
+};
+typedef struct _BT_ BT;
+
+
+struct _RA_ARENA_
+{
+	
+	IMG_CHAR *name;
+
+	
+	IMG_SIZE_T uQuantum;
+
+	
+	IMG_BOOL (*pImportAlloc)(IMG_VOID *,
+							 IMG_SIZE_T uSize,
+							 IMG_SIZE_T *pActualSize,
+							 BM_MAPPING **ppsMapping,
+							 IMG_UINT32 uFlags,
+							 IMG_UINTPTR_T *pBase);
+	IMG_VOID (*pImportFree) (IMG_VOID *,
+						 IMG_UINTPTR_T,
+						 BM_MAPPING *psMapping);
+	IMG_VOID (*pBackingStoreFree) (IMG_VOID *, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE);
+
+	
+	IMG_VOID *pImportHandle;
+
+	
+#define FREE_TABLE_LIMIT 32
+
+	
+	BT *aHeadFree [FREE_TABLE_LIMIT];
+
+	
+	BT *pHeadSegment;
+	BT *pTailSegment;
+
+	
+	HASH_TABLE *pSegmentHash;
+
+#ifdef RA_STATS
+	RA_STATISTICS sStatistics;
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+#define PROC_NAME_SIZE		64
+
+	struct proc_dir_entry* pProcInfo;
+	struct proc_dir_entry* pProcSegs;
+
+	IMG_BOOL bInitProcEntry;
+#endif
+};
+#if defined(ENABLE_RA_DUMP)
+IMG_VOID RA_Dump (RA_ARENA *pArena);
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+
+static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el);
+static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off);
+
+static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el);
+static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off);
+
+#endif 
+
+#ifdef USE_BM_FREESPACE_CHECK
+IMG_VOID CheckBMFreespace(IMG_VOID);
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+static IMG_CHAR *ReplaceSpaces(IMG_CHAR * const pS)
+{
+	IMG_CHAR *pT;
+
+	for(pT = pS; *pT != 0; pT++)
+	{
+		if (*pT == ' ' || *pT == '\t')
+		{
+			*pT = '_';
+		}
+	}
+
+	return pS;
+}
+#endif
+
+static IMG_BOOL
+_RequestAllocFail (IMG_VOID *_h,
+				  IMG_SIZE_T _uSize,
+				  IMG_SIZE_T *_pActualSize,
+				  BM_MAPPING **_ppsMapping,
+				  IMG_UINT32 _uFlags,
+				  IMG_UINTPTR_T *_pBase)
+{
+	PVR_UNREFERENCED_PARAMETER (_h);
+	PVR_UNREFERENCED_PARAMETER (_uSize);
+	PVR_UNREFERENCED_PARAMETER (_pActualSize);
+	PVR_UNREFERENCED_PARAMETER (_ppsMapping);
+	PVR_UNREFERENCED_PARAMETER (_uFlags);
+	PVR_UNREFERENCED_PARAMETER (_pBase);
+
+	return IMG_FALSE;
+}
+
+static IMG_UINT32
+pvr_log2 (IMG_SIZE_T n)
+{
+	IMG_UINT32 l = 0;
+	n>>=1;
+	while (n>0)
+	{
+		n>>=1;
+		l++;
+	}
+	return l;
+}
+
+static PVRSRV_ERROR
+_SegmentListInsertAfter (RA_ARENA *pArena,
+						 BT *pInsertionPoint,
+						 BT *pBT)
+{
+	PVR_ASSERT (pArena != IMG_NULL);
+	PVR_ASSERT (pInsertionPoint != IMG_NULL);
+
+	if ((pInsertionPoint == IMG_NULL) || (pArena == IMG_NULL))
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"_SegmentListInsertAfter: invalid parameters"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	pBT->pNextSegment = pInsertionPoint->pNextSegment;
+	pBT->pPrevSegment = pInsertionPoint;
+	if (pInsertionPoint->pNextSegment == IMG_NULL)
+		pArena->pTailSegment = pBT;
+	else
+		pInsertionPoint->pNextSegment->pPrevSegment = pBT;
+	pInsertionPoint->pNextSegment = pBT;
+
+	return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+_SegmentListInsert (RA_ARENA *pArena, BT *pBT)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	
+	if (pArena->pHeadSegment == IMG_NULL)
+	{
+		pArena->pHeadSegment = pArena->pTailSegment = pBT;
+		pBT->pNextSegment = pBT->pPrevSegment = IMG_NULL;
+	}
+	else
+	{
+		BT *pBTScan;
+
+		if (pBT->base < pArena->pHeadSegment->base)
+		{
+			
+			pBT->pNextSegment = pArena->pHeadSegment;
+			pArena->pHeadSegment->pPrevSegment = pBT;
+			pArena->pHeadSegment = pBT;
+			pBT->pPrevSegment = IMG_NULL;
+		}
+		else
+		{
+
+			
+
+
+			pBTScan = pArena->pHeadSegment;
+
+			while ((pBTScan->pNextSegment != IMG_NULL)  && (pBT->base >= pBTScan->pNextSegment->base))
+			{
+				pBTScan = pBTScan->pNextSegment;
+			}
+
+			eError = _SegmentListInsertAfter (pArena, pBTScan, pBT);
+			if (eError != PVRSRV_OK)
+			{
+				return eError;
+			}
+		}
+	}
+	return eError;
+}
+
+static IMG_VOID
+_SegmentListRemove (RA_ARENA *pArena, BT *pBT)
+{
+	if (pBT->pPrevSegment == IMG_NULL)
+		pArena->pHeadSegment = pBT->pNextSegment;
+	else
+		pBT->pPrevSegment->pNextSegment = pBT->pNextSegment;
+
+	if (pBT->pNextSegment == IMG_NULL)
+		pArena->pTailSegment = pBT->pPrevSegment;
+	else
+		pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment;
+}
+
+static BT *
+_SegmentSplit (RA_ARENA *pArena, BT *pBT, IMG_SIZE_T uSize)
+{
+	BT *pNeighbour;
+
+	PVR_ASSERT (pArena != IMG_NULL);
+
+	if (pArena == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: invalid parameter - pArena"));
+		return IMG_NULL;
+	}
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					sizeof(BT),
+					(IMG_VOID **)&pNeighbour, IMG_NULL,
+					"Boundary Tag") != PVRSRV_OK)
+	{
+		return IMG_NULL;
+	}
+
+	OSMemSet(pNeighbour, 0, sizeof(BT));
+
+#if defined(VALIDATE_ARENA_TEST)
+	pNeighbour->ui32BoundaryTagID = ++ui32BoundaryTagID;
+#endif
+
+	pNeighbour->pPrevSegment = pBT;
+	pNeighbour->pNextSegment = pBT->pNextSegment;
+	if (pBT->pNextSegment == IMG_NULL)
+		pArena->pTailSegment = pNeighbour;
+	else
+		pBT->pNextSegment->pPrevSegment = pNeighbour;
+	pBT->pNextSegment = pNeighbour;
+
+	pNeighbour->type = btt_free;
+	pNeighbour->uSize = pBT->uSize - uSize;
+	pNeighbour->base = pBT->base + uSize;
+	pNeighbour->psMapping = pBT->psMapping;
+	pBT->uSize = uSize;
+
+#if defined(VALIDATE_ARENA_TEST)
+	if (pNeighbour->pPrevSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
+	{
+		pNeighbour->eResourceType = IMPORTED_RESOURCE_TYPE;
+		pNeighbour->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
+	}
+	else if (pNeighbour->pPrevSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
+	{
+		pNeighbour->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
+		pNeighbour->eResourceSpan = RESOURCE_SPAN_FREE;
+	}
+	else
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: pNeighbour->pPrevSegment->eResourceType unrecognized"));
+		PVR_DBG_BREAK;
+	}
+#endif
+
+	return pNeighbour;
+}
+
+static IMG_VOID
+_FreeListInsert (RA_ARENA *pArena, BT *pBT)
+{
+	IMG_UINT32 uIndex;
+	uIndex = pvr_log2 (pBT->uSize);
+	pBT->type = btt_free;
+	pBT->pNextFree = pArena->aHeadFree [uIndex];
+	pBT->pPrevFree = IMG_NULL;
+	if (pArena->aHeadFree[uIndex] != IMG_NULL)
+		pArena->aHeadFree[uIndex]->pPrevFree = pBT;
+	pArena->aHeadFree [uIndex] = pBT;
+}
+
+static IMG_VOID
+_FreeListRemove (RA_ARENA *pArena, BT *pBT)
+{
+	IMG_UINT32 uIndex;
+	uIndex = pvr_log2 (pBT->uSize);
+	if (pBT->pNextFree != IMG_NULL)
+		pBT->pNextFree->pPrevFree = pBT->pPrevFree;
+	if (pBT->pPrevFree == IMG_NULL)
+		pArena->aHeadFree[uIndex] = pBT->pNextFree;
+	else
+		pBT->pPrevFree->pNextFree = pBT->pNextFree;
+}
+
+static BT *
+_BuildSpanMarker (IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+	BT *pBT;
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					sizeof(BT),
+					(IMG_VOID **)&pBT, IMG_NULL,
+					"Boundary Tag") != PVRSRV_OK)
+	{
+		return IMG_NULL;
+	}
+
+	OSMemSet(pBT, 0, sizeof(BT));
+
+#if defined(VALIDATE_ARENA_TEST)
+	pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
+#endif
+
+	pBT->type = btt_span;
+	pBT->base = base;
+	pBT->uSize = uSize;
+	pBT->psMapping = IMG_NULL;
+
+	return pBT;
+}
+
+static BT *
+_BuildBT (IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+	BT *pBT;
+
+	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					sizeof(BT),
+					(IMG_VOID **)&pBT, IMG_NULL,
+					"Boundary Tag") != PVRSRV_OK)
+	{
+		return IMG_NULL;
+	}
+
+	OSMemSet(pBT, 0, sizeof(BT));
+
+#if defined(VALIDATE_ARENA_TEST)
+	pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
+#endif
+
+	pBT->type = btt_free;
+	pBT->base = base;
+	pBT->uSize = uSize;
+
+	return pBT;
+}
+
+static BT *
+_InsertResource (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+	BT *pBT;
+	PVR_ASSERT (pArena!=IMG_NULL);
+	if (pArena == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: invalid parameter - pArena"));
+		return IMG_NULL;
+	}
+
+	pBT = _BuildBT (base, uSize);
+	if (pBT != IMG_NULL)
+	{
+
+#if defined(VALIDATE_ARENA_TEST)
+		pBT->eResourceSpan = RESOURCE_SPAN_FREE;
+		pBT->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
+#endif
+
+		if (_SegmentListInsert (pArena, pBT) != PVRSRV_OK)
+		{
+			PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: call to _SegmentListInsert failed"));
+			return IMG_NULL;
+		}
+		_FreeListInsert (pArena, pBT);
+#ifdef RA_STATS
+		pArena->sStatistics.uTotalResourceCount+=uSize;
+		pArena->sStatistics.uFreeResourceCount+=uSize;
+		pArena->sStatistics.uSpanCount++;
+#endif
+	}
+	return pBT;
+}
+
+static BT *
+_InsertResourceSpan (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+	PVRSRV_ERROR eError;
+	BT *pSpanStart;
+	BT *pSpanEnd;
+	BT *pBT;
+
+	PVR_ASSERT (pArena != IMG_NULL);
+	if (pArena == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"_InsertResourceSpan: invalid parameter - pArena"));
+		return IMG_NULL;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "RA_InsertResourceSpan: arena='%s', base=0x%x, size=0x%x",
+			  pArena->name, base, uSize));
+
+	pSpanStart = _BuildSpanMarker (base, uSize);
+	if (pSpanStart == IMG_NULL)
+	{
+		goto fail_start;
+	}
+
+#if defined(VALIDATE_ARENA_TEST)
+	pSpanStart->eResourceSpan = IMPORTED_RESOURCE_SPAN_START;
+	pSpanStart->eResourceType = IMPORTED_RESOURCE_TYPE;
+#endif
+
+	pSpanEnd = _BuildSpanMarker (base + uSize, 0);
+	if (pSpanEnd == IMG_NULL)
+	{
+		goto fail_end;
+	}
+
+#if defined(VALIDATE_ARENA_TEST)
+	pSpanEnd->eResourceSpan = IMPORTED_RESOURCE_SPAN_END;
+	pSpanEnd->eResourceType = IMPORTED_RESOURCE_TYPE;
+#endif
+
+	pBT = _BuildBT (base, uSize);
+	if (pBT == IMG_NULL)
+	{
+		goto fail_bt;
+	}
+
+#if defined(VALIDATE_ARENA_TEST)
+	pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
+	pBT->eResourceType = IMPORTED_RESOURCE_TYPE;
+#endif
+
+	eError = _SegmentListInsert (pArena, pSpanStart);
+	if (eError != PVRSRV_OK)
+	{
+		goto fail_SegListInsert;
+	}
+
+	eError = _SegmentListInsertAfter (pArena, pSpanStart, pBT);
+	if (eError != PVRSRV_OK)
+	{
+		goto fail_SegListInsert;
+	}
+
+	_FreeListInsert (pArena, pBT);
+
+	eError = _SegmentListInsertAfter (pArena, pBT, pSpanEnd);
+	if (eError != PVRSRV_OK)
+	{
+		goto fail_SegListInsert;
+	}
+
+#ifdef RA_STATS
+	pArena->sStatistics.uTotalResourceCount+=uSize;
+#endif
+	return pBT;
+
+  fail_SegListInsert:
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
+	
+  fail_bt:
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL);
+	
+  fail_end:
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL);
+	
+  fail_start:
+	return IMG_NULL;
+}
+
+static IMG_VOID
+_FreeBT (RA_ARENA *pArena, BT *pBT, IMG_BOOL bFreeBackingStore)
+{
+	BT *pNeighbour;
+	IMG_UINTPTR_T uOrigBase;
+	IMG_SIZE_T uOrigSize;
+
+	PVR_ASSERT (pArena!=IMG_NULL);
+	PVR_ASSERT (pBT!=IMG_NULL);
+
+	if ((pArena == IMG_NULL) || (pBT == IMG_NULL))
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"_FreeBT: invalid parameter"));
+		return;
+	}
+
+#ifdef RA_STATS
+	pArena->sStatistics.uLiveSegmentCount--;
+	pArena->sStatistics.uFreeSegmentCount++;
+	pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
+#endif
+
+	uOrigBase = pBT->base;
+	uOrigSize = pBT->uSize;
+
+	
+	pNeighbour = pBT->pPrevSegment;
+	if (pNeighbour!=IMG_NULL
+		&& pNeighbour->type == btt_free
+		&& pNeighbour->base + pNeighbour->uSize == pBT->base)
+	{
+		_FreeListRemove (pArena, pNeighbour);
+		_SegmentListRemove (pArena, pNeighbour);
+		pBT->base = pNeighbour->base;
+		pBT->uSize += pNeighbour->uSize;
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL);
+		
+#ifdef RA_STATS
+		pArena->sStatistics.uFreeSegmentCount--;
+#endif
+	}
+
+	
+	pNeighbour = pBT->pNextSegment;
+	if (pNeighbour!=IMG_NULL
+		&& pNeighbour->type == btt_free
+		&& pBT->base + pBT->uSize == pNeighbour->base)
+	{
+		_FreeListRemove (pArena, pNeighbour);
+		_SegmentListRemove (pArena, pNeighbour);
+		pBT->uSize += pNeighbour->uSize;
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL);
+		
+#ifdef RA_STATS
+		pArena->sStatistics.uFreeSegmentCount--;
+#endif
+	}
+
+	
+	if (pArena->pBackingStoreFree != IMG_NULL && bFreeBackingStore)
+	{
+		IMG_UINTPTR_T	uRoundedStart, uRoundedEnd;
+
+		
+		uRoundedStart = (uOrigBase / pArena->uQuantum) * pArena->uQuantum;
+		
+		if (uRoundedStart < pBT->base)
+		{
+			uRoundedStart += pArena->uQuantum;
+		}
+
+		
+		uRoundedEnd = ((uOrigBase + uOrigSize + pArena->uQuantum - 1) / pArena->uQuantum) * pArena->uQuantum;
+		
+		if (uRoundedEnd > (pBT->base + pBT->uSize))
+		{
+			uRoundedEnd -= pArena->uQuantum;
+		}
+
+		if (uRoundedStart < uRoundedEnd)
+		{
+			pArena->pBackingStoreFree(pArena->pImportHandle, (IMG_SIZE_T)uRoundedStart, (IMG_SIZE_T)uRoundedEnd, (IMG_HANDLE)0);
+		}
+	}
+
+	if (pBT->pNextSegment!=IMG_NULL && pBT->pNextSegment->type == btt_span
+		&& pBT->pPrevSegment!=IMG_NULL && pBT->pPrevSegment->type == btt_span)
+	{
+		BT *next = pBT->pNextSegment;
+		BT *prev = pBT->pPrevSegment;
+		_SegmentListRemove (pArena, next);
+		_SegmentListRemove (pArena, prev);
+		_SegmentListRemove (pArena, pBT);
+		pArena->pImportFree (pArena->pImportHandle, pBT->base, pBT->psMapping);
+#ifdef RA_STATS
+		pArena->sStatistics.uSpanCount--;
+		pArena->sStatistics.uExportCount++;
+		pArena->sStatistics.uFreeSegmentCount--;
+		pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
+		pArena->sStatistics.uTotalResourceCount-=pBT->uSize;
+#endif
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), next, IMG_NULL);
+		
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), prev, IMG_NULL);
+		
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
+		
+	}
+	else
+		_FreeListInsert (pArena, pBT);
+}
+
+
+static IMG_BOOL
+_AttemptAllocAligned (RA_ARENA *pArena,
+					  IMG_SIZE_T uSize,
+					  BM_MAPPING **ppsMapping,
+					  IMG_UINT32 uFlags,
+					  IMG_UINT32 uAlignment,
+					  IMG_UINT32 uAlignmentOffset,
+					  IMG_UINTPTR_T *base)
+{
+	IMG_UINT32 uIndex;
+	PVR_ASSERT (pArena!=IMG_NULL);
+	if (pArena == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: invalid parameter - pArena"));
+		return IMG_FALSE;
+	}
+
+	if (uAlignment>1)
+		uAlignmentOffset %= uAlignment;
+
+	
+
+	uIndex = pvr_log2 (uSize);
+
+#if 0
+	
+	if (1u<<uIndex < uSize)
+		uIndex++;
+#endif
+
+	while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex]==IMG_NULL)
+		uIndex++;
+
+	while (uIndex < FREE_TABLE_LIMIT)
+	{
+		if (pArena->aHeadFree[uIndex]!=IMG_NULL)
+		{
+			
+			BT *pBT;
+
+			pBT = pArena->aHeadFree [uIndex];
+			while (pBT!=IMG_NULL)
+			{
+				IMG_UINTPTR_T aligned_base;
+
+				if (uAlignment>1)
+					aligned_base = (pBT->base + uAlignmentOffset + uAlignment - 1) / uAlignment * uAlignment - uAlignmentOffset;
+				else
+					aligned_base = pBT->base;
+				PVR_DPF ((PVR_DBG_MESSAGE,
+						  "RA_AttemptAllocAligned: pBT-base=0x%x "
+						  "pBT-size=0x%x alignedbase=0x%x size=0x%x",
+						pBT->base, pBT->uSize, aligned_base, uSize));
+
+				if (pBT->base + pBT->uSize >= aligned_base + uSize)
+				{
+					if(!pBT->psMapping || pBT->psMapping->ui32Flags == uFlags)
+					{
+						_FreeListRemove (pArena, pBT);
+
+						PVR_ASSERT (pBT->type == btt_free);
+
+#ifdef RA_STATS
+						pArena->sStatistics.uLiveSegmentCount++;
+						pArena->sStatistics.uFreeSegmentCount--;
+						pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
+#endif
+
+						
+						if (aligned_base > pBT->base)
+						{
+							BT *pNeighbour;
+							pNeighbour = _SegmentSplit (pArena, pBT, (IMG_SIZE_T)(aligned_base - pBT->base));
+							
+							if (pNeighbour==IMG_NULL)
+							{
+								PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed"));
+								
+								_FreeListInsert (pArena, pBT);
+								return IMG_FALSE;
+							}
+
+							_FreeListInsert (pArena, pBT);
+	#ifdef RA_STATS
+							pArena->sStatistics.uFreeSegmentCount++;
+							pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
+	#endif
+							pBT = pNeighbour;
+						}
+
+						
+						if (pBT->uSize > uSize)
+						{
+							BT *pNeighbour;
+							pNeighbour = _SegmentSplit (pArena, pBT, uSize);
+							
+							if (pNeighbour==IMG_NULL)
+							{
+								PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed"));
+								
+								_FreeListInsert (pArena, pBT);
+								return IMG_FALSE;
+							}
+
+							_FreeListInsert (pArena, pNeighbour);
+	#ifdef RA_STATS
+							pArena->sStatistics.uFreeSegmentCount++;
+							pArena->sStatistics.uFreeResourceCount+=pNeighbour->uSize;
+	#endif
+						}
+
+						pBT->type = btt_live;
+
+#if defined(VALIDATE_ARENA_TEST)
+						if (pBT->eResourceType == IMPORTED_RESOURCE_TYPE)
+						{
+							pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_LIVE;
+						}
+						else if (pBT->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
+						{
+							pBT->eResourceSpan = RESOURCE_SPAN_LIVE;
+						}
+						else
+						{
+							PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned ERROR: pBT->eResourceType unrecognized"));
+							PVR_DBG_BREAK;
+						}
+#endif
+						if (!HASH_Insert (pArena->pSegmentHash, pBT->base, (IMG_UINTPTR_T) pBT))
+						{
+							_FreeBT (pArena, pBT, IMG_FALSE);
+							return IMG_FALSE;
+						}
+
+						if (ppsMapping!=IMG_NULL)
+							*ppsMapping = pBT->psMapping;
+
+						*base = pBT->base;
+
+						return IMG_TRUE;
+					}
+					else
+					{
+						PVR_DPF ((PVR_DBG_MESSAGE,
+								"AttemptAllocAligned: mismatch in flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags));
+
+					}
+				}
+				pBT = pBT->pNextFree;
+			}
+
+		}
+		uIndex++;
+	}
+
+	return IMG_FALSE;
+}
+
+
+
+RA_ARENA *
+RA_Create (IMG_CHAR *name,
+		   IMG_UINTPTR_T base,
+		   IMG_SIZE_T uSize,
+		   BM_MAPPING *psMapping,
+		   IMG_SIZE_T uQuantum,
+		   IMG_BOOL (*imp_alloc)(IMG_VOID *, IMG_SIZE_T uSize, IMG_SIZE_T *pActualSize,
+		                     BM_MAPPING **ppsMapping, IMG_UINT32 _flags, IMG_UINTPTR_T *pBase),
+		   IMG_VOID (*imp_free) (IMG_VOID *, IMG_UINTPTR_T, BM_MAPPING *),
+		   IMG_VOID (*backingstore_free) (IMG_VOID*, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE),
+		   IMG_VOID *pImportHandle)
+{
+	RA_ARENA *pArena;
+	BT *pBT;
+	IMG_INT i;
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "RA_Create: name='%s', base=0x%x, uSize=0x%x, alloc=0x%x, free=0x%x",
+			  name, base, uSize, (IMG_UINTPTR_T)imp_alloc, (IMG_UINTPTR_T)imp_free));
+
+
+	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					 sizeof (*pArena),
+					 (IMG_VOID **)&pArena, IMG_NULL,
+					 "Resource Arena") != PVRSRV_OK)
+	{
+		goto arena_fail;
+	}
+
+	pArena->name = name;
+	pArena->pImportAlloc = (imp_alloc!=IMG_NULL) ? imp_alloc : &_RequestAllocFail;
+	pArena->pImportFree = imp_free;
+	pArena->pBackingStoreFree = backingstore_free;
+	pArena->pImportHandle = pImportHandle;
+	for (i=0; i<FREE_TABLE_LIMIT; i++)
+		pArena->aHeadFree[i] = IMG_NULL;
+	pArena->pHeadSegment = IMG_NULL;
+	pArena->pTailSegment = IMG_NULL;
+	pArena->uQuantum = uQuantum;
+
+#ifdef RA_STATS
+	pArena->sStatistics.uSpanCount = 0;
+	pArena->sStatistics.uLiveSegmentCount = 0;
+	pArena->sStatistics.uFreeSegmentCount = 0;
+	pArena->sStatistics.uFreeResourceCount = 0;
+	pArena->sStatistics.uTotalResourceCount = 0;
+	pArena->sStatistics.uCumulativeAllocs = 0;
+	pArena->sStatistics.uCumulativeFrees = 0;
+	pArena->sStatistics.uImportCount = 0;
+	pArena->sStatistics.uExportCount = 0;
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+	if(strcmp(pArena->name,"") != 0)
+	{
+		IMG_INT ret;
+		IMG_CHAR szProcInfoName[PROC_NAME_SIZE];
+		IMG_CHAR szProcSegsName[PROC_NAME_SIZE];
+		struct proc_dir_entry* (*pfnCreateProcEntrySeq)(const IMG_CHAR *,
+										 IMG_VOID*,
+										 pvr_next_proc_seq_t,
+										 pvr_show_proc_seq_t,
+										 pvr_off2element_proc_seq_t,
+										 pvr_startstop_proc_seq_t,
+										 write_proc_t);
+
+		pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL);
+
+		
+		pfnCreateProcEntrySeq = pArena->bInitProcEntry ? CreateProcEntrySeq : CreatePerProcessProcEntrySeq;
+
+		ret = snprintf(szProcInfoName, sizeof(szProcInfoName), "ra_info_%s", pArena->name);
+		if (ret > 0 && ret < sizeof(szProcInfoName))
+		{
+			pArena->pProcInfo =  pfnCreateProcEntrySeq(ReplaceSpaces(szProcInfoName), pArena, NULL,
+											 RA_ProcSeqShowInfo, RA_ProcSeqOff2ElementInfo, NULL, NULL);
+		}
+		else
+		{
+			pArena->pProcInfo = 0;
+			PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name));
+		}
+
+		ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_segs_%s", pArena->name);
+		if (ret > 0 && ret < sizeof(szProcInfoName))
+		{
+			pArena->pProcSegs = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL,
+											 RA_ProcSeqShowRegs, RA_ProcSeqOff2ElementRegs, NULL, NULL);
+		}
+		else
+		{
+			pArena->pProcSegs = 0;
+			PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name));
+		}
+	}
+#endif 
+
+	pArena->pSegmentHash = HASH_Create (MINIMUM_HASH_SIZE);
+	if (pArena->pSegmentHash==IMG_NULL)
+	{
+		goto hash_fail;
+	}
+	if (uSize>0)
+	{
+		uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum;
+		pBT = _InsertResource (pArena, base, uSize);
+		if (pBT == IMG_NULL)
+		{
+			goto insert_fail;
+		}
+		pBT->psMapping = psMapping;
+
+	}
+	return pArena;
+
+insert_fail:
+	HASH_Delete (pArena->pSegmentHash);
+hash_fail:
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
+	
+arena_fail:
+	return IMG_NULL;
+}
+
+IMG_VOID
+RA_Delete (RA_ARENA *pArena)
+{
+	IMG_UINT32 uIndex;
+
+	PVR_ASSERT(pArena != IMG_NULL);
+
+	if (pArena == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: invalid parameter - pArena"));
+		return;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "RA_Delete: name='%s'", pArena->name));
+
+	for (uIndex=0; uIndex<FREE_TABLE_LIMIT; uIndex++)
+		pArena->aHeadFree[uIndex] = IMG_NULL;
+
+	while (pArena->pHeadSegment != IMG_NULL)
+	{
+		BT *pBT = pArena->pHeadSegment;
+
+		if (pBT->type != btt_free)
+		{
+			PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: allocations still exist in the arena that is being destroyed"));
+			PVR_DPF ((PVR_DBG_ERROR,"Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
+			PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
+		}
+
+		_SegmentListRemove (pArena, pBT);
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
+		
+#ifdef RA_STATS
+		pArena->sStatistics.uSpanCount--;
+#endif
+	}
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+	{
+		IMG_VOID (*pfnRemoveProcEntrySeq)(struct proc_dir_entry*);
+
+		pfnRemoveProcEntrySeq = pArena->bInitProcEntry ? RemoveProcEntrySeq : RemovePerProcessProcEntrySeq;
+
+		if (pArena->pProcInfo != 0)
+		{
+			pfnRemoveProcEntrySeq( pArena->pProcInfo );
+		}
+
+		if (pArena->pProcSegs != 0)
+		{
+			pfnRemoveProcEntrySeq( pArena->pProcSegs );
+		}
+	}
+#endif
+	HASH_Delete (pArena->pSegmentHash);
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
+	
+}
+
+IMG_BOOL
+RA_TestDelete (RA_ARENA *pArena)
+{
+	PVR_ASSERT(pArena != IMG_NULL);
+
+	if (pArena != IMG_NULL)
+	{
+		while (pArena->pHeadSegment != IMG_NULL)
+		{
+			BT *pBT = pArena->pHeadSegment;
+			if (pBT->type != btt_free)
+			{
+				PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: detected resource leak!"));
+				PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
+				return IMG_FALSE;
+			}
+		}
+	}
+
+	return IMG_TRUE;
+}
+
+IMG_BOOL
+RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+	PVR_ASSERT (pArena != IMG_NULL);
+
+	if (pArena == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"RA_Add: invalid parameter - pArena"));
+		return IMG_FALSE;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "RA_Add: name='%s', base=0x%x, size=0x%x", pArena->name, base, uSize));
+
+	uSize = (uSize + pArena->uQuantum - 1) / pArena->uQuantum * pArena->uQuantum;
+	return ((IMG_BOOL)(_InsertResource (pArena, base, uSize) != IMG_NULL));
+}
+
+IMG_BOOL
+RA_Alloc (RA_ARENA *pArena,
+		  IMG_SIZE_T uRequestSize,
+		  IMG_SIZE_T *pActualSize,
+		  BM_MAPPING **ppsMapping,
+		  IMG_UINT32 uFlags,
+		  IMG_UINT32 uAlignment,
+		  IMG_UINT32 uAlignmentOffset,
+		  IMG_UINTPTR_T *base)
+{
+	IMG_BOOL bResult;
+	IMG_SIZE_T uSize = uRequestSize;
+
+	PVR_ASSERT (pArena!=IMG_NULL);
+
+	if (pArena == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"RA_Alloc: invalid parameter - pArena"));
+		return IMG_FALSE;
+	}
+
+#if defined(VALIDATE_ARENA_TEST)
+	ValidateArena(pArena);
+#endif
+
+#ifdef USE_BM_FREESPACE_CHECK
+	CheckBMFreespace();
+#endif
+
+	if (pActualSize != IMG_NULL)
+	{
+		*pActualSize = uSize;
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "RA_Alloc: arena='%s', size=0x%x(0x%x), alignment=0x%x, offset=0x%x",
+		   pArena->name, uSize, uRequestSize, uAlignment, uAlignmentOffset));
+
+	
+
+	bResult = _AttemptAllocAligned (pArena, uSize, ppsMapping, uFlags,
+									uAlignment, uAlignmentOffset, base);
+	if (!bResult)
+	{
+		BM_MAPPING *psImportMapping;
+		IMG_UINTPTR_T import_base;
+		IMG_SIZE_T uImportSize = uSize;
+
+		
+
+
+		if (uAlignment > pArena->uQuantum)
+		{
+			uImportSize += (uAlignment - 1);
+		}
+
+		
+		uImportSize = ((uImportSize + pArena->uQuantum - 1)/pArena->uQuantum)*pArena->uQuantum;
+
+		bResult =
+			pArena->pImportAlloc (pArena->pImportHandle, uImportSize, &uImportSize,
+								 &psImportMapping, uFlags, &import_base);
+		if (bResult)
+		{
+			BT *pBT;
+			pBT = _InsertResourceSpan (pArena, import_base, uImportSize);
+			
+			if (pBT == IMG_NULL)
+			{
+				
+				pArena->pImportFree(pArena->pImportHandle, import_base,
+									psImportMapping);
+				PVR_DPF ((PVR_DBG_MESSAGE,
+						  "RA_Alloc: name='%s', size=0x%x failed!",
+						  pArena->name, uSize));
+				
+				return IMG_FALSE;
+			}
+			pBT->psMapping = psImportMapping;
+#ifdef RA_STATS
+			pArena->sStatistics.uFreeSegmentCount++;
+			pArena->sStatistics.uFreeResourceCount += uImportSize;
+			pArena->sStatistics.uImportCount++;
+			pArena->sStatistics.uSpanCount++;
+#endif
+			bResult = _AttemptAllocAligned(pArena, uSize, ppsMapping, uFlags,
+										   uAlignment, uAlignmentOffset,
+										   base);
+			if (!bResult)
+			{
+				PVR_DPF ((PVR_DBG_MESSAGE,
+						  "RA_Alloc: name='%s' uAlignment failed!",
+						  pArena->name));
+			}
+		}
+	}
+#ifdef RA_STATS
+	if (bResult)
+		pArena->sStatistics.uCumulativeAllocs++;
+#endif
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "RA_Alloc: name='%s', size=0x%x, *base=0x%x = %d",
+			  pArena->name, uSize, *base, bResult));
+
+	
+
+#if defined(VALIDATE_ARENA_TEST)
+	ValidateArena(pArena);
+#endif
+
+	return bResult;
+}
+
+
+#if defined(VALIDATE_ARENA_TEST)
+
+IMG_UINT32 ValidateArena(RA_ARENA *pArena)
+{
+	BT* pSegment;
+	RESOURCE_DESCRIPTOR eNextSpan;
+
+	pSegment = pArena->pHeadSegment;
+
+	if (pSegment == IMG_NULL)
+	{
+		return 0;
+	}
+
+	if (pSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
+	{
+		PVR_ASSERT(pSegment->eResourceSpan == IMPORTED_RESOURCE_SPAN_START);
+
+		while (pSegment->pNextSegment)
+		{
+			eNextSpan = pSegment->pNextSegment->eResourceSpan;
+
+			switch (pSegment->eResourceSpan)
+			{
+				case IMPORTED_RESOURCE_SPAN_LIVE:
+
+					if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+						  (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
+						  (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
+					{
+						
+						PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+								pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+						PVR_DBG_BREAK;
+					}
+				break;
+
+				case IMPORTED_RESOURCE_SPAN_FREE:
+
+					if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+						  (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
+					{
+						
+						PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+								pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+						PVR_DBG_BREAK;
+					}
+				break;
+
+				case IMPORTED_RESOURCE_SPAN_END:
+
+					if ((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+						(eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
+						(eNextSpan == IMPORTED_RESOURCE_SPAN_END))
+					{
+						
+						PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+								pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+						PVR_DBG_BREAK;
+					}
+				break;
+
+
+				case IMPORTED_RESOURCE_SPAN_START:
+
+					if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+						  (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE)))
+					{
+						
+						PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+								pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+						PVR_DBG_BREAK;
+					}
+				break;
+
+				default:
+					PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+								pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+					PVR_DBG_BREAK;
+				break;
+			}
+			pSegment = pSegment->pNextSegment;
+		}
+	}
+	else if (pSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
+	{
+		PVR_ASSERT((pSegment->eResourceSpan == RESOURCE_SPAN_FREE) || (pSegment->eResourceSpan == RESOURCE_SPAN_LIVE));
+
+		while (pSegment->pNextSegment)
+		{
+			eNextSpan = pSegment->pNextSegment->eResourceSpan;
+
+			switch (pSegment->eResourceSpan)
+			{
+				case RESOURCE_SPAN_LIVE:
+
+					if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
+						  (eNextSpan == RESOURCE_SPAN_LIVE)))
+					{
+						
+						PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+								pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+						PVR_DBG_BREAK;
+					}
+				break;
+
+				case RESOURCE_SPAN_FREE:
+
+					if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
+						  (eNextSpan == RESOURCE_SPAN_LIVE)))
+					{
+						
+						PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+								pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+						PVR_DBG_BREAK;
+					}
+				break;
+
+				default:
+					PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+								pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+					PVR_DBG_BREAK;
+				break;
+			}
+			pSegment = pSegment->pNextSegment;
+		}
+
+	}
+	else
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"ValidateArena ERROR: pSegment->eResourceType unrecognized"));
+
+		PVR_DBG_BREAK;
+	}
+
+	return 0;
+}
+
+#endif
+
+
+IMG_VOID
+RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore)
+{
+	BT *pBT;
+
+	PVR_ASSERT (pArena != IMG_NULL);
+
+	if (pArena == IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_ERROR,"RA_Free: invalid parameter - pArena"));
+		return;
+	}
+
+#ifdef USE_BM_FREESPACE_CHECK
+	CheckBMFreespace();
+#endif
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			  "RA_Free: name='%s', base=0x%x", pArena->name, base));
+
+	pBT = (BT *) HASH_Remove (pArena->pSegmentHash, base);
+	PVR_ASSERT (pBT != IMG_NULL);
+
+	if (pBT)
+	{
+		PVR_ASSERT (pBT->base == base);
+
+#ifdef RA_STATS
+		pArena->sStatistics.uCumulativeFrees++;
+#endif
+
+#ifdef USE_BM_FREESPACE_CHECK
+{
+	IMG_BYTE* p;
+	IMG_BYTE* endp;
+
+	p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset();
+	endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize));
+	while ((IMG_UINT32)p & 3)
+	{
+		*p++ = 0xAA;
+	}
+	while (p < (IMG_BYTE*)((IMG_UINT32)endp & 0xfffffffc))
+	{
+		*(IMG_UINT32*)p = 0xAAAAAAAA;
+		p += sizeof(IMG_UINT32);
+	}
+	while (p < endp)
+	{
+		*p++ = 0xAA;
+	}
+	PVR_DPF((PVR_DBG_MESSAGE,"BM_FREESPACE_CHECK: RA_Free Cleared %08X to %08X (size=0x%x)",(IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(),endp-1,pBT->uSize));
+}
+#endif
+		_FreeBT (pArena, pBT, bFreeBackingStore);
+	}
+}
+
+
+IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails)
+{
+	BT        *pBT;
+
+	if (psSegDetails->hSegment)
+	{
+		pBT = (BT *)psSegDetails->hSegment;
+	}
+	else
+	{
+		RA_ARENA *pArena = (RA_ARENA *)hArena;
+
+		pBT = pArena->pHeadSegment;
+	}
+	
+	while (pBT != IMG_NULL)
+	{
+		if (pBT->type == btt_live)
+		{
+			psSegDetails->uiSize = pBT->uSize;
+			psSegDetails->sCpuPhyAddr.uiAddr = pBT->base;
+			psSegDetails->hSegment = (IMG_HANDLE)pBT->pNextSegment;
+
+			return IMG_TRUE;
+		}
+
+		pBT = pBT->pNextSegment;
+	}
+
+	psSegDetails->uiSize = 0;
+	psSegDetails->sCpuPhyAddr.uiAddr = 0;
+	psSegDetails->hSegment = (IMG_HANDLE)IMG_UNDEF;
+
+	return IMG_FALSE;
+}
+
+
+#ifdef USE_BM_FREESPACE_CHECK
+RA_ARENA* pJFSavedArena = IMG_NULL;
+
+IMG_VOID CheckBMFreespace(IMG_VOID)
+{
+	BT *pBT;
+	IMG_BYTE* p;
+	IMG_BYTE* endp;
+
+	if (pJFSavedArena != IMG_NULL)
+	{
+		for (pBT=pJFSavedArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
+		{
+			if (pBT->type == btt_free)
+			{
+				p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset();
+				endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize) & 0xfffffffc);
+
+				while ((IMG_UINT32)p & 3)
+				{
+					if (*p++ != 0xAA)
+					{
+						fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p);
+						for (;;);
+						break;
+					}
+				}
+				while (p < endp)
+				{
+					if (*(IMG_UINT32*)p != 0xAAAAAAAA)
+					{
+						fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p);
+						for (;;);
+						break;
+					}
+					p += 4;
+				}
+			}
+		}
+	}
+}
+#endif
+
+
+#if (defined(CONFIG_PROC_FS) && defined(DEBUG)) || defined (RA_STATS)
+static IMG_CHAR *
+_BTType (IMG_INT eType)
+{
+	switch (eType)
+	{
+	case btt_span: return "span";
+	case btt_free: return "free";
+	case btt_live: return "live";
+	}
+	return "junk";
+}
+#endif 
+
+#if defined(ENABLE_RA_DUMP)
+IMG_VOID
+RA_Dump (RA_ARENA *pArena)
+{
+	BT *pBT;
+	PVR_ASSERT (pArena != IMG_NULL);
+	PVR_DPF ((PVR_DBG_MESSAGE,"Arena '%s':", pArena->name));
+	PVR_DPF ((PVR_DBG_MESSAGE,"  alloc=%08X free=%08X handle=%08X quantum=%d",
+			 pArena->pImportAlloc, pArena->pImportFree, pArena->pImportHandle,
+			 pArena->uQuantum));
+	PVR_DPF ((PVR_DBG_MESSAGE,"  segment Chain:"));
+	if (pArena->pHeadSegment != IMG_NULL &&
+	    pArena->pHeadSegment->pPrevSegment != IMG_NULL)
+		PVR_DPF ((PVR_DBG_MESSAGE,"  error: head boundary tag has invalid pPrevSegment"));
+	if (pArena->pTailSegment != IMG_NULL &&
+	    pArena->pTailSegment->pNextSegment != IMG_NULL)
+		PVR_DPF ((PVR_DBG_MESSAGE,"  error: tail boundary tag has invalid pNextSegment"));
+
+	for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
+	{
+		PVR_DPF ((PVR_DBG_MESSAGE,"\tbase=0x%x size=0x%x type=%s ref=%08X",
+				 (IMG_UINT32) pBT->base, pBT->uSize, _BTType (pBT->type),
+				 pBT->pRef));
+	}
+
+#ifdef HASH_TRACE
+	HASH_Dump (pArena->pSegmentHash);
+#endif
+}
+#endif 
+
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+
+
+static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el)
+{
+	PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+	RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+	IMG_INT off = (IMG_INT)el;
+
+	switch (off)
+	{
+	case 1:
+		seq_printf(sfile, "quantum\t\t\t%u\n", pArena->uQuantum);
+		break;
+	case 2:
+		seq_printf(sfile, "import_handle\t\t%08X\n", (IMG_UINT)pArena->pImportHandle);
+		break;
+#ifdef RA_STATS
+	case 3:
+		seq_printf(sfile,"span count\t\t%u\n", pArena->sStatistics.uSpanCount);
+		break;
+	case 4:
+		seq_printf(sfile, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount);
+		break;
+	case 5:
+		seq_printf(sfile, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount);
+		break;
+	case 6:
+		seq_printf(sfile, "free resource count\t%u (0x%x)\n",
+							pArena->sStatistics.uFreeResourceCount,
+							(IMG_UINT)pArena->sStatistics.uFreeResourceCount);
+		break;
+	case 7:
+		seq_printf(sfile, "total allocs\t\t%u\n", pArena->sStatistics.uCumulativeAllocs);
+		break;
+	case 8:
+		seq_printf(sfile, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees);
+		break;
+	case 9:
+		seq_printf(sfile, "import count\t\t%u\n", pArena->sStatistics.uImportCount);
+		break;
+	case 10:
+		seq_printf(sfile, "export count\t\t%u\n", pArena->sStatistics.uExportCount);
+		break;
+#endif
+	}
+
+}
+
+static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off)
+{
+#ifdef RA_STATS
+	if(off <= 9)
+#else
+	if(off <= 1)
+#endif
+		return (void*)(IMG_INT)(off+1);
+	return 0;
+}
+
+static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el)
+{
+	PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+	RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+	BT *pBT = (BT*)el;
+
+	if (el == PVR_PROC_SEQ_START_TOKEN)
+	{
+		seq_printf(sfile, "Arena \"%s\"\nBase         Size Type Ref\n", pArena->name);
+		return;
+	}
+
+	if (pBT)
+	{
+		seq_printf(sfile, "%08x %8x %4s %08x\n",
+				   (IMG_UINT)pBT->base, (IMG_UINT)pBT->uSize, _BTType (pBT->type),
+			       (IMG_UINT)pBT->psMapping);
+	}
+}
+
+static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off)
+{
+	PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+	RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+	BT *pBT = 0;
+
+	if(off == 0)
+		return PVR_PROC_SEQ_START_TOKEN;
+
+	for (pBT=pArena->pHeadSegment; --off && pBT; pBT=pBT->pNextSegment);
+
+	return (void*)pBT;
+}
+
+#endif 
+
+
+#ifdef RA_STATS
+PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena,
+							IMG_CHAR **ppszStr,
+							IMG_UINT32 *pui32StrLen)
+{
+	IMG_CHAR 	*pszStr = *ppszStr;
+	IMG_UINT32 	ui32StrLen = *pui32StrLen;
+	IMG_INT32	i32Count;
+	BT 			*pBT;
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "\nArena '%s':\n", pArena->name);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "  allocCB=%p freeCB=%p handle=%p quantum=%d\n",
+							 pArena->pImportAlloc,
+							 pArena->pImportFree,
+							 pArena->pImportHandle,
+							 pArena->uQuantum);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "span count\t\t%u\n", pArena->sStatistics.uSpanCount);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "free resource count\t%u (0x%x)\n",
+							pArena->sStatistics.uFreeResourceCount,
+							(IMG_UINT)pArena->sStatistics.uFreeResourceCount);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "total allocs\t\t%u\n", pArena->sStatistics.uCumulativeAllocs);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "import count\t\t%u\n", pArena->sStatistics.uImportCount);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "export count\t\t%u\n", pArena->sStatistics.uExportCount);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "  segment Chain:\n");
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+	if (pArena->pHeadSegment != IMG_NULL &&
+	    pArena->pHeadSegment->pPrevSegment != IMG_NULL)
+	{
+		CHECK_SPACE(ui32StrLen);
+		i32Count = OSSNPrintf(pszStr, 100, "  error: head boundary tag has invalid pPrevSegment\n");
+		UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+	}
+
+	if (pArena->pTailSegment != IMG_NULL &&
+	    pArena->pTailSegment->pNextSegment != IMG_NULL)
+	{
+		CHECK_SPACE(ui32StrLen);
+		i32Count = OSSNPrintf(pszStr, 100, "  error: tail boundary tag has invalid pNextSegment\n");
+		UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+	}
+
+	for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
+	{
+		CHECK_SPACE(ui32StrLen);
+		i32Count = OSSNPrintf(pszStr, 100, "\tbase=0x%x size=0x%x type=%s ref=%p\n",
+											 (IMG_UINT32) pBT->base,
+											 pBT->uSize,
+											 _BTType(pBT->type),
+											 pBT->psMapping);
+		UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+	}
+
+	*ppszStr = pszStr;
+	*pui32StrLen = ui32StrLen;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena,
+								IMG_CHAR **ppszStr, 
+								IMG_UINT32 *pui32StrLen)
+{
+	IMG_CHAR 	*pszStr = *ppszStr;
+	IMG_UINT32 	ui32StrLen = *pui32StrLen;
+	IMG_INT32	i32Count;
+	CHECK_SPACE(ui32StrLen);
+	i32Count = OSSNPrintf(pszStr, 100, "Bytes free: Arena %-30s: %u (0x%x)\n", pArena->name,
+		pArena->sStatistics.uFreeResourceCount,
+		pArena->sStatistics.uFreeResourceCount);
+	UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+	*ppszStr = pszStr;
+	*pui32StrLen = ui32StrLen;
+	
+	return PVRSRV_OK;
+}
+#endif
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/common/resman.c b/drivers/staging/cdv/pvr/services4/srvkm/common/resman.c
new file mode 100644
index 0000000..5088c7f
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/common/resman.c
@@ -0,0 +1,751 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "resman.h"
+
+#ifdef __linux__
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/sched.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
+#include <linux/hardirq.h>
+#else
+#include <asm/hardirq.h>
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+#include <linux/mutex.h>
+#else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/semaphore.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+static DEFINE_MUTEX(lock);
+#define	DOWN(m) mutex_lock(m)
+#define	UP(m) mutex_unlock(m)
+#else
+static DECLARE_MUTEX(lock);
+#define	DOWN(m) down(m)
+#define	UP(m) up(m)
+#endif
+
+#define ACQUIRE_SYNC_OBJ  do {							\
+		if (in_interrupt()) { 							\
+			printk("ISR cannot take RESMAN mutex\n"); 	\
+			BUG(); 										\
+		} 												\
+		else DOWN(&lock); 								\
+} while (0)
+#define RELEASE_SYNC_OBJ UP(&lock)
+
+#else
+
+#define ACQUIRE_SYNC_OBJ
+#define RELEASE_SYNC_OBJ
+
+#endif
+
+#define RESMAN_SIGNATURE 0x12345678
+
+typedef struct _RESMAN_ITEM_
+{
+#ifdef DEBUG
+	IMG_UINT32				ui32Signature;
+#endif
+	struct _RESMAN_ITEM_	**ppsThis;	
+	struct _RESMAN_ITEM_	*psNext;	
+
+	IMG_UINT32				ui32Flags;	
+	IMG_UINT32				ui32ResType;
+
+	IMG_PVOID				pvParam;	
+	IMG_UINT32				ui32Param;	
+
+	RESMAN_FREE_FN			pfnFreeResource;
+} RESMAN_ITEM;
+
+
+typedef struct _RESMAN_CONTEXT_
+{
+#ifdef DEBUG
+	IMG_UINT32					ui32Signature;
+#endif
+	struct	_RESMAN_CONTEXT_	**ppsThis;
+	struct	_RESMAN_CONTEXT_	*psNext;
+
+	PVRSRV_PER_PROCESS_DATA		*psPerProc; 
+
+	RESMAN_ITEM					*psResItemList;
+
+} RESMAN_CONTEXT;
+
+
+typedef struct
+{
+	RESMAN_CONTEXT	*psContextList; 
+
+} RESMAN_LIST, *PRESMAN_LIST;	
+
+
+PRESMAN_LIST	gpsResList = IMG_NULL;
+
+#include "lists.h"	 
+
+static IMPLEMENT_LIST_ANY_VA(RESMAN_ITEM)
+static IMPLEMENT_LIST_ANY_VA_2(RESMAN_ITEM, IMG_BOOL, IMG_FALSE)
+static IMPLEMENT_LIST_INSERT(RESMAN_ITEM)
+static IMPLEMENT_LIST_REMOVE(RESMAN_ITEM)
+static IMPLEMENT_LIST_REVERSE(RESMAN_ITEM)
+
+static IMPLEMENT_LIST_REMOVE(RESMAN_CONTEXT)
+static IMPLEMENT_LIST_INSERT(RESMAN_CONTEXT)
+
+
+#define PRINT_RESLIST(x, y, z)
+
+static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback, IMG_BOOL bForceCleanup);
+
+static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT	psContext,
+										   IMG_UINT32		ui32SearchCriteria,
+										   IMG_UINT32		ui32ResType,
+										   IMG_PVOID		pvParam,
+										   IMG_UINT32		ui32Param,
+										   IMG_BOOL			bExecuteCallback);
+
+
+#ifdef DEBUG
+	static IMG_VOID ValidateResList(PRESMAN_LIST psResList);
+	#define VALIDATERESLIST() ValidateResList(gpsResList)
+#else
+	#define VALIDATERESLIST()
+#endif
+
+
+
+
+
+
+PVRSRV_ERROR ResManInit(IMG_VOID)
+{
+	if (gpsResList == IMG_NULL)
+	{
+		
+		if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof(*gpsResList),
+						(IMG_VOID **)&gpsResList, IMG_NULL,
+						"Resource Manager List") != PVRSRV_OK)
+		{
+			return PVRSRV_ERROR_OUT_OF_MEMORY;
+		}
+
+		
+		gpsResList->psContextList = IMG_NULL;
+
+		
+		VALIDATERESLIST();
+	}
+
+	return PVRSRV_OK;
+}
+
+
+IMG_VOID ResManDeInit(IMG_VOID)
+{
+	if (gpsResList != IMG_NULL)
+	{
+		
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL);
+		gpsResList = IMG_NULL;
+	}
+}
+
+
+PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE			hPerProc,
+								 PRESMAN_CONTEXT	*phResManContext)
+{
+	PVRSRV_ERROR	eError;
+	PRESMAN_CONTEXT	psResManContext;
+
+	
+	ACQUIRE_SYNC_OBJ;
+
+	
+	VALIDATERESLIST();
+
+	
+	eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext),
+						(IMG_VOID **)&psResManContext, IMG_NULL,
+						"Resource Manager Context");
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct"));
+
+		
+		VALIDATERESLIST();
+
+		
+		RELEASE_SYNC_OBJ;
+
+		return eError;
+	}
+
+#ifdef DEBUG
+	psResManContext->ui32Signature = RESMAN_SIGNATURE;
+#endif 
+	psResManContext->psResItemList	= IMG_NULL;
+	psResManContext->psPerProc = hPerProc;
+
+	
+	List_RESMAN_CONTEXT_Insert(&gpsResList->psContextList, psResManContext);
+
+	
+	VALIDATERESLIST();
+
+	
+	RELEASE_SYNC_OBJ;
+
+	*phResManContext = psResManContext;
+
+	return PVRSRV_OK;
+}
+
+
+IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext,
+								IMG_BOOL		bKernelContext)
+{
+	
+	ACQUIRE_SYNC_OBJ;
+
+	
+	VALIDATERESLIST();
+
+	
+	PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE);
+
+	
+
+	if (!bKernelContext)
+	{
+		
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE);
+
+		
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DMA_CLIENT_FIFO_DATA, 0, 0, IMG_TRUE);
+
+		
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE);
+
+		
+		
+		List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_MODIFY_SYNC_OPS, 0, 0, IMG_TRUE);
+		List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);  
+
+		
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE);
+		
+		
+
+		
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SYNC_INFO, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_WRAP, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_MAPPING, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_CONTEXT, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_MEM_INFO, 0, 0, IMG_TRUE);
+
+		
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, 0, 0, IMG_TRUE);
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE);
+
+		
+		FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE);
+	}
+
+	
+	PVR_ASSERT(psResManContext->psResItemList == IMG_NULL);
+
+	
+	List_RESMAN_CONTEXT_Remove(psResManContext);
+
+	
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL);
+	
+
+
+	
+	VALIDATERESLIST();
+
+	
+	PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE);
+
+	
+	RELEASE_SYNC_OBJ;
+}
+
+
+PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT	psResManContext,
+							   IMG_UINT32		ui32ResType,
+							   IMG_PVOID		pvParam,
+							   IMG_UINT32		ui32Param,
+							   RESMAN_FREE_FN	pfnFreeResource)
+{
+	PRESMAN_ITEM	psNewResItem;
+
+	PVR_ASSERT(psResManContext != IMG_NULL);
+	PVR_ASSERT(ui32ResType != 0);
+
+	if (psResManContext == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: invalid parameter - psResManContext"));
+		return (PRESMAN_ITEM) IMG_NULL;
+	}
+
+	
+	ACQUIRE_SYNC_OBJ;
+
+	
+	VALIDATERESLIST();
+
+	PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource "
+			"Context 0x%x, ResType 0x%x, pvParam 0x%x, ui32Param 0x%x, "
+			"FreeFunc %08X",
+			(IMG_UINTPTR_T)psResManContext,
+			ui32ResType,
+			(IMG_UINTPTR_T)pvParam,
+			ui32Param,
+			(IMG_UINTPTR_T)pfnFreeResource));
+
+	
+	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				   sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem,
+				   IMG_NULL,
+				   "Resource Manager Item") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: "
+				"ERROR allocating new resource item"));
+
+		
+		RELEASE_SYNC_OBJ;
+
+		return((PRESMAN_ITEM)IMG_NULL);
+	}
+
+	
+#ifdef DEBUG
+	psNewResItem->ui32Signature		= RESMAN_SIGNATURE;
+#endif 
+	psNewResItem->ui32ResType		= ui32ResType;
+	psNewResItem->pvParam			= pvParam;
+	psNewResItem->ui32Param			= ui32Param;
+	psNewResItem->pfnFreeResource	= pfnFreeResource;
+	psNewResItem->ui32Flags		    = 0;
+
+	
+	List_RESMAN_ITEM_Insert(&psResManContext->psResItemList, psNewResItem);
+
+	
+	VALIDATERESLIST();
+
+	
+	RELEASE_SYNC_OBJ;
+
+	return(psNewResItem);
+}
+
+PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM	*psResItem, IMG_BOOL bForceCleanup)
+{
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(psResItem != IMG_NULL);
+
+	if (psResItem == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: NULL ptr - nothing to do"));
+		return PVRSRV_OK;
+	}
+
+	PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at %08X",
+			(IMG_UINTPTR_T)psResItem));
+
+	
+	ACQUIRE_SYNC_OBJ;
+
+	
+	VALIDATERESLIST();
+
+	
+	eError = FreeResourceByPtr(psResItem, IMG_TRUE, bForceCleanup);
+
+	
+	VALIDATERESLIST();
+
+	
+	RELEASE_SYNC_OBJ;
+
+	return(eError);
+}
+
+
+PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT	psResManContext,
+									 IMG_UINT32			ui32SearchCriteria,
+									 IMG_UINT32			ui32ResType,
+									 IMG_PVOID			pvParam,
+									 IMG_UINT32			ui32Param)
+{
+	PVRSRV_ERROR	eError;
+
+	PVR_ASSERT(psResManContext != IMG_NULL);
+
+	
+	ACQUIRE_SYNC_OBJ;
+
+	
+	VALIDATERESLIST();
+
+	PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: "
+			"Context 0x%x, Criteria 0x%x, Type 0x%x, Addr 0x%x, Param 0x%x",
+			(IMG_UINTPTR_T)psResManContext, ui32SearchCriteria, ui32ResType,
+			(IMG_UINTPTR_T)pvParam, ui32Param));
+
+	
+	eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria,
+									ui32ResType, pvParam, ui32Param,
+									IMG_TRUE);
+
+	
+	VALIDATERESLIST();
+
+	
+	RELEASE_SYNC_OBJ;
+
+	return eError;
+}
+
+
+PVRSRV_ERROR ResManDissociateRes(RESMAN_ITEM		*psResItem,
+							 PRESMAN_CONTEXT	psNewResManContext)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	PVR_ASSERT(psResItem != IMG_NULL);
+
+	if (psResItem == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: invalid parameter - psResItem"));
+		PVR_DBG_BREAK;
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+#ifdef DEBUG 
+	PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE);
+#endif
+
+	if (psNewResManContext != IMG_NULL)
+	{
+		
+		List_RESMAN_ITEM_Remove(psResItem);
+
+		
+		List_RESMAN_ITEM_Insert(&psNewResManContext->psResItemList, psResItem);
+
+	}
+	else
+	{
+		eError = FreeResourceByPtr(psResItem, IMG_FALSE, CLEANUP_WITH_POLL);
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer"));
+			return eError;
+		}
+	}
+
+	return eError;
+}
+
+static IMG_BOOL ResManFindResourceByPtr_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
+{
+	RESMAN_ITEM		*psItem;
+
+	psItem = va_arg(va, RESMAN_ITEM*);
+
+	return (IMG_BOOL)(psCurItem == psItem);
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT	psResManContext,
+												  RESMAN_ITEM		*psItem)
+{
+	PVRSRV_ERROR	eResult;
+
+	PVR_ASSERT(psResManContext != IMG_NULL);
+	PVR_ASSERT(psItem != IMG_NULL);
+
+	if ((psItem == IMG_NULL) || (psResManContext == IMG_NULL))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "ResManFindResourceByPtr: invalid parameter"));
+		PVR_DBG_BREAK;
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+#ifdef DEBUG	
+	PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
+#endif
+
+	
+	ACQUIRE_SYNC_OBJ;
+
+	PVR_DPF((PVR_DBG_MESSAGE,
+			"FindResourceByPtr: psItem=%08X, psItem->psNext=%08X",
+			(IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext));
+
+	PVR_DPF((PVR_DBG_MESSAGE,
+			"FindResourceByPtr: Resource Ctx 0x%x, Type 0x%x, Addr 0x%x, "
+			"Param 0x%x, FnCall %08X, Flags 0x%x",
+			(IMG_UINTPTR_T)psResManContext,
+			psItem->ui32ResType,
+			(IMG_UINTPTR_T)psItem->pvParam,
+			psItem->ui32Param,
+			(IMG_UINTPTR_T)psItem->pfnFreeResource,
+			psItem->ui32Flags));
+
+	
+	if(List_RESMAN_ITEM_IMG_BOOL_Any_va(psResManContext->psResItemList,
+										&ResManFindResourceByPtr_AnyVaCb,
+										psItem))
+	{
+		eResult = PVRSRV_OK;
+	}
+	else
+	{
+		eResult = PVRSRV_ERROR_NOT_OWNER;
+	}
+
+	
+	RELEASE_SYNC_OBJ;
+
+	return eResult;
+}
+
+static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM	*psItem,
+									  IMG_BOOL		bExecuteCallback,
+									  IMG_BOOL		bForceCleanup)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	PVR_ASSERT(psItem != IMG_NULL);
+
+	if (psItem == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+#ifdef DEBUG	
+	PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
+#endif
+
+	PVR_DPF((PVR_DBG_MESSAGE,
+			"FreeResourceByPtr: psItem=%08X, psItem->psNext=%08X",
+			(IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext));
+
+	PVR_DPF((PVR_DBG_MESSAGE,
+			"FreeResourceByPtr: Type 0x%x, Addr 0x%x, "
+			"Param 0x%x, FnCall %08X, Flags 0x%x",
+			psItem->ui32ResType,
+			(IMG_UINTPTR_T)psItem->pvParam, psItem->ui32Param,
+			(IMG_UINTPTR_T)psItem->pfnFreeResource, psItem->ui32Flags));
+
+	
+	List_RESMAN_ITEM_Remove(psItem);
+
+
+	
+	RELEASE_SYNC_OBJ;
+
+	
+	if (bExecuteCallback)
+	{
+		eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param, bForceCleanup);
+	 	if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function"));
+		}
+	}
+
+	
+	ACQUIRE_SYNC_OBJ;
+
+	
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL);
+
+	return(eError);
+}
+
+static IMG_VOID* FreeResourceByCriteria_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
+{
+	IMG_UINT32 ui32SearchCriteria;
+	IMG_UINT32 ui32ResType;
+	IMG_PVOID pvParam;
+	IMG_UINT32 ui32Param;
+
+	ui32SearchCriteria = va_arg(va, IMG_UINT32);
+	ui32ResType = va_arg(va, IMG_UINT32);
+	pvParam = va_arg(va, IMG_PVOID);
+	ui32Param = va_arg(va, IMG_UINT32);
+
+	
+	if(
+	
+		(((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) == 0UL) ||
+		(psCurItem->ui32ResType == ui32ResType))
+	&&
+	
+		(((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) == 0UL) ||
+			 (psCurItem->pvParam == pvParam))
+	&&
+	
+		(((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) == 0UL) ||
+			 (psCurItem->ui32Param == ui32Param))
+		)
+	{
+		return psCurItem;
+	}
+	else
+	{
+		return IMG_NULL;
+	}
+}
+
+static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT	psResManContext,
+										   IMG_UINT32		ui32SearchCriteria,
+										   IMG_UINT32		ui32ResType,
+										   IMG_PVOID		pvParam,
+										   IMG_UINT32		ui32Param,
+										   IMG_BOOL			bExecuteCallback)
+{
+	PRESMAN_ITEM	psCurItem;
+	PVRSRV_ERROR	eError = PVRSRV_OK;
+
+	
+	
+	while((psCurItem = (PRESMAN_ITEM)
+				List_RESMAN_ITEM_Any_va(psResManContext->psResItemList,
+										&FreeResourceByCriteria_AnyVaCb,
+										ui32SearchCriteria,
+										ui32ResType,
+						 				pvParam,
+						 				ui32Param)) != IMG_NULL
+		  	&& eError == PVRSRV_OK)
+	{
+		eError = FreeResourceByPtr(psCurItem, bExecuteCallback, CLEANUP_WITH_POLL);
+	}
+
+	return eError;
+}
+
+
+#ifdef DEBUG
+static IMG_VOID ValidateResList(PRESMAN_LIST psResList)
+{
+	PRESMAN_ITEM	psCurItem, *ppsThisItem;
+	PRESMAN_CONTEXT	psCurContext, *ppsThisContext;
+
+	
+	if (psResList == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet"));
+		return;
+	}
+
+	psCurContext = psResList->psContextList;
+	ppsThisContext = &psResList->psContextList;
+
+	
+	while(psCurContext != IMG_NULL)
+	{
+		
+		PVR_ASSERT(psCurContext->ui32Signature == RESMAN_SIGNATURE);
+		if (psCurContext->ppsThis != ppsThisContext)
+		{
+			PVR_DPF((PVR_DBG_WARNING,
+					"psCC=%08X psCC->ppsThis=%08X psCC->psNext=%08X ppsTC=%08X",
+					(IMG_UINTPTR_T)psCurContext,
+					(IMG_UINTPTR_T)psCurContext->ppsThis,
+					(IMG_UINTPTR_T)psCurContext->psNext,
+					(IMG_UINTPTR_T)ppsThisContext));
+			PVR_ASSERT(psCurContext->ppsThis == ppsThisContext);
+		}
+
+		
+		psCurItem = psCurContext->psResItemList;
+		ppsThisItem = &psCurContext->psResItemList;
+		while(psCurItem != IMG_NULL)
+		{
+			
+			PVR_ASSERT(psCurItem->ui32Signature == RESMAN_SIGNATURE);
+			if (psCurItem->ppsThis != ppsThisItem)
+			{
+				PVR_DPF((PVR_DBG_WARNING,
+						"psCurItem=%08X psCurItem->ppsThis=%08X psCurItem->psNext=%08X ppsThisItem=%08X",
+						(IMG_UINTPTR_T)psCurItem,
+						(IMG_UINTPTR_T)psCurItem->ppsThis,
+						(IMG_UINTPTR_T)psCurItem->psNext,
+						(IMG_UINTPTR_T)ppsThisItem));
+				PVR_ASSERT(psCurItem->ppsThis == ppsThisItem);
+			}
+
+			
+			ppsThisItem = &psCurItem->psNext;
+			psCurItem = psCurItem->psNext;
+		}
+
+		
+		ppsThisContext = &psCurContext->psNext;
+		psCurContext = psCurContext->psNext;
+	}
+}
+#endif 
+
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/.gitignore b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/.gitignore
new file mode 100644
index 0000000..2f89523
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/.gitignore
@@ -0,0 +1,5 @@
+bin_pc_i686*
+tmp_pc_i686*
+host_pc_i686*
+*.o
+*.o.cmd
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/mmu.c b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/mmu.c
new file mode 100644
index 0000000..22b9ffb
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/mmu.c
@@ -0,0 +1,3696 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "sgxdefs.h"
+#include "sgxmmu.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "hash.h"
+#include "ra.h"
+#include "pdump_km.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+#include "mmu.h"
+#include "sgxconfig.h"
+#include "sgx_bridge_km.h"
+#include "pdump_osfunc.h"
+
+#define UINT32_MAX_VALUE	0xFFFFFFFFUL
+
+#define SGX_MAX_PD_ENTRIES	(1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT))
+
+#if defined(FIX_HW_BRN_31620)
+#define SGX_MMU_PDE_DUMMY_PAGE		(0)
+#define SGX_MMU_PTE_DUMMY_PAGE		(0)
+
+#define BRN31620_PT_ADDRESS_RANGE_SHIFT		22
+#define BRN31620_PT_ADDRESS_RANGE_SIZE		(1 << BRN31620_PT_ADDRESS_RANGE_SHIFT)
+
+#define BRN31620_PDE_CACHE_FILL_SHIFT		26
+#define BRN31620_PDE_CACHE_FILL_SIZE		(1 << BRN31620_PDE_CACHE_FILL_SHIFT)
+#define BRN31620_PDE_CACHE_FILL_MASK		(BRN31620_PDE_CACHE_FILL_SIZE - 1)
+
+#define BRN31620_PDES_PER_CACHE_LINE_SHIFT	(BRN31620_PDE_CACHE_FILL_SHIFT - BRN31620_PT_ADDRESS_RANGE_SHIFT)
+#define BRN31620_PDES_PER_CACHE_LINE_SIZE	(1 << BRN31620_PDES_PER_CACHE_LINE_SHIFT)
+#define BRN31620_PDES_PER_CACHE_LINE_MASK	(BRN31620_PDES_PER_CACHE_LINE_SIZE - 1)
+
+#define BRN31620_DUMMY_PAGE_OFFSET	(1 * SGX_MMU_PAGE_SIZE)
+#define BRN31620_DUMMY_PDE_INDEX	(BRN31620_DUMMY_PAGE_OFFSET / BRN31620_PT_ADDRESS_RANGE_SIZE)
+#define BRN31620_DUMMY_PTE_INDEX	((BRN31620_DUMMY_PAGE_OFFSET - (BRN31620_DUMMY_PDE_INDEX * BRN31620_PT_ADDRESS_RANGE_SIZE))/SGX_MMU_PAGE_SIZE)
+
+#define BRN31620_CACHE_FLUSH_SHIFT		(32 - BRN31620_PDE_CACHE_FILL_SHIFT)
+#define BRN31620_CACHE_FLUSH_SIZE		(1 << BRN31620_CACHE_FLUSH_SHIFT)
+
+#define BRN31620_CACHE_FLUSH_BITS_SHIFT		5
+#define BRN31620_CACHE_FLUSH_BITS_SIZE		(1 << BRN31620_CACHE_FLUSH_BITS_SHIFT)
+#define BRN31620_CACHE_FLUSH_BITS_MASK		(BRN31620_CACHE_FLUSH_BITS_SIZE - 1)
+
+#define BRN31620_CACHE_FLUSH_INDEX_BITS		(BRN31620_CACHE_FLUSH_SHIFT - BRN31620_CACHE_FLUSH_BITS_SHIFT)
+#define BRN31620_CACHE_FLUSH_INDEX_SIZE		(1 << BRN31620_CACHE_FLUSH_INDEX_BITS)
+
+#define BRN31620_DUMMY_PAGE_SIGNATURE	0xFEEBEE01
+#endif
+
+typedef struct _MMU_PT_INFO_
+{
+	
+	IMG_VOID *hPTPageOSMemHandle;
+	IMG_CPU_VIRTADDR PTPageCpuVAddr;
+	
+	
+	IMG_UINT32 ui32ValidPTECount;
+} MMU_PT_INFO;
+
+struct _MMU_CONTEXT_
+{
+	
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	
+	IMG_CPU_VIRTADDR pvPDCpuVAddr;
+	IMG_DEV_PHYADDR sPDDevPAddr;
+
+	IMG_VOID *hPDOSMemHandle;
+
+	
+	MMU_PT_INFO *apsPTInfoList[SGX_MAX_PD_ENTRIES];
+
+	PVRSRV_SGXDEV_INFO *psDevInfo;
+
+#if defined(PDUMP)
+	IMG_UINT32 ui32PDumpMMUContextID;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	IMG_BOOL bPDumpActive;
+#endif
+#endif
+
+#if defined (FIX_HW_BRN_31620)
+	IMG_UINT32 ui32PDChangeMask[BRN31620_CACHE_FLUSH_INDEX_SIZE];
+	IMG_UINT32 ui32PDCacheRangeRefCount[BRN31620_CACHE_FLUSH_SIZE];
+	MMU_PT_INFO *apsPTInfoListSave[SGX_MAX_PD_ENTRIES];
+#endif
+	struct _MMU_CONTEXT_ *psNext;
+};
+
+struct _MMU_HEAP_
+{
+	
+	MMU_CONTEXT			*psMMUContext;
+
+	
+
+	
+	IMG_UINT32			ui32PDBaseIndex;
+	
+	IMG_UINT32			ui32PageTableCount;
+	
+	IMG_UINT32			ui32PTETotalUsable;
+	
+	IMG_UINT32			ui32PDEPageSizeCtrl;
+
+	
+
+	
+	IMG_UINT32			ui32DataPageSize;
+	
+	IMG_UINT32			ui32DataPageBitWidth;
+	
+	IMG_UINT32			ui32DataPageMask;
+
+	
+
+	
+	IMG_UINT32			ui32PTShift;
+	
+	IMG_UINT32			ui32PTBitWidth;
+	
+	IMG_UINT32			ui32PTMask;
+	
+	IMG_UINT32			ui32PTSize;
+	
+	IMG_UINT32			ui32PTNumEntriesAllocated;
+	
+	IMG_UINT32			ui32PTNumEntriesUsable;
+
+	
+
+	
+	IMG_UINT32			ui32PDShift;
+	
+	IMG_UINT32			ui32PDBitWidth;
+	
+	IMG_UINT32			ui32PDMask;
+
+	
+
+	RA_ARENA *psVMArena;
+	DEV_ARENA_DESCRIPTOR *psDevArena;
+#if defined(PDUMP)
+	PDUMP_MMU_ATTRIB sMMUAttrib;
+#endif
+};
+
+
+
+#if defined (SUPPORT_SGX_MMU_DUMMY_PAGE)
+#define DUMMY_DATA_PAGE_SIGNATURE	0xDEADBEEF
+#endif
+
+static IMG_VOID
+_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT);
+
+#if defined(PDUMP)
+static IMG_VOID
+MMU_PDumpPageTables	(MMU_HEAP *pMMUHeap,
+					 IMG_DEV_VIRTADDR DevVAddr,
+					 IMG_SIZE_T uSize,
+					 IMG_BOOL bForUnmap,
+					 IMG_HANDLE hUniqueTag);
+#endif 
+
+#define PAGE_TEST					0
+#if PAGE_TEST
+static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr);
+#endif
+
+#define PT_DEBUG 0
+#if PT_DEBUG
+static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
+{
+	IMG_UINT32 *p = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
+	IMG_UINT32 i;
+
+	
+	for(i = 0; i < 1024; i += 8)
+	{
+		PVR_DPF((PVR_DBG_WARNING,
+				 "%08X %08X %08X %08X %08X %08X %08X %08X\n",
+				 p[i + 0], p[i + 1], p[i + 2], p[i + 3],
+				 p[i + 4], p[i + 5], p[i + 6], p[i + 7]));
+	}
+}
+
+static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
+{
+	IMG_UINT32 *p = (IMG_UINT32*) psPTInfoList->PTPageCpuVAddr;
+	IMG_UINT32 i, ui32Count = 0;
+
+	
+	for(i = 0; i < 1024; i++)
+		if(p[i] & SGX_MMU_PTE_VALID)
+			ui32Count++;
+
+	if(psPTInfoList->ui32ValidPTECount != ui32Count)
+	{
+		PVR_DPF((PVR_DBG_WARNING, "ui32ValidPTECount: %u ui32Count: %u\n",
+				 psPTInfoList->ui32ValidPTECount, ui32Count));
+		DumpPT(psPTInfoList);
+		BUG();
+	}
+}
+#else 
+static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
+{
+	PVR_UNREFERENCED_PARAMETER(psPTInfoList);
+}
+
+static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
+{
+	PVR_UNREFERENCED_PARAMETER(psPTInfoList);
+}
+#endif 
+
+
+IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMUHeap)
+{
+	switch(pMMUHeap->psDevArena->DevMemHeapType)
+	{
+		case DEVICE_MEMORY_HEAP_SHARED :
+		case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
+			return IMG_TRUE;
+		case DEVICE_MEMORY_HEAP_PERCONTEXT :
+		case DEVICE_MEMORY_HEAP_KERNEL :
+			return IMG_FALSE;
+		default:
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_IsHeapShared: ERROR invalid heap type"));
+			return IMG_FALSE;
+		}
+	}
+}
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+IMG_VOID
+EnableHostAccess (MMU_CONTEXT *psMMUContext)
+{
+	IMG_UINT32 ui32RegVal;
+	IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
+
+	
+
+
+	ui32RegVal = OSReadHWReg(pvRegsBaseKM, EUR_CR_BIF_CTRL);
+
+	OSWriteHWReg(pvRegsBaseKM,
+				EUR_CR_BIF_CTRL,
+				ui32RegVal | EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
+	
+	PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
+}
+
+IMG_VOID
+DisableHostAccess (MMU_CONTEXT *psMMUContext)
+{
+	IMG_UINT32 ui32RegVal;
+	IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
+
+	
+
+
+
+	OSWriteHWReg(pvRegsBaseKM,
+				EUR_CR_BIF_CTRL,
+				ui32RegVal & ~EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
+	
+	PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, 0);
+}
+#endif
+
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+static IMG_VOID MMU_InvalidateSystemLevelCache(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+	#if defined(SGX_FEATURE_MP)
+	psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL;
+	#else
+	
+	PVR_UNREFERENCED_PARAMETER(psDevInfo);
+	#endif 
+}
+#endif 
+
+IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+	psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD;
+	#if defined(SGX_FEATURE_SYSTEM_CACHE)
+	MMU_InvalidateSystemLevelCache(psDevInfo);
+	#endif 
+}
+
+
+static IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+	psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PT;
+	#if defined(SGX_FEATURE_SYSTEM_CACHE)
+	MMU_InvalidateSystemLevelCache(psDevInfo);
+	#endif 
+}
+
+#if defined(FIX_HW_BRN_31620)
+static IMG_VOID BRN31620InvalidatePageTableEntry(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32PDIndex, IMG_UINT32 ui32PTIndex, IMG_UINT32 *pui32PTE)
+{
+	PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
+
+	
+	if (((ui32PDIndex % (BRN31620_PDE_CACHE_FILL_SIZE/BRN31620_PT_ADDRESS_RANGE_SIZE)) == BRN31620_DUMMY_PDE_INDEX)
+		&& (ui32PTIndex == BRN31620_DUMMY_PTE_INDEX))
+	{
+		*pui32PTE = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+								| SGX_MMU_PTE_DUMMY_PAGE
+								| SGX_MMU_PTE_READONLY
+								| SGX_MMU_PTE_VALID;
+	}
+	else
+	{
+		*pui32PTE = 0;
+	}
+}
+
+static IMG_BOOL BRN31620FreePageTable(MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PDIndex)
+{
+	MMU_CONTEXT *psMMUContext = psMMUHeap->psMMUContext;
+	PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
+	IMG_UINT32 ui32PDCacheLine = ui32PDIndex >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
+	IMG_UINT32 bFreePTs = IMG_FALSE;
+	IMG_UINT32 *pui32Tmp;
+
+	PVR_ASSERT(psMMUHeap != IMG_NULL);
+
+	
+	PVR_ASSERT(psMMUContext->apsPTInfoListSave[ui32PDIndex] == IMG_NULL);
+
+	psMMUContext->apsPTInfoListSave[ui32PDIndex] = psMMUContext->apsPTInfoList[ui32PDIndex];
+	psMMUContext->apsPTInfoList[ui32PDIndex] = IMG_NULL;
+
+	
+	if (--psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine] == 0)
+	{
+		IMG_UINT32 i;
+		IMG_UINT32 ui32PDIndexStart = ui32PDCacheLine * BRN31620_PDES_PER_CACHE_LINE_SIZE;
+		IMG_UINT32 ui32PDIndexEnd = ui32PDIndexStart + BRN31620_PDES_PER_CACHE_LINE_SIZE;
+		IMG_UINT32 ui32PDBitMaskIndex, ui32PDBitMaskShift;
+
+		
+		for (i=ui32PDIndexStart;i<ui32PDIndexEnd;i++)
+		{
+			
+			psMMUContext->apsPTInfoList[i] = psMMUContext->apsPTInfoListSave[i];
+			psMMUContext->apsPTInfoListSave[i] = IMG_NULL;
+			_DeferredFreePageTable(psMMUHeap, i - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
+		}
+
+		ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT;
+		ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK;
+
+		
+		if (MMU_IsHeapShared(psMMUHeap))
+		{
+			
+			MMU_CONTEXT *psMMUContextWalker = (MMU_CONTEXT*) psMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+			while(psMMUContextWalker)
+			{
+				psMMUContextWalker->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+
+				
+				pui32Tmp = (IMG_UINT32 *) psMMUContextWalker->pvPDCpuVAddr;
+				pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+												| SGX_MMU_PDE_PAGE_SIZE_4K
+												| SGX_MMU_PDE_DUMMY_PAGE
+												| SGX_MMU_PDE_VALID;
+
+				PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
+				PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContextWalker->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+				psMMUContextWalker = psMMUContextWalker->psNext;
+			}
+		}
+		else
+		{
+			psMMUContext->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+
+			
+			pui32Tmp = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
+			pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+											| SGX_MMU_PDE_PAGE_SIZE_4K
+											| SGX_MMU_PDE_DUMMY_PAGE
+											| SGX_MMU_PDE_VALID;
+
+			PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
+			PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+		}
+		
+		bFreePTs = IMG_TRUE;
+	}
+
+	return bFreePTs;
+}
+#endif
+
+static IMG_BOOL
+_AllocPageTableMemory (MMU_HEAP *pMMUHeap,
+						MMU_PT_INFO *psPTInfoList,
+						IMG_DEV_PHYADDR	*psDevPAddr)
+{
+	IMG_DEV_PHYADDR	sDevPAddr;
+	IMG_CPU_PHYADDR sCpuPAddr;
+
+	
+
+
+	if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
+	{
+		
+		if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+						   pMMUHeap->ui32PTSize,
+						   SGX_MMU_PAGE_SIZE,
+						   (IMG_VOID **)&psPTInfoList->PTPageCpuVAddr,
+						   &psPTInfoList->hPTPageOSMemHandle) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to OSAllocPages failed"));
+			return IMG_FALSE;
+		}
+
+		
+		if(psPTInfoList->PTPageCpuVAddr)
+		{
+			sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle,
+										  psPTInfoList->PTPageCpuVAddr);
+		}
+		else
+		{
+			
+			sCpuPAddr = OSMemHandleToCpuPAddr(psPTInfoList->hPTPageOSMemHandle, 0);
+		}
+
+		sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+	}
+	else
+	{
+		IMG_SYS_PHYADDR sSysPAddr;
+
+		
+
+
+		
+		if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena,
+					SGX_MMU_PAGE_SIZE,
+					IMG_NULL,
+					IMG_NULL,
+					0,
+					SGX_MMU_PAGE_SIZE,
+					0,
+					&(sSysPAddr.uiAddr))!= IMG_TRUE)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to RA_Alloc failed"));
+			return IMG_FALSE;
+		}
+
+		
+		sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+		
+		psPTInfoList->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+													SGX_MMU_PAGE_SIZE,
+													PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+													&psPTInfoList->hPTPageOSMemHandle);
+		if(!psPTInfoList->PTPageCpuVAddr)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR failed to map page tables"));
+			return IMG_FALSE;
+		}
+
+		
+		sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+		#if PAGE_TEST
+		PageTest(psPTInfoList->PTPageCpuVAddr, sDevPAddr);
+		#endif
+	}
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+	{
+		IMG_UINT32 *pui32Tmp;
+		IMG_UINT32 i;
+
+		pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
+		
+		for(i=0; i<pMMUHeap->ui32PTNumEntriesUsable; i++)
+		{
+			pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+						| SGX_MMU_PTE_VALID;
+		}
+		
+		for(; i<pMMUHeap->ui32PTNumEntriesAllocated; i++)
+		{
+			pui32Tmp[i] = 0;
+		}
+	}
+#else
+	
+	OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize);
+#endif
+
+#if defined(PDUMP)
+	{
+		IMG_UINT32 ui32Flags = 0;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+		
+		ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+		
+		PDUMPMALLOCPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, psPTInfoList->hPTPageOSMemHandle, 0, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG);
+		
+		PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfoList->hPTPageOSMemHandle, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+	}
+#endif
+	
+	
+	*psDevPAddr = sDevPAddr;
+
+	return IMG_TRUE;
+}
+
+
+static IMG_VOID
+_FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList)
+{
+	
+
+
+
+	if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
+	{
+		
+		OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+					  pMMUHeap->ui32PTSize,
+					  psPTInfoList->PTPageCpuVAddr,
+					  psPTInfoList->hPTPageOSMemHandle);
+	}
+	else
+	{
+		IMG_SYS_PHYADDR sSysPAddr;
+		IMG_CPU_PHYADDR sCpuPAddr;
+
+		
+		sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle, 
+									  psPTInfoList->PTPageCpuVAddr);
+		sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr);
+
+		
+		
+		OSUnMapPhysToLin(psPTInfoList->PTPageCpuVAddr,
+                         SGX_MMU_PAGE_SIZE,
+                         PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+                         psPTInfoList->hPTPageOSMemHandle);
+
+		
+
+
+		RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+	}
+}
+
+
+
+static IMG_VOID
+_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT)
+{
+	IMG_UINT32 *pui32PDEntry;
+	IMG_UINT32 i;
+	IMG_UINT32 ui32PDIndex;
+	SYS_DATA *psSysData;
+	MMU_PT_INFO **ppsPTInfoList;
+
+	SysAcquireData(&psSysData);
+
+	
+	ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+	
+	ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+	{
+#if PT_DEBUG
+		if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0)
+		{
+			DumpPT(ppsPTInfoList[ui32PTIndex]);
+			
+		}
+#endif
+
+		
+		PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0);
+	}
+
+#if defined(PDUMP)
+	{
+		IMG_UINT32 ui32Flags = 0;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+		ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+		
+		PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
+		if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr)
+		{
+			PDUMPFREEPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, ppsPTInfoList[ui32PTIndex]->hPTPageOSMemHandle, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG);
+		}
+	}
+#endif
+
+	switch(pMMUHeap->psDevArena->DevMemHeapType)
+	{
+		case DEVICE_MEMORY_HEAP_SHARED :
+		case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
+		{
+			
+			MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+			while(psMMUContext)
+			{
+				
+				pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
+				pui32PDEntry += ui32PDIndex;
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+				
+				pui32PDEntry[ui32PTIndex] = (psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
+											>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+											| SGX_MMU_PDE_PAGE_SIZE_4K
+											| SGX_MMU_PDE_VALID;
+#else
+				
+				if(bOSFreePT)
+				{
+					pui32PDEntry[ui32PTIndex] = 0;
+				}
+#endif
+			#if defined(PDUMP)
+				
+			#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+				if(psMMUContext->bPDumpActive)
+			#endif
+				{
+					PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+				}
+			#endif
+				
+				psMMUContext = psMMUContext->psNext;
+			}
+			break;
+		}
+		case DEVICE_MEMORY_HEAP_PERCONTEXT :
+		case DEVICE_MEMORY_HEAP_KERNEL :
+		{
+			
+			pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
+			pui32PDEntry += ui32PDIndex;
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+			
+			pui32PDEntry[ui32PTIndex] = (pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
+										>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+										| SGX_MMU_PDE_PAGE_SIZE_4K
+										| SGX_MMU_PDE_VALID;
+#else
+			
+			if(bOSFreePT)
+			{
+				pui32PDEntry[ui32PTIndex] = 0;
+			}
+#endif
+
+			
+			PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+			break;
+		}
+		default:
+		{
+			PVR_DPF((PVR_DBG_ERROR, "_DeferredFreePagetable: ERROR invalid heap type"));
+			return;
+		}
+	}
+
+	
+	if(ppsPTInfoList[ui32PTIndex] != IMG_NULL)
+	{
+		if(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr != IMG_NULL)
+		{
+			IMG_PUINT32 pui32Tmp;
+
+			pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr;
+
+			
+			for(i=0;
+				(i<pMMUHeap->ui32PTETotalUsable) && (i<pMMUHeap->ui32PTNumEntriesUsable);
+				 i++)
+			{
+				
+				pui32Tmp[i] = 0;
+			}
+
+			
+
+			if(bOSFreePT)
+			{
+				_FreePageTableMemory(pMMUHeap, ppsPTInfoList[ui32PTIndex]);
+			}
+
+			
+
+
+			pMMUHeap->ui32PTETotalUsable -= i;
+		}
+		else
+		{
+			
+			pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable;
+		}
+
+		if(bOSFreePT)
+		{
+			
+			OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof(MMU_PT_INFO),
+						ppsPTInfoList[ui32PTIndex],
+						IMG_NULL);
+			ppsPTInfoList[ui32PTIndex] = IMG_NULL;
+		}
+	}
+	else
+	{
+		
+		pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable;
+	}
+
+	PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
+}
+
+static IMG_VOID
+_DeferredFreePageTables (MMU_HEAP *pMMUHeap)
+{
+	IMG_UINT32 i;
+#if defined(FIX_HW_BRN_31620)
+	MMU_CONTEXT *psMMUContext = pMMUHeap->psMMUContext;
+	IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
+	IMG_UINT32 ui32PDIndex;
+	IMG_UINT32 *pui32Tmp;
+	IMG_UINT32 j;
+#endif
+#if defined(PDUMP)
+	PDUMPCOMMENT("Free PTs (MMU Context ID == %u, PDBaseIndex == %u, PT count == 0x%x)",
+			pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
+			pMMUHeap->ui32PDBaseIndex,
+			pMMUHeap->ui32PageTableCount);
+#endif
+#if defined(FIX_HW_BRN_31620)
+	for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
+	{
+		ui32PDIndex = (pMMUHeap->ui32PDBaseIndex + i);
+
+		if (psMMUContext->apsPTInfoList[ui32PDIndex])
+		{
+			if (psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
+			{
+				
+				for (j=0;j<SGX_MMU_PT_SIZE;j++)
+				{
+					pui32Tmp = (IMG_UINT32 *) psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+					BRN31620InvalidatePageTableEntry(psMMUContext, ui32PDIndex, j, &pui32Tmp[j]);
+				}
+			}
+			
+			if (BRN31620FreePageTable(pMMUHeap, ui32PDIndex) == IMG_TRUE)
+			{
+				bInvalidateDirectoryCache = IMG_TRUE;
+			}
+		}
+	}
+
+	
+	if (bInvalidateDirectoryCache)
+	{
+		MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
+	}
+	else
+	{
+		MMU_InvalidatePageTableCache(pMMUHeap->psMMUContext->psDevInfo);
+	}
+#else
+	for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
+	{
+		_DeferredFreePageTable(pMMUHeap, i, IMG_TRUE);
+	}
+	MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
+#endif
+}
+
+
+static IMG_BOOL
+_DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
+{
+	IMG_UINT32 ui32PageTableCount;
+	IMG_UINT32 ui32PDIndex;
+	IMG_UINT32 i;
+	IMG_UINT32 *pui32PDEntry;
+	MMU_PT_INFO **ppsPTInfoList;
+	SYS_DATA *psSysData;
+	IMG_DEV_VIRTADDR sHighDevVAddr;
+#if defined(FIX_HW_BRN_31620)
+	IMG_BOOL bFlushSystemCache = IMG_FALSE;
+	IMG_BOOL bSharedPT = IMG_FALSE;
+	IMG_DEV_VIRTADDR sDevVAddrRequestStart;
+	IMG_DEV_VIRTADDR sDevVAddrRequestEnd;
+	IMG_UINT32 ui32PDRequestStart;
+	IMG_UINT32 ui32PDRequestEnd;
+	IMG_UINT32 ui32ModifiedCachelines[BRN31620_CACHE_FLUSH_INDEX_SIZE];
+#endif
+
+	
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32
+	PVR_ASSERT(DevVAddr.uiAddr < (1<<SGX_FEATURE_ADDRESS_SPACE_SIZE));
+#endif
+
+	
+	SysAcquireData(&psSysData);
+
+	
+	ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+	
+	
+	if((UINT32_MAX_VALUE - DevVAddr.uiAddr)
+		< (ui32Size + pMMUHeap->ui32DataPageMask + pMMUHeap->ui32PTMask))
+	{
+		
+		sHighDevVAddr.uiAddr = UINT32_MAX_VALUE;
+	}
+	else
+	{
+		sHighDevVAddr.uiAddr = DevVAddr.uiAddr
+								+ ui32Size
+								+ pMMUHeap->ui32DataPageMask
+								+ pMMUHeap->ui32PTMask;
+	}
+
+	ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+	
+	if (ui32PageTableCount == 0)
+		ui32PageTableCount = 1024;
+
+#if defined(FIX_HW_BRN_31620)
+	for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+	{
+		ui32ModifiedCachelines[i] = 0;
+	}
+
+	
+	
+	
+	sDevVAddrRequestStart = DevVAddr;
+	ui32PDRequestStart = ui32PDIndex;
+	sDevVAddrRequestEnd = sHighDevVAddr;
+	ui32PDRequestEnd = ui32PageTableCount - 1;
+
+	
+	DevVAddr.uiAddr = DevVAddr.uiAddr & (~BRN31620_PDE_CACHE_FILL_MASK);
+
+	
+	sHighDevVAddr.uiAddr = ((sHighDevVAddr.uiAddr + (BRN31620_PDE_CACHE_FILL_SIZE - 1)) & (~BRN31620_PDE_CACHE_FILL_MASK));
+
+	ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+	ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+	
+	if (ui32PageTableCount == 0)
+		ui32PageTableCount = 1024;
+#endif
+
+	ui32PageTableCount -= ui32PDIndex;
+
+	
+	pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
+	pui32PDEntry += ui32PDIndex;
+
+	
+	ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+#if defined(PDUMP)
+	{
+		IMG_UINT32 ui32Flags = 0;
+		
+		
+		if( MMU_IsHeapShared(pMMUHeap) )
+		{
+			ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
+		}
+		PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc PTs (MMU Context ID == %u, PDBaseIndex == %u, Size == 0x%x)",
+				pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
+				pMMUHeap->ui32PDBaseIndex,
+				ui32Size);
+		PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc page table (page count == %08X)", ui32PageTableCount);
+		PDUMPCOMMENTWITHFLAGS(ui32Flags, "Page directory mods (page count == %08X)", ui32PageTableCount);
+	}
+#endif
+	
+	for(i=0; i<ui32PageTableCount; i++)
+	{
+		if(ppsPTInfoList[i] == IMG_NULL)
+		{
+#if defined(FIX_HW_BRN_31620)
+			
+			if (pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i])
+			{
+				
+				if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd))
+				{
+					IMG_UINT32 ui32PDCacheLine = (ui32PDIndex + i) >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
+
+					ppsPTInfoList[i] = pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i];
+					pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = IMG_NULL;
+
+					pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++;
+				}
+			}
+			else
+			{
+#endif
+			OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						 sizeof (MMU_PT_INFO),
+						 (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL,
+						 "MMU Page Table Info");
+			if (ppsPTInfoList[i] == IMG_NULL)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to OSAllocMem failed"));
+				return IMG_FALSE;
+			}
+			OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO));
+#if defined(FIX_HW_BRN_31620)
+			}
+#endif
+		}
+#if defined(FIX_HW_BRN_31620)
+		
+		if (ppsPTInfoList[i])
+		{
+#endif
+		if(ppsPTInfoList[i]->hPTPageOSMemHandle == IMG_NULL
+		&& ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL)
+		{
+			IMG_DEV_PHYADDR	sDevPAddr;
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+			IMG_UINT32 *pui32Tmp;
+			IMG_UINT32 j;
+#else
+#if !defined(FIX_HW_BRN_31620)
+			
+			PVR_ASSERT(pui32PDEntry[i] == 0);
+#endif
+#endif
+			if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed"));
+				return IMG_FALSE;
+			}
+#if defined(FIX_HW_BRN_31620)
+			bFlushSystemCache = IMG_TRUE;
+			
+			{
+				IMG_UINT32 ui32PD;
+				IMG_UINT32 ui32PDCacheLine;
+				IMG_UINT32 ui32PDBitMaskIndex;
+				IMG_UINT32 ui32PDBitMaskShift;
+
+				ui32PD = ui32PDIndex + i;
+				ui32PDCacheLine = ui32PD >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
+				ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT;
+				ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK;
+				ui32ModifiedCachelines[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+
+				
+				if ((pMMUHeap->ui32PDBaseIndex + pMMUHeap->ui32PageTableCount) < (ui32PD + 1))
+				{
+					pMMUHeap->ui32PageTableCount = (ui32PD + 1) - pMMUHeap->ui32PDBaseIndex;
+				}
+
+				if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd))
+				{
+					pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++;
+				}
+			}
+#endif
+			switch(pMMUHeap->psDevArena->DevMemHeapType)
+			{
+				case DEVICE_MEMORY_HEAP_SHARED :
+				case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
+				{
+					
+					MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+					while(psMMUContext)
+					{
+						
+						pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
+						pui32PDEntry += ui32PDIndex;
+
+						
+						pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+										| pMMUHeap->ui32PDEPageSizeCtrl
+										| SGX_MMU_PDE_VALID;
+						#if defined(PDUMP)
+						
+						#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+						if(psMMUContext->bPDumpActive)
+						#endif
+						{
+							
+							PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+						}
+						#endif 
+						
+						psMMUContext = psMMUContext->psNext;
+					}
+#if defined(FIX_HW_BRN_31620)
+					bSharedPT = IMG_TRUE;
+#endif
+					break;
+				}
+				case DEVICE_MEMORY_HEAP_PERCONTEXT :
+				case DEVICE_MEMORY_HEAP_KERNEL :
+				{
+					
+					pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+									| pMMUHeap->ui32PDEPageSizeCtrl
+									| SGX_MMU_PDE_VALID;
+
+					
+					
+					PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+					break;
+				}
+				default:
+				{
+					PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR invalid heap type"));
+					return IMG_FALSE;
+				}
+			}
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+			
+
+
+
+			MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
+#endif
+#if defined(FIX_HW_BRN_31620)
+			
+			if (((ui32PDIndex + i) < ui32PDRequestStart) || ((ui32PDIndex + i) > ui32PDRequestEnd))
+			{
+					pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = ppsPTInfoList[i];
+					ppsPTInfoList[i] = IMG_NULL;
+			}
+#endif
+		}
+		else
+		{
+#if !defined(FIX_HW_BRN_31620)
+			
+			PVR_ASSERT(pui32PDEntry[i] != 0);
+#endif
+		}
+#if defined(FIX_HW_BRN_31620)
+		}
+#endif
+	}
+
+	#if defined(SGX_FEATURE_SYSTEM_CACHE)
+	#if defined(FIX_HW_BRN_31620)
+	
+	if (bFlushSystemCache)
+	{
+	#endif
+
+	MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo);
+	#endif 
+	#if defined(FIX_HW_BRN_31620)
+	}
+
+	
+	sHighDevVAddr.uiAddr = sHighDevVAddr.uiAddr - 1;
+
+	
+	if (bFlushSystemCache)
+	{
+		MMU_CONTEXT *psMMUContext;
+
+		if (bSharedPT)
+		{
+			MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+			while(psMMUContext)
+			{
+				for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+				{
+					psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i];
+				}
+
+				
+				psMMUContext = psMMUContext->psNext;
+			}
+		}
+		else
+		{
+			for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+			{
+				pMMUHeap->psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i];
+			}
+		}
+
+		
+		psMMUContext = pMMUHeap->psMMUContext;
+		for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+		{
+			IMG_UINT32 j;
+
+			for(j=0;j<BRN31620_CACHE_FLUSH_BITS_SIZE;j++)
+			{
+				if (ui32ModifiedCachelines[i] & (1 << j))
+				{
+					PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
+					MMU_PT_INFO *psTempPTInfo = IMG_NULL;
+					IMG_UINT32 *pui32Tmp;
+
+					ui32PDIndex = (((i * BRN31620_CACHE_FLUSH_BITS_SIZE) + j) * BRN31620_PDES_PER_CACHE_LINE_SIZE) + BRN31620_DUMMY_PDE_INDEX;
+
+					
+					if (psMMUContext->apsPTInfoList[ui32PDIndex])
+					{
+						psTempPTInfo = psMMUContext->apsPTInfoList[ui32PDIndex];
+					}
+					else
+					{
+						psTempPTInfo = psMMUContext->apsPTInfoListSave[ui32PDIndex];
+					}
+
+					PVR_ASSERT(psTempPTInfo != IMG_NULL);
+
+					pui32Tmp = (IMG_UINT32 *) psTempPTInfo->PTPageCpuVAddr;
+					PVR_ASSERT(pui32Tmp != IMG_NULL);
+					pui32Tmp[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+															| SGX_MMU_PTE_DUMMY_PAGE
+															| SGX_MMU_PTE_READONLY
+															| SGX_MMU_PTE_VALID;
+
+					PDUMPCOMMENT("BRN31620 Dump PTE for dummy page after wireing up new PT");
+					PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psTempPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32Tmp[BRN31620_DUMMY_PTE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+				}
+			}
+		}
+	}
+	#endif
+
+	return IMG_TRUE;
+}
+
+
+#if defined(PDUMP)
+IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext)
+{
+	BM_CONTEXT *pBMContext = hDevMemContext;
+	PVR_ASSERT(pBMContext);
+	 
+	return pBMContext->psMMUContext->ui32PDumpMMUContextID;
+}
+
+static IMG_VOID MMU_SetPDumpAttribs(PDUMP_MMU_ATTRIB *psMMUAttrib,
+	PVRSRV_DEVICE_NODE *psDeviceNode,
+	IMG_UINT32 ui32DataPageMask,
+	IMG_UINT32 ui32PTSize)
+{
+	
+	psMMUAttrib->sDevId = psDeviceNode->sDevId;
+	
+	psMMUAttrib->pszPDRegRegion = IMG_NULL;
+	psMMUAttrib->ui32DataPageMask = ui32DataPageMask;
+	
+	psMMUAttrib->ui32PTEValid = SGX_MMU_PTE_VALID;
+	psMMUAttrib->ui32PTSize = ui32PTSize;
+	psMMUAttrib->ui32PTEAlignShift = SGX_MMU_PTE_ADDR_ALIGNSHIFT;
+	
+	psMMUAttrib->ui32PDEMask = SGX_MMU_PDE_ADDR_MASK;
+	psMMUAttrib->ui32PDEAlignShift = SGX_MMU_PDE_ADDR_ALIGNSHIFT;
+}
+#endif 
+
+PVRSRV_ERROR
+MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr)
+{
+	IMG_UINT32 *pui32Tmp;
+	IMG_UINT32 i;
+	IMG_CPU_VIRTADDR pvPDCpuVAddr;
+	IMG_DEV_PHYADDR sPDDevPAddr;
+	IMG_CPU_PHYADDR sCpuPAddr;
+	MMU_CONTEXT *psMMUContext;
+	IMG_HANDLE hPDOSMemHandle = IMG_NULL;
+	SYS_DATA *psSysData;
+	PVRSRV_SGXDEV_INFO *psDevInfo;
+#if defined(PDUMP)
+	PDUMP_MMU_ATTRIB sMMUAttrib;
+#endif
+	PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Initialise"));
+
+	SysAcquireData(&psSysData);
+#if defined(PDUMP)
+	
+	
+	MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
+						SGX_MMU_PAGE_MASK,
+						SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
+#endif
+
+	OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				 sizeof (MMU_CONTEXT),
+				 (IMG_VOID **)&psMMUContext, IMG_NULL,
+				 "MMU Context");
+	if (psMMUContext == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+	OSMemSet (psMMUContext, 0, sizeof(MMU_CONTEXT));
+
+	
+	psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+	psMMUContext->psDevInfo = psDevInfo;
+
+	
+	psMMUContext->psDeviceNode = psDeviceNode;
+
+	
+	if(psDeviceNode->psLocalDevMemArena == IMG_NULL)
+	{
+		if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+							SGX_MMU_PAGE_SIZE,
+							SGX_MMU_PAGE_SIZE,
+							&pvPDCpuVAddr,
+							&hPDOSMemHandle) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+			return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+		}
+
+		if(pvPDCpuVAddr)
+		{
+			sCpuPAddr = OSMapLinToCPUPhys(hPDOSMemHandle,
+										  pvPDCpuVAddr);
+		}
+		else
+		{
+			
+			sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0);
+		}
+		sPDDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+		#if PAGE_TEST
+		PageTest(pvPDCpuVAddr, sPDDevPAddr);
+		#endif
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+		
+		if(!psDevInfo->pvMMUContextList)
+		{
+			
+			if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+								SGX_MMU_PAGE_SIZE,
+								SGX_MMU_PAGE_SIZE,
+								&psDevInfo->pvDummyPTPageCpuVAddr,
+								&psDevInfo->hDummyPTPageOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+				return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+			}
+
+			if(psDevInfo->pvDummyPTPageCpuVAddr)
+			{
+				sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
+											  psDevInfo->pvDummyPTPageCpuVAddr);
+			}
+			else
+			{
+				
+				sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyPTPageOSMemHandle, 0);
+			}
+			psDevInfo->sDummyPTDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+			
+			if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+								SGX_MMU_PAGE_SIZE,
+								SGX_MMU_PAGE_SIZE,
+								&psDevInfo->pvDummyDataPageCpuVAddr,
+								&psDevInfo->hDummyDataPageOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+				return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+			}
+
+			if(psDevInfo->pvDummyDataPageCpuVAddr)
+			{
+				sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
+											  psDevInfo->pvDummyDataPageCpuVAddr);
+			}
+			else
+			{
+				sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyDataPageOSMemHandle, 0);
+			}
+			psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+		}
+#endif 
+#if defined(FIX_HW_BRN_31620)
+		
+		if(!psDevInfo->pvMMUContextList)
+		{
+			IMG_UINT32 j;
+			
+			if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+								SGX_MMU_PAGE_SIZE,
+								SGX_MMU_PAGE_SIZE,
+								&psDevInfo->pvBRN31620DummyPageCpuVAddr,
+								&psDevInfo->hBRN31620DummyPageOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+				return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+			}				
+
+			
+			if(psDevInfo->pvBRN31620DummyPageCpuVAddr)
+			{
+				sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle,
+											  psDevInfo->pvBRN31620DummyPageCpuVAddr);
+			}
+			else
+			{
+				sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPageOSMemHandle, 0);
+			}
+
+			pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
+			for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
+			{
+				pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
+			}
+
+			psDevInfo->sBRN31620DummyPageDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+			PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+			
+			if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+								SGX_MMU_PAGE_SIZE,
+								SGX_MMU_PAGE_SIZE,
+								&psDevInfo->pvBRN31620DummyPTCpuVAddr,
+								&psDevInfo->hBRN31620DummyPTOSMemHandle) != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+				return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+			}				
+
+			
+			if(psDevInfo->pvBRN31620DummyPTCpuVAddr)
+			{
+				sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle,
+											  psDevInfo->pvBRN31620DummyPTCpuVAddr);
+			}
+			else
+			{
+				sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPTOSMemHandle, 0);
+			}
+
+			OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE);
+			psDevInfo->sBRN31620DummyPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+			PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+		}
+#endif
+	}
+	else
+	{
+		IMG_SYS_PHYADDR sSysPAddr;
+
+		
+		if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+					SGX_MMU_PAGE_SIZE,
+					IMG_NULL,
+					IMG_NULL,
+					0,
+					SGX_MMU_PAGE_SIZE,
+					0,
+					&(sSysPAddr.uiAddr))!= IMG_TRUE)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+			return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+		}
+
+		
+		sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+		sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+		pvPDCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+										SGX_MMU_PAGE_SIZE,
+										PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+										&hPDOSMemHandle);
+		if(!pvPDCpuVAddr)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+			return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+		}
+
+		#if PAGE_TEST
+		PageTest(pvPDCpuVAddr, sPDDevPAddr);
+		#endif
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+		
+		if(!psDevInfo->pvMMUContextList)
+		{
+			
+			if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+						SGX_MMU_PAGE_SIZE,
+						IMG_NULL,
+						IMG_NULL,
+						0,
+						SGX_MMU_PAGE_SIZE,
+						0,
+						&(sSysPAddr.uiAddr))!= IMG_TRUE)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+				return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+			}
+
+			
+			sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+			psDevInfo->sDummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+			psDevInfo->pvDummyPTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+																SGX_MMU_PAGE_SIZE,
+																PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+																&psDevInfo->hDummyPTPageOSMemHandle);
+			if(!psDevInfo->pvDummyPTPageCpuVAddr)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+				return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+			}
+
+			
+			if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+						SGX_MMU_PAGE_SIZE,
+						IMG_NULL,
+						IMG_NULL,
+						0,
+						SGX_MMU_PAGE_SIZE,
+						0,
+						&(sSysPAddr.uiAddr))!= IMG_TRUE)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+				return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+			}
+
+			
+			sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+			psDevInfo->sDummyDataDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+			psDevInfo->pvDummyDataPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+																SGX_MMU_PAGE_SIZE,
+																PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+																&psDevInfo->hDummyDataPageOSMemHandle);
+			if(!psDevInfo->pvDummyDataPageCpuVAddr)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+				return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+			}
+		}
+#endif 
+#if defined(FIX_HW_BRN_31620)
+		
+		if(!psDevInfo->pvMMUContextList)
+		{
+			IMG_UINT32 j;
+			
+			if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+						SGX_MMU_PAGE_SIZE,
+						IMG_NULL,
+						IMG_NULL,
+						0,
+						SGX_MMU_PAGE_SIZE,
+						0,
+						&(sSysPAddr.uiAddr))!= IMG_TRUE)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+				return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+			}
+
+			
+			sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+			psDevInfo->sBRN31620DummyPageDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+			psDevInfo->pvBRN31620DummyPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+																SGX_MMU_PAGE_SIZE,
+																PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+																&psDevInfo->hBRN31620DummyPageOSMemHandle);
+			if(!psDevInfo->pvBRN31620DummyPageCpuVAddr)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+				return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+			}
+
+			pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
+			for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
+			{
+				pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
+			}
+			PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+			
+			if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+						SGX_MMU_PAGE_SIZE,
+						IMG_NULL,
+						IMG_NULL,
+						0,
+						SGX_MMU_PAGE_SIZE,
+						0,
+						&(sSysPAddr.uiAddr))!= IMG_TRUE)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+				return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+			}
+
+			
+			sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+			psDevInfo->sBRN31620DummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+			psDevInfo->pvBRN31620DummyPTCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+																SGX_MMU_PAGE_SIZE,
+																PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+																&psDevInfo->hBRN31620DummyPTOSMemHandle);
+
+			if(!psDevInfo->pvBRN31620DummyPTCpuVAddr)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+				return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+			}
+
+			OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE);		
+			PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+		}
+#endif 
+	}
+
+#if defined(FIX_HW_BRN_31620)
+	if (!psDevInfo->pvMMUContextList)
+	{
+		
+		psDevInfo->hKernelMMUContext = psMMUContext;
+		PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: saving kernel mmu context: %p", psMMUContext));
+	}
+#endif
+
+#if defined(PDUMP)
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	
+	{
+		PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+		if(psPerProc == IMG_NULL)
+		{
+			
+			psMMUContext->bPDumpActive = IMG_TRUE;
+		}
+		else
+		{
+			psMMUContext->bPDumpActive = psPerProc->bPDumpActive;
+		}
+	}
+#endif 
+	
+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
+	PDUMPCOMMENT("Alloc page directory for new MMU context (PDDevPAddr == 0x%08x)",
+			sPDDevPAddr.uiAddr);
+#else
+	PDUMPCOMMENT("Alloc page directory for new MMU context, 64-bit arch detected (PDDevPAddr == 0x%08x%08x)",
+			sPDDevPAddr.uiHighAddr, sPDDevPAddr.uiAddr);
+#endif
+	PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDOSMemHandle, 0, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG);
+#endif 
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+	EnableHostAccess(psMMUContext);
+#endif
+
+	if (pvPDCpuVAddr)
+	{
+		pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"));
+		return PVRSRV_ERROR_INVALID_CPU_ADDR;
+	}
+
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+	
+	for(i=0; i<SGX_MMU_PD_SIZE; i++)
+	{
+		pui32Tmp[i] = (psDevInfo->sDummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+					| SGX_MMU_PDE_PAGE_SIZE_4K
+					| SGX_MMU_PDE_VALID;
+	}
+
+	if(!psDevInfo->pvMMUContextList)
+	{
+		
+
+
+		pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr;
+		for(i=0; i<SGX_MMU_PT_SIZE; i++)
+		{
+			pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+						| SGX_MMU_PTE_VALID;
+		}
+		
+		PDUMPCOMMENT("Dummy Page table contents");
+		PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hDummyPTOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+		
+
+		pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr;
+		for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++)
+		{
+			pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE;
+		}
+		
+		PDUMPCOMMENT("Dummy Data Page contents");
+		PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+	}
+#else 
+	
+	for(i=0; i<SGX_MMU_PD_SIZE; i++)
+	{
+		
+		pui32Tmp[i] = 0;
+	}
+#endif 
+
+#if defined(PDUMP)
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	if(psMMUContext->bPDumpActive)
+#endif 
+	{
+		
+		PDUMPCOMMENT("Page directory contents");
+		PDUMPPDENTRIES(&sMMUAttrib, hPDOSMemHandle, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+	}
+#endif
+#if defined(FIX_HW_BRN_31620)
+	{
+		IMG_UINT32 i;
+		IMG_UINT32 ui32PDCount = 0;
+		IMG_UINT32 *pui32PT;
+		pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
+
+		PDUMPCOMMENT("BRN31620 Set up dummy PT");
+
+		pui32PT = (IMG_UINT32 *) psDevInfo->pvBRN31620DummyPTCpuVAddr;
+		pui32PT[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+								| SGX_MMU_PTE_DUMMY_PAGE
+								| SGX_MMU_PTE_READONLY
+								| SGX_MMU_PTE_VALID;
+
+
+#if defined(PDUMP)
+		
+		PDUMPCOMMENT("BRN31620 Dump dummy PT contents");
+		PDUMPMEMPTENTRIES(&sMMUAttrib,  psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+		PDUMPCOMMENT("BRN31620 Dump dummy page contents");
+		PDUMPMEMPTENTRIES(&sMMUAttrib,  psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+				
+		for(i=0;i<SGX_MMU_PT_SIZE;i++)
+		{
+			PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPTOSMemHandle, &pui32PT[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+		}
+#endif
+		PDUMPCOMMENT("BRN31620 Dump PDE wire up");
+		
+		for(i=0;i<SGX_MMU_PD_SIZE;i++)
+		{
+			pui32Tmp[i] = 0;
+
+			if (ui32PDCount == BRN31620_DUMMY_PDE_INDEX)
+			{
+				pui32Tmp[i] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+						| SGX_MMU_PDE_PAGE_SIZE_4K
+						| SGX_MMU_PDE_DUMMY_PAGE
+						| SGX_MMU_PDE_VALID;
+			}
+				PDUMPMEMPTENTRIES(&sMMUAttrib, hPDOSMemHandle, (IMG_VOID *) &pui32Tmp[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+			ui32PDCount++;
+			if (ui32PDCount == BRN31620_PDES_PER_CACHE_LINE_SIZE)
+			{
+				
+				ui32PDCount = 0;
+			}
+		}
+
+
+		
+		PDUMPCOMMENT("BRN31620 dummy Page table contents");
+		PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+	}
+#endif
+#if defined(PDUMP)
+	
+	{
+		PVRSRV_ERROR eError;
+		
+		IMG_UINT32 ui32MMUType = 1;
+
+		#if defined(SGX_FEATURE_36BIT_MMU)
+			ui32MMUType = 3;
+		#else
+			#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+				ui32MMUType = 2;
+			#endif
+		#endif
+
+		eError = PDumpSetMMUContext(PVRSRV_DEVICE_TYPE_SGX,
+									psDeviceNode->sDevId.pszPDumpDevName,
+									&psMMUContext->ui32PDumpMMUContextID,
+									ui32MMUType,
+									PDUMP_PT_UNIQUETAG,
+									hPDOSMemHandle,
+									pvPDCpuVAddr);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to PDumpSetMMUContext failed"));
+			return eError;
+		}
+	}
+
+	
+	PDUMPCOMMENT("Set MMU context complete (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+	for(i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+	{
+		psMMUContext->ui32PDChangeMask[i] = 0;
+	}
+
+	for(i=0;i<BRN31620_CACHE_FLUSH_SIZE;i++)
+	{
+		psMMUContext->ui32PDCacheRangeRefCount[i] = 0;
+	}
+
+	for(i=0;i<SGX_MAX_PD_ENTRIES;i++)
+	{
+		psMMUContext->apsPTInfoListSave[i] = IMG_NULL;
+	}
+#endif
+	
+	psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr;
+	psMMUContext->sPDDevPAddr = sPDDevPAddr;
+	psMMUContext->hPDOSMemHandle = hPDOSMemHandle;
+
+	
+	*ppsMMUContext = psMMUContext;
+
+	
+	*psPDDevPAddr = sPDDevPAddr;
+
+	
+	psMMUContext->psNext = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
+	psDevInfo->pvMMUContextList = (IMG_VOID*)psMMUContext;
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+	DisableHostAccess(psMMUContext);
+#endif
+
+	return PVRSRV_OK;
+}
+
+IMG_VOID
+MMU_Finalise (MMU_CONTEXT *psMMUContext)
+{
+	IMG_UINT32 *pui32Tmp, i;
+	SYS_DATA *psSysData;
+	MMU_CONTEXT **ppsMMUContext;
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined(FIX_HW_BRN_31620)
+	PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
+	MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
+#endif
+
+	SysAcquireData(&psSysData);
+
+#if defined(PDUMP)
+	
+	PDUMPCOMMENT("Clear MMU context (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
+	PDUMPCLEARMMUCONTEXT(PVRSRV_DEVICE_TYPE_SGX, psMMUContext->psDeviceNode->sDevId.pszPDumpDevName, psMMUContext->ui32PDumpMMUContextID, 2);
+
+	
+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
+	PDUMPCOMMENT("Free page directory (PDDevPAddr == 0x%08x)",
+			psMMUContext->sPDDevPAddr.uiAddr);
+#else
+	PDUMPCOMMENT("Free page directory, 64-bit arch detected (PDDevPAddr == 0x%08x%08x)",
+			psMMUContext->sPDDevPAddr.uiHighAddr, psMMUContext->sPDDevPAddr.uiAddr);
+#endif
+#endif 
+
+	PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psMMUContext->hPDOSMemHandle, psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+	PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyPTPageOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+	PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+#endif
+
+	pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr;
+
+	
+	for(i=0; i<SGX_MMU_PD_SIZE; i++)
+	{
+		
+		pui32Tmp[i] = 0;
+	}
+
+	
+
+
+
+	if(psMMUContext->psDeviceNode->psLocalDevMemArena == IMG_NULL)
+	{
+#if defined(FIX_HW_BRN_31620)
+		PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
+#endif
+		OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+						SGX_MMU_PAGE_SIZE,
+						psMMUContext->pvPDCpuVAddr,
+						psMMUContext->hPDOSMemHandle);
+
+#if defined(FIX_HW_BRN_31620)
+		
+		if (!psMMUContextList->psNext)
+		{
+			PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+			OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+							SGX_MMU_PAGE_SIZE,
+							psDevInfo->pvBRN31620DummyPageCpuVAddr,
+							psDevInfo->hBRN31620DummyPageOSMemHandle);
+
+			PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+			OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+							SGX_MMU_PAGE_SIZE,
+							psDevInfo->pvBRN31620DummyPTCpuVAddr,
+							psDevInfo->hBRN31620DummyPTOSMemHandle);
+	
+		}
+#endif
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+		
+		if(!psMMUContextList->psNext)
+		{
+			OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+							SGX_MMU_PAGE_SIZE,
+							psDevInfo->pvDummyPTPageCpuVAddr,
+							psDevInfo->hDummyPTPageOSMemHandle);
+			OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+							SGX_MMU_PAGE_SIZE,
+							psDevInfo->pvDummyDataPageCpuVAddr,
+							psDevInfo->hDummyDataPageOSMemHandle);
+		}
+#endif
+	}
+	else
+	{
+		IMG_SYS_PHYADDR sSysPAddr;
+		IMG_CPU_PHYADDR sCpuPAddr;
+
+		
+		sCpuPAddr = OSMapLinToCPUPhys(psMMUContext->hPDOSMemHandle,
+									  psMMUContext->pvPDCpuVAddr);
+		sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+		
+		OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr,
+							SGX_MMU_PAGE_SIZE,
+                            PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+							psMMUContext->hPDOSMemHandle);
+		
+		RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+		
+		if(!psMMUContextList->psNext)
+		{
+			
+			sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
+										  psDevInfo->pvDummyPTPageCpuVAddr);
+			sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+			
+			OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr,
+								SGX_MMU_PAGE_SIZE,
+                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+								psDevInfo->hDummyPTPageOSMemHandle);
+			
+			RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+
+			
+			sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyDataPageOSMemHandle,
+										  psDevInfo->pvDummyDataPageCpuVAddr);
+			sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+			
+			OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr,
+								SGX_MMU_PAGE_SIZE,
+                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+								psDevInfo->hDummyDataPageOSMemHandle);
+			
+			RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+		}
+#endif
+#if defined(FIX_HW_BRN_31620)
+		
+		if(!psMMUContextList->psNext)
+		{
+			
+			PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+			sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle,
+										  psDevInfo->pvBRN31620DummyPageCpuVAddr);
+			sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+			
+			OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPageCpuVAddr,
+								SGX_MMU_PAGE_SIZE,
+                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+								psDevInfo->hBRN31620DummyPageOSMemHandle);
+			
+			RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+
+			
+			PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+			sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle,
+										  psDevInfo->pvBRN31620DummyPTCpuVAddr);
+			sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+			
+			OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPTCpuVAddr,
+								SGX_MMU_PAGE_SIZE,
+                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+								psDevInfo->hBRN31620DummyPTOSMemHandle);
+			
+			RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+		}
+#endif
+	}
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise"));
+
+	
+	ppsMMUContext = (MMU_CONTEXT**)&psMMUContext->psDevInfo->pvMMUContextList;
+	while(*ppsMMUContext)
+	{
+		if(*ppsMMUContext == psMMUContext)
+		{
+			
+			*ppsMMUContext = psMMUContext->psNext;
+			break;
+		}
+
+		
+		ppsMMUContext = &((*ppsMMUContext)->psNext);
+	}
+
+	
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL);
+	
+}
+
+
+IMG_VOID
+MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap)
+{
+	IMG_UINT32 *pui32PDCpuVAddr = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
+	IMG_UINT32 *pui32KernelPDCpuVAddr = (IMG_UINT32 *) psMMUHeap->psMMUContext->pvPDCpuVAddr;
+	IMG_UINT32 ui32PDEntry;
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+	IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
+#endif
+
+	
+	pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+	pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+
+	
+
+
+#if defined(PDUMP)
+	PDUMPCOMMENT("Page directory shared heap range copy");
+	PDUMPCOMMENT("  (Source heap MMU Context ID == %u, PT count == 0x%x)",
+			psMMUHeap->psMMUContext->ui32PDumpMMUContextID,
+			psMMUHeap->ui32PageTableCount);
+	PDUMPCOMMENT("  (Destination MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
+#endif 
+#ifdef SUPPORT_SGX_MMU_BYPASS
+	EnableHostAccess(psMMUContext);
+#endif
+
+	for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++)
+	{
+#if (!defined(SUPPORT_SGX_MMU_DUMMY_PAGE)) && (!defined(FIX_HW_BRN_31620))
+		
+		PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0);
+#endif
+
+		
+		pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry];
+		if (pui32PDCpuVAddr[ui32PDEntry])
+		{
+			
+		#if defined(PDUMP)
+			
+		#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+			if(psMMUContext->bPDumpActive)
+		#endif 
+			{
+				PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+			}
+		#endif
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+			bInvalidateDirectoryCache = IMG_TRUE;
+#endif
+		}
+	}
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+	DisableHostAccess(psMMUContext);
+#endif
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+	if (bInvalidateDirectoryCache)
+	{
+		
+
+
+
+		MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo);
+	}
+#endif
+}
+
+
+static IMG_VOID
+MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
+						  IMG_DEV_VIRTADDR sDevVAddr,
+						  IMG_UINT32 ui32PageCount,
+						  IMG_HANDLE hUniqueTag)
+{
+	IMG_DEV_VIRTADDR	sTmpDevVAddr;
+	IMG_UINT32			i;
+	IMG_UINT32			ui32PDIndex;
+	IMG_UINT32			ui32PTIndex;
+	IMG_UINT32			*pui32Tmp;
+	IMG_BOOL			bInvalidateDirectoryCache = IMG_FALSE;
+
+#if !defined (PDUMP)
+	PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+	
+	sTmpDevVAddr = sDevVAddr;
+
+	for(i=0; i<ui32PageCount; i++)
+	{
+		MMU_PT_INFO **ppsPTInfoList;
+
+		
+		ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+
+		
+		ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+		{
+			
+			ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
+
+			
+			if (!ppsPTInfoList[0])
+			{
+				PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
+
+				
+				sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
+
+				
+				continue;
+			}
+
+			
+			pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+			
+			if (!pui32Tmp)
+			{
+				continue;
+			}
+
+			CheckPT(ppsPTInfoList[0]);
+
+			
+			if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
+			{
+				ppsPTInfoList[0]->ui32ValidPTECount--;
+			}
+			else
+			{
+				PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Page is already invalid for alloc at VAddr:0x%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
+			}
+
+			
+			PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+			
+			pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+									| SGX_MMU_PTE_VALID;
+#else
+			
+#if defined(FIX_HW_BRN_31620)
+			BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]);
+#else
+			pui32Tmp[ui32PTIndex] = 0;
+#endif
+#endif
+
+			CheckPT(ppsPTInfoList[0]);
+		}
+
+		
+
+		if (ppsPTInfoList[0] && (ppsPTInfoList[0]->ui32ValidPTECount == 0)
+			)
+		{
+#if defined(FIX_HW_BRN_31620)
+			if (BRN31620FreePageTable(psMMUHeap, ui32PDIndex) == IMG_TRUE)
+			{
+				bInvalidateDirectoryCache = IMG_TRUE;
+			}
+#else
+			_DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
+			bInvalidateDirectoryCache = IMG_TRUE;
+#endif
+		}
+
+		
+		sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
+	}
+
+	if(bInvalidateDirectoryCache)
+	{
+		MMU_InvalidateDirectoryCache(psMMUHeap->psMMUContext->psDevInfo);
+	}
+	else
+	{
+		MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
+	}
+
+#if defined(PDUMP)
+	MMU_PDumpPageTables(psMMUHeap,
+						sDevVAddr,
+						psMMUHeap->ui32DataPageSize * ui32PageCount,
+						IMG_TRUE,
+						hUniqueTag);
+#endif 
+}
+
+
+static IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap,
+                                   IMG_SIZE_T ui32Start,
+                                   IMG_SIZE_T ui32End,
+                                   IMG_HANDLE hUniqueTag)
+{
+	MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap;
+	IMG_DEV_VIRTADDR Start;
+
+	Start.uiAddr = (IMG_UINT32)ui32Start;
+
+	MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (IMG_UINT32)((ui32End - ui32Start) >> pMMUHeap->ui32PTShift), hUniqueTag);
+}
+
+MMU_HEAP *
+MMU_Create (MMU_CONTEXT *psMMUContext,
+			DEV_ARENA_DESCRIPTOR *psDevArena,
+			RA_ARENA **ppsVMArena,
+			PDUMP_MMU_ATTRIB **ppsMMUAttrib)
+{
+	MMU_HEAP *pMMUHeap;
+	IMG_UINT32 ui32ScaleSize;
+
+	PVR_UNREFERENCED_PARAMETER(ppsMMUAttrib);
+
+	PVR_ASSERT (psDevArena != IMG_NULL);
+
+	if (psDevArena == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid parameter"));
+		return IMG_NULL;
+	}
+
+	OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+				 sizeof (MMU_HEAP),
+				 (IMG_VOID **)&pMMUHeap, IMG_NULL,
+				 "MMU Heap");
+	if (pMMUHeap == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to OSAllocMem failed"));
+		return IMG_NULL;
+	}
+
+	pMMUHeap->psMMUContext = psMMUContext;
+	pMMUHeap->psDevArena = psDevArena;
+
+	
+
+
+	switch(pMMUHeap->psDevArena->ui32DataPageSize)
+	{
+		case 0x1000:
+			ui32ScaleSize = 0;
+			pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4K;
+			break;
+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+		case 0x4000:
+			ui32ScaleSize = 2;
+			pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_16K;
+			break;
+		case 0x10000:
+			ui32ScaleSize = 4;
+			pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_64K;
+			break;
+		case 0x40000:
+			ui32ScaleSize = 6;
+			pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_256K;
+			break;
+		case 0x100000:
+			ui32ScaleSize = 8;
+			pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_1M;
+			break;
+		case 0x400000:
+			ui32ScaleSize = 10;
+			pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4M;
+			break;
+#endif 
+		default:
+			PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid data page size"));
+			goto ErrorFreeHeap;
+	}
+
+	
+	pMMUHeap->ui32DataPageSize = psDevArena->ui32DataPageSize;
+	pMMUHeap->ui32DataPageBitWidth = SGX_MMU_PAGE_SHIFT + ui32ScaleSize;
+	pMMUHeap->ui32DataPageMask = pMMUHeap->ui32DataPageSize - 1;
+	
+	pMMUHeap->ui32PTShift = pMMUHeap->ui32DataPageBitWidth;
+	pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize;
+	pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<<ui32ScaleSize);
+	pMMUHeap->ui32PTSize = (IMG_UINT32)(1UL<<pMMUHeap->ui32PTBitWidth) * sizeof(IMG_UINT32);
+
+	
+	if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32))
+	{
+		pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32);
+	}
+	pMMUHeap->ui32PTNumEntriesAllocated = pMMUHeap->ui32PTSize >> 2;
+
+	
+	pMMUHeap->ui32PTNumEntriesUsable = (IMG_UINT32)(1UL << pMMUHeap->ui32PTBitWidth);
+
+	
+	pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift;
+	pMMUHeap->ui32PDBitWidth = SGX_FEATURE_ADDRESS_SPACE_SIZE - pMMUHeap->ui32PTBitWidth - pMMUHeap->ui32DataPageBitWidth;
+	pMMUHeap->ui32PDMask = SGX_MMU_PD_MASK & (SGX_MMU_PD_MASK>>(32-SGX_FEATURE_ADDRESS_SPACE_SIZE));
+
+	
+#if !defined (SUPPORT_EXTERNAL_SYSTEM_CACHE)
+	
+
+
+
+	if(psDevArena->BaseDevVAddr.uiAddr > (pMMUHeap->ui32DataPageMask | pMMUHeap->ui32PTMask))
+	{
+		
+
+
+		PVR_ASSERT ((psDevArena->BaseDevVAddr.uiAddr
+						& (pMMUHeap->ui32DataPageMask
+							| pMMUHeap->ui32PTMask)) == 0);
+	}
+#endif
+	
+	pMMUHeap->ui32PTETotalUsable = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift;
+
+	
+	pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift;
+
+	
+
+
+	pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotalUsable + pMMUHeap->ui32PTNumEntriesUsable - 1)
+										>> pMMUHeap->ui32PTBitWidth;
+	PVR_ASSERT(pMMUHeap->ui32PageTableCount > 0);
+
+	
+	pMMUHeap->psVMArena = RA_Create(psDevArena->pszName,
+									psDevArena->BaseDevVAddr.uiAddr,
+									psDevArena->ui32Size,
+									IMG_NULL,
+									MAX(HOST_PAGESIZE(), pMMUHeap->ui32DataPageSize),
+									IMG_NULL,
+									IMG_NULL,
+									&MMU_FreePageTables,
+									pMMUHeap);
+
+	if (pMMUHeap->psVMArena == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to RA_Create failed"));
+		goto ErrorFreePagetables;
+	}
+
+#if defined(PDUMP)
+	
+	MMU_SetPDumpAttribs(&pMMUHeap->sMMUAttrib,
+						psMMUContext->psDeviceNode,
+						pMMUHeap->ui32DataPageMask,
+						pMMUHeap->ui32PTSize);
+	*ppsMMUAttrib = &pMMUHeap->sMMUAttrib;
+
+	PDUMPCOMMENT("Create MMU device from arena %s (Size == 0x%x, DataPageSize == 0x%x, BaseDevVAddr == 0x%x)",
+			psDevArena->pszName,
+			psDevArena->ui32Size,
+			pMMUHeap->ui32DataPageSize,
+			psDevArena->BaseDevVAddr.uiAddr);
+#endif 
+
+#if 0 
+	
+	if(psDevArena->ui32HeapID == SGX_TILED_HEAP_ID)
+	{
+		IMG_UINT32 ui32RegVal;
+		IMG_UINT32 ui32XTileStride;
+
+		
+
+
+
+
+		ui32XTileStride	= 2;
+
+		ui32RegVal = (EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK
+						& ((psDevArena->BaseDevVAddr.uiAddr>>20)
+						<< EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT))
+					|(EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK
+						& (((psDevArena->BaseDevVAddr.uiAddr+psDevArena->ui32Size)>>20)
+						<< EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT))
+					|(EUR_CR_BIF_TILE0_CFG_MASK
+						& (((ui32XTileStride<<1)|8) << EUR_CR_BIF_TILE0_CFG_SHIFT));
+		PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_TILE0, ui32RegVal);
+	}
+#endif
+
+	
+
+	*ppsVMArena = pMMUHeap->psVMArena;
+
+	return pMMUHeap;
+
+	
+ErrorFreePagetables:
+	_DeferredFreePageTables (pMMUHeap);
+
+ErrorFreeHeap:
+	OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
+	
+
+	return IMG_NULL;
+}
+
+IMG_VOID
+MMU_Delete (MMU_HEAP *pMMUHeap)
+{
+	if (pMMUHeap != IMG_NULL)
+	{
+		PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Delete"));
+
+		if(pMMUHeap->psVMArena)
+		{
+			RA_Delete (pMMUHeap->psVMArena);
+		}
+
+#if defined(PDUMP)
+		PDUMPCOMMENT("Delete MMU device from arena %s (BaseDevVAddr == 0x%x, PT count for deferred free == 0x%x)",
+				pMMUHeap->psDevArena->pszName,
+				pMMUHeap->psDevArena->BaseDevVAddr.uiAddr,
+				pMMUHeap->ui32PageTableCount);
+#endif 
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+		EnableHostAccess(pMMUHeap->psMMUContext);
+#endif
+		_DeferredFreePageTables (pMMUHeap);
+#ifdef SUPPORT_SGX_MMU_BYPASS
+		DisableHostAccess(pMMUHeap->psMMUContext);
+#endif
+
+		OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
+		
+	}
+}
+
+IMG_BOOL
+MMU_Alloc (MMU_HEAP *pMMUHeap,
+		   IMG_SIZE_T uSize,
+		   IMG_SIZE_T *pActualSize,
+		   IMG_UINT32 uFlags,
+		   IMG_UINT32 uDevVAddrAlignment,
+		   IMG_DEV_VIRTADDR *psDevVAddr)
+{
+	IMG_BOOL bStatus;
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+		"MMU_Alloc: uSize=0x%x, flags=0x%x, align=0x%x",
+		uSize, uFlags, uDevVAddrAlignment));
+
+	
+
+	if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
+	{
+		IMG_UINTPTR_T uiAddr;
+
+		bStatus = RA_Alloc (pMMUHeap->psVMArena,
+							uSize,
+							pActualSize,
+							IMG_NULL,
+							0,
+							uDevVAddrAlignment,
+							0,
+							&uiAddr);
+		if(!bStatus)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: RA_Alloc of VMArena failed"));
+			PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Alloc of DevVAddr failed from heap %s ID%d",
+									pMMUHeap->psDevArena->pszName,
+									pMMUHeap->psDevArena->ui32HeapID));
+			return bStatus;
+		}
+
+		psDevVAddr->uiAddr = IMG_CAST_TO_DEVVADDR_UINT(uiAddr);
+	}
+
+	#ifdef SUPPORT_SGX_MMU_BYPASS
+	EnableHostAccess(pMMUHeap->psMMUContext);
+	#endif
+
+	
+	bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, (IMG_UINT32)uSize);
+
+	#ifdef SUPPORT_SGX_MMU_BYPASS
+	DisableHostAccess(pMMUHeap->psMMUContext);
+	#endif
+
+	if (!bStatus)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: _DeferredAllocPagetables failed"));
+		PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Failed to alloc pagetable(s) for DevVAddr 0x%8.8x from heap %s ID%d",
+								psDevVAddr->uiAddr,
+								pMMUHeap->psDevArena->pszName,
+								pMMUHeap->psDevArena->ui32HeapID));
+		if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
+		{
+			
+			RA_Free (pMMUHeap->psVMArena, psDevVAddr->uiAddr, IMG_FALSE);
+		}
+	}
+
+	return bStatus;
+}
+
+IMG_VOID
+MMU_Free (MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
+{
+	PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+	if (pMMUHeap == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "MMU_Free: invalid parameter"));
+		return;
+	}
+
+	PVR_DPF((PVR_DBG_MESSAGE, "MMU_Free: Freeing DevVAddr 0x%08X from heap %s ID%d",
+								DevVAddr.uiAddr,
+								pMMUHeap->psDevArena->pszName,
+								pMMUHeap->psDevArena->ui32HeapID));
+
+	if((DevVAddr.uiAddr >= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr) &&
+		(DevVAddr.uiAddr + ui32Size <= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr + pMMUHeap->psDevArena->ui32Size))
+	{
+		RA_Free (pMMUHeap->psVMArena, DevVAddr.uiAddr, IMG_TRUE);
+		return;
+	}
+
+	PVR_DPF((PVR_DBG_ERROR,"MMU_Free: Couldn't free DevVAddr %08X from heap %s ID%d (not in range of heap))",
+							DevVAddr.uiAddr,
+							pMMUHeap->psDevArena->pszName,
+							pMMUHeap->psDevArena->ui32HeapID));
+}
+
+IMG_VOID
+MMU_Enable (MMU_HEAP *pMMUHeap)
+{
+	PVR_UNREFERENCED_PARAMETER(pMMUHeap);
+	
+}
+
+IMG_VOID
+MMU_Disable (MMU_HEAP *pMMUHeap)
+{
+	PVR_UNREFERENCED_PARAMETER(pMMUHeap);
+	
+}
+
+#if defined(FIX_HW_BRN_31620)
+IMG_VOID MMU_GetCacheFlushRange(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask)
+{
+	IMG_UINT32 i;
+
+	for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+	{
+		pui32RangeMask[i] = pMMUContext->ui32PDChangeMask[i];
+
+		
+		pMMUContext->ui32PDChangeMask[i] = 0;
+	}
+}
+
+IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr)
+{
+	*psDevPAddr = pMMUContext->sPDDevPAddr;
+}
+
+#endif
+#if defined(PDUMP)
+static IMG_VOID
+MMU_PDumpPageTables	(MMU_HEAP *pMMUHeap,
+					 IMG_DEV_VIRTADDR DevVAddr,
+					 IMG_SIZE_T uSize,
+					 IMG_BOOL bForUnmap,
+					 IMG_HANDLE hUniqueTag)
+{
+	IMG_UINT32	ui32NumPTEntries;
+	IMG_UINT32	ui32PTIndex;
+	IMG_UINT32	*pui32PTEntry;
+
+	MMU_PT_INFO **ppsPTInfoList;
+	IMG_UINT32 ui32PDIndex;
+	IMG_UINT32 ui32PTDumpCount;
+
+	
+	ui32NumPTEntries = (IMG_UINT32)((uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift);
+
+	
+	ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+	
+	ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+	
+	ui32PTIndex = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
+
+	
+	PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : "");
+
+	
+	while(ui32NumPTEntries > 0)
+	{
+		MMU_PT_INFO* psPTInfo = *ppsPTInfoList++;
+
+		if(ui32NumPTEntries <= pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex)
+		{
+			ui32PTDumpCount = ui32NumPTEntries;
+		}
+		else
+		{
+			ui32PTDumpCount = pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex;
+		}
+
+		if (psPTInfo)
+		{
+			IMG_UINT32 ui32Flags = 0;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+			ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+			pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr;
+			PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(IMG_UINT32), ui32Flags, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag);
+		}
+
+		
+		ui32NumPTEntries -= ui32PTDumpCount;
+
+		
+		ui32PTIndex = 0;
+	}
+
+	PDUMPCOMMENT("Finished page table mods %s", bForUnmap ? "(for unmap)" : "");
+}
+#endif 
+
+
+static IMG_VOID
+MMU_MapPage (MMU_HEAP *pMMUHeap,
+			 IMG_DEV_VIRTADDR DevVAddr,
+			 IMG_DEV_PHYADDR DevPAddr,
+			 IMG_UINT32 ui32MemFlags)
+{
+	IMG_UINT32 ui32Index;
+	IMG_UINT32 *pui32Tmp;
+	IMG_UINT32 ui32MMUFlags = 0;
+	MMU_PT_INFO **ppsPTInfoList;
+
+	
+	PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+	
+
+	if(((PVRSRV_MEM_READ|PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ|PVRSRV_MEM_WRITE))
+	{
+		
+		ui32MMUFlags = 0;
+	}
+	else if(PVRSRV_MEM_READ & ui32MemFlags)
+	{
+		
+		ui32MMUFlags |= SGX_MMU_PTE_READONLY;
+	}
+	else if(PVRSRV_MEM_WRITE & ui32MemFlags)
+	{
+		
+		ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY;
+	}
+
+	
+	if(PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags)
+	{
+		ui32MMUFlags |= SGX_MMU_PTE_CACHECONSISTENT;
+	}
+
+#if !defined(FIX_HW_BRN_25503)
+	
+	if(PVRSRV_MEM_EDM_PROTECT & ui32MemFlags)
+	{
+		ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT;
+	}
+#endif
+
+	
+
+
+	
+	ui32Index = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+	
+	ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
+
+	CheckPT(ppsPTInfoList[0]);
+
+	
+	ui32Index = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
+
+	
+	pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+	{
+		IMG_UINT32 uTmp = pui32Tmp[ui32Index];
+		
+		
+#if defined(FIX_HW_BRN_31620)
+		if ((uTmp & SGX_MMU_PTE_VALID) && ((DevVAddr.uiAddr & BRN31620_PDE_CACHE_FILL_MASK) != BRN31620_DUMMY_PAGE_OFFSET))
+#else
+ 		if ((uTmp & SGX_MMU_PTE_VALID) != 0)
+#endif
+
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08X PDIdx:%u PTIdx:%u",
+									DevVAddr.uiAddr,
+									DevVAddr.uiAddr >> pMMUHeap->ui32PDShift,
+									ui32Index ));
+			PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08X", uTmp));
+			PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08X", DevPAddr.uiAddr));
+		}
+#if !defined(FIX_HW_BRN_31620)
+		PVR_ASSERT((uTmp & SGX_MMU_PTE_VALID) == 0);
+#endif
+	}
+#endif
+
+	
+	ppsPTInfoList[0]->ui32ValidPTECount++;
+
+	
+	pui32Tmp[ui32Index] = ((DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+						& ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT))
+						| SGX_MMU_PTE_VALID
+						| ui32MMUFlags;
+
+	CheckPT(ppsPTInfoList[0]);
+}
+
+
+IMG_VOID
+MMU_MapScatter (MMU_HEAP *pMMUHeap,
+				IMG_DEV_VIRTADDR DevVAddr,
+				IMG_SYS_PHYADDR *psSysAddr,
+				IMG_SIZE_T uSize,
+				IMG_UINT32 ui32MemFlags,
+				IMG_HANDLE hUniqueTag)
+{
+#if defined(PDUMP)
+	IMG_DEV_VIRTADDR MapBaseDevVAddr;
+#endif 
+	IMG_UINT32 uCount, i;
+	IMG_DEV_PHYADDR DevPAddr;
+
+	PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+#if defined(PDUMP)
+	MapBaseDevVAddr = DevVAddr;
+#else
+	PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif 
+
+	for (i=0, uCount=0; uCount<uSize; i++, uCount+=pMMUHeap->ui32DataPageSize)
+	{
+		IMG_SYS_PHYADDR sSysAddr;
+
+		sSysAddr = psSysAddr[i];
+
+
+		
+		PVR_ASSERT((sSysAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+		DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysAddr);
+
+		MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
+		DevVAddr.uiAddr += pMMUHeap->ui32DataPageSize;
+
+		PVR_DPF ((PVR_DBG_MESSAGE,
+				 "MMU_MapScatter: devVAddr=%08X, SysAddr=%08X, size=0x%x/0x%x",
+				  DevVAddr.uiAddr, sSysAddr.uiAddr, uCount, uSize));
+	}
+
+#if defined(PDUMP)
+	MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
+#endif 
+}
+
+IMG_VOID
+MMU_MapPages (MMU_HEAP *pMMUHeap,
+			  IMG_DEV_VIRTADDR DevVAddr,
+			  IMG_SYS_PHYADDR SysPAddr,
+			  IMG_SIZE_T uSize,
+			  IMG_UINT32 ui32MemFlags,
+			  IMG_HANDLE hUniqueTag)
+{
+	IMG_DEV_PHYADDR DevPAddr;
+#if defined(PDUMP)
+	IMG_DEV_VIRTADDR MapBaseDevVAddr;
+#endif 
+	IMG_UINT32 uCount;
+	IMG_UINT32 ui32VAdvance;
+	IMG_UINT32 ui32PAdvance;
+
+	PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+	PVR_DPF ((PVR_DBG_MESSAGE, "MMU_MapPages: heap:%s, heap_id:%d devVAddr=%08X, SysPAddr=%08X, size=0x%x",
+								pMMUHeap->psDevArena->pszName,
+								pMMUHeap->psDevArena->ui32HeapID,
+								DevVAddr.uiAddr, 
+								SysPAddr.uiAddr,
+								uSize));
+
+	
+	ui32VAdvance = pMMUHeap->ui32DataPageSize;
+	ui32PAdvance = pMMUHeap->ui32DataPageSize;
+
+#if defined(PDUMP)
+	MapBaseDevVAddr = DevVAddr;
+#else
+	PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif 
+
+	DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr);
+
+	
+	PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+#if defined(FIX_HW_BRN_23281)
+	if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
+	{
+		ui32VAdvance *= 2;
+	}
+#endif
+
+	
+
+
+	if(ui32MemFlags & PVRSRV_MEM_DUMMY)
+	{
+		ui32PAdvance = 0;
+	}
+
+	for (uCount=0; uCount<uSize; uCount+=ui32VAdvance)
+	{
+		MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
+		DevVAddr.uiAddr += ui32VAdvance;
+		DevPAddr.uiAddr += ui32PAdvance;
+	}
+
+#if defined(PDUMP)
+	MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
+#endif 
+}
+
+IMG_VOID
+MMU_MapShadow (MMU_HEAP          *pMMUHeap,
+			   IMG_DEV_VIRTADDR   MapBaseDevVAddr,
+			   IMG_SIZE_T         uByteSize,
+			   IMG_CPU_VIRTADDR   CpuVAddr,
+			   IMG_HANDLE         hOSMemHandle,
+			   IMG_DEV_VIRTADDR  *pDevVAddr,
+			   IMG_UINT32         ui32MemFlags,
+			   IMG_HANDLE         hUniqueTag)
+{
+	IMG_UINT32			i;
+	IMG_UINT32			uOffset = 0;
+	IMG_DEV_VIRTADDR	MapDevVAddr;
+	IMG_UINT32			ui32VAdvance;
+	IMG_UINT32			ui32PAdvance;
+
+#if !defined (PDUMP)
+	PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+	PVR_DPF ((PVR_DBG_MESSAGE,
+			"MMU_MapShadow: DevVAddr:%08X, Bytes:0x%x, CPUVAddr:%08X",
+			MapBaseDevVAddr.uiAddr,
+			uByteSize,
+			(IMG_UINTPTR_T)CpuVAddr));
+
+	
+	ui32VAdvance = pMMUHeap->ui32DataPageSize;
+	ui32PAdvance = pMMUHeap->ui32DataPageSize;
+
+	
+	PVR_ASSERT(((IMG_UINTPTR_T)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
+	PVR_ASSERT(((IMG_UINT32)uByteSize & pMMUHeap->ui32DataPageMask) == 0);
+	pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr;
+
+#if defined(FIX_HW_BRN_23281)
+	if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
+	{
+		ui32VAdvance *= 2;
+	}
+#endif
+
+	
+
+
+	if(ui32MemFlags & PVRSRV_MEM_DUMMY)
+	{
+		ui32PAdvance = 0;
+	}
+
+	
+	MapDevVAddr = MapBaseDevVAddr;
+	for (i=0; i<uByteSize; i+=ui32VAdvance)
+	{
+		IMG_CPU_PHYADDR CpuPAddr;
+		IMG_DEV_PHYADDR DevPAddr;
+
+		if(CpuVAddr)
+		{
+			CpuPAddr = OSMapLinToCPUPhys (hOSMemHandle,
+										  (IMG_VOID *)((IMG_UINTPTR_T)CpuVAddr + uOffset));
+		}
+		else
+		{
+			CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset);
+		}
+		DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr);
+
+		
+		PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+		PVR_DPF ((PVR_DBG_MESSAGE,
+				"Offset=0x%x: CpuVAddr=%08X, CpuPAddr=%08X, DevVAddr=%08X, DevPAddr=%08X",
+				uOffset,
+				(IMG_UINTPTR_T)CpuVAddr + uOffset,
+				CpuPAddr.uiAddr,
+				MapDevVAddr.uiAddr,
+				DevPAddr.uiAddr));
+
+		MMU_MapPage (pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags);
+
+		
+		MapDevVAddr.uiAddr += ui32VAdvance;
+		uOffset += ui32PAdvance;
+	}
+
+#if defined(PDUMP)
+	MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uByteSize, IMG_FALSE, hUniqueTag);
+#endif 
+}
+
+
+IMG_VOID
+MMU_UnmapPages (MMU_HEAP *psMMUHeap,
+				IMG_DEV_VIRTADDR sDevVAddr,
+				IMG_UINT32 ui32PageCount,
+				IMG_HANDLE hUniqueTag)
+{
+	IMG_UINT32			uPageSize = psMMUHeap->ui32DataPageSize;
+	IMG_DEV_VIRTADDR	sTmpDevVAddr;
+	IMG_UINT32			i;
+	IMG_UINT32			ui32PDIndex;
+	IMG_UINT32			ui32PTIndex;
+	IMG_UINT32			*pui32Tmp;
+
+#if !defined (PDUMP)
+	PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+	
+	sTmpDevVAddr = sDevVAddr;
+
+	for(i=0; i<ui32PageCount; i++)
+	{
+		MMU_PT_INFO **ppsPTInfoList;
+
+		
+		ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+
+		
+		ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+		
+		ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
+
+		
+		if (!ppsPTInfoList[0])
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",
+									sTmpDevVAddr.uiAddr,
+									sDevVAddr.uiAddr,
+									i,
+									ui32PDIndex,
+									ui32PTIndex));
+
+			
+			sTmpDevVAddr.uiAddr += uPageSize;
+
+			
+			continue;
+		}
+
+		CheckPT(ppsPTInfoList[0]);
+
+		
+		pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+		
+		if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
+		{
+			ppsPTInfoList[0]->ui32ValidPTECount--;
+		}
+		else
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page is already invalid for alloc at VAddr:0x%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",
+									sTmpDevVAddr.uiAddr,
+									sDevVAddr.uiAddr,
+									i,
+									ui32PDIndex,
+									ui32PTIndex));
+			PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page table entry value: 0x%08X", pui32Tmp[ui32PTIndex]));
+		}
+
+		
+		PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+		
+		pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+								| SGX_MMU_PTE_VALID;
+#else
+		
+#if defined(FIX_HW_BRN_31620)
+		BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]);
+#else
+		pui32Tmp[ui32PTIndex] = 0;
+#endif
+#endif
+
+		CheckPT(ppsPTInfoList[0]);
+
+		
+		sTmpDevVAddr.uiAddr += uPageSize;
+	}
+
+	MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
+
+#if defined(PDUMP)
+	MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag);
+#endif 
+}
+
+
+IMG_DEV_PHYADDR
+MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr)
+{
+	IMG_UINT32 *pui32PageTable;
+	IMG_UINT32 ui32Index;
+	IMG_DEV_PHYADDR sDevPAddr;
+	MMU_PT_INFO **ppsPTInfoList;
+
+	
+	ui32Index = sDevVPageAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+	
+	ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
+	if (!ppsPTInfoList[0])
+	{
+		PVR_DPF((PVR_DBG_ERROR,"MMU_GetPhysPageAddr: Not mapped in at 0x%08x", sDevVPageAddr.uiAddr));
+		sDevPAddr.uiAddr = 0;
+		return sDevPAddr;
+	}
+
+	
+	ui32Index = (sDevVPageAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
+
+	
+	pui32PageTable = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+	
+	sDevPAddr.uiAddr = pui32PageTable[ui32Index];
+
+	
+	sDevPAddr.uiAddr &= ~(pMMUHeap->ui32DataPageMask>>SGX_MMU_PTE_ADDR_ALIGNSHIFT);
+
+	
+	sDevPAddr.uiAddr <<= SGX_MMU_PTE_ADDR_ALIGNSHIFT;
+
+	return sDevPAddr;
+}
+
+
+IMG_DEV_PHYADDR MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext)
+{
+	return (pMMUContext->sPDDevPAddr);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXGetPhysPageAddrKM (IMG_HANDLE hDevMemHeap,
+								   IMG_DEV_VIRTADDR sDevVAddr,
+								   IMG_DEV_PHYADDR *pDevPAddr,
+								   IMG_CPU_PHYADDR *pCpuPAddr)
+{
+	MMU_HEAP *pMMUHeap;
+	IMG_DEV_PHYADDR DevPAddr;
+
+	
+
+	pMMUHeap = (MMU_HEAP*)BM_GetMMUHeap(hDevMemHeap);
+
+	DevPAddr = MMU_GetPhysPageAddr(pMMUHeap, sDevVAddr);
+	pCpuPAddr->uiAddr = DevPAddr.uiAddr; 
+	pDevPAddr->uiAddr = DevPAddr.uiAddr;
+
+	return (pDevPAddr->uiAddr != 0) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+
+PVRSRV_ERROR SGXGetMMUPDAddrKM(IMG_HANDLE		hDevCookie,
+								IMG_HANDLE 		hDevMemContext,
+								IMG_DEV_PHYADDR *psPDDevPAddr)
+{
+	if (!hDevCookie || !hDevMemContext || !psPDDevPAddr)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	*psPDDevPAddr = ((BM_CONTEXT*)hDevMemContext)->psMMUContext->sPDDevPAddr;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+	PVRSRV_ERROR eError;
+	SYS_DATA *psSysData;
+	RA_ARENA *psLocalDevMemArena;
+	IMG_HANDLE hOSMemHandle = IMG_NULL;
+	IMG_BYTE *pui8MemBlock = IMG_NULL;
+	IMG_SYS_PHYADDR sMemBlockSysPAddr;
+	IMG_CPU_PHYADDR sMemBlockCpuPAddr;
+
+	SysAcquireData(&psSysData);
+
+	psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+	
+	if(psLocalDevMemArena == IMG_NULL)
+	{
+		
+		eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+						      3 * SGX_MMU_PAGE_SIZE,
+						      SGX_MMU_PAGE_SIZE,
+						      (IMG_VOID **)&pui8MemBlock,
+						      &hOSMemHandle);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed"));
+			return eError;
+		}
+
+		
+		if(pui8MemBlock)
+		{
+			sMemBlockCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle,
+												  pui8MemBlock);
+		}
+		else
+		{
+			
+			sMemBlockCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, 0);
+		}
+	}
+	else
+	{
+		
+
+		if(RA_Alloc(psLocalDevMemArena,
+					3 * SGX_MMU_PAGE_SIZE,
+					IMG_NULL,
+					IMG_NULL,
+					0,
+					SGX_MMU_PAGE_SIZE,
+					0,
+					&(sMemBlockSysPAddr.uiAddr)) != IMG_TRUE)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to RA_Alloc failed"));
+			return PVRSRV_ERROR_OUT_OF_MEMORY;
+		}
+
+		
+		sMemBlockCpuPAddr = SysSysPAddrToCpuPAddr(sMemBlockSysPAddr);
+		pui8MemBlock = OSMapPhysToLin(sMemBlockCpuPAddr,
+									  SGX_MMU_PAGE_SIZE * 3,
+									  PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+									  &hOSMemHandle);
+		if(!pui8MemBlock)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR failed to map page tables"));
+			return PVRSRV_ERROR_BAD_MAPPING;
+		}
+	}
+
+	psDevInfo->hBIFResetPDOSMemHandle = hOSMemHandle;
+	psDevInfo->sBIFResetPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sMemBlockCpuPAddr);
+	psDevInfo->sBIFResetPTDevPAddr.uiAddr = psDevInfo->sBIFResetPDDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
+	psDevInfo->sBIFResetPageDevPAddr.uiAddr = psDevInfo->sBIFResetPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
+	
+	
+	psDevInfo->pui32BIFResetPD = (IMG_UINT32 *)pui8MemBlock;
+	psDevInfo->pui32BIFResetPT = (IMG_UINT32 *)(pui8MemBlock + SGX_MMU_PAGE_SIZE);
+
+	
+	OSMemSet(psDevInfo->pui32BIFResetPD, 0, SGX_MMU_PAGE_SIZE);
+	OSMemSet(psDevInfo->pui32BIFResetPT, 0, SGX_MMU_PAGE_SIZE);
+	
+	OSMemSet(pui8MemBlock + (2 * SGX_MMU_PAGE_SIZE), 0xDB, SGX_MMU_PAGE_SIZE);
+
+	return PVRSRV_OK;
+}
+
+IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+	SYS_DATA *psSysData;
+	RA_ARENA *psLocalDevMemArena;
+	IMG_SYS_PHYADDR sPDSysPAddr;
+
+	SysAcquireData(&psSysData);
+
+	psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+	
+	if(psLocalDevMemArena == IMG_NULL)
+	{
+		OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+					3 * SGX_MMU_PAGE_SIZE,
+					psDevInfo->pui32BIFResetPD,
+					psDevInfo->hBIFResetPDOSMemHandle);
+	}
+	else
+	{
+		OSUnMapPhysToLin(psDevInfo->pui32BIFResetPD,
+                         3 * SGX_MMU_PAGE_SIZE,
+                         PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+                         psDevInfo->hBIFResetPDOSMemHandle);
+
+		sPDSysPAddr = SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->sBIFResetPDDevPAddr);
+		RA_Free(psLocalDevMemArena, sPDSysPAddr.uiAddr, IMG_FALSE);
+	}
+}
+
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_DEVICE_NODE	*psDeviceNode)
+{
+	PVRSRV_ERROR eError;
+	SYS_DATA *psSysData;
+	RA_ARENA *psLocalDevMemArena;
+	IMG_HANDLE hPTPageOSMemHandle = IMG_NULL;
+	IMG_HANDLE hPDPageOSMemHandle = IMG_NULL;
+	IMG_UINT32 *pui32PD = IMG_NULL;
+	IMG_UINT32 *pui32PT = IMG_NULL;
+	IMG_CPU_PHYADDR sCpuPAddr;
+	IMG_DEV_PHYADDR sPTDevPAddr;
+	IMG_DEV_PHYADDR sPDDevPAddr;
+	PVRSRV_SGXDEV_INFO *psDevInfo;
+	IMG_UINT32 ui32PDOffset;
+	IMG_UINT32 ui32PTOffset;
+
+	psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+	SysAcquireData(&psSysData);
+
+	psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+	
+	if(psLocalDevMemArena == IMG_NULL)
+	{
+		
+		eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+						   SGX_MMU_PAGE_SIZE,
+						   SGX_MMU_PAGE_SIZE,
+						   (IMG_VOID **)&pui32PT,
+						   &hPTPageOSMemHandle);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
+			return eError;
+		}
+		ui32PTOffset = 0;
+
+		eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+						   SGX_MMU_PAGE_SIZE,
+						   SGX_MMU_PAGE_SIZE,
+						   (IMG_VOID **)&pui32PD,
+						   &hPDPageOSMemHandle);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
+			return eError;
+		}
+		ui32PDOffset = 0;
+
+		
+		if(pui32PT)
+        {
+            sCpuPAddr = OSMapLinToCPUPhys(hPTPageOSMemHandle,
+										  pui32PT);
+        }
+        else
+        {
+            
+            sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0);
+        }
+		sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+		if(pui32PD)
+        {
+            sCpuPAddr = OSMapLinToCPUPhys(hPDPageOSMemHandle,
+										  pui32PD);
+        }
+        else
+        {
+            
+            sCpuPAddr = OSMemHandleToCpuPAddr(hPDPageOSMemHandle, 0);
+        }
+		sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+	}
+	else
+	{
+		
+
+		if(RA_Alloc(psLocalDevMemArena,
+					SGX_MMU_PAGE_SIZE * 2,
+					IMG_NULL,
+					IMG_NULL,
+					0,
+					SGX_MMU_PAGE_SIZE,
+					0,
+					&(psDevInfo->sBRN22997SysPAddr.uiAddr))!= IMG_TRUE)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to RA_Alloc failed"));
+			return PVRSRV_ERROR_OUT_OF_MEMORY;
+		}
+
+		
+		sCpuPAddr = SysSysPAddrToCpuPAddr(psDevInfo->sBRN22997SysPAddr);
+		pui32PT = OSMapPhysToLin(sCpuPAddr,
+								SGX_MMU_PAGE_SIZE * 2,
+                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+								&hPTPageOSMemHandle);
+		if(!pui32PT)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR failed to map page tables"));
+			return PVRSRV_ERROR_BAD_MAPPING;
+		}
+		ui32PTOffset = 0;
+
+		
+		sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+		
+		pui32PD = pui32PT + SGX_MMU_PAGE_SIZE/sizeof(IMG_UINT32);
+		ui32PDOffset = SGX_MMU_PAGE_SIZE;
+		hPDPageOSMemHandle = hPTPageOSMemHandle;
+		sPDDevPAddr.uiAddr = sPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
+	}
+
+	OSMemSet(pui32PD, 0, SGX_MMU_PAGE_SIZE);
+	OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE);
+
+	
+	PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDPageOSMemHandle, ui32PDOffset, pui32PD, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG);
+	PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPTPageOSMemHandle, ui32PTOffset, pui32PT, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+	PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, hPDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+	PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, hPTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
+
+	psDevInfo->hBRN22997PTPageOSMemHandle = hPTPageOSMemHandle;
+	psDevInfo->hBRN22997PDPageOSMemHandle = hPDPageOSMemHandle;
+	psDevInfo->sBRN22997PTDevPAddr = sPTDevPAddr;
+	psDevInfo->sBRN22997PDDevPAddr = sPDDevPAddr;
+	psDevInfo->pui32BRN22997PD = pui32PD;
+	psDevInfo->pui32BRN22997PT = pui32PT;
+
+	return PVRSRV_OK;
+}
+
+
+IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+	IMG_UINT32 *pui32PD = psDevInfo->pui32BRN22997PD;
+	IMG_UINT32 *pui32PT = psDevInfo->pui32BRN22997PT;
+	IMG_UINT32 ui32PDIndex;
+	IMG_UINT32 ui32PTIndex;
+	IMG_DEV_VIRTADDR sDevVAddr;
+	volatile IMG_UINT32 *pui32HostPort;
+	IMG_UINT32 ui32BIFCtrl;
+
+	
+	
+	
+	pui32HostPort = (volatile IMG_UINT32*)(((IMG_UINT8*)psDevInfo->pvHostPortBaseKM) + SYS_SGX_HOSTPORT_BRN23030_OFFSET);
+
+	
+	sDevVAddr.uiAddr = SYS_SGX_HOSTPORT_BASE_DEVVADDR + SYS_SGX_HOSTPORT_BRN23030_OFFSET;
+
+	ui32PDIndex = (sDevVAddr.uiAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
+	ui32PTIndex = (sDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+
+	
+	pui32PD[ui32PDIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+							| SGX_MMU_PDE_VALID;
+	
+	pui32PT[ui32PTIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+							| SGX_MMU_PTE_VALID;
+
+	PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+	PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
+
+	
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0,
+				 psDevInfo->sBRN22997PDDevPAddr.uiAddr);
+	PDUMPPDREG(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sBRN22997PDDevPAddr.uiAddr, PDUMP_PD_UNIQUETAG);
+
+	
+	ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
+	PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+	PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+
+	
+	if (pui32HostPort)
+	{
+		 
+		IMG_UINT32 ui32Tmp;
+		ui32Tmp = *pui32HostPort;
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR,"Host Port not present for BRN22997 workaround"));
+	}
+
+	
+
+
+
+
+	
+	PDUMPCOMMENT("RDW :SGXMEM:v4:%08X\r\n", sDevVAddr.uiAddr);
+	
+    PDUMPCOMMENT("SAB :SGXMEM:v4:%08X 4 0 hostport.bin", sDevVAddr.uiAddr);
+
+	
+	pui32PD[ui32PDIndex] = 0;
+	pui32PT[ui32PTIndex] = 0;
+
+	
+	PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+	PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
+
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
+	PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+	PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+}
+
+
+IMG_VOID WorkaroundBRN22997Free(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	SYS_DATA *psSysData;
+	RA_ARENA *psLocalDevMemArena;
+	PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+
+	SysAcquireData(&psSysData);
+
+	psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+	PDUMPFREEPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN22997PDPageOSMemHandle, psDevInfo->pui32BRN22997PD, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG);
+	PDUMPFREEPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN22997PTPageOSMemHandle, psDevInfo->pui32BRN22997PT, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+	
+	if(psLocalDevMemArena == IMG_NULL)
+	{
+		if (psDevInfo->pui32BRN22997PD != IMG_NULL)
+		{
+			OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+						  SGX_MMU_PAGE_SIZE,
+						  psDevInfo->pui32BRN22997PD,
+						  psDevInfo->hBRN22997PDPageOSMemHandle);
+		}
+
+		if (psDevInfo->pui32BRN22997PT != IMG_NULL)
+		{
+			OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+						  SGX_MMU_PAGE_SIZE,
+						  psDevInfo->pui32BRN22997PT,
+						  psDevInfo->hBRN22997PTPageOSMemHandle);
+		}
+	}
+	else
+	{
+		if (psDevInfo->pui32BRN22997PT != IMG_NULL)
+		{
+			OSUnMapPhysToLin(psDevInfo->pui32BRN22997PT,
+				 SGX_MMU_PAGE_SIZE * 2,
+				 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+				 psDevInfo->hBRN22997PTPageOSMemHandle);
+
+
+			RA_Free(psLocalDevMemArena, psDevInfo->sBRN22997SysPAddr.uiAddr, IMG_FALSE);
+		}
+	}
+}
+#endif 
+
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	IMG_UINT32 *pui32PT;
+	PVRSRV_SGXDEV_INFO *psDevInfo;
+	IMG_UINT32 ui32PDIndex;
+	IMG_UINT32 ui32PTIndex;
+	PDUMP_MMU_ATTRIB sMMUAttrib;
+
+	psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+	sMMUAttrib = psDevInfo->sMMUAttrib;
+#if defined(PDUMP)
+	MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
+						SGX_MMU_PAGE_MASK,
+						SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
+#endif
+
+#if defined(PDUMP)
+	{
+		IMG_CHAR		szScript[128];
+
+		sprintf(szScript, "MALLOC :EXTSYSCACHE:PA_%08X%08X %u %u 0x%08X\r\n", 0, psDevInfo->sExtSysCacheRegsDevPBase.uiAddr, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, psDevInfo->sExtSysCacheRegsDevPBase.uiAddr);
+		PDumpOSWriteString2(szScript, PDUMP_FLAGS_CONTINUOUS);
+	}
+#endif
+
+	ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
+	ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+
+	pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+
+	
+	pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+							| SGX_MMU_PTE_VALID;
+
+#if defined(PDUMP)
+	
+	{
+		IMG_DEV_PHYADDR sDevPAddr;
+		IMG_CPU_PHYADDR sCpuPAddr;
+		IMG_UINT32 ui32PageMask;
+		IMG_UINT32 ui32PTE;
+		PVRSRV_ERROR eErr;
+
+		PDUMP_GET_SCRIPT_AND_FILE_STRING();
+
+		ui32PageMask = sMMUAttrib.ui32PTSize - 1;
+		sCpuPAddr = OSMapLinToCPUPhys(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->hPTPageOSMemHandle, &pui32PT[ui32PTIndex]);
+		sDevPAddr = SysCpuPAddrToDevPAddr(sMMUAttrib.sDevId.eDeviceType, sCpuPAddr);
+		ui32PTE = *((IMG_UINT32 *) (&pui32PT[ui32PTIndex]));
+
+		eErr = PDumpOSBufprintf(hScript,
+								ui32MaxLenScript,
+								"WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+								sMMUAttrib.sDevId.pszPDumpDevName,
+								(IMG_UINT32)(IMG_UINTPTR_T)PDUMP_PT_UNIQUETAG,
+								(sDevPAddr.uiAddr) & ~ui32PageMask,
+								(sDevPAddr.uiAddr) & ui32PageMask,
+								"EXTSYSCACHE",
+								(IMG_UINT32)(IMG_UINTPTR_T)PDUMP_PD_UNIQUETAG,
+								(ui32PTE & sMMUAttrib.ui32PDEMask) << sMMUAttrib.ui32PTEAlignShift,
+								ui32PTE & ~sMMUAttrib.ui32PDEMask);
+					if(eErr != PVRSRV_OK)
+					{
+						return eErr;
+					}
+					PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
+	}
+#endif
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	SYS_DATA *psSysData;
+	RA_ARENA *psLocalDevMemArena;
+	PVRSRV_SGXDEV_INFO *psDevInfo;
+	IMG_UINT32 ui32PDIndex;
+	IMG_UINT32 ui32PTIndex;
+	IMG_UINT32 *pui32PT;
+	PDUMP_MMU_ATTRIB sMMUAttrib;
+
+	psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+	sMMUAttrib = psDevInfo->sMMUAttrib;
+
+#if defined(PDUMP)
+	MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
+						SGX_MMU_PAGE_MASK,
+						SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
+#endif
+	SysAcquireData(&psSysData);
+
+	psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+	
+	ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
+	ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+
+	
+	if (psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex])
+	{
+		if (psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
+		{
+			pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+		}
+	}
+
+	pui32PT[ui32PTIndex] = 0;
+
+	PDUMPMEMPTENTRIES(&sMMUAttrib, psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->hPDOSMemHandle, &pui32PT[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+	return PVRSRV_OK;
+}
+#endif
+
+
+#if PAGE_TEST
+static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr)
+{
+	volatile IMG_UINT32 ui32WriteData;
+	volatile IMG_UINT32 ui32ReadData;
+	volatile IMG_UINT32 *pMem32 = (volatile IMG_UINT32 *)pMem;
+	IMG_INT n;
+	IMG_BOOL bOK=IMG_TRUE;
+
+	ui32WriteData = 0xffffffff;
+
+	for (n=0; n<1024; n++)
+	{
+		pMem32[n] = ui32WriteData;
+		ui32ReadData = pMem32[n];
+
+		if (ui32WriteData != ui32ReadData)
+		{
+			
+			PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
+			PVR_DBG_BREAK;
+			bOK = IMG_FALSE;
+		}
+ 	}
+
+	ui32WriteData = 0;
+
+	for (n=0; n<1024; n++)
+	{
+		pMem32[n] = ui32WriteData;
+		ui32ReadData = pMem32[n];
+
+		if (ui32WriteData != ui32ReadData)
+		{
+			
+			PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
+			PVR_DBG_BREAK;
+			bOK = IMG_FALSE;
+		}
+ 	}
+
+	if (bOK)
+	{
+		PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X is OK", sDevPAddr.uiAddr));
+	}
+	else
+	{
+		PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X *** FAILED ***", sDevPAddr.uiAddr));
+	}
+}
+#endif
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/mmu.h b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/mmu.h
new file mode 100644
index 0000000..59b24c4
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/mmu.h
@@ -0,0 +1,154 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _MMU_H_
+#define _MMU_H_
+
+#include "sgxinfokm.h"
+
+PVRSRV_ERROR
+MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr);
+
+IMG_VOID
+MMU_Finalise (MMU_CONTEXT *psMMUContext);
+
+
+IMG_VOID
+MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap);
+
+MMU_HEAP *
+MMU_Create (MMU_CONTEXT *psMMUContext,
+			DEV_ARENA_DESCRIPTOR *psDevArena,
+			RA_ARENA **ppsVMArena,
+			PDUMP_MMU_ATTRIB **ppsMMUAttrib);
+
+IMG_VOID
+MMU_Delete (MMU_HEAP *pMMUHeap);
+
+IMG_BOOL
+MMU_Alloc (MMU_HEAP *pMMUHeap,
+           IMG_SIZE_T uSize,
+           IMG_SIZE_T *pActualSize,
+           IMG_UINT32 uFlags,
+		   IMG_UINT32 uDevVAddrAlignment,
+           IMG_DEV_VIRTADDR *pDevVAddr);
+
+IMG_VOID
+MMU_Free (MMU_HEAP *pMMUHeap,
+          IMG_DEV_VIRTADDR DevVAddr,
+		  IMG_UINT32 ui32Size);
+
+IMG_VOID 
+MMU_Enable (MMU_HEAP *pMMUHeap);
+
+IMG_VOID 
+MMU_Disable (MMU_HEAP *pMMUHeap);
+
+IMG_VOID
+MMU_MapPages (MMU_HEAP *pMMUHeap,
+			  IMG_DEV_VIRTADDR DevVAddr,
+			  IMG_SYS_PHYADDR SysPAddr,
+			  IMG_SIZE_T uSize,
+			  IMG_UINT32 ui32MemFlags,
+			  IMG_HANDLE hUniqueTag);
+
+IMG_VOID
+MMU_MapShadow (MMU_HEAP          * pMMUHeap,
+               IMG_DEV_VIRTADDR    MapBaseDevVAddr,
+               IMG_SIZE_T          uByteSize, 
+               IMG_CPU_VIRTADDR    CpuVAddr,
+               IMG_HANDLE          hOSMemHandle,
+               IMG_DEV_VIRTADDR  * pDevVAddr,
+               IMG_UINT32          ui32MemFlags,
+               IMG_HANDLE          hUniqueTag);
+
+IMG_VOID
+MMU_UnmapPages (MMU_HEAP *psMMUHeap,
+             IMG_DEV_VIRTADDR sDevVAddr,
+             IMG_UINT32 ui32PageCount,
+             IMG_HANDLE hUniqueTag);
+
+IMG_VOID
+MMU_MapScatter (MMU_HEAP *pMMUHeap,
+				IMG_DEV_VIRTADDR DevVAddr,
+				IMG_SYS_PHYADDR *psSysAddr,
+				IMG_SIZE_T uSize,
+				IMG_UINT32 ui32MemFlags,
+				IMG_HANDLE hUniqueTag);
+
+
+IMG_DEV_PHYADDR
+MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
+
+
+IMG_DEV_PHYADDR
+MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext);
+
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+IMG_VOID
+EnableHostAccess (MMU_CONTEXT *psMMUContext);
+
+
+IMG_VOID
+DisableHostAccess (MMU_CONTEXT *psMMUContext);
+#endif
+
+IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_DEVICE_NODE	*psDeviceNode);
+
+IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+IMG_VOID WorkaroundBRN22997Free(PVRSRV_DEVICE_NODE *psDeviceNode);
+#endif 
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
+#endif 
+
+IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMU_Heap);
+
+#if defined(FIX_HW_BRN_31620)
+IMG_VOID MMU_GetCacheFlushRange(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask);
+
+IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr);
+
+#endif
+
+
+#if defined(PDUMP)
+IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext);
+#endif 
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/pb.c b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/pb.c
new file mode 100644
index 0000000..ab6523a
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/pb.c
@@ -0,0 +1,466 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "services_headers.h"
+#include "sgx_bridge_km.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+#include "pvr_bridge_km.h"
+#include "pdump_km.h"
+#include "sgxutils.h"
+
+#ifndef __linux__
+#pragma message("TODO: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE")
+#endif
+
+#include "lists.h"
+
+static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC)
+static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC)
+
+static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL;
+static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL;
+
+static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy);
+static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy);
+
+IMG_EXPORT PVRSRV_ERROR
+SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+					  IMG_HANDLE 				hDevCookie,
+					  IMG_BOOL 				bLockOnFailure,
+					  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 	**ppsHWBlockKernelMemInfo,
+					  PVRSRV_KERNEL_MEM_INFO 	***pppsSharedPBDescSubKernelMemInfos,
+					  IMG_UINT32				*ui32SharedPBDescSubKernelMemInfosCount)
+{
+	PVRSRV_STUB_PBDESC *psStubPBDesc;
+	PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL;
+	PVRSRV_SGXDEV_INFO *psSGXDevInfo;
+	PVRSRV_ERROR eError;
+
+	psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+	psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
+	if (psStubPBDesc != IMG_NULL)
+	{
+		IMG_UINT32 i;
+		PRESMAN_ITEM psResItem;
+
+		if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
+		{
+			PVR_DPF((PVR_DBG_WARNING,
+					"SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
+					ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
+		}
+
+		if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+					  sizeof(PVRSRV_KERNEL_MEM_INFO *)
+						* psStubPBDesc->ui32SubKernelMemInfosCount,
+					  (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos,
+					  IMG_NULL,
+					  "Array of Kernel Memory Info") != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed"));
+
+			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+			goto ExitNotFound;
+		}
+
+		psResItem = ResManRegisterRes(psPerProc->hResManContext,
+									  RESMAN_TYPE_SHARED_PB_DESC,
+									  psStubPBDesc,
+									  0,
+									  &SGXCleanupSharedPBDescCallback);
+
+		if (psResItem == IMG_NULL)
+		{
+			OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+					  sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount,
+					  ppsSharedPBDescSubKernelMemInfos,
+					  0);
+			
+
+			PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
+
+			eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
+			goto ExitNotFound;
+		}
+
+		*ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo;
+		*ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo;
+		*ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo;
+		*ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo;
+
+		*ui32SharedPBDescSubKernelMemInfosCount =
+			psStubPBDesc->ui32SubKernelMemInfosCount;
+
+		*pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos;
+
+		for(i=0; i<psStubPBDesc->ui32SubKernelMemInfosCount; i++)
+		{
+			ppsSharedPBDescSubKernelMemInfos[i] =
+				psStubPBDesc->ppsSubKernelMemInfos[i];
+		}
+
+		psStubPBDesc->ui32RefCount++;
+		*phSharedPBDesc = (IMG_HANDLE)psResItem;
+		return PVRSRV_OK;
+	}
+
+	eError = PVRSRV_OK;
+	if (bLockOnFailure)
+	{
+		if (psResItemCreateSharedPB == IMG_NULL)
+		{
+			psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext,
+				  RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
+				  psPerProc,
+				  0,
+				  &SGXCleanupSharedPBDescCreateLockCallback);
+
+			if (psResItemCreateSharedPB == IMG_NULL)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
+
+				eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
+				goto ExitNotFound;
+			}
+			PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
+			psPerProcCreateSharedPB = psPerProc;
+		}
+		else
+		{
+			 eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
+		}
+	}
+ExitNotFound:
+	*phSharedPBDesc = IMG_NULL;
+
+	return eError;
+}
+
+
+static PVRSRV_ERROR
+SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn)
+{
+	
+	IMG_UINT32 i;
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie;
+
+	
+
+	
+	psStubPBDescIn->ui32RefCount--;
+	if (psStubPBDescIn->ui32RefCount == 0)
+	{
+		IMG_DEV_VIRTADDR sHWPBDescDevVAddr = psStubPBDescIn->sHWPBDescDevVAddr;
+		List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn);
+		for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++)
+		{
+			
+			PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie,
+								  psStubPBDescIn->ppsSubKernelMemInfos[i]);
+		}
+
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				  sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount,
+				  psStubPBDescIn->ppsSubKernelMemInfos,
+				  0);
+		psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL;
+
+		PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo);
+
+		PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo);
+
+		PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo);
+
+		PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo);
+
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				  sizeof(PVRSRV_STUB_PBDESC),
+				  psStubPBDescIn,
+				  0);
+		
+
+		
+		SGXCleanupRequest(psDeviceNode,
+						  &sHWPBDescDevVAddr,
+						  PVRSRV_CLEANUPCMD_PB,
+						  CLEANUP_WITH_POLL);
+	}
+	return PVRSRV_OK;
+	
+}
+
+static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy)
+{
+	PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	return SGXCleanupSharedPBDescKM(psStubPBDesc);
+}
+
+static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy)
+{
+#ifdef DEBUG
+	PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam;
+	PVR_ASSERT(psPerProc == psPerProcCreateSharedPB);
+#else
+	PVR_UNREFERENCED_PARAMETER(pvParam);
+#endif
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bDummy);
+
+	psPerProcCreateSharedPB = IMG_NULL;
+	psResItemCreateSharedPB = IMG_NULL;
+
+	return PVRSRV_OK;
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc)
+{
+	PVR_ASSERT(hSharedPBDesc != IMG_NULL);
+
+	return ResManFreeResByPtr(hSharedPBDesc, CLEANUP_WITH_POLL);
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+					 IMG_HANDLE					hDevCookie,
+					 PVRSRV_KERNEL_MEM_INFO		*psSharedPBDescKernelMemInfo,
+					 PVRSRV_KERNEL_MEM_INFO		*psHWPBDescKernelMemInfo,
+					 PVRSRV_KERNEL_MEM_INFO		*psBlockKernelMemInfo,
+					 PVRSRV_KERNEL_MEM_INFO		*psHWBlockKernelMemInfo,
+					 IMG_UINT32					ui32TotalPBSize,
+					 IMG_HANDLE					*phSharedPBDesc,
+					 PVRSRV_KERNEL_MEM_INFO		**ppsSharedPBDescSubKernelMemInfos,
+					 IMG_UINT32					ui32SharedPBDescSubKernelMemInfosCount,
+					 IMG_DEV_VIRTADDR			sHWPBDescDevVAddr)
+{
+	PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL;
+	PVRSRV_ERROR eRet = PVRSRV_ERROR_INVALID_PERPROC;
+	IMG_UINT32 i;
+	PVRSRV_SGXDEV_INFO *psSGXDevInfo;
+	PRESMAN_ITEM psResItem;
+
+	
+	if (psPerProcCreateSharedPB != psPerProc)
+	{
+		goto NoAdd;
+	}
+	else
+	{
+		PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL);
+
+		ResManFreeResByPtr(psResItemCreateSharedPB, CLEANUP_WITH_POLL);
+
+		PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL);
+		PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
+	}
+
+	psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+	psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
+	if (psStubPBDesc != IMG_NULL)
+	{
+		if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
+		{
+			PVR_DPF((PVR_DBG_WARNING,
+					"SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
+					ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
+
+		}
+
+		
+		psResItem = ResManRegisterRes(psPerProc->hResManContext,
+									  RESMAN_TYPE_SHARED_PB_DESC,
+									  psStubPBDesc,
+									  0,
+									  &SGXCleanupSharedPBDescCallback);
+		if (psResItem == IMG_NULL)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+				"SGXAddSharedPBDescKM: "
+				"Failed to register existing shared "
+				"PBDesc with the resource manager"));
+			goto NoAddKeepPB;
+		}
+
+		
+		psStubPBDesc->ui32RefCount++;
+
+		*phSharedPBDesc = (IMG_HANDLE)psResItem;
+		eRet = PVRSRV_OK;
+		goto NoAddKeepPB;
+	}
+
+	if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				  sizeof(PVRSRV_STUB_PBDESC),
+				  (IMG_VOID **)&psStubPBDesc,
+				  0,
+				  "Stub Parameter Buffer Description") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
+					"StubPBDesc"));
+		eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto NoAdd;
+	}
+
+
+	psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
+
+	if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				  sizeof(PVRSRV_KERNEL_MEM_INFO *)
+				  * ui32SharedPBDescSubKernelMemInfosCount,
+				  (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos,
+				  0,
+				  "Array of Kernel Memory Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
+				 "Failed to alloc "
+				 "StubPBDesc->ppsSubKernelMemInfos"));
+		eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto NoAdd;
+	}
+
+	if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
+	   != PVRSRV_OK)
+	{
+		goto NoAdd;
+	}
+
+	if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
+	   != PVRSRV_OK)
+	{
+		goto NoAdd;
+	}
+
+	if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
+	   != PVRSRV_OK)
+	{
+		goto NoAdd;
+	}
+
+	if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo)
+	   != PVRSRV_OK)
+	{
+		goto NoAdd;
+	}
+
+	psStubPBDesc->ui32RefCount = 1;
+	psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
+	psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
+	psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
+	psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
+	psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo;
+
+	psStubPBDesc->ui32SubKernelMemInfosCount =
+		ui32SharedPBDescSubKernelMemInfosCount;
+	for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
+	{
+		psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i];
+		if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i])
+		   != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
+					 "Failed to dissociate shared PBDesc "
+					 "from process"));
+			goto NoAdd;
+		}
+	}
+
+	psStubPBDesc->sHWPBDescDevVAddr = sHWPBDescDevVAddr;
+
+	psResItem = ResManRegisterRes(psPerProc->hResManContext,
+								  RESMAN_TYPE_SHARED_PB_DESC,
+								  psStubPBDesc,
+								  0,
+								  &SGXCleanupSharedPBDescCallback);
+	if (psResItem == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
+					 "Failed to register shared PBDesc "
+					 " with the resource manager"));
+		goto NoAdd;
+	}
+	psStubPBDesc->hDevCookie = hDevCookie;
+
+	
+	List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM),
+									psStubPBDesc);
+
+	*phSharedPBDesc = (IMG_HANDLE)psResItem;
+
+	return PVRSRV_OK;
+
+NoAdd:
+	if(psStubPBDesc)
+	{
+		if(psStubPBDesc->ppsSubKernelMemInfos)
+		{
+			OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+					  sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
+					  psStubPBDesc->ppsSubKernelMemInfos,
+					  0);
+			psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
+		}
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				  sizeof(PVRSRV_STUB_PBDESC),
+				  psStubPBDesc,
+				  0);
+		
+	}
+
+NoAddKeepPB:
+	for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
+	{
+		PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]);
+	}
+
+	PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
+	PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
+
+	PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);
+	PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo);
+
+	return eRet;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h
new file mode 100644
index 0000000..8fb3002
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h
@@ -0,0 +1,160 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#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
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK_KM *psKick);
+#else
+PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick);
+#endif
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+IMG_IMPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK_KM *psKick);
+#else
+PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick);
+#endif
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+						 SGX_CCB_KICK_KM *psCCBKick);
+#else
+						 SGX_CCB_KICK *psCCBKick);
+#endif
+
+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,
+								SGX_CLIENT_INFO*	psClientInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO	*psDevInfo,
+							  SGX_MISC_INFO			*psMiscInfo,
+							  PVRSRV_DEVICE_NODE 	*psDeviceNode,
+							  IMG_HANDLE 			 hDevMemContext);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE					hDevHandle,
+							   IMG_UINT32					ui32ArraySize,
+							   PVRSRV_SGX_HWPERF_CB_ENTRY	*psHWPerfCBData,
+							   IMG_UINT32					*pui32DataCount,
+							   IMG_UINT32					*pui32ClockSpeed,
+							   IMG_UINT32					*pui32HostTimeStamp);
+
+IMG_IMPORT
+PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO		*psDevInfo,
+									   PVRSRV_KERNEL_SYNC_INFO	*psSyncInfo,
+									   IMG_BOOL bWaitForComplete);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+									PVRSRV_HEAP_INFO_KM *pasHeapInfo,
+									IMG_DEV_PHYADDR *psPDDevPAddr);
+#else
+									SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR DevInitSGXPart2KM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+							   IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+							   SGX_BRIDGE_INIT_INFO_KM *psInitInfo);
+#else
+							   SGX_BRIDGE_INIT_INFO *psInitInfo);
+#endif
+
+IMG_IMPORT PVRSRV_ERROR
+SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+					  IMG_HANDLE				hDevCookie,
+					  IMG_BOOL				bLockOnFailure,
+					  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	**ppsHWBlockKernelMemInfo,
+					  PVRSRV_KERNEL_MEM_INFO	***pppsSharedPBDescSubKernelMemInfos,
+					  IMG_UINT32				*ui32SharedPBDescSubKernelMemInfosCount);
+
+IMG_IMPORT PVRSRV_ERROR
+SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc);
+
+IMG_IMPORT PVRSRV_ERROR
+SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
+					 IMG_HANDLE 				hDevCookie,
+					 PVRSRV_KERNEL_MEM_INFO		*psSharedPBDescKernelMemInfo,
+					 PVRSRV_KERNEL_MEM_INFO		*psHWPBDescKernelMemInfo,
+					 PVRSRV_KERNEL_MEM_INFO		*psBlockKernelMemInfo,
+					 PVRSRV_KERNEL_MEM_INFO		*psHWBlockKernelMemInfo,
+					 IMG_UINT32					ui32TotalPBSize,
+					 IMG_HANDLE					*phSharedPBDesc,
+					 PVRSRV_KERNEL_MEM_INFO		**psSharedPBDescSubKernelMemInfos,
+					 IMG_UINT32					ui32SharedPBDescSubKernelMemInfosCount,
+					 IMG_DEV_VIRTADDR			sHWPBDescDevVAddr);
+
+
+IMG_IMPORT PVRSRV_ERROR
+SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+						SGX_INTERNAL_DEVINFO_KM *psSGXInternalDevInfo);
+#else
+						SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxconfig.h b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxconfig.h
new file mode 100644
index 0000000..28fffab
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxconfig.h
@@ -0,0 +1,405 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __SGXCONFIG_H__
+#define __SGXCONFIG_H__
+
+#include "sgxdefs.h"
+
+#define DEV_DEVICE_TYPE			PVRSRV_DEVICE_TYPE_SGX
+#define DEV_DEVICE_CLASS		PVRSRV_DEVICE_CLASS_3D
+
+#define DEV_MAJOR_VERSION		1
+#define DEV_MINOR_VERSION		0
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+#define SGX_KERNEL_DATA_HEAP_OFFSET		0x00001000
+#else
+#define SGX_KERNEL_DATA_HEAP_OFFSET		0x00000000
+#endif
+
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 32
+#if defined(FIX_HW_BRN_31620)
+	#if defined(SGX_FEATURE_2D_HARDWARE)
+	#define SGX_2D_HEAP_BASE					 0x04000000
+	#define SGX_2D_HEAP_SIZE					(0x08000000-0x04000000-0x00001000)
+	#endif
+
+	#define SGX_GENERAL_HEAP_BASE				 0x08000000
+	#define SGX_GENERAL_HEAP_SIZE				(0xB8000000-0x00001000)
+
+	
+	#define SGX_3DPARAMETERS_HEAP_SIZE			0x10000000
+
+	
+#if !defined(HYBRID_SHARED_PB_SIZE)
+	#define HYBRID_SHARED_PB_SIZE				(SGX_3DPARAMETERS_HEAP_SIZE >> 1)
+#endif
+#if defined(SUPPORT_HYBRID_PB)
+	#define SGX_SHARED_3DPARAMETERS_SIZE			(HYBRID_SHARED_PB_SIZE)
+	#define SGX_SHARED_3DPARAMETERS_HEAP_SIZE		(HYBRID_SHARED_PB_SIZE-0x00001000)
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE		(SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000)
+#else
+#if defined(SUPPORT_PERCONTEXT_PB)
+	#define SGX_SHARED_3DPARAMETERS_SIZE			0
+	#define SGX_SHARED_3DPARAMETERS_HEAP_SIZE		0
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE		(SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+#endif
+#if defined(SUPPORT_SHARED_PB)
+	#define SGX_SHARED_3DPARAMETERS_SIZE			SGX_3DPARAMETERS_HEAP_SIZE
+	#define SGX_SHARED_3DPARAMETERS_HEAP_SIZE		(SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE		0
+#endif
+#endif
+
+	#define SGX_SHARED_3DPARAMETERS_HEAP_BASE		 0xC0000000
+	
+
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE		 (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE)
+	
+
+	#define SGX_TADATA_HEAP_BASE				 0xD0000000
+	#define SGX_TADATA_HEAP_SIZE				(0x0D000000-0x00001000)
+
+	#define SGX_SYNCINFO_HEAP_BASE				 0xE0000000
+	#define SGX_SYNCINFO_HEAP_SIZE				(0x01000000-0x00001000)
+
+	#define SGX_PDSPIXEL_CODEDATA_HEAP_BASE		 0xE4000000
+	#define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE		(0x02000000-0x00001000)
+
+	#define SGX_KERNEL_CODE_HEAP_BASE			 0xE8000000
+	#define SGX_KERNEL_CODE_HEAP_SIZE			(0x00080000-0x00001000)
+
+	#define SGX_PDSVERTEX_CODEDATA_HEAP_BASE	 0xEC000000
+	#define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE	(0x01C00000-0x00001000)
+
+	#define SGX_KERNEL_DATA_HEAP_BASE		 	(0xF0000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+	#define SGX_KERNEL_DATA_HEAP_SIZE			(0x03000000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+	
+	#define SGX_PIXELSHADER_HEAP_BASE			 0xF4000000
+	#define SGX_PIXELSHADER_HEAP_SIZE			(0x05000000-0x00001000)
+	
+	#define SGX_VERTEXSHADER_HEAP_BASE			 0xFC000000
+	#define SGX_VERTEXSHADER_HEAP_SIZE			(0x02000000-0x00001000)
+
+#elif defined(SGX545) 
+
+	#define SGX_3DPARAMETERS_HEAP_SIZE			(0x10000000)
+
+	
+#if !defined(HYBRID_SHARED_PB_SIZE)
+	#define HYBRID_SHARED_PB_SIZE				(SGX_3DPARAMETERS_HEAP_SIZE >> 1)
+#endif
+#if defined(SUPPORT_HYBRID_PB)
+	#define SGX_SHARED_3DPARAMETERS_SIZE			(HYBRID_SHARED_PB_SIZE)
+	#define SGX_SHARED_3DPARAMETERS_HEAP_SIZE		(HYBRID_SHARED_PB_SIZE-0x00001000)
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE		(SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000)
+#else
+#if defined(SUPPORT_PERCONTEXT_PB)
+	#define SGX_SHARED_3DPARAMETERS_SIZE			0
+	#define SGX_SHARED_3DPARAMETERS_HEAP_SIZE		0
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE		(SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+#endif
+#if defined(SUPPORT_SHARED_PB)
+	#define SGX_SHARED_3DPARAMETERS_SIZE			SGX_3DPARAMETERS_HEAP_SIZE
+	#define SGX_SHARED_3DPARAMETERS_HEAP_SIZE		(SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE		0
+#endif
+#endif
+
+	#define SGX_SHARED_3DPARAMETERS_HEAP_BASE_REV1		 0x10000000
+	
+
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE_REV1	(SGX_SHARED_3DPARAMETERS_HEAP_BASE_REV1 + SGX_SHARED_3DPARAMETERS_SIZE)
+	
+
+	#define SGX_TADATA_HEAP_BASE_REV1				 0x20000000
+	#define SGX_TADATA_HEAP_SIZE_REV1				(0x0D000000-0x00001000)
+
+	#define SGX_SYNCINFO_HEAP_BASE_REV1			 0x2D000000
+	#define SGX_SYNCINFO_HEAP_SIZE_REV1			(0x01000000-0x00001000)
+
+	#define SGX_PDSPIXEL_CODEDATA_HEAP_BASE_REV1		 0x2E000000
+	#define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE_REV1		(0x02000000-0x00001000)
+
+	#define SGX_KERNEL_CODE_HEAP_BASE_REV1			 0x30000000
+	#define SGX_KERNEL_CODE_HEAP_SIZE_REV1			(0x00080000-0x00001000)
+
+	#define SGX_PDSVERTEX_CODEDATA_HEAP_BASE_REV1	 	 0x30400000
+	#define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE_REV1		(0x01C00000-0x00001000)
+
+	#define SGX_KERNEL_DATA_HEAP_BASE_REV1		 	(0x32000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+	#define SGX_KERNEL_DATA_HEAP_SIZE_REV1			(0x05000000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+	
+	#define SGX_PIXELSHADER_HEAP_BASE_REV1			 0x37000000
+	#define SGX_PIXELSHADER_HEAP_SIZE_REV1			(0x05000000-0x00001000)
+	
+	#define SGX_VERTEXSHADER_HEAP_BASE_REV1			 0x3C000000
+	#define SGX_VERTEXSHADER_HEAP_SIZE_REV1			(0x02000000-0x00001000)
+
+	#define SGX_GENERAL_HEAP_BASE_REV1			 0x3E000000
+	#define SGX_GENERAL_HEAP_SIZE_REV1			(0xB2000000-0x00001000)
+
+	/* Create stand alone texture heap to highest address that suppose more '1's is less common in 
+	 * bad address, currently limit size to 256M, should be enough...*/
+	#define SGX_TEXTURE_HEAP_BASE_REV1			 0xF0000000
+	#define SGX_TEXTURE_HEAP_SIZE_REV1			(0x10000000-0x00001000)
+
+/* Normal case below (keep original name)*/
+
+	#if defined(SGX_FEATURE_2D_HARDWARE)	/* not on 545 */
+	#define SGX_2D_HEAP_BASE					 0x00100000
+	#define SGX_2D_HEAP_SIZE					(0x08000000-0x00100000-0x00001000)
+	#else
+		#if defined(FIX_HW_BRN_26915)	/* not on 545 */
+		#define SGX_CGBUFFER_HEAP_BASE					 0x00100000
+		#define SGX_CGBUFFER_HEAP_SIZE					(0x08000000-0x00100000-0x00001000)
+		#endif
+	#endif
+
+	#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)	/* not on 545 */
+	#define SGX_GENERAL_MAPPING_HEAP_BASE		 0x08000000
+	#define SGX_GENERAL_MAPPING_HEAP_SIZE		(0x08000000-0x00001000)
+	#endif
+
+	#define SGX_GENERAL_HEAP_BASE				 0x10000000
+	#define SGX_GENERAL_HEAP_SIZE				(0xC2000000-0x00001000)
+
+	#define SGX_SHARED_3DPARAMETERS_HEAP_BASE		 0xD2000000
+	
+
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE		 (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE)
+	
+
+	#define SGX_TADATA_HEAP_BASE				 0xE2000000
+	#define SGX_TADATA_HEAP_SIZE				(0x0D000000-0x00001000)
+
+	#define SGX_SYNCINFO_HEAP_BASE				 0xEF000000
+	#define SGX_SYNCINFO_HEAP_SIZE				(0x01000000-0x00001000)
+
+	#define SGX_PDSPIXEL_CODEDATA_HEAP_BASE		 0xF0000000
+	#define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE		(0x02000000-0x00001000)
+
+	#define SGX_KERNEL_CODE_HEAP_BASE			 0xF2000000
+	#define SGX_KERNEL_CODE_HEAP_SIZE			(0x00080000-0x00001000)
+
+	#define SGX_PDSVERTEX_CODEDATA_HEAP_BASE	 0xF2400000
+	#define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE	(0x01C00000-0x00001000)
+
+	#define SGX_KERNEL_DATA_HEAP_BASE		 	(0xF4000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+	#define SGX_KERNEL_DATA_HEAP_SIZE			(0x05000000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+	
+	#define SGX_PIXELSHADER_HEAP_BASE			 0xF9000000
+	#define SGX_PIXELSHADER_HEAP_SIZE			(0x05000000-0x00001000)
+	
+	#define SGX_VERTEXSHADER_HEAP_BASE			 0xFE000000
+	#define SGX_VERTEXSHADER_HEAP_SIZE			(0x02000000-0x00001000)
+#endif 
+	
+	#define SGX_CORE_IDENTIFIED
+#endif 
+
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 28
+
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+	#define SGX_GENERAL_MAPPING_HEAP_BASE		 0x00001000
+	#define SGX_GENERAL_MAPPING_HEAP_SIZE		(0x01800000-0x00001000-0x00001000)
+
+	#define SGX_GENERAL_HEAP_BASE				 0x01800000
+	#define SGX_GENERAL_HEAP_SIZE				(0x07000000-0x00001000)
+
+#else
+	#define SGX_GENERAL_HEAP_BASE				 0x00001000
+	#define SGX_GENERAL_HEAP_SIZE				(0x08800000-0x00001000-0x00001000)
+#endif
+	
+	#define SGX_3DPARAMETERS_HEAP_SIZE			0x04000000
+
+	
+#if !defined(HYBRID_SHARED_PB_SIZE)
+	#define HYBRID_SHARED_PB_SIZE				(SGX_3DPARAMETERS_HEAP_SIZE >> 1)
+#endif
+#if defined(SUPPORT_HYBRID_PB)
+	#define SGX_SHARED_3DPARAMETERS_SIZE			(HYBRID_SHARED_PB_SIZE)
+	#define SGX_SHARED_3DPARAMETERS_HEAP_SIZE		(HYBRID_SHARED_PB_SIZE-0x00001000)
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE		(SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000)
+#else
+#if defined(SUPPORT_PERCONTEXT_PB)
+	#define SGX_SHARED_3DPARAMETERS_SIZE			0
+	#define SGX_SHARED_3DPARAMETERS_HEAP_SIZE		0
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE		(SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+#endif
+#if defined(SUPPORT_SHARED_PB)
+	#define SGX_SHARED_3DPARAMETERS_SIZE			SGX_3DPARAMETERS_HEAP_SIZE
+	#define SGX_SHARED_3DPARAMETERS_HEAP_SIZE		(SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE		0
+#endif
+#endif
+
+	#define SGX_SHARED_3DPARAMETERS_HEAP_BASE		 0x08800000
+	
+
+	#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE		 (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE)
+	
+
+	#define SGX_TADATA_HEAP_BASE				 0x0C800000
+	#define SGX_TADATA_HEAP_SIZE				(0x01000000-0x00001000)
+
+	#define SGX_SYNCINFO_HEAP_BASE				 0x0D800000
+	#define SGX_SYNCINFO_HEAP_SIZE				(0x00400000-0x00001000)
+
+	#define SGX_PDSPIXEL_CODEDATA_HEAP_BASE		 0x0DC00000
+	#define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE		(0x00800000-0x00001000)
+
+	#define SGX_KERNEL_CODE_HEAP_BASE			 0x0E400000
+	#define SGX_KERNEL_CODE_HEAP_SIZE			(0x00080000-0x00001000)
+
+	#define SGX_PDSVERTEX_CODEDATA_HEAP_BASE	 0x0E800000
+	#define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE	(0x00800000-0x00001000)
+
+	#define SGX_KERNEL_DATA_HEAP_BASE			(0x0F000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+	#define SGX_KERNEL_DATA_HEAP_SIZE			(0x00400000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+	#define SGX_PIXELSHADER_HEAP_BASE			 0x0F400000
+	#define SGX_PIXELSHADER_HEAP_SIZE			(0x00500000-0x00001000)
+
+	#define SGX_VERTEXSHADER_HEAP_BASE			 0x0FC00000
+	#define SGX_VERTEXSHADER_HEAP_SIZE			(0x00200000-0x00001000)
+
+	
+	#define SGX_CORE_IDENTIFIED
+
+#endif 
+
+#if !defined(SGX_CORE_IDENTIFIED)
+	#error "sgxconfig.h: ERROR: unspecified SGX Core version"
+#endif
+
+#if !defined (SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE)
+	#if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) >  0x4000000)
+	 	#error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE"
+	#endif
+	
+	#if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) >  0x4000000)
+	 	#error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE"
+	#endif
+#endif	
+
+#if defined(SGX_FEATURE_2D_HARDWARE) && defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+	#if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE - SGX_2D_HEAP_BASE) >= EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK)
+		#error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP inaccessable by 2D requestor"
+	#endif
+#endif
+
+#if defined (EURASIA_USE_CODE_PAGE_SIZE)
+	#if ((SGX_KERNEL_CODE_HEAP_BASE & (EURASIA_USE_CODE_PAGE_SIZE - 1)) != 0)
+		#error "sgxconfig.h: ERROR: Kernel code heap base misalignment"
+	#endif
+#endif
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+	#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+		#if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_MAPPING_HEAP_BASE)
+			#error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_MAPPING_HEAP"
+		#endif
+	#else
+		#if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
+			#error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_HEAP_BASE"
+		#endif
+	#endif
+#else
+    #if defined(FIX_HW_BRN_26915)
+		#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+			#if ((SGX_CGBUFFER_HEAP_BASE + SGX_CGBUFFER_HEAP_SIZE) >= SGX_GENERAL_MAPPING_HEAP_BASE)
+				#error "sgxconfig.h: ERROR: SGX_CGBUFFER_HEAP overlaps SGX_GENERAL_MAPPING_HEAP"
+			#endif
+		#else
+			#if ((SGX_CGBUFFER_HEAP_BASE + SGX_CGBUFFER_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
+				#error "sgxconfig.h: ERROR: SGX_CGBUFFER_HEAP overlaps SGX_GENERAL_HEAP_BASE"
+			#endif
+		#endif
+	#endif
+#endif
+
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+	#if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
+		#error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP overlaps SGX_GENERAL_HEAP"
+	#endif
+#endif
+
+#if defined(SUPPORT_HYBRID_PB)
+	#if ((HYBRID_SHARED_PB_SIZE + 0x000001000) > SGX_3DPARAMETERS_HEAP_SIZE)
+		#error "sgxconfig.h: ERROR: HYBRID_SHARED_PB_SIZE too large"
+	#endif
+#endif
+
+#if !defined(SGX545) || !defined(FIX_HW_BRN_SAMPLE_CACHE)
+#if ((SGX_GENERAL_HEAP_BASE + SGX_GENERAL_HEAP_SIZE) >= SGX_SHARED_3DPARAMETERS_HEAP_BASE)
+	#error "sgxconfig.h: ERROR: SGX_GENERAL_HEAP overlaps SGX_3DPARAMETERS_HEAP"
+#endif
+#endif
+
+#if (((SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE + SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE) >= SGX_TADATA_HEAP_BASE) && (SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE > 0))
+	#error "sgxconfig.h: ERROR: SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE overlaps SGX_TADATA_HEAP"
+#endif
+
+#if ((SGX_TADATA_HEAP_BASE + SGX_TADATA_HEAP_SIZE) >= SGX_SYNCINFO_HEAP_BASE)
+	#error "sgxconfig.h: ERROR: SGX_TADATA_HEAP overlaps SGX_SYNCINFO_HEAP"
+#endif
+
+#if ((SGX_SYNCINFO_HEAP_BASE + SGX_SYNCINFO_HEAP_SIZE) >= SGX_PDSPIXEL_CODEDATA_HEAP_BASE)
+	#error "sgxconfig.h: ERROR: SGX_SYNCINFO_HEAP overlaps SGX_PDSPIXEL_CODEDATA_HEAP"
+#endif
+
+#if ((SGX_PDSPIXEL_CODEDATA_HEAP_BASE + SGX_PDSPIXEL_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_CODE_HEAP_BASE)
+	#error "sgxconfig.h: ERROR: SGX_PDSPIXEL_CODEDATA_HEAP overlaps SGX_KERNEL_CODE_HEAP"
+#endif
+
+#if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE) >= SGX_PDSVERTEX_CODEDATA_HEAP_BASE)
+	#error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP overlaps SGX_PDSVERTEX_CODEDATA_HEAP"
+#endif
+
+#if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_DATA_HEAP_BASE)
+	#error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP overlaps SGX_KERNEL_DATA_HEAP"
+#endif
+
+#if ((SGX_KERNEL_DATA_HEAP_BASE + SGX_KERNEL_DATA_HEAP_SIZE) >= SGX_PIXELSHADER_HEAP_BASE)
+	#error "sgxconfig.h: ERROR: SGX_KERNEL_DATA_HEAP overlaps SGX_PIXELSHADER_HEAP"
+#endif
+
+#if ((SGX_PIXELSHADER_HEAP_BASE + SGX_PIXELSHADER_HEAP_SIZE) >= SGX_VERTEXSHADER_HEAP_BASE)
+	#error "sgxconfig.h: ERROR: SGX_PIXELSHADER_HEAP overlaps SGX_VERTEXSHADER_HEAP"
+#endif
+
+#if ((SGX_VERTEXSHADER_HEAP_BASE + SGX_VERTEXSHADER_HEAP_SIZE) < SGX_VERTEXSHADER_HEAP_BASE)
+	#error "sgxconfig.h: ERROR: SGX_VERTEXSHADER_HEAP_BASE size cause wraparound"
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxinfokm.h b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxinfokm.h
new file mode 100644
index 0000000..0ebe153
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxinfokm.h
@@ -0,0 +1,568 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __SGXINFOKM_H__
+#define __SGXINFOKM_H__
+
+#include "sgxdefs.h"
+#include "device.h"
+#include "power.h"
+#include "sysconfig.h"
+#include "sgxscript.h"
+#include "sgxinfo.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define		SGX_HOSTPORT_PRESENT			0x00000001UL
+
+
+#define SGX_PDUMPREG_NAME		"SGXREG"
+
+typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC;
+
+
+typedef struct _PVRSRV_SGX_CCB_INFO_ *PPVRSRV_SGX_CCB_INFO;
+
+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;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+	
+	IMG_PVOID				pvHostPortBaseKM;
+	
+	IMG_UINT32				ui32HPSize;
+	
+	IMG_SYS_PHYADDR			sHPSysPAddr;
+#endif
+
+	
+	IMG_HANDLE				hRegMapping;
+
+	
+	IMG_SYS_PHYADDR			sRegsPhysBase;
+	
+	IMG_UINT32				ui32RegSize;
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+	
+	IMG_UINT32				ui32ExtSysCacheRegsSize;
+	
+	IMG_DEV_PHYADDR			sExtSysCacheRegsDevPBase;
+	
+	IMG_UINT32				*pui32ExtSystemCacheRegsPT;
+	
+	IMG_HANDLE				hExtSystemCacheRegsPTPageOSMemHandle;
+	
+	IMG_SYS_PHYADDR			sExtSystemCacheRegsPTSysPAddr;
+#endif
+
+	
+	IMG_UINT32				ui32CoreClockSpeed;
+	IMG_UINT32				ui32uKernelTimerClock;
+
+	PVRSRV_STUB_PBDESC		*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; 
+#if defined(PDUMP)
+	IMG_UINT32				ui32KernelCCBEventKickerDumpVal; 
+#endif 
+ 	PVRSRV_KERNEL_MEM_INFO	*psKernelSGXMiscMemInfo;	
+	IMG_UINT32				aui32HostKickAddr[SGXMKIF_CMD_MAX];		
+#if defined(SGX_SUPPORT_HWPROFILING)
+	PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo;
+#endif
+	PPVRSRV_KERNEL_MEM_INFO		psKernelHWPerfCBMemInfo;		
+	PPVRSRV_KERNEL_MEM_INFO		psKernelTASigBufferMemInfo;		
+	PPVRSRV_KERNEL_MEM_INFO		psKernel3DSigBufferMemInfo;		
+#if defined(FIX_HW_BRN_29702)
+	PPVRSRV_KERNEL_MEM_INFO psKernelCFIMemInfo;	
+#endif
+#if defined(FIX_HW_BRN_29823)
+	PPVRSRV_KERNEL_MEM_INFO	psKernelDummyTermStreamMemInfo; 
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+	PPVRSRV_KERNEL_MEM_INFO	psKernelVDMSnapShotBufferMemInfo; 
+	PPVRSRV_KERNEL_MEM_INFO	psKernelVDMCtrlStreamBufferMemInfo; 
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+	defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+	PPVRSRV_KERNEL_MEM_INFO	psKernelVDMStateUpdateBufferMemInfo; 
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+	PPVRSRV_KERNEL_MEM_INFO	psKernelEDMStatusBufferMemInfo; 
+#endif
+	
+	IMG_UINT32				ui32ClientRefCount;
+
+	
+	IMG_UINT32				ui32CacheControl;
+
+	
+	IMG_UINT32				ui32ClientBuildOptions;
+
+	
+	SGX_MISCINFO_STRUCT_SIZES	sSGXStructSizes;
+
+	
+
+
+	IMG_VOID				*pvMMUContextList;
+
+	
+	IMG_BOOL				bForcePTOff;
+
+	IMG_UINT32				ui32EDMTaskReg0;
+	IMG_UINT32				ui32EDMTaskReg1;
+
+	IMG_UINT32				ui32ClkGateCtl;
+	IMG_UINT32				ui32ClkGateCtl2;
+	IMG_UINT32				ui32ClkGateStatusReg;
+	IMG_UINT32				ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+	IMG_UINT32				ui32MasterClkGateStatusReg;
+	IMG_UINT32				ui32MasterClkGateStatusMask;
+	IMG_UINT32				ui32MasterClkGateStatus2Reg;
+	IMG_UINT32				ui32MasterClkGateStatus2Mask;
+#endif 
+	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(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+	
+	IMG_HANDLE				hBRN22997PTPageOSMemHandle;
+	IMG_HANDLE				hBRN22997PDPageOSMemHandle;
+	IMG_DEV_PHYADDR 		sBRN22997PTDevPAddr;
+	IMG_DEV_PHYADDR 		sBRN22997PDDevPAddr;
+	IMG_UINT32				*pui32BRN22997PT;
+	IMG_UINT32				*pui32BRN22997PD;
+	IMG_SYS_PHYADDR 		sBRN22997SysPAddr;
+#endif 
+
+#if defined(SUPPORT_HW_RECOVERY)
+	
+	IMG_HANDLE				hTimer;
+	
+	IMG_UINT32				ui32TimeStamp;
+#endif
+
+	
+	IMG_UINT32				ui32NumResets;
+
+	
+	PVRSRV_KERNEL_MEM_INFO			*psKernelSGXHostCtlMemInfo;
+	SGXMKIF_HOST_CTL				*psSGXHostCtl;
+
+	
+	PVRSRV_KERNEL_MEM_INFO			*psKernelSGXTA3DCtlMemInfo;
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+	PVRSRV_KERNEL_MEM_INFO			*psKernelSGXPTLAWriteBackMemInfo;
+#endif
+
+	IMG_UINT32				ui32Flags;
+
+	
+	IMG_UINT32				ui32MemTilingUsage;
+
+	#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
+#if defined(PDUMP)
+	PDUMP_MMU_ATTRIB sMMUAttrib;
+#endif
+	IMG_UINT32				asSGXDevData[SGX_MAX_DEV_DATA];
+
+#if defined(FIX_HW_BRN_31620)
+	
+	IMG_VOID			*pvBRN31620DummyPageCpuVAddr;
+	IMG_HANDLE			hBRN31620DummyPageOSMemHandle;
+	IMG_DEV_PHYADDR			sBRN31620DummyPageDevPAddr;
+
+	
+	IMG_VOID			*pvBRN31620DummyPTCpuVAddr;
+	IMG_HANDLE			hBRN31620DummyPTOSMemHandle;
+	IMG_DEV_PHYADDR			sBRN31620DummyPTDevPAddr;
+
+	IMG_HANDLE			hKernelMMUContext;
+#endif
+
+} PVRSRV_SGXDEV_INFO;
+
+
+typedef struct _SGX_TIMING_INFORMATION_
+{
+	IMG_UINT32			ui32CoreClockSpeed;
+	IMG_UINT32			ui32HWRecoveryFreq;
+	IMG_BOOL			bEnableActivePM;
+	IMG_UINT32			ui32ActivePowManLatencyms;
+	IMG_UINT32			ui32uKernelFreq;
+} SGX_TIMING_INFORMATION;
+
+typedef struct _SGX_DEVICE_MAP_
+{
+	IMG_UINT32				ui32Flags;
+
+	
+	IMG_SYS_PHYADDR			sRegsSysPBase;
+	IMG_CPU_PHYADDR			sRegsCpuPBase;
+	IMG_CPU_VIRTADDR		pvRegsCpuVBase;
+	IMG_UINT32				ui32RegsSize;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+	IMG_SYS_PHYADDR			sHPSysPBase;
+	IMG_CPU_PHYADDR			sHPCpuPBase;
+	IMG_UINT32				ui32HPSize;
+#endif
+
+	
+	IMG_SYS_PHYADDR			sLocalMemSysPBase;
+	IMG_DEV_PHYADDR			sLocalMemDevPBase;
+	IMG_CPU_PHYADDR			sLocalMemCpuPBase;
+	IMG_UINT32				ui32LocalMemSize;
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+	IMG_UINT32				ui32ExtSysCacheRegsSize;
+	IMG_DEV_PHYADDR			sExtSysCacheRegsDevPBase;
+#endif
+
+	
+	IMG_UINT32				ui32IRQ;
+
+#if !defined(SGX_DYNAMIC_TIMING_INFO)
+	
+	SGX_TIMING_INFORMATION	sTimingInfo;
+#endif
+#if defined(PDUMP)
+	
+	IMG_CHAR				*pszPDumpDevName;
+#endif
+} SGX_DEVICE_MAP;
+
+
+struct _PVRSRV_STUB_PBDESC_
+{
+	IMG_UINT32		ui32RefCount;
+	IMG_UINT32		ui32TotalPBSize;
+	PVRSRV_KERNEL_MEM_INFO  *psSharedPBDescKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO  *psHWPBDescKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO	**ppsSubKernelMemInfos;
+	IMG_UINT32		ui32SubKernelMemInfosCount;
+	IMG_HANDLE		hDevCookie;
+	PVRSRV_KERNEL_MEM_INFO  *psBlockKernelMemInfo;
+	PVRSRV_KERNEL_MEM_INFO  *psHWBlockKernelMemInfo;
+	IMG_DEV_VIRTADDR	sHWPBDescDevVAddr;
+	PVRSRV_STUB_PBDESC	*psNext;
+	PVRSRV_STUB_PBDESC	**ppsThis;
+};
+
+typedef struct _PVRSRV_SGX_CCB_INFO_
+{
+	PVRSRV_KERNEL_MEM_INFO	*psCCBMemInfo;			
+	PVRSRV_KERNEL_MEM_INFO	*psCCBCtlMemInfo;		
+	SGXMKIF_COMMAND		*psCommands;			
+	IMG_UINT32				*pui32WriteOffset;		
+	volatile IMG_UINT32		*pui32ReadOffset;		
+#if defined(PDUMP)
+	IMG_UINT32				ui32CCBDumpWOff;		
+#endif
+} PVRSRV_SGX_CCB_INFO;
+
+
+typedef struct _SGX_BRIDGE_INIT_INFO_KM_
+{
+	IMG_HANDLE	hKernelCCBMemInfo;
+	IMG_HANDLE	hKernelCCBCtlMemInfo;
+	IMG_HANDLE	hKernelCCBEventKickerMemInfo;
+	IMG_HANDLE	hKernelSGXHostCtlMemInfo;
+	IMG_HANDLE	hKernelSGXTA3DCtlMemInfo;
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+	IMG_HANDLE	hKernelSGXPTLAWriteBackMemInfo;
+#endif
+	IMG_HANDLE	hKernelSGXMiscMemInfo;
+
+	IMG_UINT32	aui32HostKickAddr[SGXMKIF_CMD_MAX];
+
+	SGX_INIT_SCRIPTS sScripts;
+
+	IMG_UINT32	ui32ClientBuildOptions;
+	SGX_MISCINFO_STRUCT_SIZES	sSGXStructSizes;
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+	IMG_HANDLE	hKernelHWProfilingMemInfo;
+#endif
+#if defined(SUPPORT_SGX_HWPERF)
+	IMG_HANDLE	hKernelHWPerfCBMemInfo;
+#endif
+	IMG_HANDLE	hKernelTASigBufferMemInfo;
+	IMG_HANDLE	hKernel3DSigBufferMemInfo;
+
+#if defined(FIX_HW_BRN_29702)
+	IMG_HANDLE	hKernelCFIMemInfo;
+#endif
+#if defined(FIX_HW_BRN_29823)
+	IMG_HANDLE	hKernelDummyTermStreamMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+	IMG_HANDLE	hKernelEDMStatusBufferMemInfo;
+#endif
+
+	IMG_UINT32 ui32EDMTaskReg0;
+	IMG_UINT32 ui32EDMTaskReg1;
+
+	IMG_UINT32 ui32ClkGateStatusReg;
+	IMG_UINT32 ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+#endif 
+
+	IMG_UINT32 ui32CacheControl;
+
+	IMG_UINT32	asInitDevData[SGX_MAX_DEV_DATA];
+	IMG_HANDLE	asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
+
+} SGX_BRIDGE_INIT_INFO_KM;
+
+
+typedef struct _SGX_INTERNEL_STATUS_UPDATE_KM_
+{
+	CTL_STATUS				sCtlStatus;
+	IMG_HANDLE				hKernelMemInfo;
+} SGX_INTERNEL_STATUS_UPDATE_KM;
+
+
+typedef struct _SGX_CCB_KICK_KM_
+{
+	SGXMKIF_COMMAND		sCommand;
+	IMG_HANDLE	hCCBKernelMemInfo;
+
+	IMG_UINT32	ui32NumDstSyncObjects;
+	IMG_HANDLE	hKernelHWSyncListMemInfo;
+
+	
+	IMG_HANDLE	*pahDstSyncHandles;
+
+	IMG_UINT32	ui32NumTAStatusVals;
+	IMG_UINT32	ui32Num3DStatusVals;
+
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+	SGX_INTERNEL_STATUS_UPDATE_KM	asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS];
+	SGX_INTERNEL_STATUS_UPDATE_KM	as3DStatusUpdate[SGX_MAX_3D_STATUS_VALS];
+#else
+	IMG_HANDLE	ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
+	IMG_HANDLE	ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
+#endif
+
+	IMG_BOOL	bFirstKickOrResume;
+#if (defined(NO_HARDWARE) || defined(PDUMP))
+	IMG_BOOL	bTerminateOrAbort;
+#endif
+
+	
+	IMG_UINT32	ui32CCBOffset;
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+	
+	IMG_UINT32	ui32NumTASrcSyncs;
+	IMG_HANDLE	ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
+	IMG_UINT32	ui32NumTADstSyncs;
+	IMG_HANDLE	ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
+	IMG_UINT32	ui32Num3DSrcSyncs;
+	IMG_HANDLE	ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
+#else
+	
+	IMG_UINT32	ui32NumSrcSyncs;
+	IMG_HANDLE	ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
+#endif
+
+	
+	IMG_BOOL	bTADependency;
+	IMG_HANDLE	hTA3DSyncInfo;
+
+	IMG_HANDLE	hTASyncInfo;
+	IMG_HANDLE	h3DSyncInfo;
+#if defined(PDUMP)
+	IMG_UINT32	ui32CCBDumpWOff;
+#endif
+#if defined(NO_HARDWARE)
+	IMG_UINT32	ui32WriteOpsPendingVal;
+#endif
+} SGX_CCB_KICK_KM;
+
+
+#if defined(TRANSFER_QUEUE)
+typedef struct _PVRSRV_TRANSFER_SGX_KICK_KM_
+{
+	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		ui32Flags;
+
+	IMG_UINT32		ui32PDumpFlags;
+#if defined(PDUMP)
+	IMG_UINT32		ui32CCBDumpWOff;
+#endif
+} PVRSRV_TRANSFER_SGX_KICK_KM, *PPVRSRV_TRANSFER_SGX_KICK_KM;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _PVRSRV_2D_SGX_KICK_KM_
+{
+	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;
+
+	IMG_UINT32		ui32PDumpFlags;
+#if defined(PDUMP)
+	IMG_UINT32		ui32CCBDumpWOff;
+#endif
+} PVRSRV_2D_SGX_KICK_KM, *PPVRSRV_2D_SGX_KICK_KM;
+#endif	
+#endif 
+
+PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_VOID SGXOSTimer(IMG_VOID *pvData);
+
+IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO	*psDevInfo,
+				  IMG_BOOL				bHardwareRecovery,
+				  IMG_UINT32			ui32PDUMPFlags);
+
+IMG_VOID SGXInitClocks(PVRSRV_SGXDEV_INFO	*psDevInfo,
+					   IMG_UINT32			ui32PDUMPFlags);
+
+PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO	*psDevInfo,
+						   IMG_BOOL				bHardwareRecovery);
+PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie);
+
+PVRSRV_ERROR SGXPrePowerState(IMG_HANDLE				hDevHandle, 
+							  PVRSRV_DEV_POWER_STATE	eNewPowerState, 
+							  PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+
+PVRSRV_ERROR SGXPostPowerState(IMG_HANDLE				hDevHandle, 
+							   PVRSRV_DEV_POWER_STATE	eNewPowerState, 
+							   PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+
+PVRSRV_ERROR SGXPreClockSpeedChange(IMG_HANDLE				hDevHandle,
+									IMG_BOOL				bIdleDevice,
+									PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+
+PVRSRV_ERROR SGXPostClockSpeedChange(IMG_HANDLE				hDevHandle,
+									 IMG_BOOL				bIdleDevice,
+									 PVRSRV_DEV_POWER_STATE	eCurrentPowerState);
+
+IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO	*psDevInfo);
+
+PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+#if defined(SGX_DYNAMIC_TIMING_INFO)
+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psSGXTimingInfo);
+#endif
+
+#if defined(NO_HARDWARE)
+static INLINE IMG_VOID NoHardwareGenerateEvent(PVRSRV_SGXDEV_INFO		*psDevInfo,
+												IMG_UINT32 ui32StatusRegister,
+												IMG_UINT32 ui32StatusValue,
+												IMG_UINT32 ui32StatusMask)
+{
+	IMG_UINT32 ui32RegVal;
+
+	ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister);
+
+	ui32RegVal &= ~ui32StatusMask;
+	ui32RegVal |= (ui32StatusValue & ui32StatusMask);
+
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister, ui32RegVal);
+}
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxinit.c b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxinit.c
new file mode 100644
index 0000000..bcfd564
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxinit.c
@@ -0,0 +1,2901 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "sgxmmu.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgx_mkif_km.h"
+#include "sgxconfig.h"
+#include "sysconfig.h"
+#include "pvr_bridge_km.h"
+
+#include "sgx_bridge_km.h"
+
+#include "pdump_km.h"
+#include "ra.h"
+#include "mmu.h"
+#include "handle.h"
+#include "perproc.h"
+
+#include "sgxutils.h"
+#include "pvrversion.h"
+#include "sgx_options.h"
+
+#include "lists.h"
+#include "srvkm.h"
+#include "ttrace.h"
+#define VAR(x) #x
+
+ 
+#define CHECK_SIZE(NAME) \
+{	\
+	if (psSGXStructSizes->ui32Sizeof_##NAME != psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME) \
+	{	\
+		PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Size check failed for SGXMKIF_%s (client) = %d bytes, (ukernel) = %d bytes\n", \
+			VAR(NAME), \
+			psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME, \
+			psSGXStructSizes->ui32Sizeof_##NAME )); \
+		bStructSizesFailed = IMG_TRUE; \
+	}	\
+}
+
+#if defined (SYS_USING_INTERRUPTS)
+IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData);
+#endif
+
+
+static
+PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO	*psDevInfo,
+								   PVRSRV_DEVICE_NODE 	*psDeviceNode,
+								   IMG_HANDLE hDevMemContext);
+static IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO	*psDevInfo,
+								  IMG_BOOL				bDumpSGXRegs);
+
+#if defined(PDUMP)
+static
+PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode);
+#endif
+
+static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+#if defined(OS_SUPPORTS_IN_LISR)
+	if (OSInLISR(psDeviceNode->psSysData))
+	{
+		
+		psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
+	}
+	else
+	{
+		SGXScheduleProcessQueuesKM(psDeviceNode);
+	}
+#else
+	SGXScheduleProcessQueuesKM(psDeviceNode);
+#endif
+}
+
+static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+	if (psDevInfo->psKernelCCBInfo != IMG_NULL)
+	{
+		
+
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL);
+	}
+
+	return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc,
+								PVRSRV_DEVICE_NODE *psDeviceNode,
+#if defined (SUPPORT_SID_INTERFACE)
+								SGX_BRIDGE_INIT_INFO_KM *psInitInfo)
+#else
+								SGX_BRIDGE_INIT_INFO *psInitInfo)
+#endif
+{
+	PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+	PVRSRV_ERROR		eError;
+
+	PVRSRV_SGX_CCB_INFO	*psKernelCCBInfo = IMG_NULL;
+
+	PVR_UNREFERENCED_PARAMETER(psPerProc);
+	psDevInfo->sScripts = psInitInfo->sScripts;
+
+	psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo;
+	psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM;
+
+	psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo;
+	psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM;
+
+	psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo;
+	psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM;
+
+	psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo;
+	psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
+
+	psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo;
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+	psDevInfo->psKernelSGXPTLAWriteBackMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXPTLAWriteBackMemInfo;
+#endif
+
+	psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo;
+
+#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
+	psDevInfo->psKernelTASigBufferMemInfo = psInitInfo->hKernelTASigBufferMemInfo;
+	psDevInfo->psKernel3DSigBufferMemInfo = psInitInfo->hKernel3DSigBufferMemInfo;
+#if defined(FIX_HW_BRN_29702)
+	psDevInfo->psKernelCFIMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCFIMemInfo;
+#endif
+#if defined(FIX_HW_BRN_29823)
+	psDevInfo->psKernelDummyTermStreamMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelDummyTermStreamMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+	psDevInfo->psKernelVDMSnapShotBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMSnapShotBufferMemInfo;
+	psDevInfo->psKernelVDMCtrlStreamBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMCtrlStreamBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+	defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+	psDevInfo->psKernelVDMStateUpdateBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMStateUpdateBufferMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+	psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_SPM_MODE_0)
+	psDevInfo->psKernelTmpDPMStateMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpDPMStateMemInfo;
+#endif
+	
+	psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions;
+
+	
+	psDevInfo->sSGXStructSizes = psInitInfo->sSGXStructSizes;
+
+	
+
+	eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+						sizeof(PVRSRV_SGX_CCB_INFO),
+						(IMG_VOID **)&psKernelCCBInfo, 0,
+						"SGX Circular Command Buffer Info");
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory"));
+		goto failed_allockernelccb;
+	}
+
+
+	OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO));
+	psKernelCCBInfo->psCCBMemInfo		= psDevInfo->psKernelCCBMemInfo;
+	psKernelCCBInfo->psCCBCtlMemInfo	= psDevInfo->psKernelCCBCtlMemInfo;
+	psKernelCCBInfo->psCommands			= psDevInfo->psKernelCCB->asCommands;
+	psKernelCCBInfo->pui32WriteOffset	= &psDevInfo->psKernelCCBCtl->ui32WriteOffset;
+	psKernelCCBInfo->pui32ReadOffset	= &psDevInfo->psKernelCCBCtl->ui32ReadOffset;
+	psDevInfo->psKernelCCBInfo = psKernelCCBInfo;
+
+	
+
+	OSMemCopy(psDevInfo->aui32HostKickAddr, psInitInfo->aui32HostKickAddr,
+			  SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0]));
+
+ 	psDevInfo->bForcePTOff = IMG_FALSE;
+
+	psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl;
+
+	psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0;
+	psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1;
+	psDevInfo->ui32ClkGateCtl = psInitInfo->ui32ClkGateCtl;
+	psDevInfo->ui32ClkGateCtl2 = psInitInfo->ui32ClkGateCtl2;
+	psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg;
+	psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+	psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg;
+	psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask;
+	psDevInfo->ui32MasterClkGateStatus2Reg = psInitInfo->ui32MasterClkGateStatus2Reg;
+	psDevInfo->ui32MasterClkGateStatus2Mask = psInitInfo->ui32MasterClkGateStatus2Mask;
+#endif 
+
+
+	
+	OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData));
+
+	return PVRSRV_OK;
+
+failed_allockernelccb:
+	DeinitDevInfo(psDevInfo);
+
+	return eError;
+}
+
+
+
+
+static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands)
+{
+	IMG_UINT32 ui32PC;
+	SGX_INIT_COMMAND *psComm;
+
+	for (ui32PC = 0, psComm = psScript;
+		ui32PC < ui32NumInitCommands;
+		ui32PC++, psComm++)
+	{
+		switch (psComm->eOp)
+		{
+			case SGX_INIT_OP_WRITE_HW_REG:
+			{
+				OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
+				PDUMPCOMMENT("SGXRunScript: Write HW reg operation");
+				PDUMPREG(SGX_PDUMPREG_NAME, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
+				break;
+			}
+#if defined(PDUMP)
+			case SGX_INIT_OP_PDUMP_HW_REG:
+			{
+				PDUMPCOMMENT("SGXRunScript: Dump HW reg operation");
+				PDUMPREG(SGX_PDUMPREG_NAME, psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value);
+				break;
+			}
+#endif
+			case SGX_INIT_OP_HALT:
+			{
+				return PVRSRV_OK;
+			}
+			case SGX_INIT_OP_ILLEGAL:
+			
+			default:
+			{
+				PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp));
+				return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
+			}
+		}
+
+	}
+
+	return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
+}
+
+PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO	*psDevInfo,
+						   IMG_BOOL				bHardwareRecovery)
+{
+	PVRSRV_ERROR			eError;
+	PVRSRV_KERNEL_MEM_INFO	*psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
+	SGXMKIF_HOST_CTL		*psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM;
+	static IMG_BOOL			bFirstTime = IMG_TRUE;
+#if defined(PDUMP)
+	IMG_BOOL				bPDumpIsSuspended = PDumpIsSuspended();
+#endif 
+
+#if defined(SGX_FEATURE_MP)
+	
+#else
+	SGXInitClocks(psDevInfo, PDUMP_FLAGS_CONTINUOUS);
+#endif 
+	
+	
+
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n");
+	eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError));
+		return eError;
+	}
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n");
+
+	
+	psDevInfo->ui32NumResets++;
+	SGXReset(psDevInfo, bFirstTime || bHardwareRecovery, PDUMP_FLAGS_CONTINUOUS);
+
+#if defined(EUR_CR_POWER)
+#if defined(SGX531)
+	
+
+
+
+
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1);
+	PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 1);
+#else
+	
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0);
+	PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 0);
+#endif
+#endif
+
+	
+	*psDevInfo->pui32KernelCCBEventKicker = 0;
+#if defined(PDUMP)
+	if (!bPDumpIsSuspended)
+	{
+		psDevInfo->ui32KernelCCBEventKickerDumpVal = 0;
+		PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
+				 psDevInfo->psKernelCCBEventKickerMemInfo, 0,
+				 sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS,
+				 MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+	}
+#endif 
+
+	
+
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n");
+	eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError));
+		return eError;
+	}
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n");
+
+	
+	psSGXHostCtl->ui32HostClock = OSClockus();
+
+	psSGXHostCtl->ui32InitStatus = 0;
+#if defined(PDUMP)
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+						  "Reset the SGX microkernel initialisation status\n");
+	PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo,
+			 offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
+			 sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+			 MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+						  "Initialise the microkernel\n");
+#endif 
+
+#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
+	OSWriteMemoryBarrier();
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+				 SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0),
+				 EUR_CR_EVENT_KICK2_NOW_MASK);
+#else
+	*psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
+	OSWriteMemoryBarrier();
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+				 SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
+				 EUR_CR_EVENT_KICK_NOW_MASK);
+#endif 
+
+	OSMemoryBarrier();
+
+#if defined(PDUMP)
+	
+
+	if (!bPDumpIsSuspended)
+	{
+#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
+		PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK);
+#else
+		psDevInfo->ui32KernelCCBEventKickerDumpVal = 1;
+		PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+							  "First increment of the SGX event kicker value\n");
+		PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
+				 psDevInfo->psKernelCCBEventKickerMemInfo,
+				 0,
+				 sizeof(IMG_UINT32),
+				 PDUMP_FLAGS_CONTINUOUS,
+				 MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+		PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK);
+#endif 
+	}
+#endif 
+
+#if !defined(NO_HARDWARE)
+	
+
+	if (PollForValueKM(&psSGXHostCtl->ui32InitStatus,
+					   PVRSRV_USSE_EDM_INIT_COMPLETE,
+					   PVRSRV_USSE_EDM_INIT_COMPLETE,
+					   MAX_HW_TIME_US,
+					   MAX_HW_TIME_US/WAIT_TRY_COUNT,
+					   IMG_FALSE) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed"));
+		#if !defined(FIX_HW_BRN_23281)
+		SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+		PVR_DBG_BREAK;
+		#endif 
+		return PVRSRV_ERROR_RETRY;
+	}
+#endif 
+
+#if defined(PDUMP)
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+						  "Wait for the SGX microkernel initialisation to complete");
+	PDUMPMEMPOL(psSGXHostCtlMemInfo,
+				offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
+				PVRSRV_USSE_EDM_INIT_COMPLETE,
+				PVRSRV_USSE_EDM_INIT_COMPLETE,
+				PDUMP_POLL_OPERATOR_EQUAL,
+				PDUMP_FLAGS_CONTINUOUS,
+				MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+#endif 
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+	
+
+
+	WorkaroundBRN22997ReadHostPort(psDevInfo);
+#endif 
+
+	PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset);
+
+	bFirstTime = IMG_FALSE;
+	
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie)
+
+{
+	PVRSRV_SGXDEV_INFO	*psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie;
+	PVRSRV_ERROR		eError;
+
+	
+	if (psDevInfo->pvRegsBaseKM == IMG_NULL)
+	{
+		return PVRSRV_OK;
+	}
+
+	eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError));
+		return eError;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode)
+{
+	IMG_HANDLE hDevMemHeap = IMG_NULL;
+	PVRSRV_SGXDEV_INFO	*psDevInfo;
+	IMG_HANDLE		hKernelDevMemContext;
+	IMG_DEV_PHYADDR		sPDDevPAddr;
+	IMG_UINT32		i;
+	PVRSRV_DEVICE_NODE  *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
+	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+	PVRSRV_ERROR		eError;
+
+	
+	PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME);
+	
+	#if defined(SGX_FEATURE_MP)
+	#if !defined(SGX_FEATURE_MP_PLUS)
+	PDUMPCOMMENT("SGX Multi-processor: %d cores", SGX_FEATURE_MP_CORE_COUNT);
+	#else
+	PDUMPCOMMENT("SGX Multi-processor: %d TA cores, %d 3D cores", SGX_FEATURE_MP_CORE_COUNT_TA, SGX_FEATURE_MP_CORE_COUNT_3D);
+	#endif
+	#endif 
+
+#if (SGX_CORE_REV == 0)
+	PDUMPCOMMENT("SGX Core Revision Information: head RTL");
+#else
+	PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV);
+#endif
+
+	#if defined(SGX_FEATURE_SYSTEM_CACHE)
+	PDUMPCOMMENT("SGX System Level Cache is present\r\n");
+	#if defined(SGX_BYPASS_SYSTEM_CACHE)
+	PDUMPCOMMENT("SGX System Level Cache is bypassed\r\n");
+	#endif 
+	#endif 
+
+	PDUMPCOMMENT("SGX Initialisation Part 1");
+
+	
+	if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+					 sizeof(PVRSRV_SGXDEV_INFO),
+					 (IMG_VOID **)&psDevInfo, IMG_NULL,
+					 "SGX Device Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo"));
+		return (PVRSRV_ERROR_OUT_OF_MEMORY);
+	}
+	OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO));
+
+	
+	psDevInfo->eDeviceType 		= DEV_DEVICE_TYPE;
+	psDevInfo->eDeviceClass 	= DEV_DEVICE_CLASS;
+
+	
+	psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo;
+
+	
+	psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap;
+
+	
+	hKernelDevMemContext = BM_CreateContext(psDeviceNode,
+											&sPDDevPAddr,
+											IMG_NULL,
+											IMG_NULL);
+	if (hKernelDevMemContext == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1: Failed BM_CreateContext"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	psDevInfo->sKernelPDDevPAddr = sPDDevPAddr;
+
+	
+	for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++)
+	{
+		switch(psDeviceMemoryHeap[i].DevMemHeapType)
+		{
+			case DEVICE_MEMORY_HEAP_KERNEL:
+			case DEVICE_MEMORY_HEAP_SHARED:
+			case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+			{
+				
+				if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+				{
+					hDevMemHeap = BM_CreateHeap (hKernelDevMemContext,
+												&psDeviceMemoryHeap[i]);
+					
+
+
+					psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap;
+				}
+				break;
+			}
+		}
+	}
+#if defined(PDUMP)
+	if(hDevMemHeap)
+	{
+		
+		psDevInfo->sMMUAttrib = *((BM_HEAP*)hDevMemHeap)->psMMUAttrib;
+	}
+#endif
+	eError = MMU_BIFResetPDAlloc(psDevInfo);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset"));
+		return eError;
+	}
+
+	return PVRSRV_OK;
+}
+
+IMG_EXPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, PVRSRV_HEAP_INFO_KM *pasHeapInfo, IMG_DEV_PHYADDR *psPDDevPAddr)
+#else
+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo)
+#endif
+{
+	PVRSRV_DEVICE_NODE	*psDeviceNode;
+	PVRSRV_SGXDEV_INFO	*psDevInfo;
+	PVRSRV_ERROR		eError;
+
+	PDUMPCOMMENT("SGXGetInfoForSrvinit");
+
+	psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
+	psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+#if defined (SUPPORT_SID_INTERFACE)
+	*psPDDevPAddr = psDevInfo->sKernelPDDevPAddr;
+
+	eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, pasHeapInfo);
+#else
+	psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr;
+
+	eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]);
+#endif
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError));
+		return eError;
+	}
+
+	return eError;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc,
+                                IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+                                SGX_BRIDGE_INIT_INFO_KM *psInitInfo)
+#else
+                                SGX_BRIDGE_INIT_INFO *psInitInfo)
+#endif
+{
+	PVRSRV_DEVICE_NODE		*psDeviceNode;
+	PVRSRV_SGXDEV_INFO		*psDevInfo;
+	PVRSRV_ERROR			eError;
+	SGX_DEVICE_MAP			*psSGXDeviceMap;
+	PVRSRV_DEV_POWER_STATE	eDefaultPowerState;
+
+	PDUMPCOMMENT("SGX Initialisation Part 2");
+
+	psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
+	psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+	
+
+	eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program"));
+		goto failed_init_dev_info;
+	}
+
+
+	eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+									(IMG_VOID**)&psSGXDeviceMap);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!"));
+		return PVRSRV_ERROR_INIT_FAILURE;
+	}
+
+	
+	if (psSGXDeviceMap->pvRegsCpuVBase)
+	{
+		psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase;
+	}
+	else
+	{
+		
+		psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase,
+											   psSGXDeviceMap->ui32RegsSize,
+											   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+											   IMG_NULL);
+		if (!psDevInfo->pvRegsBaseKM)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n"));
+			return PVRSRV_ERROR_BAD_MAPPING;
+		}
+	}
+	psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize;
+	psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase;
+
+
+#if defined(SGX_FEATURE_HOST_PORT)
+	if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
+	{
+		
+		psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase,
+									  	           psSGXDeviceMap->ui32HPSize,
+									  	           PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+									  	           IMG_NULL);
+		if (!psDevInfo->pvHostPortBaseKM)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n"));
+			return PVRSRV_ERROR_BAD_MAPPING;
+		}
+		psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize;
+		psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase;
+	}
+#endif
+
+#if defined (SYS_USING_INTERRUPTS)
+
+	
+	psDeviceNode->pvISRData = psDeviceNode;
+	
+	PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler);
+
+#endif 
+
+	
+	psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK;
+	eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
+	
+	eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex,
+										&SGXPrePowerState, &SGXPostPowerState,
+										&SGXPreClockSpeedChange, &SGXPostClockSpeedChange,
+										(IMG_HANDLE)psDeviceNode,
+										PVRSRV_DEV_POWER_STATE_OFF,
+										eDefaultPowerState);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager"));
+		return eError;
+	}
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+	eError = WorkaroundBRN22997Alloc(psDeviceNode);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround"));
+		return eError;
+	}
+#endif 
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+	
+	psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize;
+	psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase;
+	eError = MMU_MapExtSystemCacheRegs(psDeviceNode);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers"));
+		return eError;
+	}
+#endif 
+
+	
+
+	OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB));
+	OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL));
+	OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker));
+	PDUMPCOMMENT("Initialise Kernel CCB");
+	PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo));
+	PDUMPCOMMENT("Initialise Kernel CCB Control");
+	PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo));
+	PDUMPCOMMENT("Initialise Kernel CCB Event Kicker");
+	PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+
+	return PVRSRV_OK;
+
+failed_init_dev_info:
+	return eError;
+}
+
+static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode)
+{
+	PVRSRV_DEVICE_NODE			*psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
+	PVRSRV_SGXDEV_INFO			*psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+	PVRSRV_ERROR				eError;
+	IMG_UINT32					ui32Heap;
+	DEVICE_MEMORY_HEAP_INFO		*psDeviceMemoryHeap;
+	SGX_DEVICE_MAP				*psSGXDeviceMap;
+
+	if (!psDevInfo)
+	{
+		
+		PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo"));
+		return PVRSRV_OK;
+	}
+
+#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;
+		}
+		psDevInfo->hTimer = IMG_NULL;
+	}
+#endif 
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+	
+	eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers"));
+		return eError;
+	}
+#endif 
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+	WorkaroundBRN22997Free(psDeviceNode);
+#endif 
+
+	MMU_BIFResetPDFree(psDevInfo);
+
+	
+
+	DeinitDevInfo(psDevInfo);
+
+	
+	psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap;
+	for(ui32Heap=0; ui32Heap<psDeviceNode->sDevMemoryInfo.ui32HeapCount; ui32Heap++)
+	{
+		switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType)
+		{
+			case DEVICE_MEMORY_HEAP_KERNEL:
+			case DEVICE_MEMORY_HEAP_SHARED:
+			case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+			{
+				if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL)
+				{
+					BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap);
+				}
+				break;
+			}
+		}
+	}
+
+	
+	eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context"));
+		return eError;
+	}
+
+	
+	eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex);
+	if (eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+	eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+									(IMG_VOID**)&psSGXDeviceMap);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!"));
+		return eError;
+	}
+
+	
+	if (!psSGXDeviceMap->pvRegsCpuVBase)
+	{
+		
+		if (psDevInfo->pvRegsBaseKM != IMG_NULL)
+		{
+			OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,
+							 psDevInfo->ui32RegSize,
+							 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+							 IMG_NULL);
+		}
+	}
+
+#if defined(SGX_FEATURE_HOST_PORT)
+	if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
+	{
+		
+		if (psDevInfo->pvHostPortBaseKM != IMG_NULL)
+		{
+			OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM,
+						   psDevInfo->ui32HPSize,
+						   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+						   IMG_NULL);
+		}
+	}
+#endif 
+
+
+	
+	OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				sizeof(PVRSRV_SGXDEV_INFO),
+				psDevInfo,
+				0);
+
+	psDeviceNode->pvDevice = IMG_NULL;
+
+	if (psDeviceMemoryHeap != IMG_NULL)
+	{
+	
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+				sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
+				psDeviceMemoryHeap,
+				0);
+	}
+
+	return PVRSRV_OK;
+}
+
+static IMG_VOID SGXDumpRegDecode(IMG_UINT32 addr, IMG_UINT32 val)
+{
+	switch (addr) {
+	case EUR_CR_EVENT_STATUS:
+		PVR_LOG(("\t(master_irq: %s, timer_irq: %s, ta_dpm_fault: %s, zls_oom: %s, "
+			 "ta_mem_free: %s, isp_end_tile: %s, dpm_initend: %s, zls_csw_finish: %s, "
+			 "pbe_end_render: %s, isp_vis_fail: %s, isp_break: %s, sw_event %s, "
+			 "ta_finish: %s, ta_terminate: %s, tpc_clear: %s, tpc_flush: %s, "
+			 "dpm_clear: %s, dpm_load: %s, dpm_store: %s, dpm_state_clear: %s, "
+			 "dpm_state_load: %s, dpm_state_store: %s, dpm_mem_thresh: %s, gbl_oom: %s, "
+			 "mt_oom: %s, 3d_mem_free: %s)",
+			 val & EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_TIMER_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK ? "yes": "no",
+			 val & EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK ? "yes" : "no",
+			 val & EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK ? "yes" : "no",
+			 val & EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK ?"yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_INITEND_MASK ?"yes":"no",
+			 val & EUR_CR_EVENT_STATUS_ISP2_ZLS_CSW_FINISHED_MASK ?"yes":"no",
+			 val & EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK ?"yes":"no",
+			 val & EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK ?"yes":"no",
+			 val & EUR_CR_EVENT_STATUS_BREAKPOINT_MASK ?"yes":"no",
+			 val & EUR_CR_EVENT_STATUS_SW_EVENT_MASK ?"yes":"no",
+			 val & EUR_CR_EVENT_STATUS_TA_FINISHED_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK ? "yes":"no",
+		       	 val & EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK ? "yes":"no"));
+		break;
+	case EUR_CR_EVENT_STATUS2:
+		PVR_LOG(("\t(mte_flush: %s, vdm_load: %s, vdm_kicked: %s, otpm_mem_clear: %s,"
+			 "otpm_flush: %s, dcu_invalid: %s, gsg_flush: %s, gsg_load: %s, "
+			 "lockup_ta: %s, lockup_3d: %s, partial_deadlock: %s, dpm_dhost_free: %s"
+			 "dpm_host_free: %s, dpm_3d_free: %s, dpm_ta_free: %s)",
+		         val & EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_VDM_CONTEXT_LOAD_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_VDM_TASK_KICKED_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_OTPM_MEM_CLEARED_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_OTPM_FLUSHED_INV_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_GSG_FLUSHED_MASK ? "yes":"no",
+		         val & EUR_CR_EVENT_STATUS2_GSG_LOADED_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_TRIG_TA_MASK ? "yes":"no",
+		         val & EUR_CR_EVENT_STATUS2_TRIG_3D_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_TRIG_DL_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK ? "yes":"no",
+			 val & EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK ? "yes":"no"));
+		break;
+	}
+}
+
+#if defined(RESTRICTED_REGISTERS) && defined(SGX_FEATURE_MP)
+
+static IMG_VOID SGXDumpMasterDebugReg (PVRSRV_SGXDEV_INFO	*psDevInfo,
+								 IMG_CHAR			*pszName,
+								 IMG_UINT32			ui32RegAddr)
+{
+	IMG_UINT32	ui32RegVal;
+	ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32RegAddr);
+	PVR_LOG(("(HYD) %s%08X", pszName, ui32RegVal));
+}
+
+#endif 
+
+static IMG_VOID SGXDumpDebugReg (PVRSRV_SGXDEV_INFO	*psDevInfo,
+								 IMG_UINT32			ui32CoreNum,
+								 IMG_CHAR			*pszName,
+								 IMG_UINT32			ui32RegAddr)
+{
+	IMG_UINT32	ui32RegVal;
+	ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(ui32RegAddr, ui32CoreNum));
+	PVR_LOG(("(P%u) %s%08X", ui32CoreNum, pszName, ui32RegVal));
+
+	SGXDumpRegDecode(ui32RegAddr, ui32RegVal);
+}
+
+static IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO	*psDevInfo,
+								  IMG_BOOL				bDumpSGXRegs)
+{
+	IMG_UINT32	ui32CoreNum;
+
+	PVR_LOG(("SGX debug (%s)", PVRVERSION_STRING));
+
+	if (bDumpSGXRegs)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Linear):   0x%08X", (IMG_UINTPTR_T)psDevInfo->pvRegsBaseKM));
+		PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Physical): 0x%08X", psDevInfo->sRegsPhysBase.uiAddr));
+
+		SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_ID:          ", EUR_CR_CORE_ID);
+		SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_REVISION:    ", EUR_CR_CORE_REVISION);
+#if defined(RESTRICTED_REGISTERS) && defined(SGX_FEATURE_MP)
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_INT_STAT:   ", EUR_CR_MASTER_BIF_INT_STAT);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_FAULT:      ",EUR_CR_MASTER_BIF_FAULT);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_CLKGATESTATUS2: ",EUR_CR_MASTER_CLKGATESTATUS2 );
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_PIM_STATUS: ",EUR_CR_MASTER_VDM_PIM_STATUS);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_BANK_SET:   ",EUR_CR_MASTER_BIF_BANK_SET);
+
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_EVENT_STATUS:   ",EUR_CR_MASTER_EVENT_STATUS);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_EVENT_STATUS2:  ",EUR_CR_MASTER_EVENT_STATUS2);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_MP_PRIMITIVE:   ",EUR_CR_MASTER_MP_PRIMITIVE);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_DPM_DPLIST_STATUS: ",EUR_CR_MASTER_DPM_DPLIST_STATUS);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_DPM_PROACTIVE_PIM_SPEC: ",EUR_CR_MASTER_DPM_PROACTIVE_PIM_SPEC);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_PAGE_MANAGEOP:  ",EUR_CR_MASTER_DPM_PAGE_MANAGEOP);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_SNAPSHOT: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_SNAPSHOT);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_LOAD_STATUS: ",EUR_CR_MASTER_VDM_CONTEXT_LOAD_STATUS);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STREAM: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STREAM);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATUS: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATUS);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE0: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE0);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE1: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE1);
+		SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_WAIT_FOR_KICK: ",EUR_CR_MASTER_VDM_WAIT_FOR_KICK);
+#endif
+		for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT_3D; ui32CoreNum++)
+		{
+			
+			SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS:     ", EUR_CR_EVENT_STATUS);
+			SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS2:    ", EUR_CR_EVENT_STATUS2);
+			SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_CTRL:         ", EUR_CR_BIF_CTRL);
+		#if defined(EUR_CR_BIF_BANK0)
+			SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_BANK0:        ", EUR_CR_BIF_BANK0);
+		#endif
+			SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_INT_STAT:     ", EUR_CR_BIF_INT_STAT);
+			SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_FAULT:        ", EUR_CR_BIF_FAULT);
+			SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_MEM_REQ_STAT: ", EUR_CR_BIF_MEM_REQ_STAT);
+			SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_CLKGATECTL:       ", EUR_CR_CLKGATECTL);
+		#if defined(EUR_CR_PDS_PC_BASE)
+			SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_PDS_PC_BASE:      ", EUR_CR_PDS_PC_BASE);
+		#endif
+		}
+	}
+
+	
+
+	QueueDumpDebugInfo();
+
+	{
+		
+
+		SGXMKIF_HOST_CTL	*psSGXHostCtl = psDevInfo->psSGXHostCtl;
+		IMG_UINT32			*pui32HostCtlBuffer = (IMG_UINT32 *)psSGXHostCtl;
+		IMG_UINT32			ui32LoopCounter;
+
+		if (psSGXHostCtl->ui32AssertFail != 0)
+		{
+			PVR_LOG(("SGX Microkernel assert fail: 0x%08X", psSGXHostCtl->ui32AssertFail));
+			psSGXHostCtl->ui32AssertFail = 0;
+		}
+
+		PVR_LOG(("SGX Host control:"));
+
+		for (ui32LoopCounter = 0;
+			 ui32LoopCounter < sizeof(*psDevInfo->psSGXHostCtl) / sizeof(*pui32HostCtlBuffer);
+			 ui32LoopCounter += 4)
+		{
+			PVR_LOG(("\t(HC-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32HostCtlBuffer),
+					pui32HostCtlBuffer[ui32LoopCounter + 0], pui32HostCtlBuffer[ui32LoopCounter + 1],
+					pui32HostCtlBuffer[ui32LoopCounter + 2], pui32HostCtlBuffer[ui32LoopCounter + 3]));
+		}
+	}
+
+	{
+		
+
+		IMG_UINT32	*pui32TA3DCtlBuffer = psDevInfo->psKernelSGXTA3DCtlMemInfo->pvLinAddrKM;
+		IMG_UINT32	ui32LoopCounter;
+
+		PVR_LOG(("SGX TA/3D control:"));
+
+		for (ui32LoopCounter = 0;
+			 ui32LoopCounter < psDevInfo->psKernelSGXTA3DCtlMemInfo->uAllocSize / sizeof(*pui32TA3DCtlBuffer);
+			 ui32LoopCounter += 4)
+		{
+			PVR_LOG(("\t(T3C-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32TA3DCtlBuffer),
+					pui32TA3DCtlBuffer[ui32LoopCounter + 0], pui32TA3DCtlBuffer[ui32LoopCounter + 1],
+					pui32TA3DCtlBuffer[ui32LoopCounter + 2], pui32TA3DCtlBuffer[ui32LoopCounter + 3]));
+		}
+	}
+
+	#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+	{
+		IMG_UINT32	*pui32MKTraceBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
+		IMG_UINT32	ui32LastStatusCode, ui32WriteOffset;
+
+		ui32LastStatusCode = *pui32MKTraceBuffer;
+		pui32MKTraceBuffer++;
+		ui32WriteOffset = *pui32MKTraceBuffer;
+		pui32MKTraceBuffer++;
+
+		PVR_LOG(("Last SGX microkernel status code: %08X", ui32LastStatusCode));
+
+		#if defined(PVRSRV_DUMP_MK_TRACE)
+		
+
+		{
+			IMG_UINT32	ui32LoopCounter;
+
+			for (ui32LoopCounter = 0;
+				 ui32LoopCounter < SGXMK_TRACE_BUFFER_SIZE;
+				 ui32LoopCounter++)
+			{
+				IMG_UINT32	*pui32BufPtr;
+				pui32BufPtr = pui32MKTraceBuffer +
+								(((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4);
+				PVR_LOG(("\t(MKT-%X) %08X %08X %08X %08X", ui32LoopCounter,
+						 pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0]));
+			}
+		}
+		#endif 
+	}
+	#endif 
+
+	{
+		
+
+		PVR_LOG(("SGX Kernel CCB WO:0x%X RO:0x%X",
+				psDevInfo->psKernelCCBCtl->ui32WriteOffset,
+				psDevInfo->psKernelCCBCtl->ui32ReadOffset));
+
+		#if defined(PVRSRV_DUMP_KERNEL_CCB)
+		{
+			IMG_UINT32	ui32LoopCounter;
+
+			for (ui32LoopCounter = 0;
+				 ui32LoopCounter < sizeof(psDevInfo->psKernelCCB->asCommands) /
+				 					sizeof(psDevInfo->psKernelCCB->asCommands[0]);
+				 ui32LoopCounter++)
+			{
+				SGXMKIF_COMMAND	*psCommand = &psDevInfo->psKernelCCB->asCommands[ui32LoopCounter];
+
+				PVR_LOG(("\t(KCCB-%X) %08X %08X - %08X %08X %08X %08X", ui32LoopCounter,
+						psCommand->ui32ServiceAddress, psCommand->ui32CacheControl,
+						psCommand->ui32Data[0], psCommand->ui32Data[1],
+						psCommand->ui32Data[2], psCommand->ui32Data[3]));
+			}
+		}
+		#endif 
+	}
+	#if defined (TTRACE)
+	PVRSRVDumpTimeTraceBuffers();
+	#endif
+
+}
+
+
+#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;
+	SGXMKIF_HOST_CTL	*psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Component);
+
+	
+
+	eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
+	if(eError != PVRSRV_OK)
+	{
+		
+
+
+		PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress"));
+		return;
+	}
+
+	psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR;
+
+	PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered"));
+
+	SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE);
+
+	
+	PDUMPSUSPEND();
+
+	
+#if defined(FIX_HW_BRN_23281)
+	
+	for (eError = PVRSRV_ERROR_RETRY; eError == PVRSRV_ERROR_RETRY;)
+#endif 
+	{
+		eError = SGXInitialise(psDevInfo, IMG_TRUE);
+	}
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError));
+	}
+
+	
+	PDUMPRESUME();
+
+	PVRSRVPowerUnlock(ui32CallerID);
+
+	
+	SGXScheduleProcessQueuesKM(psDeviceNode);
+
+	
+	
+	PVRSRVProcessQueues(IMG_TRUE);
+}
+#endif 
+
+
+#if defined(SUPPORT_HW_RECOVERY)
+IMG_VOID SGXOSTimer(IMG_VOID *pvData)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode = pvData;
+	PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+	static IMG_UINT32	ui32EDMTasks = 0;
+	static IMG_UINT32	ui32LockupCounter = 0; 
+	static IMG_UINT32	ui32OpenCLDelayCounter = 0;
+	static IMG_UINT32	ui32NumResets = 0;
+#if defined(FIX_HW_BRN_31093)
+	static IMG_BOOL		bBRN31093Inval = IMG_FALSE;
+#endif
+	IMG_UINT32		ui32CurrentEDMTasks;
+	IMG_UINT32		ui32CurrentOpenCLDelayCounter=0;
+	IMG_BOOL		bLockup = IMG_FALSE;
+	IMG_BOOL		bPoweredDown;
+
+	
+	psDevInfo->ui32TimeStamp++;
+
+#if defined(NO_HARDWARE)
+	bPoweredDown = IMG_TRUE;
+#else
+	bPoweredDown = (SGXIsDevicePowered(psDeviceNode)) ? IMG_FALSE : IMG_TRUE;
+#endif 
+
+	
+	
+	if (bPoweredDown)
+	{
+		ui32LockupCounter = 0;
+	#if defined(FIX_HW_BRN_31093)
+		bBRN31093Inval = IMG_FALSE;
+	#endif
+	}
+	else
+	{
+		
+		ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0);
+		if (psDevInfo->ui32EDMTaskReg1 != 0)
+		{
+			ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1);
+		}
+		if ((ui32CurrentEDMTasks == ui32EDMTasks) &&
+			(psDevInfo->ui32NumResets == ui32NumResets))
+		{
+			ui32LockupCounter++;
+			if (ui32LockupCounter == 3)
+			{
+				ui32LockupCounter = 0;
+				ui32CurrentOpenCLDelayCounter = (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount;
+				if(0 != ui32CurrentOpenCLDelayCounter)
+				{
+					if(ui32OpenCLDelayCounter != ui32CurrentOpenCLDelayCounter){
+						ui32OpenCLDelayCounter = ui32CurrentOpenCLDelayCounter;
+					}else{
+						ui32OpenCLDelayCounter -= 1;
+						(psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount = ui32OpenCLDelayCounter;
+					}
+					goto SGX_NoUKernel_LockUp;
+				}
+
+
+	#if defined(FIX_HW_BRN_31093)
+				if (bBRN31093Inval == IMG_FALSE)
+				{
+					
+		#if defined(FIX_HW_BRN_29997)
+					IMG_UINT32	ui32BIFCtrl;
+					
+					ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
+					OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_PAUSE_MASK);
+					
+					SGXWaitClocks(psDevInfo, 200);
+		#endif
+					
+					bBRN31093Inval = IMG_TRUE;
+					
+					OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, EUR_CR_BIF_CTRL_INVAL_PTE_MASK);
+					
+					SGXWaitClocks(psDevInfo, 200);
+						
+		#if defined(FIX_HW_BRN_29997)	
+						
+					OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+		#endif
+				}
+				else
+	#endif
+				{
+				PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks));
+
+					bLockup = IMG_TRUE;
+					(psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount = 0;
+				}
+			}
+		}
+		else
+		{
+	#if defined(FIX_HW_BRN_31093)
+			bBRN31093Inval = IMG_FALSE;
+	#endif
+			ui32LockupCounter = 0;
+			ui32EDMTasks = ui32CurrentEDMTasks;
+			ui32NumResets = psDevInfo->ui32NumResets;
+		}
+	}
+SGX_NoUKernel_LockUp:
+
+	if (bLockup)
+	{
+		SGXMKIF_HOST_CTL	*psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
+
+		
+		psSGXHostCtl->ui32HostDetectedLockups ++;
+
+		
+		HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);
+	}
+}
+#endif 
+
+
+#if defined(SYS_USING_INTERRUPTS)
+
+IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData)
+{
+	IMG_BOOL bInterruptProcessed = IMG_FALSE;
+
+
+	
+	{
+		IMG_UINT32 ui32EventStatus, ui32EventEnable;
+		IMG_UINT32 ui32EventClear = 0;
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+		IMG_UINT32 ui32EventStatus2, ui32EventEnable2;
+#endif		
+		IMG_UINT32 ui32EventClear2 = 0;
+		PVRSRV_DEVICE_NODE *psDeviceNode;
+		PVRSRV_SGXDEV_INFO *psDevInfo;
+
+		
+		if(pvData == IMG_NULL)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n"));
+			return bInterruptProcessed;
+		}
+
+		psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+		psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+		ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
+		ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE);
+
+		
+		ui32EventStatus &= ui32EventEnable;
+
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+		ui32EventStatus2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
+		ui32EventEnable2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE2);
+
+		
+		ui32EventStatus2 &= ui32EventEnable2;
+#endif 
+
+		
+
+		if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK)
+		{
+			ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK;
+		}
+
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+		if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK)
+		{
+			ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK;
+		}
+
+		if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK)
+		{
+			ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK;
+		}
+#endif 
+
+		if (ui32EventClear || ui32EventClear2)
+		{
+			bInterruptProcessed = IMG_TRUE;
+
+			
+			ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK;
+
+			
+			OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear);
+			OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32EventClear2);
+		}
+	}
+
+	return bInterruptProcessed;
+}
+
+
+static IMG_VOID SGX_MISRHandler (IMG_VOID *pvData)
+{
+	PVRSRV_DEVICE_NODE	*psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+	PVRSRV_SGXDEV_INFO	*psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+	SGXMKIF_HOST_CTL	*psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
+
+	if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) &&
+		((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL))
+	{
+		HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);
+	}
+
+#if defined(OS_SUPPORTS_IN_LISR)
+	if (psDeviceNode->bReProcessDeviceCommandComplete)
+	{
+		SGXScheduleProcessQueuesKM(psDeviceNode);
+	}
+#endif
+
+	SGXTestActivePowerEvent(psDeviceNode, ISR_ID);
+}
+#endif 
+
+
+
+#if defined(SUPPORT_MEMORY_TILING)
+PVRSRV_ERROR SGX_AllocMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
+										PVRSRV_KERNEL_MEM_INFO	*psMemInfo,
+										IMG_UINT32 ui32TilingStride,
+										IMG_UINT32 *pui32RangeIndex)
+{
+#if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS)
+	PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+	IMG_UINT32 i;
+	IMG_UINT32 ui32Start;
+	IMG_UINT32 ui32End;
+	IMG_UINT32 ui32Offset;
+	IMG_UINT32 ui32Val;
+
+	
+	for(i=0; i<10; i++)
+	{
+		if((psDevInfo->ui32MemTilingUsage & (1U << i)) == 0)
+		{
+			
+			psDevInfo->ui32MemTilingUsage |= 1U << i;
+			
+			*pui32RangeIndex = i;
+			goto RangeAllocated;
+		}
+	}
+
+	PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: all tiling ranges in use"));
+	return PVRSRV_ERROR_EXCEEDED_HW_LIMITS;
+
+RangeAllocated:
+	ui32Offset = EUR_CR_BIF_TILE0 + (i<<2);
+
+	ui32Start = psMemInfo->sDevVAddr.uiAddr;
+	ui32End = ui32Start + psMemInfo->uAllocSize + SGX_MMU_PAGE_SIZE - 1;
+
+	ui32Val = ((ui32TilingStride << EUR_CR_BIF_TILE0_CFG_SHIFT) & EUR_CR_BIF_TILE0_CFG_MASK)
+			| (((ui32End>>20) << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK)
+			| (((ui32Start>>20) << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK)
+			| (0x8 << EUR_CR_BIF_TILE0_CFG_SHIFT);
+
+	
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
+	PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
+
+	ui32Offset = EUR_CR_BIF_TILE0_ADDR_EXT + (i<<2);
+
+	ui32Val = (((ui32End>>12) << EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MAX_MASK)
+			| (((ui32Start>>12) << EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MIN_MASK);
+
+	
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
+	PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
+
+	return PVRSRV_OK;
+#else
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+	PVR_UNREFERENCED_PARAMETER(psMemInfo);
+	PVR_UNREFERENCED_PARAMETER(ui32TilingStride);
+	PVR_UNREFERENCED_PARAMETER(pui32RangeIndex);
+
+	PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: device does not support memory tiling"));
+	return PVRSRV_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+PVRSRV_ERROR SGX_FreeMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
+										IMG_UINT32 ui32RangeIndex)
+{
+#if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS)
+	PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+	IMG_UINT32 ui32Offset;
+	IMG_UINT32 ui32Val;
+
+	if(ui32RangeIndex >= 10)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: invalid Range index "));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	
+	psDevInfo->ui32MemTilingUsage &= ~(1<<ui32RangeIndex);
+
+	
+	ui32Offset = EUR_CR_BIF_TILE0 + (ui32RangeIndex<<2);
+	ui32Val = 0;
+
+	
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
+	PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
+
+	return PVRSRV_OK;
+#else
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+	PVR_UNREFERENCED_PARAMETER(ui32RangeIndex);
+
+	PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: device does not support memory tiling"));
+	return PVRSRV_ERROR_NOT_SUPPORTED;
+#endif
+}
+#endif
+
+static IMG_VOID SGXCacheInvalidate(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+	#if defined(SGX_FEATURE_MP)
+	psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL;
+	#else
+	PVR_UNREFERENCED_PARAMETER(psDevInfo);
+	#endif 
+}
+
+PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	DEVICE_MEMORY_INFO *psDevMemoryInfo;
+	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+	int heap_count;
+
+	
+	psDeviceNode->sDevId.eDeviceType		= DEV_DEVICE_TYPE;
+	psDeviceNode->sDevId.eDeviceClass		= DEV_DEVICE_CLASS;
+#if defined(PDUMP)
+	{
+		
+		SGX_DEVICE_MAP *psSGXDeviceMemMap;
+		SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+							  (IMG_VOID**)&psSGXDeviceMemMap);
+
+		psDeviceNode->sDevId.pszPDumpDevName = psSGXDeviceMemMap->pszPDumpDevName;
+		PVR_ASSERT(psDeviceNode->sDevId.pszPDumpDevName != IMG_NULL);
+	}
+	
+	psDeviceNode->sDevId.pszPDumpRegName	= SGX_PDUMPREG_NAME;
+#endif 
+
+	psDeviceNode->pfnInitDevice		= &DevInitSGXPart1;
+	psDeviceNode->pfnDeInitDevice	= &DevDeInitSGX;
+
+	psDeviceNode->pfnInitDeviceCompatCheck	= &SGXDevInitCompatCheck;
+#if defined(PDUMP)
+	psDeviceNode->pfnPDumpInitDevice = &SGXResetPDump;
+	psDeviceNode->pfnMMUGetContextID = &MMU_GetPDumpContextID;
+#endif
+	
+
+	psDeviceNode->pfnMMUInitialise = &MMU_Initialise;
+	psDeviceNode->pfnMMUFinalise = &MMU_Finalise;
+	psDeviceNode->pfnMMUInsertHeap = &MMU_InsertHeap;
+	psDeviceNode->pfnMMUCreate = &MMU_Create;
+	psDeviceNode->pfnMMUDelete = &MMU_Delete;
+	psDeviceNode->pfnMMUAlloc = &MMU_Alloc;
+	psDeviceNode->pfnMMUFree = &MMU_Free;
+	psDeviceNode->pfnMMUMapPages = &MMU_MapPages;
+	psDeviceNode->pfnMMUMapShadow = &MMU_MapShadow;
+	psDeviceNode->pfnMMUUnmapPages = &MMU_UnmapPages;
+	psDeviceNode->pfnMMUMapScatter = &MMU_MapScatter;
+	psDeviceNode->pfnMMUGetPhysPageAddr = &MMU_GetPhysPageAddr;
+	psDeviceNode->pfnMMUGetPDDevPAddr = &MMU_GetPDDevPAddr;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	psDeviceNode->pfnMMUIsHeapShared = &MMU_IsHeapShared;
+#endif
+#if defined(FIX_HW_BRN_31620)
+	psDeviceNode->pfnMMUGetCacheFlushRange = &MMU_GetCacheFlushRange;
+	psDeviceNode->pfnMMUGetPDPhysAddr = &MMU_GetPDPhysAddr;
+#else
+	psDeviceNode->pfnMMUGetCacheFlushRange = IMG_NULL;
+	psDeviceNode->pfnMMUGetPDPhysAddr = IMG_NULL;
+#endif
+#if defined (SYS_USING_INTERRUPTS)
+	
+
+	psDeviceNode->pfnDeviceISR = SGX_ISRHandler;
+	psDeviceNode->pfnDeviceMISR = SGX_MISRHandler;
+#endif
+
+#if defined(SUPPORT_MEMORY_TILING)
+	psDeviceNode->pfnAllocMemTilingRange = SGX_AllocMemTilingRange;
+	psDeviceNode->pfnFreeMemTilingRange = SGX_FreeMemTilingRange;
+#endif
+
+	
+
+	psDeviceNode->pfnDeviceCommandComplete = &SGXCommandComplete;
+
+	psDeviceNode->pfnCacheInvalidate = SGXCacheInvalidate;
+
+	
+
+	psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+	
+	psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE;
+
+	
+	psDevMemoryInfo->ui32Flags = 0;
+
+	heap_count = SGX_MAX_HEAP_ID;
+	if (!need_sample_cache_workaround)
+		--heap_count;
+	
+	if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+					 sizeof(DEVICE_MEMORY_HEAP_INFO) * heap_count,
+					 (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0,
+					 "Array of Device Memory Heap Info") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO"));
+		return (PVRSRV_ERROR_OUT_OF_MEMORY);
+	}
+	OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * heap_count);
+
+	psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+
+	
+
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID);
+	if (need_sample_cache_workaround) {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE_REV1;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE_REV1;
+	} else {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE;
+	}
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+														| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+														| PVRSRV_HAP_SINGLE_PROCESS;
+	psDeviceMemoryHeap->pszName = "General";
+	psDeviceMemoryHeap->pszBSName = "General BS";
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+#if !defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+	
+	psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+#endif
+	psDeviceMemoryHeap++;
+
+#if defined(FIX_HW_BRN_SAMPLE_CACHE)
+	/* New texture heap on high address */
+	if (need_sample_cache_workaround) {
+		psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TEXTURE_HEAP_ID);
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TEXTURE_HEAP_BASE_REV1;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_TEXTURE_HEAP_SIZE_REV1;
+		psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+			| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+			| PVRSRV_HAP_SINGLE_PROCESS;
+		psDeviceMemoryHeap->pszName = "Texture";
+		psDeviceMemoryHeap->pszBSName = "Texture BS";
+		psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+		psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+		psDeviceMemoryHeap++;
+	}
+#endif
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID);
+	if (need_sample_cache_workaround) {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE_REV1;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE_REV1;
+	} else {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE;
+	}
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+														| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+														| PVRSRV_HAP_MULTI_PROCESS;
+	psDeviceMemoryHeap->pszName = "TA Data";
+	psDeviceMemoryHeap->pszBSName = "TA Data BS";
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID);
+	if (need_sample_cache_workaround) {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE_REV1;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE_REV1;
+	} else {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE;
+	}
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+															| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+															| PVRSRV_HAP_MULTI_PROCESS;
+	psDeviceMemoryHeap->pszName = "Kernel Code";
+	psDeviceMemoryHeap->pszBSName = "Kernel Code BS";
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID);
+	if (need_sample_cache_workaround) {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE_REV1;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE_REV1;
+	} else {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE;
+	}
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+																| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+																| PVRSRV_HAP_MULTI_PROCESS;
+	psDeviceMemoryHeap->pszName = "KernelData";
+	psDeviceMemoryHeap->pszBSName = "KernelData BS";
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID);
+	if (need_sample_cache_workaround)
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE_REV1;
+	else
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE;
+	psDeviceMemoryHeap->ui32HeapSize = ((10 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
+	PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_PIXELSHADER_HEAP_SIZE);
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+																| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+																| PVRSRV_HAP_SINGLE_PROCESS;
+	psDeviceMemoryHeap->pszName = "PixelShaderUSSE";
+	psDeviceMemoryHeap->pszBSName = "PixelShaderUSSE BS";
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID);
+	if (need_sample_cache_workaround)
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE_REV1;
+	else
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE;
+	
+	psDeviceMemoryHeap->ui32HeapSize = ((4 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
+	PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_VERTEXSHADER_HEAP_SIZE);
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+																| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+																| PVRSRV_HAP_SINGLE_PROCESS;
+	psDeviceMemoryHeap->pszName = "VertexShaderUSSE";
+	psDeviceMemoryHeap->pszBSName = "VertexShaderUSSE BS";
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID);
+	if (need_sample_cache_workaround) {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE_REV1;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE_REV1;
+	} else {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE;
+	}
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+																| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+																| PVRSRV_HAP_SINGLE_PROCESS;
+	psDeviceMemoryHeap->pszName = "PDSPixelCodeData";
+	psDeviceMemoryHeap->pszBSName = "PDSPixelCodeData BS";
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID);
+	if (need_sample_cache_workaround) {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE_REV1;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE_REV1;
+	} else {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE;
+	}
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+																| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+																| PVRSRV_HAP_SINGLE_PROCESS;
+	psDeviceMemoryHeap->pszName = "PDSVertexCodeData";
+	psDeviceMemoryHeap->pszBSName = "PDSVertexCodeData BS";
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID);
+	if (need_sample_cache_workaround) {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE_REV1;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE_REV1;
+	} else {
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE;
+		psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE;
+	}
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+														| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+														| PVRSRV_HAP_MULTI_PROCESS;
+	psDeviceMemoryHeap->pszName = "CacheCoherent";
+	psDeviceMemoryHeap->pszBSName = "CacheCoherent BS";
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	
+	psDevMemoryInfo->ui32SyncHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+	psDeviceMemoryHeap++;
+
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SHARED_3DPARAMETERS_HEAP_ID);
+	if (need_sample_cache_workaround)
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SHARED_3DPARAMETERS_HEAP_BASE_REV1;
+	else
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SHARED_3DPARAMETERS_HEAP_BASE;
+	psDeviceMemoryHeap->ui32HeapSize = SGX_SHARED_3DPARAMETERS_HEAP_SIZE;
+	psDeviceMemoryHeap->pszName = "Shared 3DParameters";
+	psDeviceMemoryHeap->pszBSName = "Shared 3DParameters BS";
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+													| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+													| PVRSRV_HAP_MULTI_PROCESS;
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID);
+	if (need_sample_cache_workaround)
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE_REV1;
+	else
+		psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE;
+	psDeviceMemoryHeap->ui32HeapSize = SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE;
+	psDeviceMemoryHeap->pszName = "Percontext 3DParameters";
+	psDeviceMemoryHeap->pszBSName = "Percontext 3DParameters BS";
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+															| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+															| PVRSRV_HAP_SINGLE_PROCESS;
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+
+
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID);
+	psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE;
+	psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE;
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+														| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+														| PVRSRV_HAP_MULTI_PROCESS;
+	psDeviceMemoryHeap->pszName = "GeneralMapping";
+	psDeviceMemoryHeap->pszBSName = "GeneralMapping BS";
+	#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410)
+	
+
+
+
+
+
+
+		psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+	#else 
+		psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+	#endif 
+
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	
+	psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+	psDeviceMemoryHeap++;
+#endif 
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_2D_HEAP_ID);
+	psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE;
+	psDeviceMemoryHeap->ui32HeapSize = SGX_2D_HEAP_SIZE;
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+														| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+														| PVRSRV_HAP_SINGLE_PROCESS;
+	psDeviceMemoryHeap->pszName = "2D";
+	psDeviceMemoryHeap->pszBSName = "2D BS";
+	
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+#endif 
+
+
+#if defined(FIX_HW_BRN_26915)
+	
+	
+	psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_CGBUFFER_HEAP_ID);
+	psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_CGBUFFER_HEAP_BASE;
+	psDeviceMemoryHeap->ui32HeapSize = SGX_CGBUFFER_HEAP_SIZE;
+	psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+														| PVRSRV_MEM_RAM_BACKED_ALLOCATION
+														| PVRSRV_HAP_SINGLE_PROCESS;
+	psDeviceMemoryHeap->pszName = "CGBuffer";
+	psDeviceMemoryHeap->pszBSName = "CGBuffer BS";
+
+	psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+	
+	psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+	psDeviceMemoryHeap++;
+#endif 
+
+	
+	psDevMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+
+	return PVRSRV_OK;
+}
+
+#if defined(PDUMP)
+static
+PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)(psDeviceNode->pvDevice);
+	psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0;
+	PVR_DPF((PVR_DBG_MESSAGE, "Reset pdump CCB write offset."));
+	
+	return PVRSRV_OK;
+}
+#endif 
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE					hDevCookie,
+								SGX_CLIENT_INFO*		psClientInfo)
+{
+	PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+	
+
+	psDevInfo->ui32ClientRefCount++;
+
+	
+
+	psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
+
+	
+
+	OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData));
+
+	
+	return PVRSRV_OK;
+}
+
+
+IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO	*psDevInfo)
+{
+	PVR_LOG(("SGX panic"));
+	SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+	OSPanic();
+}
+
+
+PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVRSRV_ERROR	eError;
+	PVRSRV_SGXDEV_INFO 				*psDevInfo;
+	IMG_UINT32 			ui32BuildOptions, ui32BuildOptionsMismatch;
+#if !defined(NO_HARDWARE)
+	PPVRSRV_KERNEL_MEM_INFO			psMemInfo;
+	PVRSRV_SGX_MISCINFO_INFO		*psSGXMiscInfoInt; 	
+	PVRSRV_SGX_MISCINFO_FEATURES	*psSGXFeatures;
+	SGX_MISCINFO_STRUCT_SIZES		*psSGXStructSizes;	
+	IMG_BOOL						bStructSizesFailed;
+
+	
+	IMG_BOOL	bCheckCoreRev;
+	const IMG_UINT32 aui32CoreRevExceptions[] =
+	{
+		0x10100, 0x10101
+	};
+	const IMG_UINT32	ui32NumCoreExceptions = sizeof(aui32CoreRevExceptions) / (2*sizeof(IMG_UINT32));
+	IMG_UINT	i;
+#endif
+
+	
+	if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX)
+	{
+		PVR_LOG(("(FAIL) SGXInit: Device not of type SGX"));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+		goto chk_exit;
+	}
+
+	psDevInfo = psDeviceNode->pvDevice;
+
+	
+	
+	ui32BuildOptions = (SGX_BUILD_OPTIONS);
+	if (ui32BuildOptions != psDevInfo->ui32ClientBuildOptions)
+	{
+		ui32BuildOptionsMismatch = ui32BuildOptions ^ psDevInfo->ui32ClientBuildOptions;
+		if ( (psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0)
+		{
+			PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
+				"extra options present in client-side driver: (0x%x). Please check sgx_options.h",
+				psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch ));
+		}
+
+		if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
+		{
+			PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
+				"extra options present in KM: (0x%x). Please check sgx_options.h",
+				ui32BuildOptions & ui32BuildOptionsMismatch ));
+		}
+		eError = PVRSRV_ERROR_BUILD_MISMATCH;
+		PVR_LOG(("SGXInit: KM options 0x%x; client-side options 0x%x\n", ui32BuildOptions, psDevInfo->ui32ClientBuildOptions));
+		goto chk_exit;
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Client-side and KM driver build options match. [ OK ]"));
+	}
+
+#if !defined (NO_HARDWARE)
+	psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+
+	
+	psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
+	psSGXMiscInfoInt->ui32MiscInfoFlags = 0;
+	psSGXMiscInfoInt->ui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES;
+	eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode, IMG_NULL);
+
+	
+	if(eError != PVRSRV_OK)
+	{
+		PVR_LOG(("(FAIL) SGXInit: Unable to validate device DDK version"));
+		goto chk_exit;
+	}
+	psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+	if( (psSGXFeatures->ui32DDKVersion !=
+		((PVRVERSION_MAJ << 16) |
+		 (PVRVERSION_MIN << 8) |
+		  PVRVERSION_BRANCH) ) ||
+		(psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) )
+	{
+		PVR_LOG(("(FAIL) SGXInit: Incompatible driver DDK revision (%d)/device DDK revision (%d).",
+				PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
+		eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;
+		PVR_DBG_BREAK;
+		goto chk_exit;
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: driver DDK (%d) and device DDK (%d) match. [ OK ]",
+				PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
+	}
+
+	
+	if (psSGXFeatures->ui32CoreRevSW == 0)
+	{
+		
+
+		PVR_LOG(("SGXInit: HW core rev (%x) check skipped.",
+				psSGXFeatures->ui32CoreRev));
+	}
+	else
+	{
+		
+		bCheckCoreRev = IMG_TRUE;
+		for(i=0; i<ui32NumCoreExceptions; i+=2)
+		{
+			if( (psSGXFeatures->ui32CoreRev==aui32CoreRevExceptions[i]) &&
+				(psSGXFeatures->ui32CoreRevSW==aui32CoreRevExceptions[i+1])	)
+			{
+				PVR_LOG(("SGXInit: HW core rev (%x), SW core rev (%x) check skipped.",
+						psSGXFeatures->ui32CoreRev,
+						psSGXFeatures->ui32CoreRevSW));
+				bCheckCoreRev = IMG_FALSE;
+			}
+		}
+
+		if (bCheckCoreRev)
+		{
+			if (psSGXFeatures->ui32CoreRev != psSGXFeatures->ui32CoreRevSW)
+			{
+				PVR_LOG(("(FAIL) SGXInit: Incompatible HW core rev (%x) and SW core rev (%x).",
+						psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
+						eError = PVRSRV_ERROR_BUILD_MISMATCH;
+						goto chk_exit;
+			}
+			else
+			{
+				PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: HW core rev (%x) and SW core rev (%x) match. [ OK ]",
+						psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
+			}
+		}
+	}
+
+	
+	psSGXStructSizes = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXStructSizes;
+
+	bStructSizesFailed = IMG_FALSE;
+
+	CHECK_SIZE(HOST_CTL);
+	CHECK_SIZE(COMMAND);
+#if defined(SGX_FEATURE_2D_HARDWARE)
+	CHECK_SIZE(2DCMD);
+	CHECK_SIZE(2DCMD_SHARED);
+#endif
+	CHECK_SIZE(CMDTA);
+	CHECK_SIZE(CMDTA_SHARED);
+	CHECK_SIZE(TRANSFERCMD);
+	CHECK_SIZE(TRANSFERCMD_SHARED);
+
+	CHECK_SIZE(3DREGISTERS);
+	CHECK_SIZE(HWPBDESC);
+	CHECK_SIZE(HWRENDERCONTEXT);
+	CHECK_SIZE(HWRENDERDETAILS);
+	CHECK_SIZE(HWRTDATA);
+	CHECK_SIZE(HWRTDATASET);
+	CHECK_SIZE(HWTRANSFERCONTEXT);
+
+	if (bStructSizesFailed == IMG_TRUE)
+	{
+		PVR_LOG(("(FAIL) SGXInit: Mismatch in SGXMKIF structure sizes."));
+		eError = PVRSRV_ERROR_BUILD_MISMATCH;
+		goto chk_exit;
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: SGXMKIF structure sizes match. [ OK ]"));
+	}
+
+	
+	ui32BuildOptions = psSGXFeatures->ui32BuildOptions;
+	if (ui32BuildOptions != (SGX_BUILD_OPTIONS))
+	{
+		ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS);
+		if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0)
+		{
+			PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
+				"extra options present in driver: (0x%x). Please check sgx_options.h",
+				(SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch ));
+		}
+
+		if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
+		{
+			PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
+				"extra options present in microkernel: (0x%x). Please check sgx_options.h",
+				ui32BuildOptions & ui32BuildOptionsMismatch ));
+		}
+		eError = PVRSRV_ERROR_BUILD_MISMATCH;
+		goto chk_exit;
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Driver and microkernel build options match. [ OK ]"));
+	}
+#endif 
+
+	eError = PVRSRV_OK;
+chk_exit:
+#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK)
+	return PVRSRV_OK;
+#else
+	return eError;
+#endif
+}
+
+static
+PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO	*psDevInfo,
+								   PVRSRV_DEVICE_NODE 	*psDeviceNode,
+								   IMG_HANDLE hDevMemContext)
+{
+	PVRSRV_ERROR		eError;
+	SGXMKIF_COMMAND		sCommandData;  
+	PVRSRV_SGX_MISCINFO_INFO			*psSGXMiscInfoInt; 	
+	PVRSRV_SGX_MISCINFO_FEATURES		*psSGXFeatures;		
+	SGX_MISCINFO_STRUCT_SIZES			*psSGXStructSizes;	
+
+	PPVRSRV_KERNEL_MEM_INFO	psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+
+	if (! psMemInfo->pvLinAddrKM)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Invalid address."));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+	psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
+	psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures;
+	psSGXStructSizes = &psSGXMiscInfoInt->sSGXStructSizes;
+
+	psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY;
+
+	
+	OSMemSet(psSGXFeatures, 0, sizeof(*psSGXFeatures));
+	OSMemSet(psSGXStructSizes, 0, sizeof(*psSGXStructSizes));
+
+	
+	sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr; 
+
+	PDUMPCOMMENT("Microkernel kick for SGXGetMiscInfo");
+	eError = SGXScheduleCCBCommandKM(psDeviceNode,
+									 SGXMKIF_CMD_GETMISCINFO,
+									 &sCommandData,
+									 KERNEL_ID,
+									 0,
+									 hDevMemContext,
+									 IMG_FALSE);
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: SGXScheduleCCBCommandKM failed."));
+		return eError;
+	}
+
+	
+#if !defined(NO_HARDWARE)
+	{
+		IMG_BOOL bExit;
+
+		bExit = IMG_FALSE;
+		LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+		{
+			if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0)
+			{
+				bExit = IMG_TRUE;
+				break;
+			}
+		} END_LOOP_UNTIL_TIMEOUT();
+
+		
+		if (!bExit)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Timeout occurred waiting for misc info."));
+			return PVRSRV_ERROR_TIMEOUT;
+		}
+	}
+#endif 
+
+	return PVRSRV_OK;
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO	*psDevInfo,
+							  SGX_MISC_INFO			*psMiscInfo,
+ 							  PVRSRV_DEVICE_NODE 	*psDeviceNode,
+ 							  IMG_HANDLE 			 hDevMemContext)
+{
+	PVRSRV_ERROR eError;
+	PPVRSRV_KERNEL_MEM_INFO	psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+	IMG_UINT32	*pui32MiscInfoFlags = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->ui32MiscInfoFlags;
+
+	
+	*pui32MiscInfoFlags = 0;
+
+#if !defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+	PVR_UNREFERENCED_PARAMETER(hDevMemContext);
+#endif
+
+	switch(psMiscInfo->eRequest)
+	{
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+		case SGX_MISC_INFO_REQUEST_SET_BREAKPOINT:
+		{
+			IMG_UINT32      ui32MaskDM;
+			IMG_UINT32      ui32CtrlWEnable;
+			IMG_UINT32      ui32CtrlREnable;
+			IMG_UINT32      ui32CtrlTrapEnable;
+			IMG_UINT32		ui32RegVal;
+			IMG_UINT32		ui32StartRegVal;
+			IMG_UINT32		ui32EndRegVal;
+			SGXMKIF_COMMAND	sCommandData;
+
+			
+			if(psMiscInfo->uData.sSGXBreakpointInfo.bBPEnable)
+			{
+				
+				IMG_DEV_VIRTADDR sBPDevVAddr = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddr;
+				IMG_DEV_VIRTADDR sBPDevVAddrEnd = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddrEnd;
+
+				
+				ui32StartRegVal = sBPDevVAddr.uiAddr & EUR_CR_BREAKPOINT0_START_ADDRESS_MASK;
+				ui32EndRegVal = sBPDevVAddrEnd.uiAddr & EUR_CR_BREAKPOINT0_END_ADDRESS_MASK;
+
+				ui32MaskDM = psMiscInfo->uData.sSGXBreakpointInfo.ui32DataMasterMask;
+				ui32CtrlWEnable = psMiscInfo->uData.sSGXBreakpointInfo.bWrite;
+				ui32CtrlREnable = psMiscInfo->uData.sSGXBreakpointInfo.bRead;
+				ui32CtrlTrapEnable = psMiscInfo->uData.sSGXBreakpointInfo.bTrapped;
+
+				
+				ui32RegVal = ((ui32MaskDM<<EUR_CR_BREAKPOINT0_MASK_DM_SHIFT) & EUR_CR_BREAKPOINT0_MASK_DM_MASK) |
+							 ((ui32CtrlWEnable<<EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK) |
+							 ((ui32CtrlREnable<<EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK) |
+							 ((ui32CtrlTrapEnable<<EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK);
+			}
+			else
+			{
+				
+				ui32RegVal = ui32StartRegVal = ui32EndRegVal = 0;
+			}
+
+			
+			sCommandData.ui32Data[0] = psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex;
+			sCommandData.ui32Data[1] = ui32StartRegVal;
+			sCommandData.ui32Data[2] = ui32EndRegVal;
+			sCommandData.ui32Data[3] = ui32RegVal;
+
+			
+			psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
+
+			PDUMPCOMMENT("Microkernel kick for setting a data breakpoint");
+			eError = SGXScheduleCCBCommandKM(psDeviceNode,
+											 SGXMKIF_CMD_DATABREAKPOINT,
+											 &sCommandData,
+											 KERNEL_ID,
+											 0,
+											 hDevMemContext,
+											 IMG_FALSE);
+
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed."));
+				return eError;
+			}
+
+#if defined(NO_HARDWARE)
+			
+			psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
+#else
+			{
+				IMG_BOOL bExit;
+
+				bExit = IMG_FALSE;
+				LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+				{
+					if (psDevInfo->psSGXHostCtl->ui32BPSetClearSignal != 0)
+					{
+						bExit = IMG_TRUE;
+						
+						psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
+						break;
+					}
+				} END_LOOP_UNTIL_TIMEOUT();
+
+				
+				if (!bExit)
+				{
+					PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Timeout occurred waiting BP set/clear"));
+					return PVRSRV_ERROR_TIMEOUT;
+				}
+			}
+#endif 
+
+			return PVRSRV_OK;
+		}
+
+		case SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT:
+		{
+			
+
+
+
+
+			
+
+#if !defined(NO_HARDWARE)
+#if defined(SGX_FEATURE_MP)
+			IMG_BOOL bTrappedBPMaster;
+			IMG_UINT32 ui32CoreNum, ui32TrappedBPCoreNum;
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+			IMG_UINT32 ui32PipeNum, ui32TrappedBPPipeNum;
+#define NUM_PIPES_PLUS_ONE (SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES+1)
+#endif
+			IMG_BOOL bTrappedBPAny;
+#endif 
+			IMG_BOOL bFoundOne;
+
+#if defined(SGX_FEATURE_MP)
+			ui32TrappedBPCoreNum = 0;
+			bTrappedBPMaster = !!(EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT));
+			bTrappedBPAny = bTrappedBPMaster;
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+			ui32TrappedBPPipeNum = 0; 
+#endif
+			for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT_3D; ui32CoreNum++)
+			{
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+				
+
+
+#define SGX_MP_CORE_PIPE_SELECT(r,c,p) \
+				((SGX_MP_CORE_SELECT(EUR_CR_PARTITION_##r,c) + p*(EUR_CR_PIPE0_##r-EUR_CR_PARTITION_##r)))
+				for (ui32PipeNum = 0; ui32PipeNum < NUM_PIPES_PLUS_ONE; ui32PipeNum++)
+				{
+					bFoundOne =
+						0 != (EUR_CR_PARTITION_BREAKPOINT_TRAPPED_MASK & 
+							  OSReadHWReg(psDevInfo->pvRegsBaseKM, 
+										  SGX_MP_CORE_PIPE_SELECT(BREAKPOINT,
+																  ui32CoreNum,
+																  ui32PipeNum)));
+					if (bFoundOne)
+					{
+						bTrappedBPAny = IMG_TRUE;
+						ui32TrappedBPCoreNum = ui32CoreNum;
+						ui32TrappedBPPipeNum = ui32PipeNum;
+					}
+				}
+#else 
+				bFoundOne = !!(EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum)));
+				if (bFoundOne)
+				{
+					bTrappedBPAny = IMG_TRUE;
+					ui32TrappedBPCoreNum = ui32CoreNum;
+				}
+#endif 
+			}
+
+			psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = bTrappedBPAny;
+#else 
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+			#error Not yet considered the case for per-pipe regs in non-mp case
+#endif
+			psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = 0 != (EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT));
+#endif 
+
+			if (psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP)
+			{
+				IMG_UINT32 ui32Info0, ui32Info1;
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+				ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum, ui32TrappedBPPipeNum));
+				ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum, ui32TrappedBPPipeNum));
+#else 
+				ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum));
+				ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum));
+#endif 
+#else 
+				ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT_TRAP_INFO0);
+				ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT_TRAP_INFO1);
+#endif 
+
+#ifdef SGX_FEATURE_PERPIPE_BKPT_REGS
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT;
+				psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK;
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT;
+				psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_MASK);
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT;
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SHIFT;
+#else 
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT;
+				psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK;
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT;
+				psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_MASK);
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT;
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SHIFT;
+#endif 
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+				
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:(ui32TrappedBPCoreNum + (ui32TrappedBPPipeNum<<10));
+#else 
+				
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:ui32TrappedBPCoreNum;
+#endif 
+#else 
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+				
+#error non-mp perpipe regs not yet supported
+#else 
+				
+				psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = 65534;
+#endif 
+#endif 
+			}
+#endif 
+			return PVRSRV_OK;
+		}
+
+		case SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT:
+		{
+			
+			
+			
+#if !defined(NO_HARDWARE)
+#if defined(SGX_FEATURE_MP)
+			IMG_UINT32 ui32CoreNum;
+			IMG_BOOL bMaster;
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+			IMG_UINT32 ui32PipeNum;
+#endif
+#endif 
+			IMG_UINT32 ui32OldSeqNum, ui32NewSeqNum;
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+			ui32PipeNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum >> 10;
+			ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum & 1023;
+			bMaster = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum > 32767;
+#else 
+			ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum;
+			bMaster = ui32CoreNum > SGX_FEATURE_MP_CORE_COUNT_3D;
+#endif 
+			if (bMaster)
+			{
+				
+				
+				ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
+				OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT_TRAP, EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK);
+				do
+				{
+					ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
+				}
+				while (ui32OldSeqNum == ui32NewSeqNum);
+			}
+			else
+#endif 
+			{
+				
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+				ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT, ui32CoreNum, ui32PipeNum));
+				OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP, ui32CoreNum, ui32PipeNum), EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_MASK);
+				do
+				{
+					ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT, ui32CoreNum, ui32PipeNum));
+				}
+				while (ui32OldSeqNum == ui32NewSeqNum);
+#else 
+				ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
+				OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP, ui32CoreNum), EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK);
+				do
+				{
+					ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
+				}
+				while (ui32OldSeqNum == ui32NewSeqNum);
+#endif 
+			}
+#endif 
+			return PVRSRV_OK;
+		}
+#endif 
+
+		case SGX_MISC_INFO_REQUEST_CLOCKSPEED:
+		{
+			psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed;
+			return PVRSRV_OK;
+		}
+
+		case SGX_MISC_INFO_REQUEST_ACTIVEPOWER:
+		{
+			psMiscInfo->uData.sActivePower.ui32NumActivePowerEvents = psDevInfo->psSGXHostCtl->ui32NumActivePowerEvents;
+			return PVRSRV_OK;
+		}
+
+		case SGX_MISC_INFO_REQUEST_LOCKUPS:
+		{
+#if defined(SUPPORT_HW_RECOVERY)
+			psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = psDevInfo->psSGXHostCtl->ui32uKernelDetectedLockups;
+			psMiscInfo->uData.sLockups.ui32HostDetectedLockups = psDevInfo->psSGXHostCtl->ui32HostDetectedLockups;
+#else
+			psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = 0;
+			psMiscInfo->uData.sLockups.ui32HostDetectedLockups = 0;
+#endif
+			return PVRSRV_OK;
+		}
+
+		case SGX_MISC_INFO_REQUEST_SPM:
+		{
+			
+			return PVRSRV_OK;
+		}
+
+		case SGX_MISC_INFO_REQUEST_SGXREV:
+		{
+			PVRSRV_SGX_MISCINFO_FEATURES		*psSGXFeatures;
+			eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode, hDevMemContext);
+			if(eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
+						eError));
+				return eError;
+			}
+			psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+
+			
+			psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
+
+			
+			PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%x, sw ID 0x%x, sw Rev 0x%x\n",
+					psSGXFeatures->ui32CoreRev,
+					psSGXFeatures->ui32CoreIdSW,
+					psSGXFeatures->ui32CoreRevSW));
+			PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%x, DDK build 0x%x\n",
+					psSGXFeatures->ui32DDKVersion,
+					psSGXFeatures->ui32DDKBuild));
+
+			
+			return PVRSRV_OK;
+		}
+
+		case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV:
+		{
+			PVRSRV_SGX_MISCINFO_FEATURES		*psSGXFeatures;
+
+			psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+
+			
+			OSMemSet(psMemInfo->pvLinAddrKM, 0,
+					sizeof(PVRSRV_SGX_MISCINFO_INFO));
+
+			psSGXFeatures->ui32DDKVersion =
+				(PVRVERSION_MAJ << 16) |
+				(PVRVERSION_MIN << 8) |
+				PVRVERSION_BRANCH;
+			psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD;
+
+			
+			psSGXFeatures->ui32BuildOptions = (SGX_BUILD_OPTIONS);
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+			
+			psSGXFeatures->sDevVAEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->sDevVAddr;
+			psSGXFeatures->pvEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
+#endif
+
+			
+			psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
+			return PVRSRV_OK;
+		}
+
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+		case SGX_MISC_INFO_REQUEST_MEMREAD:
+		case SGX_MISC_INFO_REQUEST_MEMCOPY:
+		{
+			PVRSRV_ERROR eError;
+			PVRSRV_SGX_MISCINFO_FEATURES		*psSGXFeatures;
+			PVRSRV_SGX_MISCINFO_MEMACCESS		*psSGXMemSrc;	
+			PVRSRV_SGX_MISCINFO_MEMACCESS		*psSGXMemDest;	
+
+			{				
+				
+				*pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMREAD;
+				psSGXMemSrc = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessSrc;
+
+				if(psMiscInfo->sDevVAddrSrc.uiAddr != 0)
+				{
+					psSGXMemSrc->sDevVAddr = psMiscInfo->sDevVAddrSrc; 
+				}
+				else
+				{
+					return PVRSRV_ERROR_INVALID_PARAMS;
+				}				
+			}
+
+			if( psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMCOPY)
+			{				
+				
+				*pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMWRITE;
+				psSGXMemDest = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessDest;
+				
+				if(psMiscInfo->sDevVAddrDest.uiAddr != 0)
+				{
+					psSGXMemDest->sDevVAddr = psMiscInfo->sDevVAddrDest; 
+				}
+				else
+				{
+					return PVRSRV_ERROR_INVALID_PARAMS;
+				}
+			}
+
+			
+			if(psMiscInfo->hDevMemContext != IMG_NULL)
+			{
+				SGXGetMMUPDAddrKM( (IMG_HANDLE)psDeviceNode, hDevMemContext, &psSGXMemSrc->sPDDevPAddr);
+				
+				
+				psSGXMemDest->sPDDevPAddr = psSGXMemSrc->sPDDevPAddr;
+			}
+			else
+			{
+				return PVRSRV_ERROR_INVALID_PARAMS;
+			}
+
+			
+			eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
+			if(eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
+						eError));
+				return eError;
+			}
+			psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+			if(*pui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_MEMREAD_FAIL)
+			{
+				return PVRSRV_ERROR_INVALID_MISCINFO;
+			}
+#endif
+			
+			psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
+			return PVRSRV_OK;
+		}
+#endif 
+
+#if defined(SUPPORT_SGX_HWPERF)
+		case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS:
+		{
+			PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS	*psSetHWPerfStatus = &psMiscInfo->uData.sSetHWPerfStatus;
+			const IMG_UINT32	ui32ValidFlags = PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS |
+												 PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON |
+												 PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON |
+												 PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON;
+			SGXMKIF_COMMAND		sCommandData = {0};
+
+			
+			if ((psSetHWPerfStatus->ui32NewHWPerfStatus & ~ui32ValidFlags) != 0)
+			{
+				return PVRSRV_ERROR_INVALID_PARAMS;
+			}
+
+			#if defined(PDUMP)
+			PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+								  "SGX ukernel HWPerf status %u\n",
+								  psSetHWPerfStatus->ui32NewHWPerfStatus);
+			#endif 
+
+			
+			#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+			OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfGroup[0],
+					  &psSetHWPerfStatus->aui32PerfGroup[0],
+					  sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup));
+			OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfBit[0],
+					  &psSetHWPerfStatus->aui32PerfBit[0],
+					  sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit));
+			#if defined(PDUMP)
+			PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+					 offsetof(SGXMKIF_HOST_CTL, aui32PerfGroup),
+					 sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup),
+					 PDUMP_FLAGS_CONTINUOUS,
+					 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+			PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+					 offsetof(SGXMKIF_HOST_CTL, aui32PerfBit),
+					 sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit),
+					 PDUMP_FLAGS_CONTINUOUS,
+					 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+			#endif 
+			#else
+			psDevInfo->psSGXHostCtl->ui32PerfGroup = psSetHWPerfStatus->ui32PerfGroup;
+			#if defined(PDUMP)
+			PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+					 offsetof(SGXMKIF_HOST_CTL, ui32PerfGroup),
+					 sizeof(psDevInfo->psSGXHostCtl->ui32PerfGroup),
+					 PDUMP_FLAGS_CONTINUOUS,
+					 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+			#endif 
+			#endif 
+
+			
+			sCommandData.ui32Data[0] = psSetHWPerfStatus->ui32NewHWPerfStatus;
+			eError = SGXScheduleCCBCommandKM(psDeviceNode,
+											 SGXMKIF_CMD_SETHWPERFSTATUS,
+											 &sCommandData,
+											 KERNEL_ID,
+											 0,
+											 hDevMemContext,
+											 IMG_FALSE);
+			return eError;
+		}
+#endif 
+
+		case SGX_MISC_INFO_DUMP_DEBUG_INFO:
+		{
+			PVR_LOG(("User requested SGX debug info"));
+
+			
+			SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_FALSE);
+
+			return PVRSRV_OK;
+		}
+
+		case SGX_MISC_INFO_PANIC:
+		{
+			PVR_LOG(("User requested SGX panic"));
+
+			SGXPanic(psDeviceNode->pvDevice);
+
+			return PVRSRV_OK;
+		}
+
+		default:
+		{
+			
+			return PVRSRV_ERROR_INVALID_PARAMS;
+		}
+	}
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE					hDevHandle,
+							   IMG_UINT32					ui32ArraySize,
+							   PVRSRV_SGX_HWPERF_CB_ENTRY	*psClientHWPerfEntry,
+							   IMG_UINT32					*pui32DataCount,
+							   IMG_UINT32					*pui32ClockSpeed,
+							   IMG_UINT32					*pui32HostTimeStamp)
+{
+	PVRSRV_ERROR    	eError = PVRSRV_OK;
+	PVRSRV_DEVICE_NODE	*psDeviceNode = hDevHandle;
+	PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
+	SGXMKIF_HWPERF_CB	*psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;
+	IMG_UINT			i;
+
+	for (i = 0;
+		 psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize;
+		 i++)
+	{
+		SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff];
+
+		psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo;
+		psClientHWPerfEntry[i].ui32PID = psMKPerfEntry->ui32PID;
+		psClientHWPerfEntry[i].ui32RTData = psMKPerfEntry->ui32RTData;
+		psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type;
+		psClientHWPerfEntry[i].ui32Ordinal	= psMKPerfEntry->ui32Ordinal;
+		psClientHWPerfEntry[i].ui32Info	= psMKPerfEntry->ui32Info;
+		psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo,
+													psMKPerfEntry->ui32TimeWraps,
+													psMKPerfEntry->ui32Time);
+		OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0][0],
+				  &psMKPerfEntry->ui32Counters[0][0],
+				  sizeof(psMKPerfEntry->ui32Counters));
+
+		OSMemCopy(&psClientHWPerfEntry[i].ui32MiscCounters[0][0],
+				  &psMKPerfEntry->ui32MiscCounters[0][0],
+				  sizeof(psMKPerfEntry->ui32MiscCounters));
+
+		psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1);
+	}
+
+	*pui32DataCount = i;
+	*pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed;
+	*pui32HostTimeStamp = OSClockus();
+
+	return eError;
+}
+
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxkick.c b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxkick.c
new file mode 100644
index 0000000..d1220cf
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxkick.c
@@ -0,0 +1,784 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <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"
+#include "pvr_debug.h"
+#include "sgxutils.h"
+#include "ttrace.h"
+
+IMG_EXPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK_KM *psCCBKick)
+#else
+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick)
+#endif
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_KERNEL_SYNC_INFO	*psSyncInfo;
+	PVRSRV_KERNEL_MEM_INFO	*psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo;
+	SGXMKIF_CMDTA_SHARED *psTACmd;
+	IMG_UINT32 i;
+	IMG_HANDLE hDevMemContext = IMG_NULL;
+#if defined(FIX_HW_BRN_31620)
+	hDevMemContext = psCCBKick->hDevMemContext;
+#endif
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, KICK_TOKEN_DOKICK);
+
+	if (!CCB_OFFSET_IS_VALID(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset"));
+		PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK);
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+	
+	
+	psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset);
+
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_START, KICK_TOKEN_DOKICK);
+	PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CCB,
+			KICK_TOKEN_CCB_OFFSET, psCCBKick->ui32CCBOffset);
+
+	
+	if (psCCBKick->hTA3DSyncInfo)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
+
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA3D_SYNC,
+					  psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+		psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+
+		psTACmd->sTA3DDependency.ui32WriteOpsPendingVal   = psSyncInfo->psSyncData->ui32WriteOpsPending;
+
+		if (psCCBKick->bTADependency)
+		{
+			psSyncInfo->psSyncData->ui32WriteOpsPending++;
+		}
+	}
+
+	if (psCCBKick->hTASyncInfo != IMG_NULL)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
+
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA_SYNC,
+					  psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+		psTACmd->sTATQSyncReadOpsCompleteDevVAddr  = psSyncInfo->sReadOpsCompleteDevVAddr;
+		psTACmd->sTATQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+
+		psTACmd->ui32TATQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+		psTACmd->ui32TATQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+	}
+
+	if (psCCBKick->h3DSyncInfo != IMG_NULL)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
+
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_3D_SYNC,
+					  psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+		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 defined(SUPPORT_SGX_NEW_STATUS_VALS)
+			psTACmd->sCtlTAStatusInfo[i] = psCCBKick->asTAStatusUpdate[i].sCtlStatus;
+#else
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
+			psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+			psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending;
+#endif
+		}
+	}
+
+	psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals;
+	if (psCCBKick->ui32Num3DStatusVals != 0)
+	{
+		
+		for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
+		{
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+			psTACmd->sCtl3DStatusInfo[i] = psCCBKick->as3DStatusUpdate[i].sCtlStatus;
+#else
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
+			psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+			psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending;
+#endif
+		}
+	}
+
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+	
+	psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs;
+	for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+
+		psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+		psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+		
+		psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+		
+		psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+	}
+
+	psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs;
+	for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+
+		psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+		psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+		
+		psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+		
+		psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+	}
+
+	psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs;
+	for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+
+		psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+		psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+		
+		psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+		
+		psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+	}
+#else 
+	
+	psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs;
+	for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_SRC_SYNC,
+					  psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+		psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+		psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+		
+		psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+		
+		psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+	}
+#endif
+
+	if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0)
+	{
+		PVRSRV_KERNEL_MEM_INFO	*psHWDstSyncListMemInfo =
+								(PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo;
+		SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM;
+		IMG_UINT32	ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects;
+
+		PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo)->uAllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) +
+								(sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs)));
+
+		psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs;
+#if defined(PDUMP)
+		if (PDumpIsCaptureFrameKM())
+		{
+			PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n");
+			PDUMPMEM(IMG_NULL,
+					 psHWDstSyncListMemInfo,
+					 0,
+					 sizeof(SGXMKIF_HWDEVICE_SYNC_LIST),
+					 0,
+					 MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+		}
+#endif
+
+		for (i=0; i<ui32NumDstSyncs; i++)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
+
+			if (psSyncInfo)
+			{
+
+				PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_DST_SYNC,
+							psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+				psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+				psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+				psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+				psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+
+	#if defined(PDUMP)
+				if (PDumpIsCaptureFrameKM())
+				{
+					IMG_UINT32 ui32ModifiedValue;
+					IMG_UINT32 ui32SyncOffset = offsetof(SGXMKIF_HWDEVICE_SYNC_LIST, asSyncData)
+												+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT));
+					IMG_UINT32 ui32WOpsOffset = ui32SyncOffset
+												+ offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal);
+					IMG_UINT32 ui32ROpsOffset = ui32SyncOffset
+												+ offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal);
+
+					PDUMPCOMMENT("HWDeviceSyncObject for RT: %i\r\n", i);
+
+					PDUMPMEM(IMG_NULL,
+							 psHWDstSyncListMemInfo,
+							 ui32SyncOffset,
+							 sizeof(PVRSRV_DEVICE_SYNC_OBJECT),
+							 0,
+							 MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+
+					if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+						(psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+					{
+						
+						PDUMPCOMMENT("Init RT ROpsComplete\r\n");
+						PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+							psSyncInfo->psSyncDataMemInfoKM,
+							offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+							sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+							0,
+							MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+						
+						PDUMPCOMMENT("Init RT WOpsComplete\r\n");
+							PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+								psSyncInfo->psSyncDataMemInfoKM,
+								offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+								sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+								0,
+								MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+					}
+
+					psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+
+					ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1;
+
+					PDUMPCOMMENT("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i);
+
+					PDUMPMEM(&ui32ModifiedValue,
+						psHWDstSyncListMemInfo,
+						ui32WOpsOffset,
+						sizeof(IMG_UINT32),
+						0,
+						MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+
+					ui32ModifiedValue = 0;
+					PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i);
+
+					PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+						 psHWDstSyncListMemInfo,
+						 ui32ROpsOffset,
+						 sizeof(IMG_UINT32),
+						 0,
+						MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+				}
+	#endif	
+			}
+			else
+			{
+				psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0;
+				psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0;
+
+				psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0;
+				psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0;
+			}
+		}
+	}
+	
+	
+
+
+	psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY;
+
+#if defined(PDUMP)
+	if (PDumpIsCaptureFrameKM())
+	{
+		PDUMPCOMMENT("Shared part of TA command\r\n");
+
+		PDUMPMEM(psTACmd,
+				 psCCBMemInfo,
+				 psCCBKick->ui32CCBDumpWOff,
+				 sizeof(SGXMKIF_CMDTA_SHARED),
+				 0,
+				 MAKEUNIQUETAG(psCCBMemInfo));
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+		for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+		{
+			IMG_UINT32 	ui32ModifiedValue;
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+
+			if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+				(psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+			{
+				
+				PDUMPCOMMENT("Init RT TA-SRC ROpsComplete\r\n", i);
+				PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					psSyncInfo->psSyncDataMemInfoKM,
+					offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+					sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+					0,
+					MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+				
+				PDUMPCOMMENT("Init RT TA-SRC WOpsComplete\r\n");
+					PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+						psSyncInfo->psSyncDataMemInfoKM,
+						offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+						sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+						0,
+						MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+			}
+
+			psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+
+			ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
+
+			PDUMPCOMMENT("Modify TA SrcSync %d ROpsPendingVal\r\n", i);
+
+			PDUMPMEM(&ui32ModifiedValue,
+				 psCCBMemInfo,
+				 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
+					(i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+				 sizeof(IMG_UINT32),
+				 0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+
+			PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i);
+
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+				psCCBMemInfo,
+				psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
+					(i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+				sizeof(IMG_UINT32),
+				0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+		}
+
+		for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+		{
+			IMG_UINT32 	ui32ModifiedValue;
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+
+			if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+				(psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+			{
+				
+				PDUMPCOMMENT("Init RT TA-DST ROpsComplete\r\n", i);
+				PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					psSyncInfo->psSyncDataMemInfoKM,
+					offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+					sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+					0,
+					MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+				
+				PDUMPCOMMENT("Init RT TA-DST WOpsComplete\r\n");
+					PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+						psSyncInfo->psSyncDataMemInfoKM,
+						offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+						sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+						0,
+						MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+			}
+
+			psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+
+			ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1;
+
+			PDUMPCOMMENT("Modify TA DstSync %d WOpPendingVal\r\n", i);
+
+			PDUMPMEM(&ui32ModifiedValue,
+				 psCCBMemInfo,
+				 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
+					(i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+				 sizeof(IMG_UINT32),
+				 0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+
+			PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i);
+
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+				psCCBMemInfo,
+				psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
+					(i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+				sizeof(IMG_UINT32),
+				0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+		}
+
+		for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+		{
+			IMG_UINT32 	ui32ModifiedValue;
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+
+			if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+				(psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+			{
+				
+				PDUMPCOMMENT("Init RT 3D-SRC ROpsComplete\r\n", i);
+				PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					psSyncInfo->psSyncDataMemInfoKM,
+					offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+					sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+					0,
+					MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+				
+				PDUMPCOMMENT("Init RT 3D-SRC WOpsComplete\r\n");
+					PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+						psSyncInfo->psSyncDataMemInfoKM,
+						offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+						sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+						0,
+						MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+			}
+
+			psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+
+			ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
+
+			PDUMPCOMMENT("Modify 3D SrcSync %d ROpsPendingVal\r\n", i);
+
+			PDUMPMEM(&ui32ModifiedValue,
+				 psCCBMemInfo,
+				 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
+					(i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+				 sizeof(IMG_UINT32),
+				 0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+
+			PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i);
+
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+				psCCBMemInfo,
+				psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
+					(i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+				sizeof(IMG_UINT32),
+				0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+		}
+#else
+		for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+		{
+			IMG_UINT32 	ui32ModifiedValue;
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+
+			if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+				(psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+			{
+				
+				PDUMPCOMMENT("Init RT ROpsComplete\r\n");
+				PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					psSyncInfo->psSyncDataMemInfoKM,
+					offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+					sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+					0,
+					MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+				
+				PDUMPCOMMENT("Init RT WOpsComplete\r\n");
+					PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+						psSyncInfo->psSyncDataMemInfoKM,
+						offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+						sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+						0,
+						MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+			}
+
+			psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+
+			ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
+
+			PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i);
+
+			PDUMPMEM(&ui32ModifiedValue,
+				 psCCBMemInfo,
+				 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) +
+					(i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+				 sizeof(IMG_UINT32),
+				 0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+
+			PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i);
+
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+				psCCBMemInfo,
+				psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) +
+					(i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+				sizeof(IMG_UINT32),
+				0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+		}
+
+		if (psCCBKick->hTASyncInfo != IMG_NULL)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
+
+			PDUMPCOMMENT("Modify TA/TQ ROpPendingVal\r\n");
+
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					psCCBMemInfo,
+					psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui32TATQSyncReadOpsPendingVal),
+					sizeof(IMG_UINT32),
+					0,
+					MAKEUNIQUETAG(psCCBMemInfo));
+			psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+		}
+
+		if (psCCBKick->h3DSyncInfo != IMG_NULL)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
+
+			PDUMPCOMMENT("Modify 3D/TQ ROpPendingVal\r\n");
+
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					psCCBMemInfo,
+					psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui323DTQSyncReadOpsPendingVal),
+					sizeof(IMG_UINT32),
+					0,
+					MAKEUNIQUETAG(psCCBMemInfo));
+			psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+		}
+
+#endif
+
+		for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
+		{
+#if !defined(SUPPORT_SGX_NEW_STATUS_VALS)
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
+			PDUMPCOMMENT("Modify TA status value in TA cmd\r\n");
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+				 psCCBMemInfo,
+				 psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue),
+				 sizeof(IMG_UINT32),
+				 0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+#endif
+		}
+
+		for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
+		{
+#if !defined(SUPPORT_SGX_NEW_STATUS_VALS)
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
+			PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n");
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+				 psCCBMemInfo,
+				 psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue),
+				 sizeof(IMG_UINT32),
+				 0,
+				MAKEUNIQUETAG(psCCBMemInfo));
+#endif
+		}
+	}
+#endif	
+
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_END,
+			KICK_TOKEN_DOKICK);
+
+	eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0, hDevMemContext, psCCBKick->bLastInScene);
+	if (eError == PVRSRV_ERROR_RETRY)
+	{
+		if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0)
+		{
+			for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++)
+			{
+				
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
+
+				if (psSyncInfo)
+				{
+					psSyncInfo->psSyncData->ui32WriteOpsPending--;
+#if defined(PDUMP)
+					if (PDumpIsCaptureFrameKM())
+					{
+						psSyncInfo->psSyncData->ui32LastOpDumpVal--;
+					}
+#endif
+				}
+			}
+		}
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+		for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+			psSyncInfo->psSyncData->ui32ReadOpsPending--;
+		}
+		for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+			psSyncInfo->psSyncData->ui32WriteOpsPending--;
+		}
+		for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+			psSyncInfo->psSyncData->ui32ReadOpsPending--;
+		}
+#else
+		for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+			psSyncInfo->psSyncData->ui32ReadOpsPending--;
+		}
+#endif
+
+		PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+				KICK_TOKEN_DOKICK);
+		return eError;
+	}
+	else if (PVRSRV_OK != eError)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed."));
+		PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+				KICK_TOKEN_DOKICK);
+		return eError;
+	}
+
+
+#if defined(NO_HARDWARE)
+
+
+	
+	if (psCCBKick->hTA3DSyncInfo)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
+
+		if (psCCBKick->bTADependency)
+		{
+			psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+		}
+	}
+
+	if (psCCBKick->hTASyncInfo != IMG_NULL)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
+
+		psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
+	}
+
+	if (psCCBKick->h3DSyncInfo != IMG_NULL)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
+
+		psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
+	}
+
+	
+	for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
+	{
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+		PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->asTAStatusUpdate[i].hKernelMemInfo;
+		
+		*(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM
+						+ (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr
+						- psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
+#else
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
+		psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
+#endif
+	}
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+	
+	for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+		psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
+	}
+	for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+		psSyncInfo->psSyncData->ui32WriteOpsComplete =  psSyncInfo->psSyncData->ui32WriteOpsPending;
+	}
+	for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+		psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
+	}
+#else
+	
+	for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+		psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
+	}
+#endif
+
+	if (psCCBKick->bTerminateOrAbort)
+	{
+		if (psCCBKick->ui32NumDstSyncObjects > 0)
+		{
+			PVRSRV_KERNEL_MEM_INFO	*psHWDstSyncListMemInfo =
+								(PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo;
+			SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM;
+
+			for (i=0; i<psCCBKick->ui32NumDstSyncObjects; i++)
+			{
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
+				if (psSyncInfo)
+					psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1;
+			}
+		}
+
+		
+		for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
+		{
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+			PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->as3DStatusUpdate[i].hKernelMemInfo;
+			
+			*(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM
+							+ (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr
+							- psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;
+#else
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
+			psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;
+#endif
+		}
+	}
+#endif
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+			KICK_TOKEN_DOKICK);
+	return eError;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxpower.c b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxpower.c
new file mode 100644
index 0000000..3947cdd
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxpower.c
@@ -0,0 +1,481 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "sgxapi_km.h"
+#include "sgx_mkif_km.h"
+#include "sgxutils.h"
+#include "pdump_km.h"
+
+
+#if defined(SUPPORT_HW_RECOVERY)
+static PVRSRV_ERROR SGXAddTimer(PVRSRV_DEVICE_NODE		*psDeviceNode,
+								SGX_TIMING_INFORMATION	*psSGXTimingInfo,
+								IMG_HANDLE				*phTimer)
+{
+	
+
+
+	*phTimer = OSAddTimer(SGXOSTimer, psDeviceNode,
+						  1000 * 50 / psSGXTimingInfo->ui32uKernelFreq);
+	if(*phTimer == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXAddTimer : Failed to register timer callback function"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	return PVRSRV_OK;
+}
+#endif 
+
+
+static PVRSRV_ERROR SGXUpdateTimingInfo(PVRSRV_DEVICE_NODE	*psDeviceNode)
+{
+	PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
+#if defined(SGX_DYNAMIC_TIMING_INFO)
+	SGX_TIMING_INFORMATION	sSGXTimingInfo = {0};
+#else
+	SGX_DEVICE_MAP		*psSGXDeviceMap;
+#endif
+	IMG_UINT32		ui32ActivePowManSampleRate;
+	SGX_TIMING_INFORMATION	*psSGXTimingInfo;
+
+
+#if defined(SGX_DYNAMIC_TIMING_INFO)
+	psSGXTimingInfo = &sSGXTimingInfo;
+	SysGetSGXTimingInformation(psSGXTimingInfo);
+#else
+	SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+						  (IMG_VOID**)&psSGXDeviceMap);
+	psSGXTimingInfo = &psSGXDeviceMap->sTimingInfo;
+#endif
+
+#if defined(SUPPORT_HW_RECOVERY)
+	{
+		PVRSRV_ERROR			eError;
+		IMG_UINT32	ui32OlduKernelFreq;
+
+		if (psDevInfo->hTimer != IMG_NULL)
+		{
+			ui32OlduKernelFreq = psDevInfo->ui32CoreClockSpeed / psDevInfo->ui32uKernelTimerClock;
+			if (ui32OlduKernelFreq != psSGXTimingInfo->ui32uKernelFreq)
+			{
+				
+
+				IMG_HANDLE hNewTimer;
+				
+				eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &hNewTimer);
+				if (eError == PVRSRV_OK)
+				{
+					eError = OSRemoveTimer(psDevInfo->hTimer);
+					if (eError != PVRSRV_OK)
+					{
+						PVR_DPF((PVR_DBG_ERROR,"SGXUpdateTimingInfo: Failed to remove timer"));
+					}
+					psDevInfo->hTimer = hNewTimer;
+				}
+				else
+				{
+					
+				}
+			}
+		}
+		else
+		{
+			eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &psDevInfo->hTimer);
+			if (eError != PVRSRV_OK)
+			{
+				return eError;
+			}
+		}
+
+		psDevInfo->psSGXHostCtl->ui32HWRecoverySampleRate =
+			psSGXTimingInfo->ui32uKernelFreq / psSGXTimingInfo->ui32HWRecoveryFreq;
+	}
+#endif 
+
+	
+	psDevInfo->ui32CoreClockSpeed = psSGXTimingInfo->ui32CoreClockSpeed;
+	psDevInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq;
+
+	
+	psDevInfo->psSGXHostCtl->ui32uKernelTimerClock = psDevInfo->ui32uKernelTimerClock;
+#if defined(PDUMP)
+	PDUMPCOMMENT("Host Control - Microkernel clock");
+	PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+			 offsetof(SGXMKIF_HOST_CTL, ui32uKernelTimerClock),
+			 sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+			 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+#endif 
+
+	if (psSGXTimingInfo->bEnableActivePM)
+	{
+		ui32ActivePowManSampleRate =
+			psSGXTimingInfo->ui32uKernelFreq * psSGXTimingInfo->ui32ActivePowManLatencyms / 1000;
+		
+
+
+
+
+
+
+		ui32ActivePowManSampleRate += 1;
+	}
+	else
+	{
+		ui32ActivePowManSampleRate = 0;
+	}
+
+	psDevInfo->psSGXHostCtl->ui32ActivePowManSampleRate = ui32ActivePowManSampleRate;
+#if defined(PDUMP)
+	PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+			 offsetof(SGXMKIF_HOST_CTL, ui32ActivePowManSampleRate),
+			 sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+			 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+#endif 
+
+	return PVRSRV_OK;
+}
+
+
+static IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO	*psDevInfo)
+{
+	#if defined(SUPPORT_HW_RECOVERY)
+	PVRSRV_ERROR	eError;
+
+	eError = OSEnableTimer(psDevInfo->hTimer);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXStartTimer : Failed to enable host timer"));
+	}
+	#else
+	PVR_UNREFERENCED_PARAMETER(psDevInfo);
+	#endif 
+}
+
+
+static IMG_VOID SGXPollForClockGating (PVRSRV_SGXDEV_INFO	*psDevInfo,
+									   IMG_UINT32			ui32Register,
+									   IMG_UINT32			ui32RegisterValue,
+									   IMG_CHAR				*pszComment)
+{
+	PVR_UNREFERENCED_PARAMETER(psDevInfo);
+	PVR_UNREFERENCED_PARAMETER(ui32Register);
+	PVR_UNREFERENCED_PARAMETER(ui32RegisterValue);
+	PVR_UNREFERENCED_PARAMETER(pszComment);
+
+	#if !defined(NO_HARDWARE)
+	PVR_ASSERT(psDevInfo != IMG_NULL);
+
+	 
+	if (PollForValueKM((IMG_UINT32 *)psDevInfo->pvRegsBaseKM + (ui32Register >> 2),
+						0,
+						ui32RegisterValue,
+						MAX_HW_TIME_US,
+						MAX_HW_TIME_US/WAIT_TRY_COUNT,
+						IMG_FALSE) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXPollForClockGating: %s failed.", pszComment));
+		PVR_DBG_BREAK;
+	}
+	#endif 
+
+	PDUMPCOMMENT("%s", pszComment);
+	PDUMPREGPOL(SGX_PDUMPREG_NAME, ui32Register, 0, ui32RegisterValue, PDUMP_POLL_OPERATOR_EQUAL);
+}
+
+
+PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE				hDevHandle,
+							   PVRSRV_DEV_POWER_STATE	eNewPowerState,
+							   PVRSRV_DEV_POWER_STATE	eCurrentPowerState)
+{
+	if ((eNewPowerState != eCurrentPowerState) &&
+		(eNewPowerState != PVRSRV_DEV_POWER_STATE_ON))
+	{
+		PVRSRV_ERROR		eError;
+		PVRSRV_DEVICE_NODE	*psDeviceNode = hDevHandle;
+		PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
+		IMG_UINT32			ui32PowerCmd, ui32CompleteStatus;
+		SGXMKIF_COMMAND		sCommand = {0};
+		IMG_UINT32			ui32Core;
+		IMG_UINT32			ui32CoresEnabled;
+
+		#if defined(SUPPORT_HW_RECOVERY)
+		
+		eError = OSDisableTimer(psDevInfo->hTimer);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to disable timer"));
+			return eError;
+		}
+		#endif 
+
+		if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+		{
+			
+			ui32PowerCmd = PVRSRV_POWERCMD_POWEROFF;
+			ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE;
+			PDUMPCOMMENT("SGX power off request");
+		}
+		else
+		{
+			
+			ui32PowerCmd = PVRSRV_POWERCMD_IDLE;
+			ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE;
+			PDUMPCOMMENT("SGX idle request");
+		}
+
+		sCommand.ui32Data[1] = ui32PowerCmd;
+
+		eError = SGXScheduleCCBCommand(psDeviceNode, SGXMKIF_CMD_POWER, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to submit power down command"));
+			return eError;
+		}
+
+		
+		#if !defined(NO_HARDWARE)
+		if (PollForValueKM(&psDevInfo->psSGXHostCtl->ui32PowerStatus,
+							ui32CompleteStatus,
+							ui32CompleteStatus,
+							MAX_HW_TIME_US,
+							MAX_HW_TIME_US/WAIT_TRY_COUNT,
+							IMG_FALSE) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for SGX ukernel power transition failed."));
+			PVR_DBG_BREAK;
+		}
+		#endif 
+
+		#if defined(PDUMP)
+		PDUMPCOMMENT("TA/3D CCB Control - Wait for power event on uKernel.");
+		PDUMPMEMPOL(psDevInfo->psKernelSGXHostCtlMemInfo,
+					offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus),
+					ui32CompleteStatus,
+					ui32CompleteStatus,
+					PDUMP_POLL_OPERATOR_EQUAL,
+					0,
+					MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+		#endif 
+
+#if defined(SGX_FEATURE_MP)
+		ui32CoresEnabled = ((OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE) & EUR_CR_MASTER_CORE_ENABLE_MASK) >> EUR_CR_MASTER_CORE_ENABLE_SHIFT) + 1;
+#else
+		ui32CoresEnabled = 1;
+#endif
+
+		for (ui32Core = 0; ui32Core < ui32CoresEnabled; ui32Core++)
+		{
+			
+			SGXPollForClockGating(psDevInfo,
+								  SGX_MP_CORE_SELECT(psDevInfo->ui32ClkGateStatusReg, ui32Core),
+								  psDevInfo->ui32ClkGateStatusMask,
+								  "Wait for SGX clock gating");
+		}
+
+		#if defined(SGX_FEATURE_MP)
+		
+		SGXPollForClockGating(psDevInfo,
+							  psDevInfo->ui32MasterClkGateStatusReg,
+							  psDevInfo->ui32MasterClkGateStatusMask,
+							  "Wait for SGX master clock gating");
+
+		SGXPollForClockGating(psDevInfo,
+							  psDevInfo->ui32MasterClkGateStatus2Reg,
+							  psDevInfo->ui32MasterClkGateStatus2Mask,
+							  "Wait for SGX master clock gating (2)");
+		#endif 
+
+		if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+		{
+			
+			eError = SGXDeinitialise(psDevInfo);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: SGXDeinitialise failed: %u", eError));
+				return eError;
+			}
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE				hDevHandle,
+								PVRSRV_DEV_POWER_STATE	eNewPowerState,
+								PVRSRV_DEV_POWER_STATE	eCurrentPowerState)
+{
+	if ((eNewPowerState != eCurrentPowerState) &&
+		(eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON))
+	{
+		PVRSRV_ERROR		eError;
+		PVRSRV_DEVICE_NODE	*psDeviceNode = hDevHandle;
+		PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
+		SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+
+		
+		psSGXHostCtl->ui32PowerStatus = 0;
+		#if defined(PDUMP)
+		PDUMPCOMMENT("Host Control - Reset power status");
+		PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+				 offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus),
+				 sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+				 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+		#endif 
+
+		if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+		{
+			
+
+			
+
+			eError = SGXUpdateTimingInfo(psDeviceNode);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
+				return eError;
+			}
+
+			
+
+			eError = SGXInitialise(psDevInfo, IMG_FALSE);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXInitialise failed"));
+				return eError;
+			}
+		}
+		else
+		{
+			
+
+			SGXMKIF_COMMAND		sCommand = {0};
+
+			sCommand.ui32Data[1] = PVRSRV_POWERCMD_RESUME;
+			eError = SGXScheduleCCBCommand(psDeviceNode, SGXMKIF_CMD_POWER, &sCommand, ISR_ID, 0, IMG_NULL, IMG_FALSE);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState failed to schedule CCB command: %u", eError));
+				return eError;
+			}
+		}
+
+		SGXStartTimer(psDevInfo);
+	}
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SGXPreClockSpeedChange (IMG_HANDLE				hDevHandle,
+									 IMG_BOOL				bIdleDevice,
+									 PVRSRV_DEV_POWER_STATE	eCurrentPowerState)
+{
+	PVRSRV_ERROR		eError;
+	PVRSRV_DEVICE_NODE	*psDeviceNode = hDevHandle;
+	PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
+
+	PVR_UNREFERENCED_PARAMETER(psDevInfo);
+
+	if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)
+	{
+		if (bIdleDevice)
+		{
+			
+			PDUMPSUSPEND();
+
+			eError = SGXPrePowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_IDLE,
+									  PVRSRV_DEV_POWER_STATE_ON);
+
+			if (eError != PVRSRV_OK)
+			{
+				PDUMPRESUME();
+				return eError;
+			}
+		}
+	}
+
+	PVR_DPF((PVR_DBG_MESSAGE,"SGXPreClockSpeedChange: SGX clock speed was %uHz",
+			psDevInfo->ui32CoreClockSpeed));
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SGXPostClockSpeedChange (IMG_HANDLE				hDevHandle,
+									  IMG_BOOL					bIdleDevice,
+									  PVRSRV_DEV_POWER_STATE	eCurrentPowerState)
+{
+	PVRSRV_DEVICE_NODE	*psDeviceNode = hDevHandle;
+	PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
+	IMG_UINT32			ui32OldClockSpeed = psDevInfo->ui32CoreClockSpeed;
+
+	PVR_UNREFERENCED_PARAMETER(ui32OldClockSpeed);
+
+	if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)
+	{
+		PVRSRV_ERROR eError;
+
+		
+
+		eError = SGXUpdateTimingInfo(psDeviceNode);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
+			return eError;
+		}
+
+		if (bIdleDevice)
+		{
+			
+			eError = SGXPostPowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_ON,
+									   PVRSRV_DEV_POWER_STATE_IDLE);
+
+			PDUMPRESUME();
+
+			if (eError != PVRSRV_OK)
+			{
+				return eError;
+			}
+		}
+		else
+		{
+			SGXStartTimer(psDevInfo);
+		}
+	}
+
+	PVR_DPF((PVR_DBG_MESSAGE,"SGXPostClockSpeedChange: SGX clock speed changed from %uHz to %uHz",
+			ui32OldClockSpeed, psDevInfo->ui32CoreClockSpeed));
+
+	return PVRSRV_OK;
+}
+
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxreset.c b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxreset.c
new file mode 100644
index 0000000..519783f
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxreset.c
@@ -0,0 +1,668 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "sgxdefs.h"
+#include "sgxmmu.h"
+#include "services_headers.h"
+#include "sgxinfokm.h"
+#include "sgxconfig.h"
+#include "sgxutils.h"
+
+#include "pdump_km.h"
+
+
+IMG_VOID SGXInitClocks(PVRSRV_SGXDEV_INFO	*psDevInfo,
+					   IMG_UINT32			ui32PDUMPFlags)
+{
+	IMG_UINT32	ui32RegVal;
+	
+#if !defined(PDUMP)
+	PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif 
+	
+	ui32RegVal = psDevInfo->ui32ClkGateCtl;
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL, ui32RegVal);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_CLKGATECTL, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(EUR_CR_CLKGATECTL2)
+	ui32RegVal = psDevInfo->ui32ClkGateCtl2;
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL2, ui32RegVal);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_CLKGATECTL2, ui32RegVal, ui32PDUMPFlags);
+#endif
+}
+
+
+static IMG_VOID SGXResetInitBIFContexts(PVRSRV_SGXDEV_INFO	*psDevInfo,
+										IMG_UINT32			ui32PDUMPFlags)
+{
+	IMG_UINT32	ui32RegVal;
+
+#if !defined(PDUMP)
+	PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif 
+
+	ui32RegVal = 0;
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the BIF bank settings\r\n");
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags);
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
+#endif 
+
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the BIF directory list\r\n");
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+	{
+		IMG_UINT32	ui32DirList, ui32DirListReg;
+
+		for (ui32DirList = 1;
+			 ui32DirList < SGX_FEATURE_BIF_NUM_DIRLISTS;
+			 ui32DirList++)
+		{
+			ui32DirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (ui32DirList - 1);
+			OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32DirListReg, ui32RegVal);
+			PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, ui32DirListReg, ui32RegVal, ui32PDUMPFlags);
+		}
+	}
+#endif 
+}
+
+
+static IMG_VOID SGXResetSetupBIFContexts(PVRSRV_SGXDEV_INFO	*psDevInfo,
+										 IMG_UINT32			ui32PDUMPFlags)
+{
+	IMG_UINT32	ui32RegVal;
+
+#if !defined(PDUMP)
+	PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif 
+	
+	#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+	
+	ui32RegVal = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT);
+
+	#if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA)
+	
+	ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT);
+	#endif 
+
+	#if defined(FIX_HW_BRN_23410)
+	
+	ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT);
+	#endif 
+
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Set up EDM requestor page table in BIF\r\n");
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
+	#endif 
+
+	{
+		IMG_UINT32	ui32EDMDirListReg;
+
+		
+		#if (SGX_BIF_DIR_LIST_INDEX_EDM == 0)
+		ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0;
+		#else
+		
+		ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1);
+		#endif 
+
+		ui32RegVal = psDevInfo->sKernelPDDevPAddr.uiAddr >> SGX_MMU_PDE_ADDR_ALIGNSHIFT;
+		
+#if defined(FIX_HW_BRN_28011)
+		OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
+		PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
+#endif
+
+		OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, ui32RegVal);
+		PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the EDM's directory list base\r\n");
+		PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, ui32EDMDirListReg, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
+	}
+}
+
+
+static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO	*psDevInfo,
+							  IMG_UINT32			ui32PDUMPFlags,
+							  IMG_BOOL				bPDump)
+{
+#if defined(PDUMP) || defined(EMULATOR)
+	IMG_UINT32	ui32ReadRegister;
+
+	#if defined(SGX_FEATURE_MP)
+	ui32ReadRegister = EUR_CR_MASTER_SOFT_RESET;
+	#else
+	ui32ReadRegister = EUR_CR_SOFT_RESET;
+	#endif 
+#endif
+
+#if !defined(PDUMP)
+	PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif 
+
+	
+	SGXWaitClocks(psDevInfo, 100);
+	if (bPDump)
+	{
+		PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags);
+#if defined(PDUMP)
+		PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Read back to flush the register writes\r\n");
+		PDumpRegRead(SGX_PDUMPREG_NAME, ui32ReadRegister, ui32PDUMPFlags);
+#endif
+	}
+
+#if defined(EMULATOR)
+	
+
+	OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32ReadRegister);
+#endif
+}
+
+
+#if !defined(SGX_FEATURE_MP)
+static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO	*psDevInfo,
+								  IMG_BOOL				bResetBIF,
+								  IMG_UINT32			ui32PDUMPFlags,
+								  IMG_BOOL				bPDump)
+{
+	IMG_UINT32 ui32SoftResetRegVal;
+
+	ui32SoftResetRegVal =
+					
+					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;
+
+#ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TWOD_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_TE_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TE_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_MTE_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MTE_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_ISP2_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ISP2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_PDS_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PDS_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_PBE_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PBE_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_MADD_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MADD_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_ITR_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ITR_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_TEX_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TEX_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_VDM_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_VDM_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK)
+	ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK;
+#endif
+
+#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(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags);
+	}
+}
+
+
+static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO	*psDevInfo,
+							    IMG_UINT32			ui32PDUMPFlags,
+								IMG_BOOL			bPDump)
+{
+	IMG_UINT32 ui32RegVal;
+
+	
+#if defined(EUR_CR_BIF_CTRL_INVAL)
+	ui32RegVal = EUR_CR_BIF_CTRL_INVAL_ALL_MASK;
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, ui32RegVal);
+	if (bPDump)
+	{
+		PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL_INVAL, ui32RegVal, ui32PDUMPFlags);
+	}
+#else
+	ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK;
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+	if (bPDump)
+	{
+		PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+	}
+
+	ui32RegVal = 0;
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+	if (bPDump)
+	{
+		PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+	}
+#endif
+	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,
+							MAX_HW_TIME_US/WAIT_TRY_COUNT,
+							IMG_FALSE) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"Wait for DC invalidate failed."));
+			PVR_DBG_BREAK;
+		}
+
+		if (bPDump)
+		{
+			PDUMPREGPOLWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_REQ_STAT, 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ui32PDUMPFlags, PDUMP_POLL_OPERATOR_EQUAL);
+		}
+	}
+#endif 
+}
+#endif 
+
+
+IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO	*psDevInfo,
+				  IMG_BOOL				bHardwareRecovery,
+				  IMG_UINT32			ui32PDUMPFlags)
+#if !defined(SGX_FEATURE_MP)
+{
+	IMG_UINT32 ui32RegVal;
+#if defined(EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK)
+	const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK;
+#else
+	const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_MASK;
+#endif
+
+#if !defined(PDUMP)
+	PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif 
+
+	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(SGX_PDUMPREG_NAME, 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(SGX_PDUMPREG_NAME, 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(SGX_PDUMPREG_NAME, 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_36BIT_MMU)
+	
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK, ui32PDUMPFlags);
+#endif
+
+	SGXResetInitBIFContexts(psDevInfo, ui32PDUMPFlags);
+
+#if defined(EUR_CR_BIF_MEM_ARB_CONFIG)
+	
+
+	ui32RegVal	= (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, ui32RegVal);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal, ui32PDUMPFlags);
+#endif 
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+	#if defined(SGX_BYPASS_SYSTEM_CACHE)
+		
+		ui32RegVal = MNE_CR_CTRL_BYPASS_ALL_MASK;
+	#else
+		#if defined(FIX_HW_BRN_26620)
+			ui32RegVal = 0;
+		#else
+			
+			ui32RegVal = MNE_CR_CTRL_BYP_CC_MASK;
+		#endif
+		#if defined(FIX_HW_BRN_34028)
+			
+			ui32RegVal |= (8 << MNE_CR_CTRL_BYPASS_SHIFT);
+		#endif
+	#endif 
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, MNE_CR_CTRL, ui32RegVal);
+	PDUMPREG(SGX_PDUMPREG_NAME, MNE_CR_CTRL, ui32RegVal);
+#endif 
+
+	if (bHardwareRecovery)
+	{
+		
+
+
+
+
+
+
+		ui32RegVal = (IMG_UINT32)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_ADDR_ALIGNSHIFT)
+													| SGX_MMU_PDE_PAGE_SIZE_4K
+													| SGX_MMU_PDE_VALID;
+			psDevInfo->pui32BIFResetPT[ui32PTIndex] = (psDevInfo->sBIFResetPageDevPAddr.uiAddr
+													>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+													| 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;
+		}
+	}
+	else
+	{
+		
+		SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE);
+		SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+	}	
+
+	
+
+	SGXResetSetupBIFContexts(psDevInfo, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA)
+	
+	#if ((SGX_2D_HEAP_BASE & ~EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK) != 0)
+		#error "SGXReset: SGX_2D_HEAP_BASE doesn't match EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK alignment"
+	#endif
+	
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags);
+#endif
+
+	
+	SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+	PVR_DPF((PVR_DBG_MESSAGE,"Soft Reset of SGX"));
+
+	
+	ui32RegVal = 0;
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
+
+	
+	SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n");
+}
+
+#else
+
+{
+	IMG_UINT32 ui32RegVal;
+	
+	PVR_UNREFERENCED_PARAMETER(bHardwareRecovery);
+
+#if !defined(PDUMP)
+	PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif 
+
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX MP reset sequence\r\n");
+
+	
+	ui32RegVal = EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK  |
+				 EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK  |
+				 EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK  |
+				 EUR_CR_MASTER_SOFT_RESET_MCI_RESET_MASK  |
+				 EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK;
+
+#if defined(SGX_FEATURE_PTLA)
+	ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_MASK;
+#endif
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+	ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK;
+#endif
+
+	
+	ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(0)  |
+				  EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(1)  |
+				  EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(2)  |
+				  EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(3);
+
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal);
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Soft reset hydra partition, hard reset the cores\r\n");
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
+
+	SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+	ui32RegVal = 0;
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_CTRL, ui32RegVal);
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra BIF control\r\n");
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+	#if defined(SGX_BYPASS_SYSTEM_CACHE)
+		ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_MASK;
+	#else
+		ui32RegVal = EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK |
+		#if defined(FIX_HW_BRN_30954)
+						EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_MASK |
+		#endif
+		#if defined(PVR_SLC_8KB_ADDRESS_MODE)
+						(4 << EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT) |
+		#endif
+						(0xC << EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT);
+		OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
+		PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra SLC control\r\n");
+		PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
+
+		ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK;
+	#if defined(FIX_HW_BRN_31620)
+		ui32RegVal |= EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_MASK;
+	#endif
+	#if defined(FIX_HW_BRN_31195)
+		ui32RegVal |= EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_MASK |
+				EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_MASK |
+				EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_MASK |
+				EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_MASK |
+				EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_MASK;
+	#endif
+	#endif 
+		OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
+		PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra SLC bypass control\r\n");
+		PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
+#endif 
+
+	SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+	
+	ui32RegVal = 0;
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal);
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Remove the resets from all of SGX\r\n");
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
+	
+	SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Turn on the slave cores' clock gating\r\n");
+	SGXInitClocks(psDevInfo, ui32PDUMPFlags);
+
+	SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the slave BIFs\r\n");
+
+#if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_31620) || defined(FIX_HW_BRN_31671) || defined(FIX_HW_BRN_32085)
+	#if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_32085)
+	
+	ui32RegVal = (1<<EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT);
+	#else
+	ui32RegVal = (1<<EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT) | EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_MASK; 
+	#endif
+	#if !defined(FIX_HW_BRN_31620) && !defined(FIX_HW_BRN_31671)
+	
+	ui32RegVal |= EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK;
+	#endif
+
+	
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_MMU_CTRL, ui32RegVal);
+	PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_BIF_MMU_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+	#if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_32085)
+	
+	ui32RegVal = (1<<EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT);
+	#else
+	ui32RegVal = (1<<EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT) | EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK; 
+	#endif
+	#if !defined(FIX_HW_BRN_31620) && !defined(FIX_HW_BRN_31671)
+	
+	ui32RegVal |= EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK;
+	#endif
+
+	
+	{
+		IMG_UINT32 ui32Core;
+
+		for (ui32Core=0;ui32Core<SGX_FEATURE_MP_CORE_COUNT;ui32Core++)
+		{
+			OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BIF_MMU_CTRL, ui32Core), ui32RegVal);
+			PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_BIF_MMU_CTRL, ui32Core), ui32RegVal, ui32PDUMPFlags);
+		}
+	}
+#endif
+
+	SGXResetInitBIFContexts(psDevInfo, ui32PDUMPFlags);
+	SGXResetSetupBIFContexts(psDevInfo, ui32PDUMPFlags);
+	
+	PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX MP reset sequence\r\n");
+}	
+#endif 
+
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxtransfer.c b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxtransfer.c
new file mode 100644
index 0000000..8a9415f
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxtransfer.c
@@ -0,0 +1,750 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if defined(TRANSFER_QUEUE)
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "sgxinfo.h"
+#include "sysconfig.h"
+#include "pdump_km.h"
+#include "mmu.h"
+#include "pvr_bridge.h"
+#include "sgx_bridge_km.h"
+#include "sgxinfokm.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+#include "sgxutils.h"
+#include "ttrace.h"
+
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK_KM *psKick)
+#else
+IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick)
+#endif
+{
+	PVRSRV_KERNEL_MEM_INFO		*psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
+	SGXMKIF_COMMAND				sCommand = {0};
+	SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd;
+	PVRSRV_KERNEL_SYNC_INFO 	*psSyncInfo;
+	PVRSRV_ERROR				eError;
+	IMG_UINT32					loop;
+	IMG_HANDLE					hDevMemContext = IMG_NULL;
+	IMG_BOOL					abSrcSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS];
+	IMG_UINT32					ui32RealSrcSyncNum = 0;
+	IMG_BOOL					abDstSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS];
+	IMG_UINT32					ui32RealDstSyncNum = 0;
+
+
+#if defined(PDUMP)
+	IMG_BOOL bPersistentProcess = IMG_FALSE;
+	
+	{
+		PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+		if(psPerProc != IMG_NULL)
+		{
+			bPersistentProcess = psPerProc->bPDumpPersistent;
+		}
+	}
+#endif 
+#if defined(FIX_HW_BRN_31620)
+	hDevMemContext = psKick->hDevMemContext;
+#endif
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, TRANSFER_TOKEN_SUBMIT);
+
+	for (loop = 0; loop < SGX_MAX_TRANSFER_SYNC_OPS; loop++)
+	{
+		abSrcSyncEnable[loop] = IMG_TRUE;
+		abDstSyncEnable[loop] = IMG_TRUE;
+	}
+
+	if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset"));
+		PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+				TRANSFER_TOKEN_SUBMIT);
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+	
+	
+	psSharedTransferCmd =  CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
+
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_START, TRANSFER_TOKEN_SUBMIT);
+	PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CCB,
+			TRANSFER_TOKEN_CCB_OFFSET, psKick->ui32SharedCmdCCBOffset);
+
+	if (psKick->hTASyncInfo != IMG_NULL)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_TA_SYNC,
+					  psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+		psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+		psSharedTransferCmd->ui32TASyncReadOpsPendingVal  = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+		psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+		psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+	}
+	else
+	{
+		psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
+		psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
+	}
+
+	if (psKick->h3DSyncInfo != IMG_NULL)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+
+		PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_3D_SYNC,
+					  psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+		psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+		psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+		psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+		psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+	}
+	else
+	{
+		psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
+		psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
+	}
+
+	
+	for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumSrcSync); loop++)
+	{
+		IMG_UINT32 i;
+
+		PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+	
+		for (i = 0; i < loop; i++)	
+		{
+			if (abSrcSyncEnable[i])
+			{
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i];
+
+				if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr)
+				{
+					PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same src synchronized multiple times!"));
+					abSrcSyncEnable[loop] = IMG_FALSE;
+					break;
+				}
+			}
+		}
+		if (abSrcSyncEnable[loop])
+		{
+			ui32RealSrcSyncNum++;
+		}
+	}
+	for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumDstSync); loop++)
+	{
+		IMG_UINT32 i;
+
+		PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+	
+		for (i = 0; i < loop; i++)	
+		{
+			if (abDstSyncEnable[i])
+			{
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i];
+
+				if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr)
+				{
+					PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same dst synchronized multiple times!"));
+					abDstSyncEnable[loop] = IMG_FALSE;
+					break;
+				}
+			}
+		}
+		if (abDstSyncEnable[loop])
+		{
+			ui32RealDstSyncNum++;
+		}
+	}
+
+	psSharedTransferCmd->ui32NumSrcSyncs = ui32RealSrcSyncNum; 
+	psSharedTransferCmd->ui32NumDstSyncs = ui32RealDstSyncNum; 
+
+	if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
+	{
+		IMG_UINT32 i = 0;
+
+		for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+		{
+			if (abSrcSyncEnable[loop])
+			{
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+
+				PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_SRC_SYNC,
+						psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+				psSharedTransferCmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+				psSharedTransferCmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+				psSharedTransferCmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; 
+				psSharedTransferCmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+				i++;
+			}
+		}
+		PVR_ASSERT(i == ui32RealSrcSyncNum);
+
+		i = 0;
+		for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+		{
+			if (abDstSyncEnable[loop])
+			{
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+
+				PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_DST_SYNC,
+						psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+				psSharedTransferCmd->asDstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+				psSharedTransferCmd->asDstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+				psSharedTransferCmd->asDstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+				psSharedTransferCmd->asDstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+				i++;
+			}
+		}
+		PVR_ASSERT(i == ui32RealDstSyncNum);
+
+		
+		for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+		{
+			if (abSrcSyncEnable[loop])
+			{
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+				psSyncInfo->psSyncData->ui32ReadOpsPending++;
+			}
+		}
+		for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+		{
+			if (abDstSyncEnable[loop])
+			{
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+				psSyncInfo->psSyncData->ui32WriteOpsPending++;
+			}
+		}
+	}
+
+#if defined(PDUMP)
+	if ((PDumpIsCaptureFrameKM()
+	|| ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) 
+	&&  (bPersistentProcess == IMG_FALSE) )
+	{
+		PDUMPCOMMENT("Shared part of transfer command\r\n");
+		PDUMPMEM(psSharedTransferCmd,
+				psCCBMemInfo,
+				psKick->ui32CCBDumpWOff,
+				sizeof(SGXMKIF_TRANSFERCMD_SHARED),
+				psKick->ui32PDumpFlags,
+				MAKEUNIQUETAG(psCCBMemInfo));
+
+		if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
+		{
+			IMG_UINT32 i = 0;
+
+			for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+			{
+				if (abSrcSyncEnable[loop])
+				{
+					psSyncInfo = psKick->ahSrcSyncInfo[loop];
+
+					PDUMPCOMMENT("Hack src surface write op in transfer cmd\r\n");
+					PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+							psCCBMemInfo,
+							psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)),
+							sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+							psKick->ui32PDumpFlags,
+							MAKEUNIQUETAG(psCCBMemInfo));
+
+					PDUMPCOMMENT("Hack src surface read op in transfer cmd\r\n");
+					PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+							psCCBMemInfo,
+							psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)),
+							sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+							psKick->ui32PDumpFlags,
+							MAKEUNIQUETAG(psCCBMemInfo));
+					i++;
+				}
+			}
+
+			i = 0;
+			for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+			{
+				if (abDstSyncEnable[i])
+				{
+					psSyncInfo = psKick->ahDstSyncInfo[loop];
+
+					PDUMPCOMMENT("Hack dest surface write op in transfer cmd\r\n");
+					PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+							psCCBMemInfo,
+							psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)),
+							sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+							psKick->ui32PDumpFlags,
+							MAKEUNIQUETAG(psCCBMemInfo));
+
+					PDUMPCOMMENT("Hack dest surface read op in transfer cmd\r\n");
+					PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+							psCCBMemInfo,
+							psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)),
+							sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+							psKick->ui32PDumpFlags,
+							MAKEUNIQUETAG(psCCBMemInfo));
+					i++;
+				}
+			}
+
+			
+			for (loop = 0; loop < (psKick->ui32NumSrcSync); loop++)
+			{
+				if (abSrcSyncEnable[loop])
+				{	
+					psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+					psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+				}
+			}
+
+			for (loop = 0; loop < (psKick->ui32NumDstSync); loop++)
+			{
+				if (abDstSyncEnable[loop])
+				{
+					psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
+					psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+				}
+			}
+		}
+
+		if (psKick->hTASyncInfo != IMG_NULL)
+		{
+			psSyncInfo = psKick->hTASyncInfo;
+
+			PDUMPCOMMENT("Tweak TA/TQ surface write op in transfer cmd\r\n");
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+					psCCBMemInfo,
+					psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32TASyncWriteOpsPendingVal)),
+					sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+					psKick->ui32PDumpFlags,
+					MAKEUNIQUETAG(psCCBMemInfo));
+
+			psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+		}
+
+		if (psKick->h3DSyncInfo != IMG_NULL)
+		{
+			psSyncInfo = psKick->h3DSyncInfo;
+
+			PDUMPCOMMENT("Tweak 3D/TQ surface write op in transfer cmd\r\n");
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+					psCCBMemInfo,
+					psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui323DSyncWriteOpsPendingVal)),
+					sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+					psKick->ui32PDumpFlags,
+					MAKEUNIQUETAG(psCCBMemInfo));
+
+			psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+		}
+	}
+#endif
+
+	sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
+	
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_END,
+			TRANSFER_TOKEN_SUBMIT);
+
+	eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE);
+
+	if (eError == PVRSRV_ERROR_RETRY)
+	{
+		
+		if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
+		{
+			for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+			{
+				if (abSrcSyncEnable[loop])
+				{
+					psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+					psSyncInfo->psSyncData->ui32ReadOpsPending--;
+#if defined(PDUMP)
+					if (PDumpIsCaptureFrameKM()
+							|| ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+					{
+						psSyncInfo->psSyncData->ui32LastReadOpDumpVal--;
+					}
+#endif
+				}
+			}
+			for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+			{
+				if (abDstSyncEnable[loop])
+				{
+					psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+					psSyncInfo->psSyncData->ui32WriteOpsPending--;
+#if defined(PDUMP)
+					if (PDumpIsCaptureFrameKM()
+							|| ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+					{
+						psSyncInfo->psSyncData->ui32LastOpDumpVal--;
+					}
+#endif
+				}
+			}
+		}
+
+		
+		if (psKick->hTASyncInfo != IMG_NULL)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+			psSyncInfo->psSyncData->ui32WriteOpsPending--;
+		}
+
+		
+		if (psKick->h3DSyncInfo != IMG_NULL)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+			psSyncInfo->psSyncData->ui32WriteOpsPending--;
+		}
+	}
+
+	else if (PVRSRV_OK != eError)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed."));
+		PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+				TRANSFER_TOKEN_SUBMIT);
+		return eError;
+	}
+	
+
+#if defined(NO_HARDWARE)
+	if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0)
+	{
+		
+		for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+		{
+			if (abSrcSyncEnable[loop])
+			{
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+				psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+			}
+		}
+
+		for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+		{
+			if (abDstSyncEnable[loop])
+			{
+				psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+				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
+	PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+			TRANSFER_TOKEN_SUBMIT);
+	return eError;
+}
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK_KM *psKick)
+#else
+IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick)
+#endif
+					    
+{
+	PVRSRV_KERNEL_MEM_INFO  *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
+	SGXMKIF_COMMAND sCommand = {0};
+	SGXMKIF_2DCMD_SHARED *ps2DCmd;
+	PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+	PVRSRV_ERROR eError;
+	IMG_UINT32 i;
+	IMG_HANDLE hDevMemContext = IMG_NULL;
+#if defined(PDUMP)
+	IMG_BOOL bPersistentProcess = IMG_FALSE;
+	
+	{
+		PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+		if(psPerProc != IMG_NULL)
+		{
+			bPersistentProcess = psPerProc->bPDumpPersistent;
+		}
+	}
+#endif 
+#if defined(FIX_HW_BRN_31620)
+	hDevMemContext = psKick->hDevMemContext;
+#endif
+
+	if (!CCB_OFFSET_IS_VALID(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+	
+	
+	ps2DCmd =  CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
+
+	OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd));
+
+	
+	if (psKick->hTASyncInfo != IMG_NULL)
+	{
+		psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+		ps2DCmd->sTASyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+		ps2DCmd->sTASyncData.ui32ReadOpsPendingVal = 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.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+		ps2DCmd->s3DSyncData.ui32ReadOpsPendingVal = 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 = psKick->ahSrcSyncInfo[i];
+
+		ps2DCmd->sSrcSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+		ps2DCmd->sSrcSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+		ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+		ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+	}
+
+	if (psKick->hDstSyncInfo != IMG_NULL)
+	{
+		psSyncInfo = psKick->hDstSyncInfo;
+
+		ps2DCmd->sDstSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+		ps2DCmd->sDstSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+		ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+		ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+	}
+
+	
+	for (i = 0; i < psKick->ui32NumSrcSync; i++)
+	{
+		psSyncInfo = psKick->ahSrcSyncInfo[i];
+		psSyncInfo->psSyncData->ui32ReadOpsPending++;
+	}
+
+	if (psKick->hDstSyncInfo != IMG_NULL)
+	{
+		psSyncInfo = psKick->hDstSyncInfo;
+		psSyncInfo->psSyncData->ui32WriteOpsPending++;
+	}
+
+#if defined(PDUMP)
+	if ((PDumpIsCaptureFrameKM()
+	|| ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+	&&  (bPersistentProcess == IMG_FALSE) )
+	{
+		
+		PDUMPCOMMENT("Shared part of 2D command\r\n");
+		PDUMPMEM(ps2DCmd,
+				psCCBMemInfo,
+				psKick->ui32CCBDumpWOff,
+				sizeof(SGXMKIF_2DCMD_SHARED),
+				psKick->ui32PDumpFlags,
+				MAKEUNIQUETAG(psCCBMemInfo));
+
+		for (i = 0; i < psKick->ui32NumSrcSync; i++)
+		{
+			psSyncInfo = psKick->ahSrcSyncInfo[i];
+
+			PDUMPCOMMENT("Hack src surface write op in 2D cmd\r\n");
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+					psCCBMemInfo,
+					psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal),
+					sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+					psKick->ui32PDumpFlags,
+					MAKEUNIQUETAG(psCCBMemInfo));
+
+			PDUMPCOMMENT("Hack src surface read op in 2D cmd\r\n");
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					psCCBMemInfo,
+					psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal),
+					sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+					psKick->ui32PDumpFlags,
+					MAKEUNIQUETAG(psCCBMemInfo));
+		}
+
+		if (psKick->hDstSyncInfo != IMG_NULL)
+		{
+			psSyncInfo = psKick->hDstSyncInfo;
+
+			PDUMPCOMMENT("Hack dest surface write op in 2D cmd\r\n");
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+					psCCBMemInfo,
+					psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal),
+					sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+					psKick->ui32PDumpFlags,
+					MAKEUNIQUETAG(psCCBMemInfo));
+
+			PDUMPCOMMENT("Hack dest surface read op in 2D cmd\r\n");
+			PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+					psCCBMemInfo,
+					psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal),
+					sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+					psKick->ui32PDumpFlags,
+					MAKEUNIQUETAG(psCCBMemInfo));
+		}
+
+		
+		for (i = 0; i < psKick->ui32NumSrcSync; i++)
+		{
+			psSyncInfo = psKick->ahSrcSyncInfo[i];
+			psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+		}
+
+		if (psKick->hDstSyncInfo != IMG_NULL)
+		{
+			psSyncInfo = psKick->hDstSyncInfo;
+			psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+		}
+	}		
+#endif
+
+	sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr;
+	
+	eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE);	
+
+	if (eError == PVRSRV_ERROR_RETRY)
+	{
+		
+
+#if defined(PDUMP)
+		if (PDumpIsCaptureFrameKM())
+		{
+			for (i = 0; i < psKick->ui32NumSrcSync; i++)
+			{
+				psSyncInfo = psKick->ahSrcSyncInfo[i];
+				psSyncInfo->psSyncData->ui32LastReadOpDumpVal--;
+			}
+
+			if (psKick->hDstSyncInfo != IMG_NULL)
+			{
+				psSyncInfo = psKick->hDstSyncInfo;
+				psSyncInfo->psSyncData->ui32LastOpDumpVal--;
+			}
+		}
+#endif
+
+		for (i = 0; i < psKick->ui32NumSrcSync; i++)
+		{
+			psSyncInfo = psKick->ahSrcSyncInfo[i];
+			psSyncInfo->psSyncData->ui32ReadOpsPending--;
+		}
+
+		if (psKick->hDstSyncInfo != IMG_NULL)
+		{
+			psSyncInfo = psKick->hDstSyncInfo;
+			psSyncInfo->psSyncData->ui32WriteOpsPending--;
+		}
+
+		
+		if (psKick->hTASyncInfo != IMG_NULL)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+			psSyncInfo->psSyncData->ui32WriteOpsPending--;
+		}
+
+		
+		if (psKick->h3DSyncInfo != IMG_NULL)
+		{
+			psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+
+			psSyncInfo->psSyncData->ui32WriteOpsPending--;
+		}
+	}
+
+	
+
+
+#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;
+	}
+
+	if (psKick->hDstSyncInfo != IMG_NULL)
+	{
+		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 --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxutils.c b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxutils.c
new file mode 100644
index 0000000..1fbca00
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxutils.c
@@ -0,0 +1,1586 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "sgx_bridge_km.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgx_mkif_km.h"
+#include "sysconfig.h"
+#include "pdump_km.h"
+#include "mmu.h"
+#include "pvr_bridge_km.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+#include "sgxutils.h"
+#include "ttrace.h"
+
+#ifdef __linux__
+#include <linux/kernel.h>	
+#include <linux/string.h>	
+#else
+#include <stdio.h>
+#endif
+
+
+#if defined(SYS_CUSTOM_POWERDOWN)
+PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE	* psDeviceNode, IMG_UINT32 ui32CallerID);
+#endif
+
+
+
+static IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE	* psDeviceNode,
+										IMG_UINT32           ui32CallerID)
+{
+	PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
+	SGXMKIF_HOST_CTL	*psSGXHostCtl = psDevInfo->psSGXHostCtl;
+
+	
+	psSGXHostCtl->ui32NumActivePowerEvents++;
+
+	if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0)
+	{
+		
+
+
+		if (ui32CallerID == ISR_ID)
+		{
+			psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
+		}
+		else
+		{
+			SGXScheduleProcessQueuesKM(psDeviceNode);
+		}
+	}
+}
+
+
+IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE	*psDeviceNode,
+								  IMG_UINT32			ui32CallerID)
+{
+	PVRSRV_ERROR		eError = PVRSRV_OK;
+	PVRSRV_SGXDEV_INFO	*psDevInfo = psDeviceNode->pvDevice;
+	SGXMKIF_HOST_CTL	*psSGXHostCtl = psDevInfo->psSGXHostCtl;
+
+	if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0) &&
+		((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0))
+	{
+		
+		psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
+
+		
+		PDUMPSUSPEND();
+
+#if defined(SYS_CUSTOM_POWERDOWN)
+		
+
+
+		eError = SysPowerDownMISR(psDeviceNode, ui32CallerID);
+#else
+		eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+											 PVRSRV_DEV_POWER_STATE_OFF,
+											 ui32CallerID, IMG_FALSE);
+		if (eError == PVRSRV_OK)
+		{
+			SGXPostActivePowerEvent(psDeviceNode, ui32CallerID);
+		}
+#endif
+		if (eError == PVRSRV_ERROR_RETRY)
+		{
+			
+
+			psSGXHostCtl->ui32InterruptClearFlags &= ~PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
+			eError = PVRSRV_OK;
+		}
+
+		
+		PDUMPRESUME();
+	}
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%u", eError));
+	}
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SGXAcquireKernelCCBSlot)
+#endif
+static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psCCB)
+{
+	LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+	{
+		if(((*psCCB->pui32WriteOffset + 1) & 255) != *psCCB->pui32ReadOffset)
+		{
+			return &psCCB->psCommands[*psCCB->pui32WriteOffset];
+		}
+
+		OSSleepms(1);
+	} END_LOOP_UNTIL_TIMEOUT();
+
+	
+	return IMG_NULL;
+}
+
+PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE	*psDeviceNode,
+								   SGXMKIF_CMD_TYPE		eCmdType,
+								   SGXMKIF_COMMAND		*psCommandData,
+								   IMG_UINT32			ui32CallerID,
+								   IMG_UINT32			ui32PDumpFlags,
+								   IMG_HANDLE			hDevMemContext,
+								   IMG_BOOL				bLastInScene)
+{
+	PVRSRV_SGX_CCB_INFO *psKernelCCB;
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	SGXMKIF_COMMAND *psSGXCommand;
+	PVRSRV_SGXDEV_INFO 	*psDevInfo = psDeviceNode->pvDevice;
+#if defined(FIX_HW_BRN_31620)
+	IMG_UINT32 ui32CacheMasks[4];
+	IMG_UINT32 i;
+	MMU_CONTEXT		*psMMUContext;
+#endif
+#if defined(PDUMP)
+	IMG_VOID *pvDumpCommand;
+	IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended();
+	IMG_BOOL bPersistentProcess = IMG_FALSE;
+#else
+	PVR_UNREFERENCED_PARAMETER(ui32CallerID);
+	PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+	for(i=0;i<4;i++)
+	{
+		ui32CacheMasks[i] = 0;
+	}
+
+	psMMUContext = psDevInfo->hKernelMMUContext;
+	psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[0]);
+
+	
+	if (hDevMemContext)
+	{
+		BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext;
+
+		psMMUContext = psBMContext->psMMUContext;
+		psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[2]);
+	}
+
+	
+	if (ui32CacheMasks[0] || ui32CacheMasks[1] || ui32CacheMasks[2] || ui32CacheMasks[3])
+	{
+		psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD;
+	}
+#endif
+
+#if defined(FIX_HW_BRN_28889)
+	
+
+
+
+	if ( (eCmdType != SGXMKIF_CMD_PROCESS_QUEUES) &&
+		 ((psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_DATA) != 0) &&
+		 ((psDevInfo->ui32CacheControl & (SGXMKIF_CC_INVAL_BIF_PT | SGXMKIF_CC_INVAL_BIF_PD)) != 0))
+	{
+	#if defined(PDUMP)
+		PVRSRV_KERNEL_MEM_INFO	*psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
+	#endif
+		SGXMKIF_HOST_CTL	*psSGXHostCtl = psDevInfo->psSGXHostCtl;
+		SGXMKIF_COMMAND		sCacheCommand = {0};
+
+		eError = SGXScheduleCCBCommand(psDeviceNode,
+									   SGXMKIF_CMD_PROCESS_QUEUES,
+									   &sCacheCommand,
+									   ui32CallerID,
+									   ui32PDumpFlags,
+									   hDevMemContext,
+									   bLastInScene);
+		if (eError != PVRSRV_OK)
+		{
+			goto Exit;
+		}
+
+		
+		#if !defined(NO_HARDWARE)
+		if(PollForValueKM(&psSGXHostCtl->ui32InvalStatus,
+						  PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+						  PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+						  2 * MAX_HW_TIME_US,
+						  MAX_HW_TIME_US/WAIT_TRY_COUNT,
+						  IMG_FALSE) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommand: Wait for uKernel to Invalidate BIF cache failed"));
+			PVR_DBG_BREAK;
+		}
+		#endif
+
+		#if defined(PDUMP)
+		
+		PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for BIF cache invalidate request to complete");
+		PDUMPMEMPOL(psSGXHostCtlMemInfo,
+					offsetof(SGXMKIF_HOST_CTL, ui32InvalStatus),
+					PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+					PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+					PDUMP_POLL_OPERATOR_EQUAL,
+					0,
+					MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+		#endif 
+
+		psSGXHostCtl->ui32InvalStatus &= ~(PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE);
+		PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+	}
+#else
+	PVR_UNREFERENCED_PARAMETER(hDevMemContext);
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+	if ((eCmdType != SGXMKIF_CMD_FLUSHPDCACHE) && (psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_BIF_PD))
+	{
+		SGXMKIF_COMMAND		sPDECacheCommand = {0};
+		IMG_DEV_PHYADDR		sDevPAddr;
+
+		
+		psMMUContext = psDevInfo->hKernelMMUContext;
+
+		psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr);
+		sPDECacheCommand.ui32Data[0] = sDevPAddr.uiAddr | 1;
+		sPDECacheCommand.ui32Data[1] = ui32CacheMasks[0];
+		sPDECacheCommand.ui32Data[2] = ui32CacheMasks[1];
+
+		
+		if (hDevMemContext)
+		{
+			BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext;
+
+			psMMUContext = psBMContext->psMMUContext;
+
+			psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr);
+			
+			sPDECacheCommand.ui32Data[3] = sDevPAddr.uiAddr | 1;
+			sPDECacheCommand.ui32Data[4] = ui32CacheMasks[2];
+			sPDECacheCommand.ui32Data[5] = ui32CacheMasks[3];
+		}
+
+		
+		if (sPDECacheCommand.ui32Data[1] | sPDECacheCommand.ui32Data[2] | sPDECacheCommand.ui32Data[4] |
+			sPDECacheCommand.ui32Data[5])
+		{
+			eError = SGXScheduleCCBCommand(psDeviceNode,
+										   SGXMKIF_CMD_FLUSHPDCACHE,
+										   &sPDECacheCommand,
+										   ui32CallerID,
+										   ui32PDumpFlags,
+										   hDevMemContext,
+										   bLastInScene);
+			if (eError != PVRSRV_OK)
+			{
+				goto Exit;
+			}
+		}
+	}
+#endif
+#if defined(PDUMP)
+	
+	{
+		PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+		if(psPerProc != IMG_NULL)
+		{
+			bPersistentProcess = psPerProc->bPDumpPersistent;
+		}
+	}
+#endif 
+	psKernelCCB = psDevInfo->psKernelCCBInfo;
+
+	psSGXCommand = SGXAcquireKernelCCBSlot(psKernelCCB);
+
+	
+	if(!psSGXCommand)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Wait for CCB space timed out")) ;
+		eError = PVRSRV_ERROR_TIMEOUT;
+		goto Exit;
+	}
+
+	
+	psCommandData->ui32CacheControl = psDevInfo->ui32CacheControl;
+
+#if defined(PDUMP)
+	
+	psDevInfo->sPDContext.ui32CacheControl |= psDevInfo->ui32CacheControl;
+#endif
+
+	
+	psDevInfo->ui32CacheControl = 0;
+
+	
+	*psSGXCommand = *psCommandData;
+
+	if (eCmdType >= SGXMKIF_CMD_MAX)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Unknown command type: %d", eCmdType)) ;
+		eError = PVRSRV_ERROR_INVALID_CCB_COMMAND;
+		goto Exit;
+	}
+
+	if ((eCmdType == SGXMKIF_CMD_TA) && bLastInScene)
+	{
+		SYS_DATA *psSysData;
+
+		
+		SysAcquireData(&psSysData);
+
+		if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+		{
+			OSFlushCPUCacheKM();
+		}
+		else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+		{
+			OSCleanCPUCacheKM();
+		}
+
+		
+		psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE;
+	}
+
+	PVR_ASSERT(eCmdType < SGXMKIF_CMD_MAX);
+	psSGXCommand->ui32ServiceAddress = psDevInfo->aui32HostKickAddr[eCmdType];	 
+
+#if defined(PDUMP)
+	if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) &&
+		(bPersistentProcess == IMG_FALSE) )
+	{
+		
+		PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for space in the Kernel CCB\r\n");
+		PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo,
+					offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset),
+					(psKernelCCB->ui32CCBDumpWOff + 1) & 0xff,
+					0xff,
+					PDUMP_POLL_OPERATOR_NOTEQUAL,
+					ui32PDumpFlags,
+					MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
+
+		PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB command (type == %d)\r\n", eCmdType);
+		pvDumpCommand = (IMG_VOID *)((IMG_UINT8 *)psKernelCCB->psCCBMemInfo->pvLinAddrKM + (*psKernelCCB->pui32WriteOffset * sizeof(SGXMKIF_COMMAND)));
+
+		PDUMPMEM(pvDumpCommand,
+					psKernelCCB->psCCBMemInfo,
+					psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND),
+					sizeof(SGXMKIF_COMMAND),
+					ui32PDumpFlags,
+					MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo));
+
+		
+		PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl,
+					psKernelCCB->psCCBMemInfo,
+					psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) +
+					offsetof(SGXMKIF_COMMAND, ui32CacheControl),
+					sizeof(IMG_UINT32),
+					ui32PDumpFlags,
+					MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo));
+
+		if (PDumpIsCaptureFrameKM()
+		|| ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+		{
+			
+			psDevInfo->sPDContext.ui32CacheControl = 0;
+		}
+	}
+#endif
+
+#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+	
+	eError = PollForValueKM (psKernelCCB->pui32ReadOffset,
+								*psKernelCCB->pui32WriteOffset,
+								0xFF,
+								MAX_HW_TIME_US,
+								MAX_HW_TIME_US/WAIT_TRY_COUNT,
+								IMG_FALSE);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Timeout waiting for previous command to be read")) ;
+		eError = PVRSRV_ERROR_TIMEOUT;
+		goto Exit;
+	}
+#endif
+
+	
+
+	*psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255;
+
+#if defined(PDUMP)
+	if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) &&
+		(bPersistentProcess == IMG_FALSE) )
+	{
+	#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+		PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for previous Kernel CCB CMD to be read\r\n");
+		PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo,
+					offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset),
+					(psKernelCCB->ui32CCBDumpWOff),
+					0xFF,
+					PDUMP_POLL_OPERATOR_EQUAL,
+					ui32PDumpFlags,
+					MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
+	#endif
+
+		if (PDumpIsCaptureFrameKM()
+		|| ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+		{
+			psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF;
+			psDevInfo->ui32KernelCCBEventKickerDumpVal = (psDevInfo->ui32KernelCCBEventKickerDumpVal + 1) & 0xFF;
+		}
+
+		PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB write offset\r\n");
+		PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff,
+				 psKernelCCB->psCCBCtlMemInfo,
+				 offsetof(PVRSRV_SGX_CCB_CTL, ui32WriteOffset),
+				 sizeof(IMG_UINT32),
+				 ui32PDumpFlags,
+				 MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
+		PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB event kicker\r\n");
+		PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
+				 psDevInfo->psKernelCCBEventKickerMemInfo,
+				 0,
+				 sizeof(IMG_UINT32),
+				 ui32PDumpFlags,
+				 MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+		PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kick the SGX microkernel\r\n");
+	#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+		PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, ui32PDumpFlags);
+	#else
+		PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, ui32PDumpFlags);
+	#endif
+	}
+#endif
+
+	*psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
+
+	OSWriteMemoryBarrier();
+
+	
+	PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE,
+			MKSYNC_TOKEN_KERNEL_CCB_OFFSET, *psKernelCCB->pui32WriteOffset);
+	PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE,
+			MKSYNC_TOKEN_CORE_CLK, psDevInfo->ui32CoreClockSpeed);
+	PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE,
+			MKSYNC_TOKEN_UKERNEL_CLK, psDevInfo->ui32uKernelTimerClock);
+
+
+#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+				SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0),
+				EUR_CR_EVENT_KICK2_NOW_MASK);
+#else
+	OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+				SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
+				EUR_CR_EVENT_KICK_NOW_MASK);
+#endif
+
+	OSMemoryBarrier();
+
+#if defined(NO_HARDWARE)
+	
+	*psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255;
+#endif
+
+Exit:
+	return eError;
+}
+
+
+PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE		*psDeviceNode,
+									 SGXMKIF_CMD_TYPE		eCmdType,
+									 SGXMKIF_COMMAND		*psCommandData,
+									 IMG_UINT32				ui32CallerID,
+									 IMG_UINT32				ui32PDumpFlags,
+									 IMG_HANDLE				hDevMemContext,
+									 IMG_BOOL				bLastInScene)
+{
+	PVRSRV_ERROR		eError;
+
+	
+	PDUMPSUSPEND();
+
+	
+	eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+										 PVRSRV_DEV_POWER_STATE_ON,
+										 ui32CallerID,
+										 IMG_TRUE);
+
+	PDUMPRESUME();
+
+	if (eError == PVRSRV_OK)
+	{
+		psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE;
+	}
+	else
+	{
+		if (eError == PVRSRV_ERROR_RETRY)
+		{
+			if (ui32CallerID == ISR_ID)
+			{
+				SYS_DATA *psSysData;
+				
+				
+
+
+				psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
+				eError = PVRSRV_OK;
+
+				SysAcquireData(&psSysData);
+				OSScheduleMISR(psSysData);
+			}
+			else
+			{
+				
+
+			}
+		}
+		else
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - "
+					 "ui32CallerID:%d eError:%u", ui32CallerID, eError));
+		}
+
+		return eError;
+	}
+
+	eError = SGXScheduleCCBCommand(psDeviceNode, eCmdType, psCommandData, ui32CallerID, ui32PDumpFlags, hDevMemContext, bLastInScene);
+
+	PVRSRVPowerUnlock(ui32CallerID);
+	return eError;
+}
+
+
+PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVRSRV_ERROR 		eError;
+	PVRSRV_SGXDEV_INFO 	*psDevInfo = psDeviceNode->pvDevice;
+	SGXMKIF_HOST_CTL	*psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
+	IMG_UINT32			ui32PowerStatus;
+	SGXMKIF_COMMAND		sCommand = {0};
+
+	ui32PowerStatus = psHostCtl->ui32PowerStatus;
+	if ((ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0)
+	{
+		
+		return PVRSRV_OK;
+	}
+
+	eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0, IMG_NULL, IMG_FALSE);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %u", eError));
+		return eError;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex);
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+									SGX_INTERNAL_DEVINFO_KM *psSGXInternalDevInfo)
+#else
+									SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo)
+#endif
+{
+	PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+	psSGXInternalDevInfo->ui32Flags = psDevInfo->ui32Flags;
+	psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff;
+
+	
+	psSGXInternalDevInfo->hHostCtlKernelMemInfoHandle =
+		(IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo;
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
+							   IMG_DEV_VIRTADDR   *psHWDataDevVAddr,
+							   IMG_UINT32          ui32CleanupType,
+							   IMG_BOOL            bForceCleanup)
+{
+	PVRSRV_ERROR			eError;
+	PVRSRV_SGXDEV_INFO		*psDevInfo = psDeviceNode->pvDevice;
+	PVRSRV_KERNEL_MEM_INFO	*psHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
+	SGXMKIF_HOST_CTL		*psHostCtl = psHostCtlMemInfo->pvLinAddrKM;
+
+	SGXMKIF_COMMAND		sCommand = {0};
+
+
+	if (bForceCleanup != FORCE_CLEANUP)
+	{
+		sCommand.ui32Data[0] = ui32CleanupType;
+		sCommand.ui32Data[1] = (psHWDataDevVAddr == IMG_NULL) ? 0 : psHWDataDevVAddr->uiAddr;
+		PDUMPCOMMENTWITHFLAGS(0, "Request ukernel resource clean-up, Type %u, Data 0x%X", sCommand.ui32Data[0], sCommand.ui32Data[1]);
+	
+		eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CLEANUP, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE);
+		if (eError != PVRSRV_OK)
+		{
+				PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command"));
+				PVR_DBG_BREAK;
+				return eError;
+		}
+		
+		
+		#if !defined(NO_HARDWARE)
+		if(PollForValueKM(&psHostCtl->ui32CleanupStatus,
+						  PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+						  PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+						  10 * MAX_HW_TIME_US,
+						  1000,
+						  IMG_TRUE) != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up (%u) failed", ui32CleanupType));
+			eError = PVRSRV_ERROR_TIMEOUT;
+			PVR_DBG_BREAK;
+		}
+		#endif
+	
+		#if defined(PDUMP)
+		
+		PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete");
+		PDUMPMEMPOL(psHostCtlMemInfo,
+					offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus),
+					PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+					PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+					PDUMP_POLL_OPERATOR_EQUAL,
+					0,
+					MAKEUNIQUETAG(psHostCtlMemInfo));
+		#endif 
+	
+		if (eError != PVRSRV_OK)
+		{
+			return eError;
+		}
+	}
+	
+	psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE);
+	PDUMPMEM(IMG_NULL, psHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHostCtlMemInfo));
+
+	
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+	psDevInfo->ui32CacheControl |= (SGXMKIF_CC_INVAL_BIF_SL | SGXMKIF_CC_INVAL_DATA);
+#else
+	psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_DATA;
+#endif
+	return PVRSRV_OK;
+}
+
+
+typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+    PVRSRV_KERNEL_MEM_INFO *psHWRenderContextMemInfo;
+    IMG_HANDLE hBlockAlloc;
+	PRESMAN_ITEM psResItem;
+} SGX_HW_RENDER_CONTEXT_CLEANUP;
+
+
+static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID		pvParam,
+													  IMG_UINT32	ui32Param,
+													  IMG_BOOL		bForceCleanup)
+{
+	PVRSRV_ERROR eError;
+	SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup = pvParam;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+	eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+					  &psCleanup->psHWRenderContextMemInfo->sDevVAddr,
+					  PVRSRV_CLEANUPCMD_RC,
+					  bForceCleanup);
+
+    
+    PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+            psCleanup->psHWRenderContextMemInfo);
+
+    
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+			  sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+			  psCleanup,
+			  psCleanup->hBlockAlloc);
+	
+
+	return eError;
+}
+
+typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+    PVRSRV_KERNEL_MEM_INFO *psHWTransferContextMemInfo;
+	IMG_HANDLE hBlockAlloc;
+	PRESMAN_ITEM psResItem;
+} SGX_HW_TRANSFER_CONTEXT_CLEANUP;
+
+
+static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID	pvParam,
+														IMG_UINT32	ui32Param,
+														IMG_BOOL	bForceCleanup)
+{
+	PVRSRV_ERROR eError;
+	SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+	eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+					  &psCleanup->psHWTransferContextMemInfo->sDevVAddr,
+					  PVRSRV_CLEANUPCMD_TC,
+					  bForceCleanup);
+
+    
+    PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+            psCleanup->psHWTransferContextMemInfo);
+
+    
+	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+			  sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+			  psCleanup,
+			  psCleanup->hBlockAlloc);
+	
+
+	return eError;
+}
+
+IMG_EXPORT
+IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE				hDeviceNode,
+                                        IMG_CPU_VIRTADDR        *psHWRenderContextCpuVAddr,
+                                        IMG_UINT32              ui32HWRenderContextSize,
+                                        IMG_UINT32              ui32OffsetToPDDevPAddr,
+                                        IMG_HANDLE              hDevMemContext,
+                                        IMG_DEV_VIRTADDR        *psHWRenderContextDevVAddr,
+										PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_ERROR eError;
+	IMG_HANDLE hBlockAlloc;
+	SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+    PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+	DEVICE_MEMORY_INFO	*psDevMemoryInfo;
+    DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+    IMG_HANDLE hDevMemContextInt;
+    MMU_CONTEXT *psMMUContext;
+    IMG_DEV_PHYADDR sPDDevPAddr;
+    int iPtrByte;
+    IMG_UINT8 *pSrc;
+    IMG_UINT8 *pDst;
+	PRESMAN_ITEM psResItem;
+
+	eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+						(IMG_VOID **)&psCleanup,
+						&hBlockAlloc,
+						"SGX Hardware Render Context Cleanup");
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure"));
+		goto exit0;
+	}
+
+	psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+    psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+    eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+                               psPerProc,
+                               psHeapInfo->hDevMemHeap,
+                               PVRSRV_MEM_READ | PVRSRV_MEM_WRITE 
+                                 | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT 
+                                 | PVRSRV_MEM_CACHE_CONSISTENT,
+                               ui32HWRenderContextSize,
+                               32,
+                               &psCleanup->psHWRenderContextMemInfo,
+                               "HW Render Context");
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate device memory for HW Render Context"));
+		goto exit1;
+	}
+
+    eError = OSCopyFromUser(psPerProc,
+                            psCleanup->psHWRenderContextMemInfo->pvLinAddrKM,
+                            psHWRenderContextCpuVAddr,
+                            ui32HWRenderContextSize);
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+		goto exit2;
+	}
+
+    
+    psHWRenderContextDevVAddr->uiAddr = psCleanup->psHWRenderContextMemInfo->sDevVAddr.uiAddr;
+
+    
+    eError = PVRSRVLookupHandle(psPerProc->psHandleBase, 
+                           &hDevMemContextInt,
+                           hDevMemContext,
+                           PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+    if (eError != PVRSRV_OK)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Can't lookup DevMem Context"));
+        goto exit2;
+    }
+
+    psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+    sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+    
+
+
+
+
+    pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+    pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM;
+    pDst += ui32OffsetToPDDevPAddr;
+
+    for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+    {
+        pDst[iPtrByte] = pSrc[iPtrByte];
+    }
+
+#if defined(PDUMP)
+    
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Render context struct");
+
+	PDUMPMEM(
+        IMG_NULL, 
+        psCleanup->psHWRenderContextMemInfo,
+        0, 
+        ui32HWRenderContextSize, 
+        PDUMP_FLAGS_CONTINUOUS, 
+        MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo));
+
+    
+	PDUMPCOMMENT("Page directory address in HW render context");
+    PDUMPPDDEVPADDR(
+            psCleanup->psHWRenderContextMemInfo,
+            ui32OffsetToPDDevPAddr,
+            sPDDevPAddr,
+            MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo),
+            PDUMP_PD_UNIQUETAG);
+#endif
+
+	psCleanup->hBlockAlloc = hBlockAlloc;
+	psCleanup->psDeviceNode = psDeviceNode;
+
+	psResItem = ResManRegisterRes(psPerProc->hResManContext,
+								  RESMAN_TYPE_HW_RENDER_CONTEXT,
+								  (IMG_VOID *)psCleanup,
+								  0,
+								  &SGXCleanupHWRenderContextCallback);
+
+    if (psResItem == IMG_NULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed"));
+        goto exit2;
+    }
+
+	psCleanup->psResItem = psResItem;
+
+	return (IMG_HANDLE)psCleanup;
+
+exit2:
+	 PVRSRVFreeDeviceMemKM(hDeviceNode,
+                           psCleanup->psHWRenderContextMemInfo);
+exit1:
+    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+              sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+              psCleanup,
+              psCleanup->hBlockAlloc);
+    
+exit0:
+    return IMG_NULL;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOOL bForceCleanup)
+{
+	PVRSRV_ERROR eError;
+	SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+
+	PVR_ASSERT(hHWRenderContext != IMG_NULL);
+
+	psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext;
+
+	if (psCleanup == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWRenderContextKM: invalid parameter"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup);
+
+	return eError;
+}
+
+
+IMG_EXPORT
+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE				hDeviceNode,
+                                          IMG_CPU_VIRTADDR          *psHWTransferContextCpuVAddr,
+                                          IMG_UINT32                ui32HWTransferContextSize,
+                                          IMG_UINT32                ui32OffsetToPDDevPAddr,
+                                          IMG_HANDLE                hDevMemContext,
+                                          IMG_DEV_VIRTADDR          *psHWTransferContextDevVAddr,
+										  PVRSRV_PER_PROCESS_DATA	*psPerProc)
+{
+	PVRSRV_ERROR eError;
+	IMG_HANDLE hBlockAlloc;
+	SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+    PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+	DEVICE_MEMORY_INFO	*psDevMemoryInfo;
+    DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+    IMG_HANDLE hDevMemContextInt;
+    MMU_CONTEXT *psMMUContext;
+    IMG_DEV_PHYADDR sPDDevPAddr;
+    int iPtrByte;
+    IMG_UINT8 *pSrc;
+    IMG_UINT8 *pDst;
+	PRESMAN_ITEM psResItem;
+
+	eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+						(IMG_VOID **)&psCleanup,
+						&hBlockAlloc,
+						"SGX Hardware Transfer Context Cleanup");
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure"));
+		goto exit0;
+	}
+
+	psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+    psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+    eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+                               psPerProc,
+                               psHeapInfo->hDevMemHeap,
+                               PVRSRV_MEM_READ | PVRSRV_MEM_WRITE 
+                                 | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT 
+                                 | PVRSRV_MEM_CACHE_CONSISTENT,
+                               ui32HWTransferContextSize,
+                               32,
+                               &psCleanup->psHWTransferContextMemInfo,
+                               "HW Render Context");
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate device memory for HW Render Context"));
+		goto exit1;
+	}
+
+    eError = OSCopyFromUser(psPerProc,
+                            psCleanup->psHWTransferContextMemInfo->pvLinAddrKM,
+                            psHWTransferContextCpuVAddr,
+                            ui32HWTransferContextSize);
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+		goto exit2;
+	}
+
+    
+    psHWTransferContextDevVAddr->uiAddr = psCleanup->psHWTransferContextMemInfo->sDevVAddr.uiAddr;
+
+    
+    eError = PVRSRVLookupHandle(psPerProc->psHandleBase, 
+                           &hDevMemContextInt,
+                           hDevMemContext,
+                           PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+    if (eError != PVRSRV_OK)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Can't lookup DevMem Context"));
+        goto exit2;
+    }
+
+    psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+    sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+    
+
+
+
+
+    pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+    pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM;
+    pDst += ui32OffsetToPDDevPAddr;
+
+    for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+    {
+        pDst[iPtrByte] = pSrc[iPtrByte];
+    }
+
+#if defined(PDUMP)
+    
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Transfer context struct");
+
+	PDUMPMEM(
+        IMG_NULL, 
+        psCleanup->psHWTransferContextMemInfo,
+        0, 
+        ui32HWTransferContextSize, 
+        PDUMP_FLAGS_CONTINUOUS, 
+        MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo));
+
+    
+	PDUMPCOMMENT("Page directory address in HW transfer context");
+
+    PDUMPPDDEVPADDR(
+            psCleanup->psHWTransferContextMemInfo,
+            ui32OffsetToPDDevPAddr,
+            sPDDevPAddr,
+            MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo),
+            PDUMP_PD_UNIQUETAG);
+#endif
+
+	psCleanup->hBlockAlloc = hBlockAlloc;
+	psCleanup->psDeviceNode = psDeviceNode;
+
+	psResItem = ResManRegisterRes(psPerProc->hResManContext,
+								  RESMAN_TYPE_HW_TRANSFER_CONTEXT,
+								  psCleanup,
+								  0,
+								  &SGXCleanupHWTransferContextCallback);
+
+	if (psResItem == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed"));
+        goto exit2;
+    }
+
+	psCleanup->psResItem = psResItem;
+
+	return (IMG_HANDLE)psCleanup;
+
+exit2:
+    PVRSRVFreeDeviceMemKM(hDeviceNode,
+            psCleanup->psHWTransferContextMemInfo);
+exit1:
+    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+              sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+              psCleanup,
+              psCleanup->hBlockAlloc);
+    
+
+exit0:
+    return IMG_NULL;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup)
+{
+	PVRSRV_ERROR eError;
+	SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+
+	PVR_ASSERT(hHWTransferContext != IMG_NULL);
+
+	psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext;
+
+	if (psCleanup == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWTransferContextKM: invalid parameter"));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup);
+
+	return eError;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXSetTransferContextPriorityKM(
+                IMG_HANDLE hDeviceNode,
+                IMG_HANDLE hHWTransferContext,
+                IMG_UINT32 ui32Priority,
+                IMG_UINT32 ui32OffsetOfPriorityField)
+{
+	SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+    IMG_UINT8 *pSrc;
+    IMG_UINT8 *pDst;
+    int iPtrByte;
+	PVR_UNREFERENCED_PARAMETER(hDeviceNode);
+
+    if (hHWTransferContext != IMG_NULL)
+    {
+        psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext;
+
+        if ((ui32OffsetOfPriorityField + sizeof(ui32Priority)) 
+            >= psCleanup->psHWTransferContextMemInfo->uAllocSize)
+        {
+            PVR_DPF((
+                PVR_DBG_ERROR, 
+                "SGXSetTransferContextPriorityKM: invalid context prioirty offset"));
+
+            return PVRSRV_ERROR_INVALID_PARAMS;
+        }
+
+        
+
+
+        pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM;
+        pDst += ui32OffsetOfPriorityField;
+        pSrc = (IMG_UINT8 *)&ui32Priority;
+
+        for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++)
+        {
+            pDst[iPtrByte] = pSrc[iPtrByte];
+        }
+    }
+    return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXSetRenderContextPriorityKM(
+                IMG_HANDLE hDeviceNode,
+                IMG_HANDLE hHWRenderContext,
+                IMG_UINT32 ui32Priority,
+                IMG_UINT32 ui32OffsetOfPriorityField)
+{
+	SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+    IMG_UINT8 *pSrc;
+    IMG_UINT8 *pDst;
+    int iPtrByte;
+	PVR_UNREFERENCED_PARAMETER(hDeviceNode);
+
+    if (hHWRenderContext != IMG_NULL)
+    {
+        psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext;
+        if ((ui32OffsetOfPriorityField + sizeof(ui32Priority)) 
+            >= psCleanup->psHWRenderContextMemInfo->uAllocSize)
+        {
+            PVR_DPF((
+                PVR_DBG_ERROR, 
+                "SGXSetContextPriorityKM: invalid HWRenderContext prioirty offset"));
+
+            return PVRSRV_ERROR_INVALID_PARAMS;
+        }
+
+        
+
+
+        pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM;
+        pDst += ui32OffsetOfPriorityField;
+
+        pSrc = (IMG_UINT8 *)&ui32Priority;
+
+        for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++)
+        {
+            pDst[iPtrByte] = pSrc[iPtrByte];
+        }
+    }
+    return PVRSRV_OK;
+}
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_
+{
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+	PVRSRV_KERNEL_MEM_INFO *psHW2DContextMemInfo;
+	IMG_HANDLE hBlockAlloc;
+	PRESMAN_ITEM psResItem;
+} SGX_HW_2D_CONTEXT_CLEANUP;
+
+static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID  pvParam,
+												  IMG_UINT32 ui32Param,
+												  IMG_BOOL   bForceCleanup)
+{
+	PVRSRV_ERROR eError;
+	SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+    
+    eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+					  &psCleanup->psHW2DContextMemInfo->sDevVAddr,
+					  PVRSRV_CLEANUPCMD_2DC,
+					  bForceCleanup);
+
+    
+    PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+            psCleanup->psHW2DContextMemInfo);
+
+    
+    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+			  sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+			  psCleanup,
+			  psCleanup->hBlockAlloc);
+                  
+
+	return eError;
+}
+
+IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE				hDeviceNode,
+                                    IMG_CPU_VIRTADDR        *psHW2DContextCpuVAddr,
+                                    IMG_UINT32              ui32HW2DContextSize,
+                                    IMG_UINT32              ui32OffsetToPDDevPAddr,
+                                    IMG_HANDLE              hDevMemContext,
+                                    IMG_DEV_VIRTADDR        *psHW2DContextDevVAddr,
+									PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	PVRSRV_ERROR eError;
+	IMG_HANDLE hBlockAlloc;
+	SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
+    PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+	DEVICE_MEMORY_INFO	*psDevMemoryInfo;
+    DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+    IMG_HANDLE hDevMemContextInt;
+    MMU_CONTEXT *psMMUContext;
+    IMG_DEV_PHYADDR sPDDevPAddr;
+    int iPtrByte;
+    IMG_UINT8 *pSrc;
+    IMG_UINT8 *pDst;
+	PRESMAN_ITEM psResItem;
+
+	eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+						sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+						(IMG_VOID **)&psCleanup,
+						&hBlockAlloc,
+						"SGX Hardware 2D Context Cleanup");
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure"));
+		goto exit0;
+	}
+
+	psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+    psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+    eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+                               psPerProc,
+                               psHeapInfo->hDevMemHeap,
+                               PVRSRV_MEM_READ | PVRSRV_MEM_WRITE 
+                                 | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT 
+                                 | PVRSRV_MEM_CACHE_CONSISTENT,
+                               ui32HW2DContextSize,
+                               32,
+                               &psCleanup->psHW2DContextMemInfo,
+                               "HW 2D Context");
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate device memory for HW Render Context"));
+		goto exit1;
+	}
+
+    eError = OSCopyFromUser(psPerProc,
+                            psCleanup->psHW2DContextMemInfo->pvLinAddrKM,
+                            psHW2DContextCpuVAddr,
+                            ui32HW2DContextSize);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+		goto exit2;
+	}
+ 
+    
+    psHW2DContextDevVAddr->uiAddr = psCleanup->psHW2DContextMemInfo->sDevVAddr.uiAddr;
+
+    
+    eError = PVRSRVLookupHandle(psPerProc->psHandleBase, 
+                           &hDevMemContextInt,
+                           hDevMemContext,
+                           PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+    if (eError != PVRSRV_OK)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Can't lookup DevMem Context"));
+        goto exit2;
+    }
+
+    psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+    sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+    
+
+
+
+
+    pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+    pDst = (IMG_UINT8 *)psCleanup->psHW2DContextMemInfo->pvLinAddrKM;
+    pDst += ui32OffsetToPDDevPAddr;
+
+    for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+    {
+        pDst[iPtrByte] = pSrc[iPtrByte];
+    }
+
+#if defined(PDUMP)
+    
+	PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW 2D context struct");
+
+	PDUMPMEM(
+        IMG_NULL, 
+        psCleanup->psHW2DContextMemInfo,
+        0, 
+        ui32HW2DContextSize, 
+        PDUMP_FLAGS_CONTINUOUS, 
+        MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo));
+
+    
+	PDUMPCOMMENT("Page directory address in HW 2D transfer context");
+    PDUMPPDDEVPADDR(
+            psCleanup->psHW2DContextMemInfo,
+            ui32OffsetToPDDevPAddr,
+            sPDDevPAddr,
+            MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo),
+            PDUMP_PD_UNIQUETAG);
+#endif
+
+	psCleanup->hBlockAlloc = hBlockAlloc;
+	psCleanup->psDeviceNode = psDeviceNode;
+
+	psResItem = ResManRegisterRes(psPerProc->hResManContext,
+								  RESMAN_TYPE_HW_2D_CONTEXT,
+								  psCleanup,
+								  0,
+								  &SGXCleanupHW2DContextCallback);
+
+	if (psResItem == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed"));
+        goto exit2;
+	}
+
+	psCleanup->psResItem = psResItem;
+
+	return (IMG_HANDLE)psCleanup;
+
+exit2:
+    PVRSRVFreeDeviceMemKM(hDeviceNode,
+                         psCleanup->psHW2DContextMemInfo);
+exit1:
+    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+              sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+              psCleanup,
+              psCleanup->hBlockAlloc);
+    
+exit0:
+    return IMG_NULL;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext, IMG_BOOL bForceCleanup)
+{
+	PVRSRV_ERROR eError;
+	SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
+
+	PVR_ASSERT(hHW2DContext != IMG_NULL);
+
+	if (hHW2DContext == IMG_NULL)
+	{
+		return (PVRSRV_ERROR_INVALID_PARAMS);
+	}
+
+	psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)hHW2DContext;
+
+	eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup);
+
+	return eError;
+}
+#endif 
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SGX2DQuerySyncOpsComplete)
+#endif
+static INLINE
+IMG_BOOL SGX2DQuerySyncOpsComplete(PVRSRV_KERNEL_SYNC_INFO	*psSyncInfo,
+								   IMG_UINT32				ui32ReadOpsPending,
+								   IMG_UINT32				ui32WriteOpsPending)
+{
+	PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData;
+
+	return (IMG_BOOL)(
+					  (psSyncData->ui32ReadOpsComplete >= ui32ReadOpsPending) &&
+					  (psSyncData->ui32WriteOpsComplete >= ui32WriteOpsPending)
+					 );
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO	*psDevInfo,
+									   PVRSRV_KERNEL_SYNC_INFO *psSyncInfo,
+									   IMG_BOOL bWaitForComplete)
+{
+	IMG_UINT32	ui32ReadOpsPending, ui32WriteOpsPending;
+
+	PVR_UNREFERENCED_PARAMETER(psDevInfo);
+
+	PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Start"));
+
+	ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending;
+	ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending;
+
+	if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending))
+	{
+		
+		PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Blits complete."));
+		return PVRSRV_OK;
+	}
+
+	
+	if (!bWaitForComplete)
+	{
+		
+		PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Ops pending."));
+		return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+	}
+
+	
+	PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling."));
+
+	LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+	{
+		OSSleepms(1);
+
+		if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending))
+		{
+			
+			PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over.  Blits complete."));
+			return PVRSRV_OK;
+		}
+
+		OSSleepms(1);
+	} END_LOOP_UNTIL_TIMEOUT();
+
+	
+	PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending."));
+
+#if defined(DEBUG)
+	{
+		PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData;
+
+		PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: 0x%x, Syncdata: 0x%x",
+				(IMG_UINTPTR_T)psSyncInfo, (IMG_UINTPTR_T)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;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode,
+									  IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr,
+									  IMG_BOOL bForceCleanup)
+{
+	PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL);
+
+	return SGXCleanupRequest(psDeviceNode,
+					  &sHWRTDataSetDevVAddr,
+					  PVRSRV_CLEANUPCMD_RT,
+					  bForceCleanup);
+}
+
+
+IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO	*psDevInfo,
+							   IMG_UINT32			ui32TimeWraps,
+							   IMG_UINT32			ui32Time)
+{
+#if defined(EUR_CR_TIMER)
+	PVR_UNREFERENCED_PARAMETER(psDevInfo);
+	PVR_UNREFERENCED_PARAMETER(ui32TimeWraps);
+	return ui32Time;
+#else
+	IMG_UINT64	ui64Clocks;
+	IMG_UINT32	ui32Clocksx16;
+
+	ui64Clocks = ((IMG_UINT64)ui32TimeWraps * psDevInfo->ui32uKernelTimerClock) +
+					(psDevInfo->ui32uKernelTimerClock - (ui32Time & EUR_CR_EVENT_TIMER_VALUE_MASK));
+	ui32Clocksx16 = (IMG_UINT32)(ui64Clocks / 16);
+
+	return ui32Clocksx16;
+#endif 
+}
+
+
+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO	*psDevInfo,
+					   IMG_UINT32			ui32SGXClocks)
+{
+	
+
+	OSWaitus(1 + (ui32SGXClocks * 1000000 / psDevInfo->ui32CoreClockSpeed));
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetSGXRevDataKM(PVRSRV_DEVICE_NODE* psDeviceNode, IMG_UINT32 *pui32SGXCoreRev,
+				IMG_UINT32 *pui32SGXCoreID)
+{
+	PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+	SGX_MISC_INFO sMiscInfo;
+	PVRSRV_ERROR eError;
+
+	sMiscInfo.eRequest = SGX_MISC_INFO_REQUEST_SGXREV;
+	eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, NULL);
+
+	*pui32SGXCoreRev = sMiscInfo.uData.sSGXFeatures.ui32CoreRev;
+	*pui32SGXCoreID = sMiscInfo.uData.sSGXFeatures.ui32CoreID;
+	return eError;
+}
+
+
+PVRSRV_ERROR SGXContextSuspend(PVRSRV_DEVICE_NODE	*psDeviceNode,
+							   IMG_DEV_VIRTADDR		*psHWContextDevVAddr,
+							   IMG_BOOL				bResume)
+{
+	PVRSRV_ERROR		eError;
+	SGXMKIF_COMMAND		sCommand = {0};
+
+	sCommand.ui32Data[0] = psHWContextDevVAddr->uiAddr;
+	sCommand.ui32Data[1] = bResume ? PVRSRV_CTXSUSPCMD_RESUME : PVRSRV_CTXSUSPCMD_SUSPEND;
+
+	eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CONTEXTSUSPEND, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SGXContextSuspend: Failed to submit context suspend command"));
+		return eError;
+	}
+
+	return eError;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxutils.h b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxutils.h
new file mode 100644
index 0000000..ae6dbc7
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/devices/sgx/sgxutils.h
@@ -0,0 +1,141 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "perproc.h"
+#include "sgxinfokm.h"
+
+ 
+#define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psCCBKick, offset) \
+	((sizeof(type) <= (psCCBMemInfo)->uAllocSize) && \
+	((psCCBKick)->offset <= (psCCBMemInfo)->uAllocSize - sizeof(type)))
+
+#define	CCB_DATA_FROM_OFFSET(type, psCCBMemInfo, psCCBKick, offset) \
+	((type *)(((IMG_CHAR *)(psCCBMemInfo)->pvLinAddrKM) + \
+		(psCCBKick)->offset))
+
+
+IMG_IMPORT
+IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE	*psDeviceNode,
+								 IMG_UINT32			ui32CallerID);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE	*psDeviceNode,
+								   SGXMKIF_CMD_TYPE		eCommandType,
+								   SGXMKIF_COMMAND		*psCommandData,
+								   IMG_UINT32			ui32CallerID,
+								   IMG_UINT32			ui32PDumpFlags,
+								   IMG_HANDLE			hDevMemContext,
+								   IMG_BOOL				bLastInScene);
+IMG_IMPORT
+PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE		*psDeviceNode,
+									 SGXMKIF_CMD_TYPE		eCommandType,
+									 SGXMKIF_COMMAND		*psCommandData,
+									 IMG_UINT32				ui32CallerID,
+									 IMG_UINT32				ui32PDumpFlags,
+									 IMG_HANDLE				hDevMemContext,
+									 IMG_BOOL				bLastInScene);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_IMPORT
+IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_IMPORT
+IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE				psDeviceNode,
+                                        IMG_CPU_VIRTADDR        *psHWRenderContextCpuVAddr,
+                                        IMG_UINT32              ui32HWRenderContextSize,
+                                        IMG_UINT32              ui32OffsetToPDDevPAddr,
+                                        IMG_HANDLE              hDevMemContext,
+                                        IMG_DEV_VIRTADDR        *psHWRenderContextDevVAddr,
+										PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+IMG_IMPORT
+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE		      psDeviceNode,
+                                          IMG_CPU_VIRTADDR        *psHWTransferContextCpuVAddr,
+                                          IMG_UINT32              ui32HWTransferContextSize,
+                                          IMG_UINT32              ui32OffsetToPDDevPAddr,
+                                          IMG_HANDLE              hDevMemContext,
+                                          IMG_DEV_VIRTADDR        *psHWTransferContextDevVAddr,
+										  PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psSGXDevInfo,
+									  IMG_DEV_VIRTADDR psHWRTDataSetDevVAddr,
+									  IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXSetRenderContextPriorityKM(IMG_HANDLE       hDeviceNode,
+                                           IMG_HANDLE       hHWRenderContext,
+                                           IMG_UINT32       ui32Priority,
+                                           IMG_UINT32       ui32OffsetOfPriorityField);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXSetTransferContextPriorityKM(IMG_HANDLE       hDeviceNode,
+                                             IMG_HANDLE       hHWTransferContext,
+                                             IMG_UINT32       ui32Priority,
+                                             IMG_UINT32       ui32OffsetOfPriorityField);
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+IMG_IMPORT
+IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE				psDeviceNode,
+                                    IMG_CPU_VIRTADDR        *psHW2DContextCpuVAddr,
+                                    IMG_UINT32              ui32HW2DContextSize,
+                                    IMG_UINT32              ui32OffsetToPDDevPAddr,
+                                    IMG_HANDLE              hDevMemContext,
+                                    IMG_DEV_VIRTADDR        *psHW2DContextDevVAddr,
+									PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext, IMG_BOOL bForceCleanup);
+#endif
+
+IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO	*psDevInfo,
+							   IMG_UINT32			ui32TimeWraps,
+							   IMG_UINT32			ui32Time);
+
+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO	*psDevInfo,
+					   IMG_UINT32			ui32SGXClocks);
+
+PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE	*psDeviceNode,
+							IMG_DEV_VIRTADDR	*psHWDataDevVAddr,
+							IMG_UINT32			ui32CleanupType,
+							IMG_BOOL			bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetSGXRevDataKM(PVRSRV_DEVICE_NODE* psDeviceNode, IMG_UINT32 *pui32SGXCoreRev,
+				IMG_UINT32 *pui32SGXCoreID);
+
+PVRSRV_ERROR SGXContextSuspend(PVRSRV_DEVICE_NODE	*psDeviceNode,
+							   IMG_DEV_VIRTADDR		*psHWContextDevVAddr,
+							   IMG_BOOL				bResume);
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/.gitignore b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/.gitignore
new file mode 100644
index 0000000..2f89523
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/.gitignore
@@ -0,0 +1,5 @@
+bin_pc_i686*
+tmp_pc_i686*
+host_pc_i686*
+*.o
+*.o.cmd
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/env_data.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/env_data.h
new file mode 100644
index 0000000..7716529
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/env_data.h
@@ -0,0 +1,66 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _ENV_DATA_
+#define _ENV_DATA_
+
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+#include <linux/workqueue.h>
+#endif
+
+#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
+{
+	IMG_VOID		*pvBridgeData;
+	struct pm_dev		*psPowerDevice;
+	IMG_BOOL		bLISRInstalled;
+	IMG_BOOL		bMISRInstalled;
+	IMG_UINT32		ui32IRQ;
+	IMG_VOID		*pvISRCookie;
+#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+	struct workqueue_struct	*psWorkQueue;
+#endif
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+	struct work_struct	sMISRWork;
+	IMG_VOID		*pvMISRData;
+#else
+	struct tasklet_struct	sMISRTasklet;
+#endif
+} ENV_DATA;
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/env_perproc.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/env_perproc.h
new file mode 100644
index 0000000..dabf1e3
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/env_perproc.h
@@ -0,0 +1,56 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __ENV_PERPROC_H__
+#define __ENV_PERPROC_H__
+
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+
+#include "services.h"
+#include "handle.h"
+
+typedef struct _PVRSRV_ENV_PER_PROCESS_DATA_
+{
+	IMG_HANDLE hBlockAlloc;
+	struct proc_dir_entry *psProcDir;
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+	struct list_head sDRMAuthListHead;
+#endif
+} PVRSRV_ENV_PER_PROCESS_DATA;
+
+IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
+
+PVRSRV_ERROR LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
+
+IMG_VOID LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
+ 
+PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
+
+IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID);
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/event.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/event.c
new file mode 100644
index 0000000..7e160c3
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/event.c
@@ -0,0 +1,293 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/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/spinlock.h>
+#include <linux/timer.h>
+#include <linux/capability.h>
+#include <linux/sched.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"
+#include "lock.h"
+#include "event.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
+{
+   	atomic_t	sTimeStamp;
+   	IMG_UINT32  ui32TimeStampPrevious;
+#if defined(DEBUG)
+	IMG_UINT	ui32Stats;
+#endif
+    wait_queue_head_t sWait;	
+	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 *psEventObjectList;
+
+	if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), 
+		(IMG_VOID **)&psEventObjectList, IMG_NULL,
+		"Linux Event Object List") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list"));		
+		return PVRSRV_ERROR_OUT_OF_MEMORY;	
+	}
+
+	INIT_LIST_HEAD(&psEventObjectList->sList);
+
+	rwlock_init(&psEventObjectList->sLock);
+	
+	*phEventObjectList = (IMG_HANDLE *) psEventObjectList;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList)
+{
+
+	PVRSRV_LINUX_EVENT_OBJECT_LIST *psEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList ;
+
+	if(psEventObjectList)	
+	{
+		IMG_BOOL bListEmpty;
+
+		read_lock(&psEventObjectList->sLock);
+		bListEmpty = list_empty(&psEventObjectList->sList);
+		read_unlock(&psEventObjectList->sLock);
+
+		if (!bListEmpty) 
+		{
+			 PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty"));
+			 return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+		}
+
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), psEventObjectList, IMG_NULL);
+		
+	}
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject)
+{
+	if(hOSEventObjectList)
+	{
+		if(hOSEventObject)
+		{
+			PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject; 
+#if defined(DEBUG)
+			PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectListDelete: Event object waits: %u", psLinuxEventObject->ui32Stats));
+#endif
+			if(ResManFreeResByPtr(psLinuxEventObject->hResItem, CLEANUP_WITH_POLL) != PVRSRV_OK)
+			{
+				return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+			}
+			
+			return PVRSRV_OK;
+		}
+	}
+	return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+
+}
+
+static PVRSRV_ERROR LinuxEventObjectDeleteCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bForceCleanup)
+{
+	PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = pvParam;
+	PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList;
+	unsigned long ulLockFlags;
+
+	PVR_UNREFERENCED_PARAMETER(ui32Param);
+	PVR_UNREFERENCED_PARAMETER(bForceCleanup);
+
+	write_lock_irqsave(&psLinuxEventObjectList->sLock, ulLockFlags);
+	list_del(&psLinuxEventObject->sList);
+	write_unlock_irqrestore(&psLinuxEventObjectList->sLock, ulLockFlags);
+
+#if defined(DEBUG)
+	PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDeleteCallback: Event object waits: %u", psLinuxEventObject->ui32Stats));
+#endif	
+
+	OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), psLinuxEventObject, IMG_NULL);
+	
+
+	return PVRSRV_OK;
+}
+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; 
+	IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+	PVRSRV_PER_PROCESS_DATA *psPerProc;
+	unsigned long ulLockFlags;
+
+	psPerProc = PVRSRVPerProcessData(ui32PID);
+	if (psPerProc == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: Couldn't find per-process data"));
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	
+	if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), 
+		(IMG_VOID **)&psLinuxEventObject, IMG_NULL,
+		"Linux Event Object") != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory "));		
+		return PVRSRV_ERROR_OUT_OF_MEMORY;	
+	}
+	
+	INIT_LIST_HEAD(&psLinuxEventObject->sList);
+
+	atomic_set(&psLinuxEventObject->sTimeStamp, 0);
+	psLinuxEventObject->ui32TimeStampPrevious = 0;
+
+#if defined(DEBUG)
+	psLinuxEventObject->ui32Stats = 0;
+#endif
+    init_waitqueue_head(&psLinuxEventObject->sWait);
+
+	psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList;
+
+	psLinuxEventObject->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+													 RESMAN_TYPE_EVENT_OBJECT,
+													 psLinuxEventObject,
+													 0,
+													 &LinuxEventObjectDeleteCallback);	
+
+	write_lock_irqsave(&psLinuxEventObjectList->sLock, ulLockFlags);
+	list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList);
+	write_unlock_irqrestore(&psLinuxEventObjectList->sLock, ulLockFlags);
+	
+	*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, *psList;
+
+	psList = &psLinuxEventObjectList->sList;
+
+	
+	read_lock(&psLinuxEventObjectList->sLock);
+	list_for_each(psListEntry, psList) 
+	{       	
+
+		psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList);	
+		
+		atomic_inc(&psLinuxEventObject->sTimeStamp);	
+	 	wake_up_interruptible(&psLinuxEventObject->sWait);
+	}
+	read_unlock(&psLinuxEventObjectList->sLock);
+
+	return 	PVRSRV_OK;
+  	
+}
+
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout)
+{
+	IMG_UINT32 ui32TimeStamp;
+	DEFINE_WAIT(sWait);
+
+	PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject;
+
+	IMG_UINT32 ui32TimeOutJiffies = msecs_to_jiffies(ui32MSTimeout);
+	
+	do	
+	{
+		prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE);
+		ui32TimeStamp = (IMG_UINT32)atomic_read(&psLinuxEventObject->sTimeStamp);
+   	
+		if(psLinuxEventObject->ui32TimeStampPrevious != ui32TimeStamp)
+		{
+			break;
+		}
+
+		LinuxUnLockMutex(&gPVRSRVLock);		
+
+		ui32TimeOutJiffies = (IMG_UINT32)schedule_timeout((IMG_INT32)ui32TimeOutJiffies);
+		
+		LinuxLockMutex(&gPVRSRVLock);
+#if defined(DEBUG)
+		psLinuxEventObject->ui32Stats++;
+#endif			
+
+		
+	} while (ui32TimeOutJiffies);
+
+	finish_wait(&psLinuxEventObject->sWait, &sWait);	
+
+	psLinuxEventObject->ui32TimeStampPrevious = ui32TimeStamp;
+
+	return ui32TimeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT;
+
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/event.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/event.h
new file mode 100644
index 0000000..3035283
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/event.h
@@ -0,0 +1,32 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+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);
+PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList);
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout);
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/linkage.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/linkage.h
new file mode 100644
index 0000000..e64012c
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/linkage.h
@@ -0,0 +1,52 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __LINKAGE_H__
+#define __LINKAGE_H__
+
+#if !defined(SUPPORT_DRI_DRM)
+long PVRSRV_BridgeDispatchKM(struct file *file, unsigned int cmd, unsigned long arg);
+#endif
+
+IMG_VOID PVRDPFInit(IMG_VOID);
+PVRSRV_ERROR PVROSFuncInit(IMG_VOID);
+IMG_VOID PVROSFuncDeInit(IMG_VOID);
+
+#ifdef DEBUG
+
+IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
+void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el);
+
+#ifdef PVR_MANUAL_POWER_CONTROL
+IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
+
+void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el);
+
+#endif 
+
+#endif	
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/lock.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/lock.h
new file mode 100644
index 0000000..a0854c3
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/lock.h
@@ -0,0 +1,32 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __LOCK_H__
+#define __LOCK_H__
+
+extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mm.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mm.c
new file mode 100644
index 0000000..a96d28c
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mm.c
@@ -0,0 +1,2027 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#include <linux/wrapper.h>
+#endif
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/sched.h>
+
+#include "img_defs.h"
+#include "services.h"
+#include "servicesint.h"
+#include "syscommon.h"
+#include "mutils.h"
+#include "mm.h"
+#include "pvrmmap.h"
+#include "mmap.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+#include "proc.h"
+#include "mutex.h"
+#include "lock.h"
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+	#include "lists.h"
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+typedef enum {
+    DEBUG_MEM_ALLOC_TYPE_KMALLOC,
+    DEBUG_MEM_ALLOC_TYPE_VMALLOC,
+    DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
+    DEBUG_MEM_ALLOC_TYPE_IOREMAP,
+    DEBUG_MEM_ALLOC_TYPE_IO,
+    DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE,
+    DEBUG_MEM_ALLOC_TYPE_COUNT
+}DEBUG_MEM_ALLOC_TYPE;
+
+typedef struct _DEBUG_MEM_ALLOC_REC
+{
+    DEBUG_MEM_ALLOC_TYPE    eAllocType;
+	IMG_VOID				*pvKey; 
+    IMG_VOID                *pvCpuVAddr;
+    IMG_UINT32              ulCpuPAddr;
+    IMG_VOID                *pvPrivateData;
+	IMG_UINT32				ui32Bytes;
+	pid_t					pid;
+    IMG_CHAR                *pszFileName;
+    IMG_UINT32              ui32Line;
+    
+    struct _DEBUG_MEM_ALLOC_REC   *psNext;
+	struct _DEBUG_MEM_ALLOC_REC   **ppsThis;
+}DEBUG_MEM_ALLOC_REC;
+
+static IMPLEMENT_LIST_ANY_VA_2(DEBUG_MEM_ALLOC_REC, IMG_BOOL, IMG_FALSE)
+static IMPLEMENT_LIST_ANY_VA(DEBUG_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_FOR_EACH(DEBUG_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_INSERT(DEBUG_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_REMOVE(DEBUG_MEM_ALLOC_REC)
+
+
+static DEBUG_MEM_ALLOC_REC *g_MemoryRecords;
+
+static IMG_UINT32 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
+static IMG_UINT32 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
+
+static IMG_UINT32 g_SysRAMWaterMark;
+static IMG_UINT32 g_SysRAMHighWaterMark;
+
+static IMG_UINT32 g_IOMemWaterMark;
+static IMG_UINT32 g_IOMemHighWaterMark;
+
+static IMG_VOID DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType,
+                                       IMG_VOID *pvKey,
+                                       IMG_VOID *pvCpuVAddr,
+                                       IMG_UINT32 ulCpuPAddr,
+                                       IMG_VOID *pvPrivateData,
+                                       IMG_UINT32 ui32Bytes,
+                                       IMG_CHAR *pszFileName,
+                                       IMG_UINT32 ui32Line);
+
+static IMG_VOID DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+static IMG_CHAR *DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType);
+
+
+static struct proc_dir_entry *g_SeqFileMemoryRecords =0;
+static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off);
+static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementMemoryRecords(struct seq_file * sfile, loff_t off);
+
+#endif
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+typedef struct _DEBUG_LINUX_MEM_AREA_REC
+{
+	LinuxMemArea                *psLinuxMemArea;
+    IMG_UINT32                  ui32Flags;
+	pid_t					    pid;
+
+	struct _DEBUG_LINUX_MEM_AREA_REC  *psNext;
+	struct _DEBUG_LINUX_MEM_AREA_REC  **ppsThis;
+}DEBUG_LINUX_MEM_AREA_REC;
+
+
+static IMPLEMENT_LIST_ANY_VA(DEBUG_LINUX_MEM_AREA_REC)
+static IMPLEMENT_LIST_FOR_EACH(DEBUG_LINUX_MEM_AREA_REC)
+static IMPLEMENT_LIST_INSERT(DEBUG_LINUX_MEM_AREA_REC)
+static IMPLEMENT_LIST_REMOVE(DEBUG_LINUX_MEM_AREA_REC)
+
+
+
+
+static DEBUG_LINUX_MEM_AREA_REC *g_LinuxMemAreaRecords;
+static IMG_UINT32 g_LinuxMemAreaCount;
+static IMG_UINT32 g_LinuxMemAreaWaterMark;
+static IMG_UINT32 g_LinuxMemAreaHighWaterMark;
+
+
+static struct proc_dir_entry *g_SeqFileMemArea=0;
+
+static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off);
+static void ProcSeqShowMemArea(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementMemArea(struct seq_file *sfile, loff_t off);
+
+#endif
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static PVRSRV_LINUX_MUTEX g_sDebugMutex;
+#endif
+
+#if (defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS))
+static void ProcSeqStartstopDebugMutex(struct seq_file *sfile,IMG_BOOL start);
+#endif
+
+static LinuxKMemCache *psLinuxMemAreaCache;
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+static IMG_VOID ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length);
+static IMG_VOID UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length);
+#endif
+
+static LinuxMemArea *LinuxMemAreaStructAlloc(IMG_VOID);
+static IMG_VOID LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea);
+#if defined(DEBUG_LINUX_MEM_AREAS)
+static IMG_VOID DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags);
+static DEBUG_LINUX_MEM_AREA_REC *DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea);
+static IMG_VOID DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea);
+#endif
+
+PVRSRV_ERROR
+LinuxMMInit(IMG_VOID)
+{
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+	LinuxInitMutex(&g_sDebugMutex);
+#endif
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    {
+		g_SeqFileMemArea = CreateProcReadEntrySeq(
+									"mem_areas", 
+									NULL, 
+									ProcSeqNextMemArea,
+									ProcSeqShowMemArea,
+									ProcSeqOff2ElementMemArea,
+									ProcSeqStartstopDebugMutex
+								   );
+		if(!g_SeqFileMemArea)
+        {
+            return PVRSRV_ERROR_OUT_OF_MEMORY;
+        }
+    }
+#endif
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    {
+		g_SeqFileMemoryRecords =CreateProcReadEntrySeq(
+									"meminfo", 
+									NULL, 
+									ProcSeqNextMemoryRecords,
+									ProcSeqShowMemoryRecords, 
+									ProcSeqOff2ElementMemoryRecords,
+									ProcSeqStartstopDebugMutex
+								   );
+        if(!g_SeqFileMemoryRecords)
+        {
+            return PVRSRV_ERROR_OUT_OF_MEMORY;
+        }
+    }
+#endif
+
+    psLinuxMemAreaCache = KMemCacheCreateWrapper("img-mm", sizeof(LinuxMemArea), 0, 0);
+    if(!psLinuxMemAreaCache)
+    {
+        PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__));
+        return PVRSRV_ERROR_OUT_OF_MEMORY;
+    }
+
+    return PVRSRV_OK;
+}
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+static IMG_VOID LinuxMMCleanup_MemAreas_ForEachCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord)
+{
+	LinuxMemArea *psLinuxMemArea;
+
+	psLinuxMemArea = psCurrentRecord->psLinuxMemArea;
+	PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up Linux memory area (%p), type=%s, size=%d bytes",
+				__FUNCTION__,
+				psCurrentRecord->psLinuxMemArea,
+				LinuxMemAreaTypeToString(psCurrentRecord->psLinuxMemArea->eAreaType),
+				psCurrentRecord->psLinuxMemArea->ui32ByteSize));
+	
+	LinuxMemAreaDeepFree(psLinuxMemArea);
+}
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static IMG_VOID LinuxMMCleanup_MemRecords_ForEachVa(DEBUG_MEM_ALLOC_REC *psCurrentRecord)
+
+{
+	
+	PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: "
+							"type=%s "
+							"CpuVAddr=%p "
+							"CpuPAddr=0x%08x, "
+							"allocated @ file=%s,line=%d",
+			__FUNCTION__,
+			DebugMemAllocRecordTypeToString(psCurrentRecord->eAllocType),
+			psCurrentRecord->pvCpuVAddr,
+			psCurrentRecord->ulCpuPAddr,
+			psCurrentRecord->pszFileName,
+			psCurrentRecord->ui32Line));
+	switch(psCurrentRecord->eAllocType)
+	{
+		case DEBUG_MEM_ALLOC_TYPE_KMALLOC:
+			KFreeWrapper(psCurrentRecord->pvCpuVAddr);
+			break;
+		case DEBUG_MEM_ALLOC_TYPE_IOREMAP:
+			IOUnmapWrapper(psCurrentRecord->pvCpuVAddr);
+			break;
+		case DEBUG_MEM_ALLOC_TYPE_IO:
+			
+			DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, psCurrentRecord->pvKey, __FILE__, __LINE__);
+			break;
+		case DEBUG_MEM_ALLOC_TYPE_VMALLOC:
+			VFreeWrapper(psCurrentRecord->pvCpuVAddr);
+			break;
+		case DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES:
+			
+			DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, psCurrentRecord->pvKey, __FILE__, __LINE__);
+			break;
+		case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE:
+			KMemCacheFreeWrapper(psCurrentRecord->pvPrivateData, psCurrentRecord->pvCpuVAddr);
+			break;
+		default:
+			PVR_ASSERT(0);
+	}
+}
+#endif
+
+
+IMG_VOID
+LinuxMMCleanup(IMG_VOID)
+{
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    {
+        if(g_LinuxMemAreaCount)
+        {
+            PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: There are %d LinuxMemArea allocation unfreed (%d bytes)",
+                    __FUNCTION__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark));
+        }
+		
+		List_DEBUG_LINUX_MEM_AREA_REC_ForEach(g_LinuxMemAreaRecords,
+											LinuxMMCleanup_MemAreas_ForEachCb);
+
+		RemoveProcEntrySeq( g_SeqFileMemArea );
+    }
+#endif
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    {
+        
+        
+		List_DEBUG_MEM_ALLOC_REC_ForEach(g_MemoryRecords,
+										LinuxMMCleanup_MemRecords_ForEachVa);
+
+		RemoveProcEntrySeq( g_SeqFileMemoryRecords );
+    }
+#endif
+
+    if(psLinuxMemAreaCache)
+    {
+        KMemCacheDestroyWrapper(psLinuxMemAreaCache); 
+        psLinuxMemAreaCache=NULL;
+    }
+}
+
+
+IMG_VOID *
+_KMallocWrapper(IMG_UINT32 ui32ByteSize, gfp_t uFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+    IMG_VOID *pvRet;
+    pvRet = kmalloc(ui32ByteSize, uFlags);
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    if(pvRet)
+    {
+        DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMALLOC,
+                               pvRet,
+                               pvRet,
+                               0,
+                               NULL,
+                               ui32ByteSize,
+                               pszFileName,
+                               ui32Line
+                               );
+    }
+#else
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+    return pvRet;
+}
+
+
+IMG_VOID
+_KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMALLOC, pvCpuVAddr, pszFileName,  ui32Line);
+#else
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+    kfree(pvCpuVAddr);
+}
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static IMG_VOID
+DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType,
+                       IMG_VOID *pvKey,
+                       IMG_VOID *pvCpuVAddr,
+                       IMG_UINT32 ulCpuPAddr,
+                       IMG_VOID *pvPrivateData,
+                       IMG_UINT32 ui32Bytes,
+                       IMG_CHAR *pszFileName,
+                       IMG_UINT32 ui32Line)
+{
+    DEBUG_MEM_ALLOC_REC *psRecord;
+
+
+    LinuxLockMutex(&g_sDebugMutex);
+    psRecord = kzalloc(sizeof(DEBUG_MEM_ALLOC_REC), GFP_KERNEL);
+    if (psRecord == NULL) {
+	/* If it can't allocate memory, it means that we can't
+	 * record the usage of memory. So skip it as
+	 * it is harmless.
+	 */
+    	LinuxUnLockMutex(&g_sDebugMutex);
+	PVR_DPF((PVR_DBG_ERROR,
+			"%s: failed to allocate linux memory record.",
+		__func__));
+	return;
+    }
+
+    psRecord->eAllocType = eAllocType;
+    psRecord->pvKey = pvKey;
+    psRecord->pvCpuVAddr = pvCpuVAddr;
+    psRecord->ulCpuPAddr = ulCpuPAddr;
+    psRecord->pvPrivateData = pvPrivateData;
+    psRecord->pid = OSGetCurrentProcessIDKM();
+    psRecord->ui32Bytes = ui32Bytes;
+    psRecord->pszFileName = pszFileName;
+    psRecord->ui32Line = ui32Line;
+    
+	List_DEBUG_MEM_ALLOC_REC_Insert(&g_MemoryRecords, psRecord);
+    
+    g_WaterMarkData[eAllocType] += ui32Bytes;
+    if(g_WaterMarkData[eAllocType] > g_HighWaterMarkData[eAllocType])
+    {
+        g_HighWaterMarkData[eAllocType] = g_WaterMarkData[eAllocType];
+    }
+
+    if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
+       || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
+       || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
+       || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
+    {
+        g_SysRAMWaterMark += ui32Bytes;
+        if(g_SysRAMWaterMark > g_SysRAMHighWaterMark)
+        {
+            g_SysRAMHighWaterMark = g_SysRAMWaterMark;
+        }
+    }
+    else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
+            || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
+    {
+        g_IOMemWaterMark += ui32Bytes;
+        if(g_IOMemWaterMark > g_IOMemHighWaterMark)
+        {
+            g_IOMemHighWaterMark = g_IOMemWaterMark;
+        }
+    }
+
+    LinuxUnLockMutex(&g_sDebugMutex);
+}
+
+
+static IMG_BOOL DebugMemAllocRecordRemove_AnyVaCb(DEBUG_MEM_ALLOC_REC *psCurrentRecord, va_list va)
+{
+	DEBUG_MEM_ALLOC_TYPE eAllocType;
+	IMG_VOID *pvKey;
+	
+	eAllocType = va_arg(va, DEBUG_MEM_ALLOC_TYPE);
+	pvKey = va_arg(va, IMG_VOID*);
+
+	if(psCurrentRecord->eAllocType == eAllocType
+		&& psCurrentRecord->pvKey == pvKey)
+	{
+		eAllocType = psCurrentRecord->eAllocType;
+		g_WaterMarkData[eAllocType] -= psCurrentRecord->ui32Bytes;
+		
+		if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
+		   || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
+		   || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
+		   || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
+		{
+			g_SysRAMWaterMark -= psCurrentRecord->ui32Bytes;
+		}
+		else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
+				|| eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
+		{
+			g_IOMemWaterMark -= psCurrentRecord->ui32Bytes;
+		}
+		
+		List_DEBUG_MEM_ALLOC_REC_Remove(psCurrentRecord);
+		kfree(psCurrentRecord);
+
+		return IMG_TRUE;
+	}
+	else
+	{
+		return IMG_FALSE;
+	}
+}
+
+
+static IMG_VOID
+DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+    LinuxLockMutex(&g_sDebugMutex);
+
+    
+	if(!List_DEBUG_MEM_ALLOC_REC_IMG_BOOL_Any_va(g_MemoryRecords,
+												DebugMemAllocRecordRemove_AnyVaCb,
+												eAllocType,
+												pvKey))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for type=%s with pvKey=%p (called from %s, line %d\n",
+		__FUNCTION__, DebugMemAllocRecordTypeToString(eAllocType), pvKey,
+		pszFileName, ui32Line));
+	}
+
+    LinuxUnLockMutex(&g_sDebugMutex);
+}
+
+
+static IMG_CHAR *
+DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType)
+{
+    IMG_CHAR *apszDebugMemoryRecordTypes[] = {
+        "KMALLOC",
+        "VMALLOC",
+        "ALLOC_PAGES",
+        "IOREMAP",
+        "IO",
+        "KMEM_CACHE_ALLOC"
+    };
+    return apszDebugMemoryRecordTypes[eAllocType];
+}
+#endif
+
+
+
+IMG_VOID *
+_VMallocWrapper(IMG_UINT32 ui32Bytes,
+                IMG_UINT32 ui32AllocFlags,
+                IMG_CHAR *pszFileName,
+                IMG_UINT32 ui32Line)
+{
+    pgprot_t PGProtFlags;
+    IMG_VOID *pvRet;
+    
+    switch(ui32AllocFlags & PVRSRV_HAP_CACHETYPE_MASK)
+    {
+        case PVRSRV_HAP_CACHED:
+            PGProtFlags = PAGE_KERNEL;
+            break;
+        case PVRSRV_HAP_WRITECOMBINE:
+            PGProtFlags = PGPROT_WC(PAGE_KERNEL);
+            break;
+        case PVRSRV_HAP_UNCACHED:
+            PGProtFlags = PGPROT_UC(PAGE_KERNEL);
+            break;
+        default:
+            PVR_DPF((PVR_DBG_ERROR,
+                     "VMAllocWrapper: unknown mapping flags=0x%08x",
+                     ui32AllocFlags));
+            dump_stack();
+            return NULL;
+    }
+
+	
+    pvRet = __vmalloc(ui32Bytes, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PGProtFlags);
+    
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    if(pvRet)
+    {
+        DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMALLOC,
+                               pvRet,
+                               pvRet,
+                               0,
+                               NULL,
+                               PAGE_ALIGN(ui32Bytes),
+                               pszFileName,
+                               ui32Line
+                               );
+    }
+#else
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+    return pvRet;
+}
+
+
+IMG_VOID
+_VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMALLOC, pvCpuVAddr, pszFileName, ui32Line);
+#else
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+    vfree(pvCpuVAddr);
+}
+
+
+LinuxMemArea *
+NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
+{
+    LinuxMemArea *psLinuxMemArea;
+    IMG_VOID *pvCpuVAddr;
+
+    psLinuxMemArea = LinuxMemAreaStructAlloc();
+    if(!psLinuxMemArea)
+    {
+        goto failed;
+    }
+
+    pvCpuVAddr = VMallocWrapper(ui32Bytes, ui32AreaFlags);
+    if(!pvCpuVAddr)
+    {
+        goto failed;
+    }
+    
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+    
+    ReservePages(pvCpuVAddr, ui32Bytes);
+#endif
+
+    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC;
+    psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr;
+    psLinuxMemArea->ui32ByteSize = ui32Bytes;
+    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+    
+    if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
+        OSInvalidateCPUCacheRangeKM(psLinuxMemArea, pvCpuVAddr, ui32Bytes);
+
+    return psLinuxMemArea;
+
+failed:
+    PVR_DPF((PVR_DBG_ERROR, "%s: failed!", __FUNCTION__));
+    if(psLinuxMemArea)
+        LinuxMemAreaStructFree(psLinuxMemArea);
+    return NULL;
+}
+
+
+IMG_VOID
+FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+    PVR_ASSERT(psLinuxMemArea);
+    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_VMALLOC);
+    PVR_ASSERT(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+	UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress,
+                    psLinuxMemArea->ui32ByteSize);
+#endif
+
+    PVR_DPF((PVR_DBG_MESSAGE,"%s: pvCpuVAddr: %p",
+             __FUNCTION__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress));
+    VFreeWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
+
+    LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+static IMG_VOID
+ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length)
+{
+	IMG_VOID *pvPage;
+	IMG_VOID *pvEnd = pvAddress + ui32Length;
+
+	for(pvPage = pvAddress; pvPage < pvEnd;  pvPage += PAGE_SIZE)
+	{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+		SetPageReserved(vmalloc_to_page(pvPage));
+#else
+		mem_map_reserve(vmalloc_to_page(pvPage));
+#endif
+	}
+}
+
+
+static IMG_VOID
+UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length)
+{
+	IMG_VOID *pvPage;
+	IMG_VOID *pvEnd = pvAddress + ui32Length;
+
+	for(pvPage = pvAddress; pvPage < pvEnd;  pvPage += PAGE_SIZE)
+	{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+		ClearPageReserved(vmalloc_to_page(pvPage));
+#else
+		mem_map_unreserve(vmalloc_to_page(pvPage));
+#endif
+	}
+}
+#endif 
+
+
+IMG_VOID *
+_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
+               IMG_UINT32 ui32Bytes,
+               IMG_UINT32 ui32MappingFlags,
+               IMG_CHAR *pszFileName,
+               IMG_UINT32 ui32Line)
+{
+    IMG_VOID *pvIORemapCookie;
+    
+    switch(ui32MappingFlags & PVRSRV_HAP_CACHETYPE_MASK)
+    {
+        case PVRSRV_HAP_CACHED:
+	    pvIORemapCookie = (IMG_VOID *)IOREMAP(BasePAddr.uiAddr, ui32Bytes);
+            break;
+        case PVRSRV_HAP_WRITECOMBINE:
+	    pvIORemapCookie = (IMG_VOID *)IOREMAP_WC(BasePAddr.uiAddr, ui32Bytes);
+            break;
+        case PVRSRV_HAP_UNCACHED:
+            pvIORemapCookie = (IMG_VOID *)IOREMAP_UC(BasePAddr.uiAddr, ui32Bytes);
+            break;
+        default:
+            PVR_DPF((PVR_DBG_ERROR, "IORemapWrapper: unknown mapping flags"));
+            return NULL;
+    }
+    
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    if(pvIORemapCookie)
+    {
+        DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IOREMAP,
+                               pvIORemapCookie,
+                               pvIORemapCookie,
+                               BasePAddr.uiAddr,
+                               NULL,
+                               ui32Bytes,
+                               pszFileName,
+                               ui32Line
+                               );
+    }
+#else
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+    return pvIORemapCookie;
+}
+
+
+IMG_VOID
+_IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IOREMAP, pvIORemapCookie, pszFileName, ui32Line);
+#else
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+    iounmap(pvIORemapCookie);
+}
+
+
+LinuxMemArea *
+NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
+                       IMG_UINT32 ui32Bytes,
+                       IMG_UINT32 ui32AreaFlags)
+{
+    LinuxMemArea *psLinuxMemArea;
+    IMG_VOID *pvIORemapCookie;
+
+    psLinuxMemArea = LinuxMemAreaStructAlloc();
+    if(!psLinuxMemArea)
+    {
+        return NULL;
+    }
+
+    pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32AreaFlags);
+    if(!pvIORemapCookie)
+    {
+        LinuxMemAreaStructFree(psLinuxMemArea);
+        return NULL;
+    }
+
+    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IOREMAP;
+    psLinuxMemArea->uData.sIORemap.pvIORemapCookie = pvIORemapCookie;
+    psLinuxMemArea->uData.sIORemap.CPUPhysAddr = BasePAddr;
+    psLinuxMemArea->ui32ByteSize = ui32Bytes;
+    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+    return psLinuxMemArea;
+}
+
+
+IMG_VOID
+FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IOREMAP);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+    
+    IOUnmapWrapper(psLinuxMemArea->uData.sIORemap.pvIORemapCookie);
+
+    LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static IMG_BOOL
+TreatExternalPagesAsContiguous(IMG_SYS_PHYADDR *psSysPhysAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig)
+{
+	IMG_UINT32 ui32;
+	IMG_UINT32 ui32AddrChk;
+	IMG_UINT32 ui32NumPages = RANGE_TO_PAGES(ui32Bytes);
+
+	
+	for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
+		ui32 < ui32NumPages;
+		ui32++, ui32AddrChk = (bPhysContig) ? (ui32AddrChk + PAGE_SIZE) : psSysPhysAddr[ui32].uiAddr)
+	{
+		if (!pfn_valid(PHYS_TO_PFN(ui32AddrChk)))
+		{
+			break;
+		}
+	}
+	if (ui32 == ui32NumPages)
+	{
+		return IMG_FALSE;
+	}
+
+	if (!bPhysContig)
+	{
+		for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
+			ui32 < ui32NumPages;
+			ui32++, ui32AddrChk += PAGE_SIZE)
+		{
+			if (psSysPhysAddr[ui32].uiAddr != ui32AddrChk)
+			{
+				return IMG_FALSE;
+			}
+		}
+	}
+
+	return IMG_TRUE;
+}
+#endif
+
+LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags)
+{
+    LinuxMemArea *psLinuxMemArea;
+
+    psLinuxMemArea = LinuxMemAreaStructAlloc();
+    if(!psLinuxMemArea)
+    {
+        return NULL;
+    }
+
+    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_EXTERNAL_KV;
+    psLinuxMemArea->uData.sExternalKV.pvExternalKV = pvCPUVAddr;
+    psLinuxMemArea->uData.sExternalKV.bPhysContig =
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+	(bPhysContig || TreatExternalPagesAsContiguous(pBasePAddr, ui32Bytes, bPhysContig))
+                                                    ? IMG_TRUE : IMG_FALSE;
+#else
+	bPhysContig;
+#endif
+    if (psLinuxMemArea->uData.sExternalKV.bPhysContig)
+    {
+	psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr = *pBasePAddr;
+    }
+    else
+    {
+	psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr = pBasePAddr;
+    }
+    psLinuxMemArea->ui32ByteSize = ui32Bytes;
+    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+    return psLinuxMemArea;
+}
+
+
+IMG_VOID
+FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+    
+    LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+LinuxMemArea *
+NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
+                  IMG_UINT32 ui32Bytes,
+                  IMG_UINT32 ui32AreaFlags)
+{
+    LinuxMemArea *psLinuxMemArea = LinuxMemAreaStructAlloc();
+    if(!psLinuxMemArea)
+    {
+        return NULL;
+    }
+
+    
+    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IO;
+    psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr = BasePAddr.uiAddr;
+    psLinuxMemArea->ui32ByteSize = ui32Bytes;
+    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IO,
+                           (IMG_VOID *)BasePAddr.uiAddr,
+                           0,
+                           BasePAddr.uiAddr,
+                           NULL,
+                           ui32Bytes,
+                           "unknown",
+                           0
+                           );
+#endif
+   
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+    return psLinuxMemArea;
+}
+
+
+IMG_VOID
+FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IO);
+    
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO,
+                              (IMG_VOID *)psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr, __FILE__, __LINE__);
+#endif
+
+    
+
+    LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+LinuxMemArea *
+NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
+{
+    LinuxMemArea *psLinuxMemArea;
+    IMG_UINT32 ui32PageCount;
+    struct page **pvPageList;
+    IMG_HANDLE hBlockPageList;
+    IMG_INT32 i;		
+    PVRSRV_ERROR eError;
+    
+    psLinuxMemArea = LinuxMemAreaStructAlloc();
+    if(!psLinuxMemArea)
+    {
+        goto failed_area_alloc;
+    }
+    
+    ui32PageCount = RANGE_TO_PAGES(ui32Bytes);
+    eError = OSAllocMem(0, sizeof(*pvPageList) * ui32PageCount, (IMG_VOID **)&pvPageList, &hBlockPageList,
+							"Array of pages");
+    if(eError != PVRSRV_OK)
+    {
+        goto failed_page_list_alloc;
+    }
+    
+    for(i=0; i<(IMG_INT32)ui32PageCount; i++)
+    {
+        pvPageList[i] = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, 0);
+        if(!pvPageList[i])
+        {
+            goto failed_alloc_pages;
+        }
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+    	
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))		
+    	SetPageReserved(pvPageList[i]);
+#else
+        mem_map_reserve(pvPageList[i]);
+#endif
+#endif
+
+    }
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
+                           pvPageList,
+                           0,
+                           0,
+                           NULL,
+                           PAGE_ALIGN(ui32Bytes),
+                           "unknown",
+                           0
+                           );
+#endif
+
+    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES;
+    psLinuxMemArea->uData.sPageList.pvPageList = pvPageList;
+    psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList;
+    psLinuxMemArea->ui32ByteSize = ui32Bytes;
+    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+    
+    if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
+    {
+        psLinuxMemArea->bNeedsCacheInvalidate = IMG_TRUE;
+    }
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+    return psLinuxMemArea;
+    
+failed_alloc_pages:
+    for(i--; i >= 0; i--)
+    {
+        __free_pages(pvPageList[i], 0);
+    }
+    (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
+	psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL; 
+failed_page_list_alloc:
+    LinuxMemAreaStructFree(psLinuxMemArea);
+failed_area_alloc:
+    PVR_DPF((PVR_DBG_ERROR, "%s: failed", __FUNCTION__));
+    
+    return NULL;
+}
+
+
+IMG_VOID
+FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+    IMG_UINT32 ui32PageCount;
+    struct page **pvPageList;
+    IMG_HANDLE hBlockPageList;
+    IMG_INT32 i;
+
+    PVR_ASSERT(psLinuxMemArea);
+    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+    
+    ui32PageCount = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
+    pvPageList = psLinuxMemArea->uData.sPageList.pvPageList;
+    hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList;
+    
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, __FILE__, __LINE__);
+#endif
+
+    for(i=0;i<(IMG_INT32)ui32PageCount;i++)
+    {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))		
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))		
+        ClearPageReserved(pvPageList[i]);
+#else
+        mem_map_reserve(pvPageList[i]);
+#endif		
+#endif	
+        __free_pages(pvPageList[i], 0);
+    }
+
+    (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
+	psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL; 
+
+    LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+struct page*
+LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea,
+                         IMG_UINT32 ui32ByteOffset)
+{
+    IMG_UINT32 ui32PageIndex;
+    IMG_CHAR *pui8Addr;
+
+    switch(psLinuxMemArea->eAreaType)
+    {
+        case LINUX_MEM_AREA_ALLOC_PAGES:
+            ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
+            return psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
+ 
+        case LINUX_MEM_AREA_VMALLOC:
+            pui8Addr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
+            pui8Addr += ui32ByteOffset;
+            return vmalloc_to_page(pui8Addr);
+ 
+        case LINUX_MEM_AREA_SUB_ALLOC:
+             
+            return LinuxMemAreaOffsetToPage(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea,
+                                            psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset
+                                             + ui32ByteOffset);
+        default:
+            PVR_DPF((PVR_DBG_ERROR,
+                    "%s: Unsupported request for struct page from LinuxMemArea with type=%s",
+                    __FUNCTION__, LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType)));
+            return NULL;
+    }
+}
+
+
+LinuxKMemCache *
+KMemCacheCreateWrapper(IMG_CHAR *pszName,
+                       size_t Size,
+                       size_t Align,
+                       IMG_UINT32 ui32Flags)
+{
+#if defined(DEBUG_LINUX_SLAB_ALLOCATIONS)
+    ui32Flags |= SLAB_POISON|SLAB_RED_ZONE;
+#endif
+    return kmem_cache_create(pszName, Size, Align, ui32Flags, NULL
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
+				, NULL
+#endif	
+			    );
+}
+
+
+IMG_VOID
+KMemCacheDestroyWrapper(LinuxKMemCache *psCache)
+{
+    kmem_cache_destroy(psCache);
+}
+
+
+IMG_VOID *
+_KMemCacheAllocWrapper(LinuxKMemCache *psCache,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
+                      gfp_t Flags,
+#else
+                      IMG_INT Flags,
+#endif
+                      IMG_CHAR *pszFileName,
+                      IMG_UINT32 ui32Line)
+{
+    IMG_VOID *pvRet;
+    
+    pvRet = kmem_cache_zalloc(psCache, Flags);
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    if (pvRet)
+	DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE,
+                           pvRet,
+                           pvRet,
+                           0,
+                           psCache,
+                           kmem_cache_size(psCache),
+                           pszFileName,
+                           ui32Line
+                           );
+#else
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+    
+    return pvRet;
+}
+
+
+IMG_VOID
+_KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, pvObject, pszFileName, ui32Line);
+#else
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+    kmem_cache_free(psCache, pvObject);
+}
+
+
+const IMG_CHAR *
+KMemCacheNameWrapper(LinuxKMemCache *psCache)
+{
+    PVR_UNREFERENCED_PARAMETER(psCache);
+
+    
+    return "";
+}
+
+
+LinuxMemArea *
+NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
+                   IMG_UINT32 ui32ByteOffset,
+                   IMG_UINT32 ui32Bytes)
+{
+    LinuxMemArea *psLinuxMemArea;
+    
+    PVR_ASSERT((ui32ByteOffset+ui32Bytes) <= psParentLinuxMemArea->ui32ByteSize);
+    
+    psLinuxMemArea = LinuxMemAreaStructAlloc();
+    if(!psLinuxMemArea)
+    {
+        return NULL;
+    }
+    
+    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_SUB_ALLOC;
+    psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea = psParentLinuxMemArea;
+    psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset = ui32ByteOffset;
+    psLinuxMemArea->ui32ByteSize = ui32Bytes;
+    psLinuxMemArea->ui32AreaFlags = psParentLinuxMemArea->ui32AreaFlags;
+    psLinuxMemArea->bNeedsCacheInvalidate = psParentLinuxMemArea->bNeedsCacheInvalidate;
+    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+    
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    {
+        DEBUG_LINUX_MEM_AREA_REC *psParentRecord;
+        psParentRecord = DebugLinuxMemAreaRecordFind(psParentLinuxMemArea);
+        DebugLinuxMemAreaRecordAdd(psLinuxMemArea, psParentRecord->ui32Flags);
+    }
+#endif
+    
+    return psLinuxMemArea;
+}
+
+
+static IMG_VOID
+FreeSubLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+    
+    
+
+    LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+static LinuxMemArea *
+LinuxMemAreaStructAlloc(IMG_VOID)
+{
+#if 0
+    LinuxMemArea *psLinuxMemArea;
+    psLinuxMemArea = kmem_cache_alloc(psLinuxMemAreaCache, GFP_KERNEL);
+    printk(KERN_ERR "%s: psLinuxMemArea=%p\n", __FUNCTION__, psLinuxMemArea);
+    dump_stack();
+    return psLinuxMemArea;
+#else
+    return KMemCacheAllocWrapper(psLinuxMemAreaCache, GFP_KERNEL);
+#endif
+}
+
+
+static IMG_VOID
+LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea)
+{
+    KMemCacheFreeWrapper(psLinuxMemAreaCache, psLinuxMemArea);
+    
+    
+}
+
+
+IMG_VOID
+LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea)
+{
+    switch(psLinuxMemArea->eAreaType)
+    {
+        case LINUX_MEM_AREA_VMALLOC:
+            FreeVMallocLinuxMemArea(psLinuxMemArea);
+            break;
+        case LINUX_MEM_AREA_ALLOC_PAGES:
+            FreeAllocPagesLinuxMemArea(psLinuxMemArea);
+            break;
+        case LINUX_MEM_AREA_IOREMAP:
+            FreeIORemapLinuxMemArea(psLinuxMemArea);
+            break;
+	case LINUX_MEM_AREA_EXTERNAL_KV:
+	    FreeExternalKVLinuxMemArea(psLinuxMemArea);
+	    break;
+        case LINUX_MEM_AREA_IO:
+            FreeIOLinuxMemArea(psLinuxMemArea);
+            break;
+        case LINUX_MEM_AREA_SUB_ALLOC:
+            FreeSubLinuxMemArea(psLinuxMemArea);
+            break;
+        default:
+            PVR_DPF((PVR_DBG_ERROR, "%s: Unknown are type (%d)\n",
+                     __FUNCTION__, psLinuxMemArea->eAreaType));
+            break;
+    }
+}
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+static IMG_VOID
+DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags)
+{
+    DEBUG_LINUX_MEM_AREA_REC *psNewRecord;
+    const IMG_CHAR *pi8FlagsString;
+    
+    LinuxLockMutex(&g_sDebugMutex);
+
+    if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+    {
+        g_LinuxMemAreaWaterMark += psLinuxMemArea->ui32ByteSize;
+        if(g_LinuxMemAreaWaterMark > g_LinuxMemAreaHighWaterMark)
+        {
+            g_LinuxMemAreaHighWaterMark = g_LinuxMemAreaWaterMark;
+        }
+    }
+    g_LinuxMemAreaCount++;
+    
+    
+    psNewRecord = kmalloc(sizeof(DEBUG_LINUX_MEM_AREA_REC), GFP_KERNEL);
+    if(psNewRecord)
+    {
+        
+        psNewRecord->psLinuxMemArea = psLinuxMemArea;
+        psNewRecord->ui32Flags = ui32Flags;
+        psNewRecord->pid = OSGetCurrentProcessIDKM();
+		
+		List_DEBUG_LINUX_MEM_AREA_REC_Insert(&g_LinuxMemAreaRecords, psNewRecord);
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+                 "%s: failed to allocate linux memory area record.",
+                 __FUNCTION__));
+    }
+    
+    
+    pi8FlagsString = HAPFlagsToString(ui32Flags);
+    if(strstr(pi8FlagsString, "UNKNOWN"))
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+                 "%s: Unexpected flags (0x%08x) associated with psLinuxMemArea @ %p",
+                 __FUNCTION__,
+                 ui32Flags,
+                 psLinuxMemArea));
+        
+    }
+
+    LinuxUnLockMutex(&g_sDebugMutex);
+}
+
+
+
+static IMG_VOID* MatchLinuxMemArea_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord,
+										   va_list va)
+{
+	LinuxMemArea *psLinuxMemArea;
+	
+	psLinuxMemArea = va_arg(va, LinuxMemArea*);
+	if(psCurrentRecord->psLinuxMemArea == psLinuxMemArea)
+	{
+		return psCurrentRecord;
+	}
+	else
+	{
+		return IMG_NULL;
+	}
+}
+
+
+static DEBUG_LINUX_MEM_AREA_REC *
+DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea)
+{
+    DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
+
+    LinuxLockMutex(&g_sDebugMutex);
+	psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+														MatchLinuxMemArea_AnyVaCb,
+														psLinuxMemArea);
+	
+    LinuxUnLockMutex(&g_sDebugMutex);
+
+    return psCurrentRecord;
+}
+
+
+static IMG_VOID
+DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea)
+{
+    DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
+
+    LinuxLockMutex(&g_sDebugMutex);
+
+    if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+    {
+        g_LinuxMemAreaWaterMark -= psLinuxMemArea->ui32ByteSize;
+    }
+    g_LinuxMemAreaCount--;
+
+    
+	psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+														MatchLinuxMemArea_AnyVaCb,
+														psLinuxMemArea);
+	if(psCurrentRecord)
+	{
+		
+		List_DEBUG_LINUX_MEM_AREA_REC_Remove(psCurrentRecord);
+		kfree(psCurrentRecord);
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for psLinuxMemArea=%p\n",
+        	     __FUNCTION__, psLinuxMemArea));
+	}
+
+    LinuxUnLockMutex(&g_sDebugMutex);
+}
+#endif
+
+
+IMG_VOID *
+LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea)
+{
+    switch(psLinuxMemArea->eAreaType)
+    {
+        case LINUX_MEM_AREA_VMALLOC:
+            return psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
+        case LINUX_MEM_AREA_IOREMAP:
+            return psLinuxMemArea->uData.sIORemap.pvIORemapCookie;
+	case LINUX_MEM_AREA_EXTERNAL_KV:
+	    return psLinuxMemArea->uData.sExternalKV.pvExternalKV;
+        case LINUX_MEM_AREA_SUB_ALLOC:
+        {
+            IMG_CHAR *pAddr =
+                LinuxMemAreaToCpuVAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);  
+            if(!pAddr)
+            {
+                return NULL;
+            }
+            return pAddr + psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset;
+        }
+        default:
+            return NULL;
+    }
+}
+
+
+IMG_CPU_PHYADDR
+LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset)
+{
+    IMG_CPU_PHYADDR CpuPAddr;
+    
+    CpuPAddr.uiAddr = 0;
+
+    switch(psLinuxMemArea->eAreaType)
+    {
+        case LINUX_MEM_AREA_IOREMAP:
+        {
+            CpuPAddr = psLinuxMemArea->uData.sIORemap.CPUPhysAddr;
+            CpuPAddr.uiAddr += ui32ByteOffset;
+            break;
+        }
+	case LINUX_MEM_AREA_EXTERNAL_KV:
+	{
+	    if (psLinuxMemArea->uData.sExternalKV.bPhysContig)
+	    {
+		CpuPAddr = SysSysPAddrToCpuPAddr(psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr);
+		CpuPAddr.uiAddr += ui32ByteOffset;
+	    }
+	    else
+	    {
+		IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
+		IMG_SYS_PHYADDR SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageIndex];
+
+		CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr);
+                CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
+	    }
+            break;
+	}
+        case LINUX_MEM_AREA_IO:
+        {
+            CpuPAddr = psLinuxMemArea->uData.sIO.CPUPhysAddr;
+            CpuPAddr.uiAddr += ui32ByteOffset;
+            break;
+        }
+        case LINUX_MEM_AREA_VMALLOC:
+        {
+            IMG_CHAR *pCpuVAddr;
+            pCpuVAddr =
+                (IMG_CHAR *)psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
+            pCpuVAddr += ui32ByteOffset;
+            CpuPAddr.uiAddr = VMallocToPhys(pCpuVAddr);
+            break;
+        }
+        case LINUX_MEM_AREA_ALLOC_PAGES:
+        {
+            struct page *page;
+            IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
+            page = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
+            CpuPAddr.uiAddr = page_to_phys(page);
+            CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
+            break;
+        }
+        case LINUX_MEM_AREA_SUB_ALLOC:
+        {
+            CpuPAddr =
+                OSMemHandleToCpuPAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea,
+                                      psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset
+                                        + ui32ByteOffset);
+            break;
+        }
+        default:
+        {
+            PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n",
+                     __FUNCTION__, psLinuxMemArea->eAreaType));
+            PVR_ASSERT(CpuPAddr.uiAddr);
+           break;
+        }
+   }
+    
+    return CpuPAddr;
+}
+
+
+IMG_BOOL
+LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea)
+{
+    switch(psLinuxMemArea->eAreaType)
+    {
+        case LINUX_MEM_AREA_IOREMAP:
+        case LINUX_MEM_AREA_IO:
+            return IMG_TRUE;
+
+	case LINUX_MEM_AREA_EXTERNAL_KV:
+	    return psLinuxMemArea->uData.sExternalKV.bPhysContig;
+
+        case LINUX_MEM_AREA_VMALLOC:
+        case LINUX_MEM_AREA_ALLOC_PAGES:
+	    return IMG_FALSE;
+
+        case LINUX_MEM_AREA_SUB_ALLOC:
+             
+	    return LinuxMemAreaPhysIsContig(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);
+
+        default:
+            PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n",
+                     __FUNCTION__, psLinuxMemArea->eAreaType));
+	    break;
+    }
+    return IMG_FALSE;
+}
+
+
+const IMG_CHAR *
+LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType)
+{
+    
+    switch(eMemAreaType)
+    {
+        case LINUX_MEM_AREA_IOREMAP:
+            return "LINUX_MEM_AREA_IOREMAP";
+	case LINUX_MEM_AREA_EXTERNAL_KV:
+	    return "LINUX_MEM_AREA_EXTERNAL_KV";
+        case LINUX_MEM_AREA_IO:
+            return "LINUX_MEM_AREA_IO";
+        case LINUX_MEM_AREA_VMALLOC:
+            return "LINUX_MEM_AREA_VMALLOC";
+        case LINUX_MEM_AREA_SUB_ALLOC:
+            return "LINUX_MEM_AREA_SUB_ALLOC";
+        case LINUX_MEM_AREA_ALLOC_PAGES:
+            return "LINUX_MEM_AREA_ALLOC_PAGES";
+        default:
+            PVR_ASSERT(0);
+    }
+
+    return "";
+}
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static void ProcSeqStartstopDebugMutex(struct seq_file *sfile, IMG_BOOL start) 
+{
+	if(start) 
+	{
+	    LinuxLockMutex(&g_sDebugMutex);		
+	}
+	else
+	{
+	    LinuxUnLockMutex(&g_sDebugMutex);
+	}
+}
+#endif 
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+
+static IMG_VOID* DecOffMemAreaRec_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psNode, va_list va)
+{
+	off_t *pOff = va_arg(va, off_t*);
+	if (--(*pOff))
+	{
+		return IMG_NULL;
+	}
+	else
+	{
+		return psNode;
+	}
+}
+
+ 
+static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off) 
+{
+    DEBUG_LINUX_MEM_AREA_REC *psRecord;
+	psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
+				List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+													DecOffMemAreaRec_AnyVaCb,
+													&off);
+	return (void*)psRecord;
+}
+
+static void* ProcSeqOff2ElementMemArea(struct seq_file * sfile, loff_t off)
+{
+    DEBUG_LINUX_MEM_AREA_REC *psRecord;
+	if(!off) 
+	{
+		return PVR_PROC_SEQ_START_TOKEN;
+	}
+
+	psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
+				List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+													DecOffMemAreaRec_AnyVaCb,
+													&off);
+	return (void*)psRecord;
+}
+
+
+static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
+{
+    DEBUG_LINUX_MEM_AREA_REC *psRecord = (DEBUG_LINUX_MEM_AREA_REC*)el; 
+	if(el == PVR_PROC_SEQ_START_TOKEN) 
+	{
+
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+        seq_printf( sfile,
+              			  "Number of Linux Memory Areas: %u\n"
+                          "At the current water mark these areas correspond to %u bytes (excluding SUB areas)\n"
+                          "At the highest water mark these areas corresponded to %u bytes (excluding SUB areas)\n"
+                          "\nDetails for all Linux Memory Areas:\n"
+                          "%s %-24s %s %s %-8s %-5s %s\n",
+                          g_LinuxMemAreaCount,
+                          g_LinuxMemAreaWaterMark,
+                          g_LinuxMemAreaHighWaterMark,
+                          "psLinuxMemArea",
+                          "LinuxMemType",
+                          "CpuVAddr",
+                          "CpuPAddr",
+                          "Bytes",
+                          "Pid",
+                          "Flags"
+                         );
+#else
+        seq_printf( sfile,
+                          "<mem_areas_header>\n"
+                          "\t<count>%u</count>\n"
+                          "\t<watermark key=\"mar0\" description=\"current\" bytes=\"%u\"/>\n" 
+                          "\t<watermark key=\"mar1\" description=\"high\" bytes=\"%u\"/>\n" 
+                          "</mem_areas_header>\n",
+                          g_LinuxMemAreaCount,
+                          g_LinuxMemAreaWaterMark,
+                          g_LinuxMemAreaHighWaterMark
+                         );
+#endif
+		return;
+	}
+
+        seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+                       "%8p       %-24s %8p %08x %-8d %-5u %08x=(%s)\n",
+#else
+                       "<linux_mem_area>\n"
+                       "\t<pointer>%8p</pointer>\n"
+                       "\t<type>%s</type>\n"
+                       "\t<cpu_virtual>%8p</cpu_virtual>\n"
+                       "\t<cpu_physical>%08x</cpu_physical>\n"
+                       "\t<bytes>%ld</bytes>\n"
+                       "\t<pid>%u</pid>\n"
+                       "\t<flags>%08lx</flags>\n"
+                       "\t<flags_string>%s</flags_string>\n"
+                       "</linux_mem_area>\n",
+#endif
+                       psRecord->psLinuxMemArea,
+                       LinuxMemAreaTypeToString(psRecord->psLinuxMemArea->eAreaType),
+                       LinuxMemAreaToCpuVAddr(psRecord->psLinuxMemArea),
+                       LinuxMemAreaToCpuPAddr(psRecord->psLinuxMemArea,0).uiAddr,
+                       psRecord->psLinuxMemArea->ui32ByteSize,
+                       psRecord->pid,
+                       psRecord->ui32Flags,
+                       HAPFlagsToString(psRecord->ui32Flags)
+                      );
+
+}
+
+#endif 
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+
+static IMG_VOID* DecOffMemAllocRec_AnyVaCb(DEBUG_MEM_ALLOC_REC *psNode, va_list va)
+{
+	off_t *pOff = va_arg(va, off_t*);
+	if (--(*pOff))
+	{
+		return IMG_NULL;
+	}
+	else
+	{
+		return psNode;
+	}
+}
+
+
+ 
+static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off) 
+{
+    DEBUG_MEM_ALLOC_REC *psRecord;
+	psRecord = (DEBUG_MEM_ALLOC_REC*)
+		List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
+										DecOffMemAllocRec_AnyVaCb,
+										&off);
+#if defined(DEBUG_LINUX_XML_PROC_FILES)
+	if(!psRecord) 
+	{
+		seq_printf( sfile, "</meminfo>\n");
+	}
+#endif
+
+	return (void*)psRecord;
+}
+
+static void* ProcSeqOff2ElementMemoryRecords(struct seq_file *sfile, loff_t off)
+{
+    DEBUG_MEM_ALLOC_REC *psRecord;
+	if(!off) 
+	{
+		return PVR_PROC_SEQ_START_TOKEN;
+	}
+
+	psRecord = (DEBUG_MEM_ALLOC_REC*)
+		List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
+										DecOffMemAllocRec_AnyVaCb,
+										&off);
+
+#if defined(DEBUG_LINUX_XML_PROC_FILES)
+	if(!psRecord) 
+	{
+		seq_printf( sfile, "</meminfo>\n");
+	}
+#endif
+
+	return (void*)psRecord;
+}
+
+static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el)
+{
+    DEBUG_MEM_ALLOC_REC *psRecord = (DEBUG_MEM_ALLOC_REC*)el;
+	if(el == PVR_PROC_SEQ_START_TOKEN) 
+	{
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+        
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Current Water Mark of bytes allocated via kmalloc",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Highest Water Mark of bytes allocated via kmalloc",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Current Water Mark of bytes allocated via vmalloc",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Highest Water Mark of bytes allocated via vmalloc",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Current Water Mark of bytes allocated via alloc_pages",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Highest Water Mark of bytes allocated via alloc_pages",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Current Water Mark of bytes allocated via ioremap",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Highest Water Mark of bytes allocated via ioremap",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Current Water Mark of bytes reserved for \"IO\" memory areas",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Highest Water Mark of bytes allocated for \"IO\" memory areas",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Current Water Mark of bytes allocated via kmem_cache_alloc",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "Highest Water Mark of bytes allocated via kmem_cache_alloc",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+        seq_printf( sfile, "\n");
+
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "The Current Water Mark for memory allocated from system RAM",
+                           g_SysRAMWaterMark);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "The Highest Water Mark for memory allocated from system RAM",
+                           g_SysRAMHighWaterMark);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "The Current Water Mark for memory allocated from IO memory",
+                           g_IOMemWaterMark);
+        seq_printf( sfile, "%-60s: %d bytes\n",
+                           "The Highest Water Mark for memory allocated from IO memory",
+                           g_IOMemHighWaterMark);
+
+        seq_printf( sfile, "\n");
+
+		seq_printf( sfile, "Details for all known allocations:\n"
+                           "%-16s %-8s %-8s %-10s %-5s %-10s %s\n",
+                           "Type",
+                           "CpuVAddr",
+                           "CpuPAddr",
+                           "Bytes",
+                           "PID",
+                           "PrivateData",
+                           "Filename:Line");
+
+#else 
+		
+		
+		seq_printf( sfile, "<meminfo>\n<meminfo_header>\n");
+		seq_printf( sfile,
+                           "<watermark key=\"mr0\" description=\"kmalloc_current\" bytes=\"%d\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr1\" description=\"kmalloc_high\" bytes=\"%d\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr2\" description=\"vmalloc_current\" bytes=\"%d\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr3\" description=\"vmalloc_high\" bytes=\"%d\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr4\" description=\"alloc_pages_current\" bytes=\"%d\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr5\" description=\"alloc_pages_high\" bytes=\"%d\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr6\" description=\"ioremap_current\" bytes=\"%d\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr7\" description=\"ioremap_high\" bytes=\"%d\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr8\" description=\"io_current\" bytes=\"%d\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr9\" description=\"io_high\" bytes=\"%d\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr10\" description=\"kmem_cache_current\" bytes=\"%d\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+		seq_printf( sfile,
+                           "<watermark key=\"mr11\" description=\"kmem_cache_high\" bytes=\"%d\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+		seq_printf( sfile,"\n" );
+
+		seq_printf( sfile,
+                           "<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%d\"/>\n",
+                           g_SysRAMWaterMark);
+		seq_printf( sfile,
+                           "<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%d\"/>\n",
+                           g_SysRAMHighWaterMark);
+		seq_printf( sfile,
+                           "<watermark key=\"mr16\" description=\"system_io_current\" bytes=\"%d\"/>\n",
+                           g_IOMemWaterMark);
+		seq_printf( sfile,
+                           "<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%d\"/>\n",
+                           g_IOMemHighWaterMark);
+
+		seq_printf( sfile, "</meminfo_header>\n");
+
+#endif 
+		return;
+	}
+
+    if(psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
+    {
+		seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+                           "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
+#else
+                           "<allocation>\n"
+                           "\t<type>%s</type>\n"
+                           "\t<cpu_virtual>%-8p</cpu_virtual>\n"
+                           "\t<cpu_physical>%08x</cpu_physical>\n"
+                           "\t<bytes>%d</bytes>\n"
+                           "\t<pid>%d</pid>\n"
+                           "\t<private>%s</private>\n"
+                           "\t<filename>%s</filename>\n"
+                           "\t<line>%d</line>\n"
+                           "</allocation>\n",
+#endif
+                           DebugMemAllocRecordTypeToString(psRecord->eAllocType),
+                           psRecord->pvCpuVAddr,
+                           psRecord->ulCpuPAddr,
+                           psRecord->ui32Bytes,
+                           psRecord->pid,
+                           "NULL",
+                           psRecord->pszFileName,
+                           psRecord->ui32Line);
+    }
+    else
+    {
+		seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+                           "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
+#else
+                           "<allocation>\n"
+                           "\t<type>%s</type>\n"
+                           "\t<cpu_virtual>%-8p</cpu_virtual>\n"
+                           "\t<cpu_physical>%08x</cpu_physical>\n"
+                           "\t<bytes>%d</bytes>\n"
+                           "\t<pid>%d</pid>\n"
+                           "\t<private>%s</private>\n"
+                           "\t<filename>%s</filename>\n"
+                           "\t<line>%d</line>\n"
+                           "</allocation>\n",
+#endif
+                           DebugMemAllocRecordTypeToString(psRecord->eAllocType),
+                           psRecord->pvCpuVAddr,
+                           psRecord->ulCpuPAddr,
+                           psRecord->ui32Bytes,
+                           psRecord->pid,
+                           KMemCacheNameWrapper(psRecord->pvPrivateData),
+                           psRecord->pszFileName,
+                           psRecord->ui32Line);
+    }
+}
+
+#endif 
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MMAP_AREAS)
+const IMG_CHAR *
+HAPFlagsToString(IMG_UINT32 ui32Flags)
+{
+    static IMG_CHAR szFlags[50];
+    IMG_INT32 i32Pos = 0;
+    IMG_UINT32 ui32CacheTypeIndex, ui32MapTypeIndex;
+    IMG_CHAR *apszCacheTypes[] = {
+        "UNCACHED",
+        "CACHED",
+        "WRITECOMBINE",
+        "UNKNOWN"
+    };
+    IMG_CHAR *apszMapType[] = {
+        "KERNEL_ONLY",
+        "SINGLE_PROCESS",
+        "MULTI_PROCESS",
+        "FROM_EXISTING_PROCESS",
+        "NO_CPU_VIRTUAL",
+        "UNKNOWN"
+    };
+    
+    
+    if(ui32Flags & PVRSRV_HAP_UNCACHED){
+        ui32CacheTypeIndex=0;
+    }else if(ui32Flags & PVRSRV_HAP_CACHED){
+        ui32CacheTypeIndex=1;
+    }else if(ui32Flags & PVRSRV_HAP_WRITECOMBINE){
+        ui32CacheTypeIndex=2;
+    }else{
+        ui32CacheTypeIndex=3;
+        PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type (%u)",
+                 __FUNCTION__, (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)));
+    }
+
+    
+    if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY){
+        ui32MapTypeIndex = 0;
+    }else if(ui32Flags & PVRSRV_HAP_SINGLE_PROCESS){
+        ui32MapTypeIndex = 1;
+    }else if(ui32Flags & PVRSRV_HAP_MULTI_PROCESS){
+        ui32MapTypeIndex = 2;
+    }else if(ui32Flags & PVRSRV_HAP_FROM_EXISTING_PROCESS){
+        ui32MapTypeIndex = 3;
+    }else if(ui32Flags & PVRSRV_HAP_NO_CPU_VIRTUAL){
+        ui32MapTypeIndex = 4;
+    }else{
+        ui32MapTypeIndex = 5;
+        PVR_DPF((PVR_DBG_ERROR, "%s: unknown map type (%u)",
+                 __FUNCTION__, (ui32Flags & PVRSRV_HAP_MAPTYPE_MASK)));
+    }
+
+    i32Pos = sprintf(szFlags, "%s|", apszCacheTypes[ui32CacheTypeIndex]);
+    if (i32Pos <= 0)
+    {
+	PVR_DPF((PVR_DBG_ERROR, "%s: sprintf for cache type %u failed (%d)",
+		__FUNCTION__, ui32CacheTypeIndex, i32Pos));
+	szFlags[0] = 0;
+    }
+    else
+    {
+        sprintf(szFlags + i32Pos, "%s", apszMapType[ui32MapTypeIndex]);
+    }
+
+    return szFlags;
+}
+#endif
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mm.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mm.h
new file mode 100644
index 0000000..b32f5e8
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mm.h
@@ -0,0 +1,336 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __IMG_LINUX_MM_H__
+#define __IMG_LINUX_MM_H__
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+
+#include <asm/io.h>
+
+#define	PHYS_TO_PFN(phys) ((phys) >> PAGE_SHIFT)
+#define PFN_TO_PHYS(pfn) ((pfn) << PAGE_SHIFT)
+
+#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
+
+#define	ADDR_TO_PAGE_OFFSET(addr) (((unsigned long)(addr)) & (PAGE_SIZE - 1))
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+#define	REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_pfn_range(vma, addr, pfn, size, prot)
+#else
+#define	REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot)
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12))
+#define	IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_pfn_range(vma, addr, pfn, size, prot)
+#else
+#define	IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot)
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#define	VM_INSERT_PAGE(vma, addr, page) vm_insert_page(vma, addr, page)
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+#define VM_INSERT_PAGE(vma, addr, page) remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, vma->vm_page_prot);
+#else
+#define VM_INSERT_PAGE(vma, addr, page) remap_page_range(vma, addr, page_to_phys(page), PAGE_SIZE, vma->vm_page_prot);
+#endif
+#endif
+
+static inline IMG_UINT32 VMallocToPhys(IMG_VOID *pCpuVAddr)
+{
+	return (page_to_phys(vmalloc_to_page(pCpuVAddr)) + ADDR_TO_PAGE_OFFSET(pCpuVAddr));
+		
+}
+
+typedef enum {
+    LINUX_MEM_AREA_IOREMAP,
+	LINUX_MEM_AREA_EXTERNAL_KV,
+    LINUX_MEM_AREA_IO,
+    LINUX_MEM_AREA_VMALLOC,
+    LINUX_MEM_AREA_ALLOC_PAGES,
+    LINUX_MEM_AREA_SUB_ALLOC,
+    LINUX_MEM_AREA_TYPE_COUNT
+}LINUX_MEM_AREA_TYPE;
+
+typedef struct _LinuxMemArea LinuxMemArea;
+
+
+struct _LinuxMemArea {
+    LINUX_MEM_AREA_TYPE eAreaType;
+    union _uData
+    {
+        struct _sIORemap
+        {
+            
+            IMG_CPU_PHYADDR CPUPhysAddr;
+            IMG_VOID *pvIORemapCookie;
+        }sIORemap;
+        struct _sExternalKV
+        {
+            
+	    IMG_BOOL bPhysContig;
+	    union {
+		    
+		    IMG_SYS_PHYADDR SysPhysAddr;
+		    IMG_SYS_PHYADDR *pSysPhysAddr;
+	    } uPhysAddr;
+            IMG_VOID *pvExternalKV;
+        }sExternalKV;
+        struct _sIO
+        {
+            
+            IMG_CPU_PHYADDR CPUPhysAddr;
+        }sIO;
+        struct _sVmalloc
+        {
+            
+            IMG_VOID *pvVmallocAddress;
+        }sVmalloc;
+        struct _sPageList
+        {
+            
+            struct page **pvPageList;
+	    IMG_HANDLE hBlockPageList;
+        }sPageList;
+        struct _sSubAlloc
+        {
+            
+            LinuxMemArea *psParentLinuxMemArea;
+            IMG_UINT32 ui32ByteOffset;
+        }sSubAlloc;
+    }uData;
+
+    IMG_UINT32 ui32ByteSize;		
+
+    IMG_UINT32 ui32AreaFlags;		
+
+    IMG_BOOL bMMapRegistered;		
+
+    IMG_BOOL bNeedsCacheInvalidate;	
+
+    
+    struct list_head	sMMapItem;
+
+    
+    struct list_head	sMMapOffsetStructList;
+};
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
+typedef kmem_cache_t LinuxKMemCache;
+#else
+typedef struct kmem_cache LinuxKMemCache;
+#endif
+
+
+PVRSRV_ERROR LinuxMMInit(IMG_VOID);
+
+
+IMG_VOID LinuxMMCleanup(IMG_VOID);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define KMallocWrapper(ui32ByteSize, uFlags) _KMallocWrapper(ui32ByteSize, uFlags, __FILE__, __LINE__)
+#else
+#define KMallocWrapper(ui32ByteSize, uFlags) _KMallocWrapper(ui32ByteSize, uFlags, NULL, 0)
+#endif
+IMG_VOID *_KMallocWrapper(IMG_UINT32 ui32ByteSize, gfp_t uFlags, IMG_CHAR *szFileName, IMG_UINT32 ui32Line);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
+#else
+#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, NULL, 0)
+#endif
+IMG_VOID _KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, __FILE__, __LINE__)
+#else
+#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, NULL, 0)
+#endif
+IMG_VOID *_VMallocWrapper(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AllocFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
+#else
+#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, NULL, 0)
+#endif
+IMG_VOID _VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+LinuxMemArea *NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
+    _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, __FILE__, __LINE__)
+#else
+#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
+    _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, NULL, 0)
+#endif
+IMG_VOID *_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
+                          IMG_UINT32 ui32Bytes,
+                          IMG_UINT32 ui32MappingFlags,
+                          IMG_CHAR *pszFileName,
+                          IMG_UINT32 ui32Line);
+
+
+LinuxMemArea *NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define IOUnmapWrapper(pvIORemapCookie) \
+    _IOUnmapWrapper(pvIORemapCookie, __FILE__, __LINE__)
+#else
+#define IOUnmapWrapper(pvIORemapCookie) \
+    _IOUnmapWrapper(pvIORemapCookie, NULL, 0)
+#endif
+IMG_VOID _IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+struct page *LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
+
+
+LinuxKMemCache *KMemCacheCreateWrapper(IMG_CHAR *pszName, size_t Size, size_t Align, IMG_UINT32 ui32Flags);
+
+
+IMG_VOID KMemCacheDestroyWrapper(LinuxKMemCache *psCache);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, __FILE__, __LINE__)
+#else
+#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, NULL, 0)
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
+IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, gfp_t Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+#else
+IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, int Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, __FILE__, __LINE__)
+#else
+#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, NULL, 0)
+#endif
+IMG_VOID _KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+const IMG_CHAR *KMemCacheNameWrapper(LinuxKMemCache *psCache);
+
+
+LinuxMemArea *NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+LinuxMemArea *NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+LinuxMemArea *NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
+                                 IMG_UINT32 ui32ByteOffset,
+                                 IMG_UINT32 ui32Bytes);
+
+
+IMG_VOID LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea);
+
+
+#if defined(LINUX_MEM_AREAS_DEBUG)
+IMG_VOID LinuxMemAreaRegister(LinuxMemArea *psLinuxMemArea);
+#else
+#define LinuxMemAreaRegister(X)
+#endif
+
+
+IMG_VOID *LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea);
+
+
+IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
+
+
+#define	 LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) PHYS_TO_PFN(LinuxMemAreaToCpuPAddr(psLinuxMemArea, ui32ByteOffset).uiAddr)
+
+IMG_BOOL LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea);
+
+static inline LinuxMemArea *
+LinuxMemAreaRoot(LinuxMemArea *psLinuxMemArea)
+{
+    if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
+    {
+        return psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
+    }
+    else
+    {
+        return psLinuxMemArea;
+    }
+}
+
+
+static inline LINUX_MEM_AREA_TYPE
+LinuxMemAreaRootType(LinuxMemArea *psLinuxMemArea)
+{
+    return LinuxMemAreaRoot(psLinuxMemArea)->eAreaType;
+}
+
+
+const IMG_CHAR *LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType);
+
+
+#if defined(DEBUG) || defined(DEBUG_LINUX_MEM_AREAS)
+const IMG_CHAR *HAPFlagsToString(IMG_UINT32 ui32Flags);
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mmap.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mmap.c
new file mode 100644
index 0000000..00c8b9d
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mmap.c
@@ -0,0 +1,1151 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#include <linux/wrapper.h>
+#endif
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/shmparam.h>
+#include <asm/pgtable.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#include <linux/sched.h>
+#include <asm/current.h>
+#endif
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#endif
+
+#include "img_defs.h"
+#include "services.h"
+#include "servicesint.h"
+#include "pvrmmap.h"
+#include "mutils.h"
+#include "mmap.h"
+#include "mm.h"
+#include "pvr_debug.h"
+#include "osfunc.h"
+#include "proc.h"
+#include "mutex.h"
+#include "handle.h"
+#include "perproc.h"
+#include "env_perproc.h"
+#include "bridged_support.h"
+#if defined(SUPPORT_DRI_DRM)
+#include "pvr_drm.h"
+#endif
+
+#if !defined(PVR_SECURE_HANDLES) && !defined (SUPPORT_SID_INTERFACE)
+#error "The mmap code requires PVR_SECURE_HANDLES"
+#endif
+
+static PVRSRV_LINUX_MUTEX g_sMMapMutex;
+
+static LinuxKMemCache *g_psMemmapCache = NULL;
+static LIST_HEAD(g_sMMapAreaList);
+static LIST_HEAD(g_sMMapOffsetStructList);
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+static IMG_UINT32 g_ui32RegisteredAreas = 0;
+static IMG_UINT32 g_ui32TotalByteSize = 0;
+#endif
+
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+static struct proc_dir_entry *g_ProcMMap;
+#endif 
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+#define MMAP2_PGOFF_RESOLUTION (32-PAGE_SHIFT+12)
+#define RESERVED_PGOFF_BITS 1
+#define	MAX_MMAP_HANDLE		((1UL<<(MMAP2_PGOFF_RESOLUTION-RESERVED_PGOFF_BITS))-1)
+
+#define	FIRST_PHYSICAL_PFN	0
+#define	LAST_PHYSICAL_PFN	(FIRST_PHYSICAL_PFN + MAX_MMAP_HANDLE)
+#define	FIRST_SPECIAL_PFN	(LAST_PHYSICAL_PFN + 1)
+#define	LAST_SPECIAL_PFN	(FIRST_SPECIAL_PFN + MAX_MMAP_HANDLE)
+
+#else	
+
+#if PAGE_SHIFT != 12
+#error This build variant has not yet been made non-4KB page-size aware
+#endif
+
+#if defined(PVR_MMAP_OFFSET_BASE)
+#define	FIRST_SPECIAL_PFN 	PVR_MMAP_OFFSET_BASE
+#else
+#define	FIRST_SPECIAL_PFN	0x80000000UL
+#endif
+
+#if defined(PVR_NUM_MMAP_HANDLES)
+#define	MAX_MMAP_HANDLE		PVR_NUM_MMAP_HANDLES
+#else
+#define	MAX_MMAP_HANDLE		0x7fffffffUL
+#endif
+
+#endif	
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_BOOL
+PFNIsPhysical(IMG_UINT32 pfn)
+{
+	
+	return ( (pfn <= LAST_PHYSICAL_PFN)) ? IMG_TRUE : IMG_FALSE;
+}
+
+static inline IMG_BOOL
+PFNIsSpecial(IMG_UINT32 pfn)
+{
+	
+	return ((pfn >= FIRST_SPECIAL_PFN) ) ? IMG_TRUE : IMG_FALSE;
+}
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_HANDLE
+MMapOffsetToHandle(IMG_UINT32 pfn)
+{
+	if (PFNIsPhysical(pfn))
+	{
+		PVR_ASSERT(PFNIsPhysical(pfn));
+		return IMG_NULL;
+	}
+	return (IMG_HANDLE)(pfn - FIRST_SPECIAL_PFN);
+}
+#endif
+
+static inline IMG_UINT32
+#if defined (SUPPORT_SID_INTERFACE)
+HandleToMMapOffset(IMG_SID hHandle)
+#else
+HandleToMMapOffset(IMG_HANDLE hHandle)
+#endif
+{
+	IMG_UINT32 ulHandle = (IMG_UINT32)hHandle;
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+	if (PFNIsSpecial(ulHandle))
+	{
+		PVR_ASSERT(PFNIsSpecial(ulHandle));
+		return 0;
+	}
+#endif
+	return ulHandle + FIRST_SPECIAL_PFN;
+}
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_BOOL
+LinuxMemAreaUsesPhysicalMap(LinuxMemArea *psLinuxMemArea)
+{
+    return LinuxMemAreaPhysIsContig(psLinuxMemArea);
+}
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_UINT32
+GetCurrentThreadID(IMG_VOID)
+{
+	
+	return (IMG_UINT32)current->pid;
+}
+#endif
+
+static PKV_OFFSET_STRUCT
+CreateOffsetStruct(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize)
+{
+    PKV_OFFSET_STRUCT psOffsetStruct;
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+    const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea));
+#endif
+
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+    PVR_DPF((PVR_DBG_MESSAGE,
+             "%s(%s, psLinuxMemArea: 0x%p, ui32AllocFlags: 0x%8x)",
+             __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags));
+#endif
+
+    PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
+
+    PVR_ASSERT(psLinuxMemArea->bMMapRegistered);
+
+    psOffsetStruct = KMemCacheAllocWrapper(g_psMemmapCache, GFP_KERNEL);
+    if(psOffsetStruct == IMG_NULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR,"PVRMMapRegisterArea: Couldn't alloc another mapping record from cache"));
+        return IMG_NULL;
+    }
+    
+    psOffsetStruct->ui32MMapOffset = ui32Offset;
+
+    psOffsetStruct->psLinuxMemArea = psLinuxMemArea;
+
+    psOffsetStruct->ui32RealByteSize = ui32RealByteSize;
+
+    
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+    psOffsetStruct->ui32TID = GetCurrentThreadID();
+#endif
+    psOffsetStruct->ui32PID = OSGetCurrentProcessIDKM();
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+    
+    psOffsetStruct->pszName = pszName;
+#endif
+
+    list_add_tail(&psOffsetStruct->sAreaItem, &psLinuxMemArea->sMMapOffsetStructList);
+
+    return psOffsetStruct;
+}
+
+
+static IMG_VOID
+DestroyOffsetStruct(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+#ifdef DEBUG
+    IMG_CPU_PHYADDR CpuPAddr;
+    CpuPAddr = LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0);
+#endif
+
+    list_del(&psOffsetStruct->sAreaItem);
+
+    if (psOffsetStruct->bOnMMapList)
+    {
+        list_del(&psOffsetStruct->sMMapItem);
+    }
+
+#ifdef DEBUG
+    PVR_DPF((PVR_DBG_MESSAGE, "%s: Table entry: "
+             "psLinuxMemArea=%p, CpuPAddr=0x%08X", __FUNCTION__,
+             psOffsetStruct->psLinuxMemArea,
+             CpuPAddr.uiAddr));
+#endif
+    
+    KMemCacheFreeWrapper(g_psMemmapCache, psOffsetStruct);
+}
+
+
+static inline IMG_VOID
+DetermineUsersSizeAndByteOffset(LinuxMemArea *psLinuxMemArea,
+                               IMG_UINT32 *pui32RealByteSize,
+                               IMG_UINT32 *pui32ByteOffset)
+{
+    IMG_UINT32 ui32PageAlignmentOffset;
+    IMG_CPU_PHYADDR CpuPAddr;
+    
+    CpuPAddr = LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0);
+    ui32PageAlignmentOffset = ADDR_TO_PAGE_OFFSET(CpuPAddr.uiAddr);
+    
+    *pui32ByteOffset = ui32PageAlignmentOffset;
+
+    *pui32RealByteSize = PAGE_ALIGN(psLinuxMemArea->ui32ByteSize + ui32PageAlignmentOffset);
+}
+
+
+PVRSRV_ERROR
+PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+                             IMG_SID     hMHandle,
+#else
+                             IMG_HANDLE hMHandle,
+#endif
+                             IMG_UINT32 *pui32MMapOffset,
+                             IMG_UINT32 *pui32ByteOffset,
+                             IMG_UINT32 *pui32RealByteSize,
+                             IMG_UINT32 *pui32UserVAddr)
+{
+    LinuxMemArea *psLinuxMemArea;
+    PKV_OFFSET_STRUCT psOffsetStruct;
+    IMG_HANDLE hOSMemHandle;
+    PVRSRV_ERROR eError;
+
+    LinuxLockMutex(&g_sMMapMutex);
+
+    PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE);
+
+    eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle);
+    if (eError != PVRSRV_OK)
+    {
+#if defined (SUPPORT_SID_INTERFACE)
+        PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %x failed", __FUNCTION__, hMHandle));
+#else
+        PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle));
+#endif
+
+        goto exit_unlock;
+    }
+
+    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+    DetermineUsersSizeAndByteOffset(psLinuxMemArea,
+                                   pui32RealByteSize,
+                                   pui32ByteOffset);
+
+    
+    list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+    {
+        if (psPerProc->ui32PID == psOffsetStruct->ui32PID)
+        {
+
+	   PVR_ASSERT(*pui32RealByteSize == psOffsetStruct->ui32RealByteSize);
+	   
+	   *pui32MMapOffset = psOffsetStruct->ui32MMapOffset;
+	   *pui32UserVAddr = psOffsetStruct->ui32UserVAddr;
+	   psOffsetStruct->ui32RefCount++;
+
+	   eError = PVRSRV_OK;
+	   goto exit_unlock;
+        }
+    }
+
+    
+    *pui32UserVAddr = 0;
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+    if (LinuxMemAreaUsesPhysicalMap(psLinuxMemArea))
+    {
+        *pui32MMapOffset = LinuxMemAreaToCpuPFN(psLinuxMemArea, 0);
+        PVR_ASSERT(PFNIsPhysical(*pui32MMapOffset));
+    }
+    else
+#endif
+    {
+        *pui32MMapOffset = HandleToMMapOffset(hMHandle);
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+        PVR_ASSERT(PFNIsSpecial(*pui32MMapOffset));
+#endif
+    }
+
+    psOffsetStruct = CreateOffsetStruct(psLinuxMemArea, *pui32MMapOffset, *pui32RealByteSize);
+    if (psOffsetStruct == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+	goto exit_unlock;
+    }
+
+    
+    list_add_tail(&psOffsetStruct->sMMapItem, &g_sMMapOffsetStructList);
+
+    psOffsetStruct->bOnMMapList = IMG_TRUE;
+
+    psOffsetStruct->ui32RefCount++;
+
+    eError = PVRSRV_OK;
+
+	
+
+
+	*pui32MMapOffset = *pui32MMapOffset << (PAGE_SHIFT - 12);
+
+exit_unlock:
+    LinuxUnLockMutex(&g_sMMapMutex);
+
+    return eError;
+}
+
+
+PVRSRV_ERROR
+PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+				IMG_SID   hMHandle,
+#else
+				IMG_HANDLE hMHandle,
+#endif
+				IMG_BOOL *pbMUnmap,
+				IMG_UINT32 *pui32RealByteSize,
+                                IMG_UINT32 *pui32UserVAddr)
+{
+    LinuxMemArea *psLinuxMemArea;
+    PKV_OFFSET_STRUCT psOffsetStruct;
+    IMG_HANDLE hOSMemHandle;
+    PVRSRV_ERROR eError;
+    IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+
+    LinuxLockMutex(&g_sMMapMutex);
+
+    PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE);
+
+    eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle);
+    if (eError != PVRSRV_OK)
+    {
+#if defined (SUPPORT_SID_INTERFACE)
+	PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %x failed", __FUNCTION__, hMHandle));
+#else
+	PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle));
+#endif
+
+	goto exit_unlock;
+    }
+
+    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+    
+    list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+    {
+        if (psOffsetStruct->ui32PID == ui32PID)
+        {
+	    if (psOffsetStruct->ui32RefCount == 0)
+	    {
+		PVR_DPF((PVR_DBG_ERROR, "%s: Attempt to release mmap data with zero reference count for offset struct 0x%p, memory area %p", __FUNCTION__, psOffsetStruct, psLinuxMemArea));
+		eError = PVRSRV_ERROR_STILL_MAPPED;
+		goto exit_unlock;
+	    }
+
+	    psOffsetStruct->ui32RefCount--;
+
+	    *pbMUnmap = (IMG_BOOL)((psOffsetStruct->ui32RefCount == 0) && (psOffsetStruct->ui32UserVAddr != 0));
+
+	    *pui32UserVAddr = (*pbMUnmap) ? psOffsetStruct->ui32UserVAddr : 0;
+	    *pui32RealByteSize = (*pbMUnmap) ? psOffsetStruct->ui32RealByteSize : 0;
+
+	    eError = PVRSRV_OK;
+	    goto exit_unlock;
+        }
+    }
+
+    
+#if defined (SUPPORT_SID_INTERFACE)
+    PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle %x (memory area %p)", __FUNCTION__, hMHandle, psLinuxMemArea));
+#else
+    PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle %p (memory area %p)", __FUNCTION__, hMHandle, psLinuxMemArea));
+#endif
+
+    eError =  PVRSRV_ERROR_MAPPING_NOT_FOUND;
+
+exit_unlock:
+    LinuxUnLockMutex(&g_sMMapMutex);
+
+    return eError;
+}
+
+static inline PKV_OFFSET_STRUCT
+FindOffsetStructByOffset(IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize)
+{
+    PKV_OFFSET_STRUCT psOffsetStruct;
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+    IMG_UINT32 ui32TID = GetCurrentThreadID();
+#endif
+    IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+
+    list_for_each_entry(psOffsetStruct, &g_sMMapOffsetStructList, sMMapItem)
+    {
+        if (ui32Offset == psOffsetStruct->ui32MMapOffset && ui32RealByteSize == psOffsetStruct->ui32RealByteSize && psOffsetStruct->ui32PID == ui32PID)
+        {
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+	    
+	    if (!PFNIsPhysical(ui32Offset) || psOffsetStruct->ui32TID == ui32TID)
+#endif
+	    {
+	        return psOffsetStruct;
+	    }
+        }
+    }
+
+    return IMG_NULL;
+}
+
+
+static IMG_BOOL
+DoMapToUser(LinuxMemArea *psLinuxMemArea,
+            struct vm_area_struct* ps_vma,
+            IMG_UINT32 ui32ByteOffset)
+{
+    IMG_UINT32 ui32ByteSize;
+
+    if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
+    {
+        return DoMapToUser(LinuxMemAreaRoot(psLinuxMemArea),		 
+                    ps_vma,
+                    psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset + ui32ByteOffset);
+    }
+
+    
+    ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start;
+    PVR_ASSERT(ADDR_TO_PAGE_OFFSET(ui32ByteSize) == 0);
+
+#if defined (__sparc__)
+    
+#error "SPARC not supported"
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+    if (PFNIsPhysical(ps_vma->vm_pgoff))
+    {
+	IMG_INT result;
+
+	PVR_ASSERT(LinuxMemAreaPhysIsContig(psLinuxMemArea));
+	PVR_ASSERT(LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) == ps_vma->vm_pgoff);
+        
+	result = IO_REMAP_PFN_RANGE(ps_vma, ps_vma->vm_start, ps_vma->vm_pgoff, ui32ByteSize, ps_vma->vm_page_prot);
+
+        if(result == 0)
+        {
+            return IMG_TRUE;
+        }
+
+        PVR_DPF((PVR_DBG_MESSAGE, "%s: Failed to map contiguous physical address range (%d), trying non-contiguous path", __FUNCTION__, result));
+    }
+#endif
+
+    {
+        
+        IMG_UINT32 ulVMAPos;
+	IMG_UINT32 ui32ByteEnd = ui32ByteOffset + ui32ByteSize;
+	IMG_UINT32 ui32PA;
+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+	IMG_BOOL bMixedMap = IMG_FALSE;
+#endif
+	
+	for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
+	{
+	    IMG_UINT32 pfn =  LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA);
+
+	    if (!pfn_valid(pfn))
+	    {
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+                PVR_DPF((PVR_DBG_ERROR,"%s: Error - PFN invalid: 0x%x", __FUNCTION__, pfn));
+                return IMG_FALSE;
+#else
+		bMixedMap = IMG_TRUE;
+#endif
+	    }
+	}
+
+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+	if (bMixedMap)
+	{
+            ps_vma->vm_flags |= VM_MIXEDMAP;
+	}
+#endif
+	
+        ulVMAPos = ps_vma->vm_start;
+	for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
+	{
+	    IMG_UINT32 pfn;
+	    IMG_INT result;
+
+	    pfn =  LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA);
+
+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+	    if (bMixedMap)
+	    {
+		result = vm_insert_mixed(ps_vma, ulVMAPos, pfn);
+                if(result != 0)
+                {
+                    PVR_DPF((PVR_DBG_ERROR,"%s: Error - vm_insert_mixed failed (%d)", __FUNCTION__, result));
+                    return IMG_FALSE;
+                }
+	    }
+	    else
+#endif
+	    {
+		struct page *psPage;
+
+	        PVR_ASSERT(pfn_valid(pfn));
+
+	        psPage = pfn_to_page(pfn);
+
+	        result = VM_INSERT_PAGE(ps_vma,  ulVMAPos, psPage);
+                if(result != 0)
+                {
+                    PVR_DPF((PVR_DBG_ERROR,"%s: Error - VM_INSERT_PAGE failed (%d)", __FUNCTION__, result));
+                    return IMG_FALSE;
+                }
+	    }
+            ulVMAPos += PAGE_SIZE;
+        }
+    }
+
+    return IMG_TRUE;
+}
+
+
+static IMG_VOID
+MMapVOpenNoLock(struct vm_area_struct* ps_vma)
+{
+    PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
+    PVR_ASSERT(psOffsetStruct != IMG_NULL)
+    psOffsetStruct->ui32Mapped++;
+    PVR_ASSERT(!psOffsetStruct->bOnMMapList);
+
+    if (psOffsetStruct->ui32Mapped > 1)
+    {
+	PVR_DPF((PVR_DBG_WARNING, "%s: Offset structure 0x%p is being shared across processes (psOffsetStruct->ui32Mapped: %u)", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32Mapped));
+        PVR_ASSERT((ps_vma->vm_flags & VM_DONTCOPY) == 0);
+    }
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+
+    PVR_DPF((PVR_DBG_MESSAGE,
+             "%s: psLinuxMemArea 0x%p, KVAddress 0x%p MMapOffset %d, ui32Mapped %d",
+             __FUNCTION__,
+             psOffsetStruct->psLinuxMemArea,
+             LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
+             psOffsetStruct->ui32MMapOffset,
+             psOffsetStruct->ui32Mapped));
+#endif
+}
+
+
+static void
+MMapVOpen(struct vm_area_struct* ps_vma)
+{
+    LinuxLockMutex(&g_sMMapMutex);
+
+    MMapVOpenNoLock(ps_vma);
+
+    LinuxUnLockMutex(&g_sMMapMutex);
+}
+
+
+static IMG_VOID
+MMapVCloseNoLock(struct vm_area_struct* ps_vma)
+{
+    PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
+    PVR_ASSERT(psOffsetStruct != IMG_NULL)
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+    PVR_DPF((PVR_DBG_MESSAGE,
+             "%s: psLinuxMemArea %p, CpuVAddr %p ui32MMapOffset %d, ui32Mapped %d",
+             __FUNCTION__,
+             psOffsetStruct->psLinuxMemArea,
+             LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
+             psOffsetStruct->ui32MMapOffset,
+             psOffsetStruct->ui32Mapped));
+#endif
+
+    PVR_ASSERT(!psOffsetStruct->bOnMMapList);
+    psOffsetStruct->ui32Mapped--;
+    if (psOffsetStruct->ui32Mapped == 0)
+    {
+	if (psOffsetStruct->ui32RefCount != 0)
+	{
+	        PVR_DPF((PVR_DBG_MESSAGE, "%s: psOffsetStruct %p has non-zero reference count (ui32RefCount = %u). User mode address of start of mapping: 0x%x", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32RefCount, psOffsetStruct->ui32UserVAddr));
+	}
+
+	DestroyOffsetStruct(psOffsetStruct);
+    }
+
+    ps_vma->vm_private_data = NULL;
+}
+
+static void
+MMapVClose(struct vm_area_struct* ps_vma)
+{
+    LinuxLockMutex(&g_sMMapMutex);
+
+    MMapVCloseNoLock(ps_vma);
+
+    LinuxUnLockMutex(&g_sMMapMutex);
+}
+
+
+static struct vm_operations_struct MMapIOOps =
+{
+	.open=MMapVOpen,
+	.close=MMapVClose
+};
+
+
+int
+PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma)
+{
+    IMG_UINT32 ui32ByteSize;
+    PKV_OFFSET_STRUCT psOffsetStruct;
+    int iRetVal = 0;
+
+    PVR_UNREFERENCED_PARAMETER(pFile);
+
+    LinuxLockMutex(&g_sMMapMutex);
+    
+    ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start;
+    
+    PVR_DPF((PVR_DBG_MESSAGE, "%s: Received mmap(2) request with ui32MMapOffset 0x%08lx,"
+                              " and ui32ByteSize %d(0x%08x)",
+            __FUNCTION__,
+            ps_vma->vm_pgoff,
+            ui32ByteSize, ui32ByteSize));
+   
+    psOffsetStruct = FindOffsetStructByOffset(ps_vma->vm_pgoff, ui32ByteSize);
+    if (psOffsetStruct == IMG_NULL)
+    {
+#if defined(SUPPORT_DRI_DRM)
+        LinuxUnLockMutex(&g_sMMapMutex);
+
+#if !defined(SUPPORT_DRI_DRM_EXT)
+	
+        return drm_mmap(pFile, ps_vma);
+#else
+	
+	return -ENOENT;
+#endif
+#else
+        PVR_UNREFERENCED_PARAMETER(pFile);
+
+        PVR_DPF((PVR_DBG_ERROR,
+             "%s: Attempted to mmap unregistered area at vm_pgoff 0x%lx",
+             __FUNCTION__, ps_vma->vm_pgoff));
+        iRetVal = -EINVAL;
+#endif
+        goto unlock_and_return;
+    }
+    list_del(&psOffsetStruct->sMMapItem);
+    psOffsetStruct->bOnMMapList = IMG_FALSE;
+
+    
+    if (((ps_vma->vm_flags & VM_WRITE) != 0) &&
+        ((ps_vma->vm_flags & VM_SHARED) == 0))
+    {
+        PVR_DPF((PVR_DBG_ERROR, "%s: Cannot mmap non-shareable writable areas", __FUNCTION__));
+        iRetVal = -EINVAL;
+        goto unlock_and_return;
+    }
+   
+    PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped psLinuxMemArea 0x%p\n",
+         __FUNCTION__, psOffsetStruct->psLinuxMemArea));
+
+    ps_vma->vm_flags |= VM_RESERVED;
+    ps_vma->vm_flags |= VM_IO;
+
+    
+    ps_vma->vm_flags |= VM_DONTEXPAND;
+    
+    
+    ps_vma->vm_flags |= VM_DONTCOPY;
+
+    ps_vma->vm_private_data = (void *)psOffsetStruct;
+    
+    switch(psOffsetStruct->psLinuxMemArea->ui32AreaFlags & PVRSRV_HAP_CACHETYPE_MASK)
+    {
+        case PVRSRV_HAP_CACHED:
+            
+            break;
+        case PVRSRV_HAP_WRITECOMBINE:
+	    ps_vma->vm_page_prot = PGPROT_WC(ps_vma->vm_page_prot);
+            break;
+        case PVRSRV_HAP_UNCACHED:
+            ps_vma->vm_page_prot = PGPROT_UC(ps_vma->vm_page_prot);
+            break;
+        default:
+            PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type", __FUNCTION__));
+	    iRetVal = -EINVAL;
+	    goto unlock_and_return;
+    }
+    
+    
+    ps_vma->vm_ops = &MMapIOOps;
+    
+    if(!DoMapToUser(psOffsetStruct->psLinuxMemArea, ps_vma, 0))
+    {
+        iRetVal = -EAGAIN;
+        goto unlock_and_return;
+    }
+    
+    PVR_ASSERT(psOffsetStruct->ui32UserVAddr == 0)
+
+    psOffsetStruct->ui32UserVAddr = ps_vma->vm_start;
+
+    
+    if(psOffsetStruct->psLinuxMemArea->bNeedsCacheInvalidate)
+    {
+        IMG_UINT32 ui32RealByteSize, ui32ByteOffset;
+        IMG_VOID *pvBase;
+
+        DetermineUsersSizeAndByteOffset(psOffsetStruct->psLinuxMemArea,
+                                        &ui32RealByteSize,
+                                        &ui32ByteOffset);
+
+        ui32RealByteSize = psOffsetStruct->psLinuxMemArea->ui32ByteSize;
+        pvBase = (IMG_VOID *)ps_vma->vm_start + ui32ByteOffset;
+
+        OSInvalidateCPUCacheRangeKM(psOffsetStruct->psLinuxMemArea,
+                                    pvBase, ui32RealByteSize);
+        psOffsetStruct->psLinuxMemArea->bNeedsCacheInvalidate = IMG_FALSE;
+    }
+
+    
+    MMapVOpenNoLock(ps_vma);
+    
+    PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped area at offset 0x%08lx\n",
+             __FUNCTION__, ps_vma->vm_pgoff));
+    
+unlock_and_return:
+    if (iRetVal != 0 && psOffsetStruct != IMG_NULL)
+    {
+	DestroyOffsetStruct(psOffsetStruct);
+    }
+
+    LinuxUnLockMutex(&g_sMMapMutex);
+    
+    return iRetVal;
+}
+
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+
+static void ProcSeqStartstopMMapRegistations(struct seq_file *sfile,IMG_BOOL start) 
+{
+	if(start) 
+	{
+	    LinuxLockMutex(&g_sMMapMutex);		
+	}
+	else
+	{
+	    LinuxUnLockMutex(&g_sMMapMutex);
+	}
+}
+
+
+static void* ProcSeqOff2ElementMMapRegistrations(struct seq_file *sfile, loff_t off)
+{
+    LinuxMemArea *psLinuxMemArea;
+	if(!off) 
+	{
+		return PVR_PROC_SEQ_START_TOKEN;
+	}
+
+    list_for_each_entry(psLinuxMemArea, &g_sMMapAreaList, sMMapItem)
+    {
+        PKV_OFFSET_STRUCT psOffsetStruct;
+
+	 	list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+        {
+	    	off--;
+	    	if (off == 0)
+	    	{				
+				PVR_ASSERT(psOffsetStruct->psLinuxMemArea == psLinuxMemArea);
+				return (void*)psOffsetStruct;
+		    }
+        }
+    }
+	return (void*)0;
+}
+
+static void* ProcSeqNextMMapRegistrations(struct seq_file *sfile,void* el,loff_t off)
+{
+	return ProcSeqOff2ElementMMapRegistrations(sfile,off);
+}
+
+
+static void ProcSeqShowMMapRegistrations(struct seq_file *sfile, void *el)
+{
+	KV_OFFSET_STRUCT *psOffsetStruct = (KV_OFFSET_STRUCT*)el;
+    LinuxMemArea *psLinuxMemArea;
+	IMG_UINT32 ui32RealByteSize;
+	IMG_UINT32 ui32ByteOffset;
+
+	if(el == PVR_PROC_SEQ_START_TOKEN) 
+	{
+        seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+						  "Allocations registered for mmap: %u\n"
+                          "In total these areas correspond to %u bytes\n"
+                          "psLinuxMemArea "
+						  "UserVAddr "
+						  "KernelVAddr "
+						  "CpuPAddr "
+                          "MMapOffset "
+                          "ByteLength "
+                          "LinuxMemType             "
+						  "Pid   Name     Flags\n",
+#else
+                          "<mmap_header>\n"
+                          "\t<count>%u</count>\n"
+                          "\t<bytes>%u</bytes>\n"
+                          "</mmap_header>\n",
+#endif
+						  g_ui32RegisteredAreas,
+                          g_ui32TotalByteSize
+                          );
+		return;
+	}
+
+   	psLinuxMemArea = psOffsetStruct->psLinuxMemArea;
+
+	DetermineUsersSizeAndByteOffset(psLinuxMemArea,
+									&ui32RealByteSize,
+									&ui32ByteOffset);
+
+	seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+						"%-8p       %08x %-8p %08x %08x   %-8d   %-24s %-5u %-8s %08x(%s)\n",
+#else
+                        "<mmap_record>\n"
+						"\t<pointer>%-8p</pointer>\n"
+                        "\t<user_virtual>%-8x</user_virtual>\n"
+                        "\t<kernel_virtual>%-8p</kernel_virtual>\n"
+                        "\t<cpu_physical>%08x</cpu_physical>\n"
+                        "\t<mmap_offset>%08x</mmap_offset>\n"
+                        "\t<bytes>%-8d</bytes>\n"
+                        "\t<linux_mem_area_type>%-24s</linux_mem_area_type>\n"
+                        "\t<pid>%-5u</pid>\n"
+                        "\t<name>%-8s</name>\n"
+                        "\t<flags>%08x</flags>\n"
+                        "\t<flags_string>%s</flags_string>\n"
+                        "</mmap_record>\n",
+#endif
+                        psLinuxMemArea,
+						psOffsetStruct->ui32UserVAddr + ui32ByteOffset,
+						LinuxMemAreaToCpuVAddr(psLinuxMemArea),
+                        LinuxMemAreaToCpuPAddr(psLinuxMemArea,0).uiAddr,
+						psOffsetStruct->ui32MMapOffset,
+						psLinuxMemArea->ui32ByteSize,
+                        LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType),
+						psOffsetStruct->ui32PID,
+						psOffsetStruct->pszName,
+						psLinuxMemArea->ui32AreaFlags,
+                        HAPFlagsToString(psLinuxMemArea->ui32AreaFlags));
+}
+
+#endif
+
+
+PVRSRV_ERROR
+PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea)
+{
+    PVRSRV_ERROR eError;
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+    const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea));
+#endif
+
+    LinuxLockMutex(&g_sMMapMutex);
+
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+    PVR_DPF((PVR_DBG_MESSAGE,
+             "%s(%s, psLinuxMemArea 0x%p, ui32AllocFlags 0x%8x)",
+             __FUNCTION__, pszName, psLinuxMemArea,  psLinuxMemArea->ui32AreaFlags));
+#endif
+
+    PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
+
+    
+    if(psLinuxMemArea->bMMapRegistered)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "%s: psLinuxMemArea 0x%p is already registered",
+                __FUNCTION__, psLinuxMemArea));
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+	goto exit_unlock;
+    }
+
+    list_add_tail(&psLinuxMemArea->sMMapItem, &g_sMMapAreaList);
+
+    psLinuxMemArea->bMMapRegistered = IMG_TRUE;
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+    g_ui32RegisteredAreas++;
+    
+    if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+    {
+        g_ui32TotalByteSize += psLinuxMemArea->ui32ByteSize;
+    }
+#endif
+
+    eError = PVRSRV_OK;
+
+exit_unlock:
+    LinuxUnLockMutex(&g_sMMapMutex);
+
+    return eError;
+}
+
+
+PVRSRV_ERROR
+PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea)
+{
+    PVRSRV_ERROR eError;
+    PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct;
+
+    LinuxLockMutex(&g_sMMapMutex);
+
+    PVR_ASSERT(psLinuxMemArea->bMMapRegistered);
+
+    list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+    {
+	if (psOffsetStruct->ui32Mapped != 0)
+	{
+	     PVR_DPF((PVR_DBG_ERROR, "%s: psOffsetStruct 0x%p for memory area 0x0x%p is still mapped; psOffsetStruct->ui32Mapped %u",  __FUNCTION__, psOffsetStruct, psLinuxMemArea, psOffsetStruct->ui32Mapped));
+		eError = PVRSRV_ERROR_STILL_MAPPED;
+		goto exit_unlock;
+	}
+	else
+	{
+	      
+	     PVR_DPF((PVR_DBG_WARNING, "%s: psOffsetStruct 0x%p was never mapped",  __FUNCTION__, psOffsetStruct));
+	}
+
+	PVR_ASSERT((psOffsetStruct->ui32Mapped == 0) && psOffsetStruct->bOnMMapList);
+
+	DestroyOffsetStruct(psOffsetStruct);
+    }
+
+    list_del(&psLinuxMemArea->sMMapItem);
+
+    psLinuxMemArea->bMMapRegistered = IMG_FALSE;
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+    g_ui32RegisteredAreas--;
+    if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+    {
+        g_ui32TotalByteSize -= psLinuxMemArea->ui32ByteSize;
+    }
+#endif
+
+    eError = PVRSRV_OK;
+
+exit_unlock:
+    LinuxUnLockMutex(&g_sMMapMutex);
+    return eError;
+}
+
+
+PVRSRV_ERROR
+LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc)
+{
+    PVR_UNREFERENCED_PARAMETER(psEnvPerProc);
+
+    return PVRSRV_OK;
+}
+
+IMG_VOID
+LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc)
+{
+    PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct;
+    IMG_BOOL bWarn = IMG_FALSE;
+    IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+
+    PVR_UNREFERENCED_PARAMETER(psEnvPerProc);
+
+    LinuxLockMutex(&g_sMMapMutex);
+
+    list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &g_sMMapOffsetStructList, sMMapItem)
+    {
+	if (psOffsetStruct->ui32PID == ui32PID)
+	{
+	    if (!bWarn)
+	    {
+		PVR_DPF((PVR_DBG_WARNING, "%s: process has unmapped offset structures. Removing them", __FUNCTION__));
+		bWarn = IMG_TRUE;
+	    }
+	    PVR_ASSERT(psOffsetStruct->ui32Mapped == 0);
+	    PVR_ASSERT(psOffsetStruct->bOnMMapList);
+
+	    DestroyOffsetStruct(psOffsetStruct);
+	}
+    }
+
+    LinuxUnLockMutex(&g_sMMapMutex);
+}
+
+
+PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
+{
+    PVRSRV_ERROR eError;
+
+    eError = PVRSRVSetMaxHandle(psHandleBase, MAX_MMAP_HANDLE);
+    if (eError != PVRSRV_OK)
+    {
+	PVR_DPF((PVR_DBG_ERROR,"%s: failed to set handle limit (%d)", __FUNCTION__, eError));
+	return eError;
+    }
+
+    return eError;
+}
+
+
+IMG_VOID
+PVRMMapInit(IMG_VOID)
+{
+    LinuxInitMutex(&g_sMMapMutex);
+
+    g_psMemmapCache = KMemCacheCreateWrapper("img-mmap", sizeof(KV_OFFSET_STRUCT), 0, 0);
+    if (!g_psMemmapCache)
+    {
+        PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__));
+	goto error;
+    }
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+	g_ProcMMap = CreateProcReadEntrySeq("mmap", NULL, 
+						  ProcSeqNextMMapRegistrations,
+						  ProcSeqShowMMapRegistrations,
+						  ProcSeqOff2ElementMMapRegistrations,
+						  ProcSeqStartstopMMapRegistations
+						 );
+#endif  
+    return;
+
+error:
+    PVRMMapCleanup();
+    return;
+}
+
+
+IMG_VOID
+PVRMMapCleanup(IMG_VOID)
+{
+    PVRSRV_ERROR eError;
+
+    if (!list_empty(&g_sMMapAreaList))
+    {
+	LinuxMemArea *psLinuxMemArea, *psTmpMemArea;
+
+	PVR_DPF((PVR_DBG_ERROR, "%s: Memory areas are still registered with MMap", __FUNCTION__));
+	
+	PVR_TRACE(("%s: Unregistering memory areas", __FUNCTION__));
+ 	list_for_each_entry_safe(psLinuxMemArea, psTmpMemArea, &g_sMMapAreaList, sMMapItem)
+	{
+		eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "%s: PVRMMapRemoveRegisteredArea failed (%d)", __FUNCTION__, eError));
+		}
+		PVR_ASSERT(eError == PVRSRV_OK);
+
+		LinuxMemAreaDeepFree(psLinuxMemArea);
+	}
+    }
+    PVR_ASSERT(list_empty((&g_sMMapAreaList)));
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+    RemoveProcEntrySeq(g_ProcMMap);
+#endif 
+
+    if(g_psMemmapCache)
+    {
+        KMemCacheDestroyWrapper(g_psMemmapCache);
+        g_psMemmapCache = NULL;
+    }
+}
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mmap.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mmap.h
new file mode 100644
index 0000000..224e652
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mmap.h
@@ -0,0 +1,122 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined(__MMAP_H__)
+#define __MMAP_H__
+
+#include <linux/mm.h>
+#include <linux/list.h>
+
+#if defined(VM_MIXEDMAP)
+#define	PVR_MAKE_ALL_PFNS_SPECIAL
+#endif
+
+#include "perproc.h"
+#include "mm.h"
+
+typedef struct KV_OFFSET_STRUCT_TAG
+{
+    
+    IMG_UINT32			ui32Mapped;
+
+    
+    IMG_UINT32                  ui32MMapOffset;
+    
+    IMG_UINT32			ui32RealByteSize;
+
+    
+    LinuxMemArea                *psLinuxMemArea;
+    
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+    
+    IMG_UINT32			ui32TID;
+#endif
+
+    
+    IMG_UINT32			ui32PID;
+
+    
+    IMG_BOOL			bOnMMapList;
+
+    
+    IMG_UINT32			ui32RefCount;
+
+    
+    IMG_UINT32			ui32UserVAddr;
+
+    
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+    const IMG_CHAR		*pszName;
+#endif
+    
+   
+   struct list_head		sMMapItem;
+
+   
+   struct list_head		sAreaItem;
+}KV_OFFSET_STRUCT, *PKV_OFFSET_STRUCT;
+
+
+
+IMG_VOID PVRMMapInit(IMG_VOID);
+
+
+IMG_VOID PVRMMapCleanup(IMG_VOID);
+
+
+PVRSRV_ERROR PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea);
+
+
+PVRSRV_ERROR PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea);
+
+
+PVRSRV_ERROR PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+                                          IMG_SID     hMHandle,
+#else
+                                          IMG_HANDLE hMHandle,
+#endif
+                                          IMG_UINT32 *pui32MMapOffset,
+                                          IMG_UINT32 *pui32ByteOffset,
+                                          IMG_UINT32 *pui32RealByteSize,
+                                          IMG_UINT32 *pui32UserVAddr);
+
+PVRSRV_ERROR
+PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+				IMG_SID   hMHandle,
+#else
+				IMG_HANDLE hMHandle,
+#endif
+				IMG_BOOL *pbMUnmap,
+				IMG_UINT32 *pui32RealByteSize,
+                                IMG_UINT32 *pui32UserVAddr);
+
+int PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma);
+
+
+#endif	
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/module.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/module.c
new file mode 100644
index 0000000..9899d85
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/module.c
@@ -0,0 +1,771 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#if defined(SUPPORT_DRI_DRM)
+#define	PVR_MOD_STATIC
+#else
+	
+	#if defined(LDM_PLATFORM)
+		#define	PVR_LDM_PLATFORM_MODULE
+		#define	PVR_LDM_MODULE
+	#else
+		#if defined(LDM_PCI)
+			#define PVR_LDM_PCI_MODULE
+			#define	PVR_LDM_MODULE
+		#endif
+	#endif
+#define	PVR_MOD_STATIC	static
+#endif
+
+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED)
+#if !defined(NO_HARDWARE)
+#define PVR_USE_PRE_REGISTERED_PLATFORM_DEV
+#endif
+#endif
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
+#include "env_perproc.h"
+#endif
+#endif
+
+#if defined(PVR_LDM_PLATFORM_MODULE)
+#include <linux/platform_device.h>
+#endif 
+
+#if defined(PVR_LDM_PCI_MODULE)
+#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"
+#include "kernelbuffer.h"
+#include "syscommon.h"
+#include "pvrmmap.h"
+#include "mutils.h"
+#include "mm.h"
+#include "mmap.h"
+#include "mutex.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "perproc.h"
+#include "handle.h"
+#include "pvr_bridge_km.h"
+#include "proc.h"
+#include "pvrmodule.h"
+#include "private_data.h"
+#include "lock.h"
+#include "linkage.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#include "pvr_drm.h"
+#endif
+#define PVRSRV_MODNAME	"PowerVR"
+#define DRVNAME		PVRSRV_MODNAME
+#define DEVNAME		PVRSRV_MODNAME
+
+#if defined(SUPPORT_DRI_DRM)
+#define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
+#else
+#define PRIVATE_DATA(pFile) ((pFile)->private_data)
+#endif
+
+MODULE_SUPPORTED_DEVICE(DEVNAME);
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+#include <linux/moduleparam.h>
+extern IMG_UINT32 gPVRDebugLevel;
+module_param(gPVRDebugLevel, uint, 0644);
+MODULE_PARM_DESC(gPVRDebugLevel, "Sets the level of debug output (default 0x7)");
+#endif 
+
+ 
+EXPORT_SYMBOL(PVRGetDisplayClassJTable);
+EXPORT_SYMBOL(PVRGetBufferClassJTable);
+
+#if defined(PVR_LDM_MODULE)
+static struct class *psPvrClass;
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+static int AssignedMajorNumber;
+
+static int PVRSRVOpen(struct inode* pInode, struct file* pFile);
+static int PVRSRVRelease(struct inode* pInode, struct file* pFile);
+
+static struct file_operations pvrsrv_fops =
+{
+	.owner=THIS_MODULE,
+	.unlocked_ioctl = PVRSRV_BridgeDispatchKM,
+	.open=PVRSRVOpen,
+	.release=PVRSRVRelease,
+	.mmap=PVRMMap,
+};
+#endif
+
+PVRSRV_LINUX_MUTEX gPVRSRVLock;
+
+IMG_UINT32 gui32ReleasePID;
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+static IMG_UINT32 gPVRPowerLevel;
+#endif
+
+#if defined(PVR_LDM_MODULE)
+
+#if defined(PVR_LDM_PLATFORM_MODULE)
+#define	LDM_DEV	struct platform_device
+#define	LDM_DRV	struct platform_driver
+#endif 
+
+#if defined(PVR_LDM_PCI_MODULE)
+#define	LDM_DEV	struct pci_dev
+#define	LDM_DRV	struct pci_driver
+#endif 
+#if defined(PVR_LDM_PLATFORM_MODULE)
+static int PVRSRVDriverRemove(LDM_DEV *device);
+static int PVRSRVDriverProbe(LDM_DEV *device);
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+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(PVR_LDM_PCI_MODULE)
+struct pci_device_id powervr_id_table[] __devinitdata = {
+	{PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID)},
+#if defined (SYS_SGX_DEV1_DEVICE_ID)
+	{PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID)},
+#endif
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, powervr_id_table);
+#endif
+
+#if defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+static struct platform_device_id powervr_id_table[] __devinitdata = {
+	{SYS_SGX_DEV_NAME, 0},
+	{}
+};
+#endif
+
+static LDM_DRV powervr_driver = {
+#if defined(PVR_LDM_PLATFORM_MODULE)
+	.driver = {
+		.name		= DRVNAME,
+	},
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+	.name		= DRVNAME,
+#endif
+#if defined(PVR_LDM_PCI_MODULE) || defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+	.id_table = powervr_id_table,
+#endif
+	.probe		= PVRSRVDriverProbe,
+#if defined(PVR_LDM_PLATFORM_MODULE)
+	.remove		= PVRSRVDriverRemove,
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+	.remove		= __devexit_p(PVRSRVDriverRemove),
+#endif
+	.suspend	= PVRSRVDriverSuspend,
+	.resume		= PVRSRVDriverResume,
+	.shutdown	= PVRSRVDriverShutdown,
+};
+
+LDM_DEV *gpsPVRLDMDev;
+
+#if defined(MODULE) && defined(PVR_LDM_PLATFORM_MODULE) && \
+	!defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+static void PVRSRVDeviceRelease(struct device unref__ *pDevice)
+{
+}
+
+static struct platform_device powervr_device = {
+	.name			= DEVNAME,
+	.id				= -1,
+	.dev 			= {
+		.release	= PVRSRVDeviceRelease
+	}
+};
+#endif
+
+#if defined(PVR_LDM_PLATFORM_MODULE)
+static int PVRSRVDriverProbe(LDM_DEV *pDevice)
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+static int __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id)
+#endif
+{
+	SYS_DATA *psSysData;
+
+	PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice));
+
+#if 0
+	
+	if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
+	{
+		return -EINVAL;
+	}
+#endif	
+	
+	psSysData = SysAcquireDataNoCheck();
+	if ( psSysData == IMG_NULL)
+	{
+		gpsPVRLDMDev = pDevice;
+
+		if (SysInitialise() != PVRSRV_OK)
+		{
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+static int PVRSRVDriverRemove(LDM_DEV *pDevice)
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+static void __devexit PVRSRVDriverRemove(LDM_DEV *pDevice)
+#endif
+{
+	SYS_DATA *psSysData;
+
+	PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice));
+
+	SysAcquireData(&psSysData);
+	
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+	if (gPVRPowerLevel != 0)
+	{
+		if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
+		{
+			gPVRPowerLevel = 0;
+		}
+	}
+#endif
+	(void) SysDeinitialise(psSysData);
+
+	gpsPVRLDMDev = IMG_NULL;
+
+#if 0
+	if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
+	{
+		return -EINVAL;
+	}
+#endif
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+	return 0;
+#endif
+#if defined (PVR_LDM_PCI_MODULE)
+	return;
+#endif
+}
+#endif 
+
+
+#if defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV)
+PVR_MOD_STATIC void PVRSRVDriverShutdown(LDM_DEV *pDevice)
+{
+	PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
+
+	(void) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
+}
+
+#endif 
+
+
+#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV)
+int PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state)
+#else
+PVR_MOD_STATIC int PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state)
+#endif
+{
+#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
+	PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice));
+
+	if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
+	{
+		return -EINVAL;
+	}
+#endif
+	return 0;
+}
+
+
+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV)
+int PVRSRVDriverResume(struct drm_device *pDevice)
+#else
+PVR_MOD_STATIC int PVRSRVDriverResume(LDM_DEV *pDevice)
+#endif
+{
+#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
+	PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice));
+
+	if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
+	{
+		return -EINVAL;
+	}
+#endif
+	return 0;
+}
+#endif 
+
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)
+IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
+{
+	IMG_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_SYS_POWER_STATE_D3) != PVRSRV_OK)
+				{
+					return -EINVAL;
+				}
+			}
+			else
+			{
+				if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
+				{
+					return -EINVAL;
+				}
+			}
+
+			gPVRPowerLevel = PVRPowerLevel;
+		}
+	}
+	return (count);
+}
+
+void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el)	
+{
+	seq_printf(sfile, "%lu\n", gPVRPowerLevel);
+}
+
+#endif
+
+#if defined(SUPPORT_DRI_DRM)
+int PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pFile)
+#else
+static int PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile)
+#endif
+{
+	PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+	IMG_HANDLE hBlockAlloc;
+	int iRet = -ENOMEM;
+	PVRSRV_ERROR eError;
+	IMG_UINT32 ui32PID;
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+	PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+#endif
+
+	LinuxLockMutex(&gPVRSRVLock);
+
+	ui32PID = OSGetCurrentProcessIDKM();
+
+	if (PVRSRVProcessConnect(ui32PID, 0) != PVRSRV_OK)
+		goto err_unlock;
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+	psEnvPerProc = PVRSRVPerProcessPrivateData(ui32PID);
+	if (psEnvPerProc == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: No per-process private data", __FUNCTION__));
+		goto err_unlock;
+	}
+#endif
+
+	eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+						sizeof(PVRSRV_FILE_PRIVATE_DATA),
+						(IMG_PVOID *)&psPrivateData,
+						&hBlockAlloc,
+						"File Private Data");
+
+	if(eError != PVRSRV_OK)
+		goto err_unlock;
+
+#if defined (SUPPORT_SID_INTERFACE)
+	psPrivateData->hKernelMemInfo = 0;
+#else
+	psPrivateData->hKernelMemInfo = NULL;
+#endif
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+	psPrivateData->psDRMFile = pFile;
+
+	list_add_tail(&psPrivateData->sDRMAuthListItem, &psEnvPerProc->sDRMAuthListHead);
+#endif
+	psPrivateData->ui32OpenPID = ui32PID;
+	psPrivateData->hBlockAlloc = hBlockAlloc;
+	PRIVATE_DATA(pFile) = psPrivateData;
+	iRet = 0;
+err_unlock:	
+	LinuxUnLockMutex(&gPVRSRVLock);
+	return iRet;
+}
+
+
+#if defined(SUPPORT_DRI_DRM)
+void PVRSRVRelease(void *pvPrivData)
+#else
+static int PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile)
+#endif
+{
+	PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+
+	LinuxLockMutex(&gPVRSRVLock);
+
+#if defined(SUPPORT_DRI_DRM)
+	psPrivateData = (PVRSRV_FILE_PRIVATE_DATA *)pvPrivData;
+#else
+	psPrivateData = PRIVATE_DATA(pFile);
+#endif
+	if (psPrivateData != IMG_NULL)
+	{
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+		list_del(&psPrivateData->sDRMAuthListItem);
+#endif
+
+		
+		gui32ReleasePID = psPrivateData->ui32OpenPID;
+		PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID);
+		gui32ReleasePID = 0;
+
+		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				  sizeof(PVRSRV_FILE_PRIVATE_DATA),
+				  psPrivateData, psPrivateData->hBlockAlloc);
+
+#if !defined(SUPPORT_DRI_DRM)
+		PRIVATE_DATA(pFile) = IMG_NULL; 
+#endif
+	}
+
+	LinuxUnLockMutex(&gPVRSRVLock);
+
+#if !defined(SUPPORT_DRI_DRM)
+	return 0;
+#endif
+}
+
+
+#if defined(SUPPORT_DRI_DRM)
+int PVRCore_Init(void)
+#else
+static int __init PVRCore_Init(void)
+#endif
+{
+	int error;
+#if !defined(PVR_LDM_MODULE)
+	PVRSRV_ERROR eError;
+#else
+	struct device *psDev;
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+	
+	PVRDPFInit();
+#endif
+	PVR_TRACE(("PVRCore_Init"));
+
+	LinuxInitMutex(&gPVRSRVLock);
+
+	if (CreateProcEntries ())
+	{
+		error = -ENOMEM;
+		return error;
+	}
+
+	if (PVROSFuncInit() != PVRSRV_OK)
+	{
+		error = -ENOMEM;
+		goto init_failed;
+	}
+
+	PVRLinuxMUtilsInit();
+
+	if(LinuxMMInit() != PVRSRV_OK)
+	{
+		error = -ENOMEM;
+		goto init_failed;
+	}
+
+	LinuxBridgeInit();
+
+	PVRMMapInit();
+
+#if defined(PVR_LDM_MODULE)
+
+#if defined(PVR_LDM_PLATFORM_MODULE)
+	if ((error = platform_driver_register(&powervr_driver)) != 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error));
+
+		goto init_failed;
+	}
+
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+	if ((error = platform_device_register(&powervr_device)) != 0)
+	{
+		platform_driver_unregister(&powervr_driver);
+
+		PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error));
+
+		goto init_failed;
+	}
+#endif
+#endif 
+
+#if defined(PVR_LDM_PCI_MODULE)
+	if ((error = pci_register_driver(&powervr_driver)) != 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error));
+
+		goto init_failed;
+	}
+#endif 
+
+#else 
+	
+	if ((eError = SysInitialise()) != PVRSRV_OK)
+	{
+		error = -ENODEV;
+#if defined(TCF_REV) && (TCF_REV == 110)
+		if(eError == PVRSRV_ERROR_NOT_SUPPORTED)
+		{
+			printk("\nAtlas wrapper (FPGA image) version mismatch");
+			error = -ENODEV;
+		}
+#endif
+		goto init_failed;
+	}
+#endif 
+
+#if !defined(SUPPORT_DRI_DRM)
+	AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops);
+
+	if (AssignedMajorNumber <= 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number"));
+
+		error = -EBUSY;
+		goto sys_deinit;
+	}
+
+	PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
+#endif 
+
+#if defined(PVR_LDM_MODULE)
+	
+	psPvrClass = class_create(THIS_MODULE, "pvr");
+
+	if (IS_ERR(psPvrClass))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create class (%ld)", PTR_ERR(psPvrClass)));
+		error = -EBUSY;
+		goto unregister_device;
+	}
+
+	psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0),
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+				  NULL,
+#endif 
+				  DEVNAME);
+	if (IS_ERR(psDev))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev)));
+		error = -EBUSY;
+		goto destroy_class;
+	}
+#endif 
+
+	return 0;
+
+#if defined(PVR_LDM_MODULE)
+destroy_class:
+	class_destroy(psPvrClass);
+unregister_device:
+	unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME);
+#endif
+#if !defined(SUPPORT_DRI_DRM)
+sys_deinit:
+#endif
+#if defined(PVR_LDM_MODULE)
+#if defined(PVR_LDM_PCI_MODULE)
+	pci_unregister_driver(&powervr_driver);
+#endif
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+	platform_device_unregister(&powervr_device);
+#endif
+	platform_driver_unregister(&powervr_driver);
+#endif
+
+#else	
+	
+	{
+		SYS_DATA *psSysData;
+
+		psSysData = SysAcquireDataNoCheck();
+		if (psSysData != IMG_NULL)
+		{
+			(void) SysDeinitialise(psSysData);
+		}
+	}
+#endif	
+init_failed:
+	PVRMMapCleanup();
+	LinuxMMCleanup();
+	LinuxBridgeDeInit();
+	PVROSFuncDeInit();
+	RemoveProcEntries();
+
+	return error;
+
+} 
+
+
+#if defined(SUPPORT_DRI_DRM)
+void PVRCore_Cleanup(void)
+#else
+static void __exit PVRCore_Cleanup(void)
+#endif
+{
+#if !defined(PVR_LDM_MODULE)
+	SYS_DATA *psSysData;
+#endif
+	PVR_TRACE(("PVRCore_Cleanup"));
+
+#if !defined(PVR_LDM_MODULE)
+	SysAcquireData(&psSysData);
+#endif
+
+#if defined(PVR_LDM_MODULE)
+	device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
+	class_destroy(psPvrClass);
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
+	if (
+#endif	
+		unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME)
+#if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
+								;
+#else	
+								)
+	{
+		PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber));
+	}
+#endif	
+#endif	
+
+#if defined(PVR_LDM_MODULE)
+
+#if defined(PVR_LDM_PCI_MODULE)
+	pci_unregister_driver(&powervr_driver);
+#endif
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+	platform_device_unregister(&powervr_device);
+#endif
+	platform_driver_unregister(&powervr_driver);
+#endif
+
+#else 
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+	if (gPVRPowerLevel != 0)
+	{
+		if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
+		{
+			gPVRPowerLevel = 0;
+		}
+	}
+#endif
+	
+	(void) SysDeinitialise(psSysData);
+#endif 
+
+	PVRMMapCleanup();
+
+	LinuxMMCleanup();
+
+	LinuxBridgeDeInit();
+
+	PVROSFuncDeInit();
+
+	RemoveProcEntries();
+
+	PVR_TRACE(("PVRCore_Cleanup: unloading"));
+}
+
+#if !defined(SUPPORT_DRI_DRM)
+module_init(PVRCore_Init);
+module_exit(PVRCore_Cleanup);
+#endif
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mutex.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mutex.h
new file mode 100644
index 0000000..b2c744a
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mutex.h
@@ -0,0 +1,85 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __INCLUDED_LINUX_MUTEX_H_
+#define __INCLUDED_LINUX_MUTEX_H_
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#include <linux/mutex.h>
+#else
+#include <asm/semaphore.h>
+#endif
+
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+
+typedef struct mutex PVRSRV_LINUX_MUTEX;
+
+#else 
+
+
+typedef struct {
+    struct semaphore sSemaphore;
+    
+    atomic_t Count;
+}PVRSRV_LINUX_MUTEX;
+
+#endif
+
+
+static inline IMG_VOID  LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) {
+    mutex_init(psPVRSRVMutex);
+}
+
+static inline IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) {
+    mutex_lock(psPVRSRVMutex);
+}
+
+static inline PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) {
+	if(mutex_lock_interruptible(psPVRSRVMutex) == -EINTR) {
+		return PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR; 
+	} else {
+		return PVRSRV_OK;
+	}
+}
+
+static inline IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) {
+	return mutex_trylock(psPVRSRVMutex);
+}
+
+static inline IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) {
+	mutex_unlock(psPVRSRVMutex);
+}
+
+static inline  IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) {
+	return (mutex_is_locked(psPVRSRVMutex)) ? IMG_TRUE : IMG_FALSE;
+}
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mutils.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mutils.c
new file mode 100644
index 0000000..a012cf5
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mutils.c
@@ -0,0 +1,136 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "mutils.h"
+
+#if defined(SUPPORT_LINUX_X86_PAT)
+#define	PAT_LINUX_X86_WC	1
+
+#define	PAT_X86_ENTRY_BITS	8
+
+#define	PAT_X86_BIT_PWT		1U
+#define	PAT_X86_BIT_PCD		2U
+#define	PAT_X86_BIT_PAT		4U
+#define	PAT_X86_BIT_MASK	(PAT_X86_BIT_PAT | PAT_X86_BIT_PCD | PAT_X86_BIT_PWT)
+
+static IMG_BOOL g_write_combining_available = IMG_FALSE;
+
+#define	PROT_TO_PAT_INDEX(v, B) ((v & _PAGE_ ## B) ? PAT_X86_BIT_ ## B : 0)
+
+static inline IMG_UINT
+pvr_pat_index(pgprotval_t prot_val)
+{
+	IMG_UINT ret = 0;
+	pgprotval_t val = prot_val & _PAGE_CACHE_MASK;
+
+	ret |= PROT_TO_PAT_INDEX(val, PAT);
+	ret |= PROT_TO_PAT_INDEX(val, PCD);
+	ret |= PROT_TO_PAT_INDEX(val, PWT);
+
+	return ret;
+}
+
+static inline IMG_UINT
+pvr_pat_entry(u64 pat, IMG_UINT index)
+{
+	return (IMG_UINT)(pat >> (index * PAT_X86_ENTRY_BITS)) & PAT_X86_BIT_MASK;
+}
+
+static IMG_VOID
+PVRLinuxX86PATProbe(IMG_VOID)
+{
+	
+	if (cpu_has_pat)	 
+	{
+		u64 pat;
+		IMG_UINT pat_index;
+		IMG_UINT pat_entry;
+
+		PVR_TRACE(("%s: PAT available", __FUNCTION__));
+		
+		rdmsrl(MSR_IA32_CR_PAT, pat);
+		PVR_TRACE(("%s: Top 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat >> 32)));
+		PVR_TRACE(("%s: Bottom 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat)));
+
+		pat_index = pvr_pat_index(_PAGE_CACHE_WC);
+		PVR_TRACE(("%s: PAT index for write combining: %u", __FUNCTION__, pat_index));
+
+		pat_entry = pvr_pat_entry(pat, pat_index);
+		PVR_TRACE(("%s: PAT entry for write combining: 0x%.2x (should be 0x%.2x)", __FUNCTION__, pat_entry, PAT_LINUX_X86_WC));
+
+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+		g_write_combining_available = (IMG_BOOL)(pat_entry == PAT_LINUX_X86_WC);
+#endif
+	}
+#if defined(DEBUG)
+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+	if (g_write_combining_available)
+	{
+		PVR_TRACE(("%s: Write combining available via PAT", __FUNCTION__));
+	}
+	else
+	{
+		PVR_TRACE(("%s: Write combining not available", __FUNCTION__));
+	}
+#else	
+	PVR_TRACE(("%s: Write combining disabled in driver build", __FUNCTION__));
+#endif	
+#endif	
+}
+
+pgprot_t
+pvr_pgprot_writecombine(pgprot_t prot)
+{
+    
+     
+    return (g_write_combining_available) ?
+		__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) : pgprot_noncached(prot);
+}
+#endif	
+
+IMG_VOID
+PVRLinuxMUtilsInit(IMG_VOID)
+{
+#if defined(SUPPORT_LINUX_X86_PAT)
+	PVRLinuxX86PATProbe();
+#endif
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mutils.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mutils.h
new file mode 100644
index 0000000..b2a8ba0
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/mutils.h
@@ -0,0 +1,103 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __IMG_LINUX_MUTILS_H__
+#define __IMG_LINUX_MUTILS_H__
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#if !(defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)))
+#if defined(SUPPORT_LINUX_X86_PAT)
+#undef SUPPORT_LINUX_X86_PAT
+#endif
+#endif
+
+#if defined(SUPPORT_LINUX_X86_PAT)
+	pgprot_t pvr_pgprot_writecombine(pgprot_t prot);
+	#define	PGPROT_WC(pv)	pvr_pgprot_writecombine(pv)
+#else
+	#if defined(__arm__) || defined(__sh__)
+		#define	PGPROT_WC(pv)	pgprot_writecombine(pv)
+	#else
+		#if defined(__i386__) || defined(__mips__)
+			#define	PGPROT_WC(pv)	pgprot_noncached(pv)
+		#else
+			#define PGPROT_WC(pv)	pgprot_noncached(pv)
+			#error  Unsupported architecture!
+		#endif
+	#endif
+#endif
+
+#define	PGPROT_UC(pv)	pgprot_noncached(pv)
+
+#if defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+	#define	IOREMAP(pa, bytes)	ioremap_cache(pa, bytes)
+#else	
+	#if defined(__arm__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+		#define	IOREMAP(pa, bytes)	ioremap_cached(pa, bytes)
+	#else
+		#define IOREMAP(pa, bytes)	ioremap(pa, bytes)
+	#endif
+#endif
+
+#if defined(SUPPORT_LINUX_X86_PAT)
+	#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+		#define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes)
+	#else
+		#define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes)
+	#endif
+#else
+	#if defined(__arm__)
+		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
+			#define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes)
+		#else
+			#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+				#define	IOREMAP_WC(pa, bytes)	ioremap_nocache(pa, bytes)
+			#else
+				#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17))
+					#define	IOREMAP_WC(pa, bytes)	__ioremap(pa, bytes, L_PTE_BUFFERABLE)
+				#else
+					#define IOREMAP_WC(pa, bytes)	__ioremap(pa, bytes, , L_PTE_BUFFERABLE, 1)
+				#endif
+			#endif
+		#endif
+	#else
+		#define IOREMAP_WC(pa, bytes)	ioremap_nocache(pa, bytes)
+	#endif
+#endif
+
+#define	IOREMAP_UC(pa, bytes)	ioremap_nocache(pa, bytes)
+
+IMG_VOID PVRLinuxMUtilsInit(IMG_VOID);
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/osfunc.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/osfunc.c
new file mode 100644
index 0000000..7d4f21b
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/osfunc.c
@@ -0,0 +1,3115 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/io.h>
+#include <asm/page.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#include <asm/system.h>
+#endif
+#include <asm/cacheflush.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/hugetlb.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 <linux/spinlock.h>
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || \
+	defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) || \
+	defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || \
+	defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) || \
+	defined(PVR_LINUX_USING_WORKQUEUES)
+#include <linux/workqueue.h>
+#endif
+
+#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"
+#include "event.h"
+#include "linkage.h"
+
+#define PVRSRV_MODNAME "PowerVR"
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
+#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, wait)
+#else
+#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, 0, wait)
+#endif
+
+#if defined(PVR_LINUX_USING_WORKQUEUES) && !defined(CONFIG_PREEMPT)
+#error "A preemptible Linux kernel is required when using workqueues"
+#endif
+
+#if defined(EMULATOR)
+#define EVENT_OBJECT_TIMEOUT_MS		(2000)
+#else
+#define EVENT_OBJECT_TIMEOUT_MS		(100)
+#endif 
+
+#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc)
+#else
+PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
+#endif
+{
+    PVR_UNREFERENCED_PARAMETER(ui32Flags);
+    PVR_UNREFERENCED_PARAMETER(phBlockAlloc);
+
+    if (ui32Size > PAGE_SIZE)
+    {
+        
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+        *ppvCpuVAddr = _VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED, pszFilename, ui32Line);
+#else
+        *ppvCpuVAddr = VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED);
+#endif
+        if (*ppvCpuVAddr)
+        {
+            return PVRSRV_OK;
+        }
+    }
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    *ppvCpuVAddr = _KMallocWrapper(ui32Size, GFP_KERNEL | __GFP_NOWARN, pszFilename, ui32Line);
+#else
+    *ppvCpuVAddr = KMallocWrapper(ui32Size, GFP_KERNEL | __GFP_NOWARN);
+#endif
+    if (!*ppvCpuVAddr)
+    {
+        return PVRSRV_ERROR_OUT_OF_MEMORY;
+    }
+
+    return PVRSRV_OK;
+}
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24))
+
+static inline int is_vmalloc_addr(const void *pvCpuVAddr)
+{
+	unsigned long lAddr = (unsigned long)pvCpuVAddr;
+	return lAddr >= VMALLOC_START && lAddr < VMALLOC_END;
+}
+
+#endif 
+
+#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc)
+#else
+PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
+#endif
+{	
+    PVR_UNREFERENCED_PARAMETER(ui32Flags);
+    PVR_UNREFERENCED_PARAMETER(ui32Size);
+    PVR_UNREFERENCED_PARAMETER(hBlockAlloc);
+
+    if (is_vmalloc_addr(pvCpuVAddr))
+    {
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+        _VFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
+#else
+        VFreeWrapper(pvCpuVAddr);
+#endif
+    }
+    else
+    {
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+        _KFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
+#else
+        KFreeWrapper(pvCpuVAddr);
+#endif
+    }
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+OSAllocPages_Impl(IMG_UINT32 ui32AllocFlags,
+				  IMG_UINT32 ui32Size,
+				  IMG_UINT32 ui32PageSize,
+				  IMG_VOID **ppvCpuVAddr,
+				  IMG_HANDLE *phOSMemHandle)
+{
+    LinuxMemArea *psLinuxMemArea;
+
+    PVR_UNREFERENCED_PARAMETER(ui32PageSize);
+
+#if 0
+    
+    if(ui32AllocFlags & PVRSRV_HAP_SINGLE_PROCESS)
+    {
+        ui32AllocFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
+        ui32AllocFlags |= PVRSRV_HAP_MULTI_PROCESS;
+    }
+#endif
+
+    switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
+    {
+        case PVRSRV_HAP_KERNEL_ONLY:
+        {
+            psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
+            if(!psLinuxMemArea)
+            {
+                return PVRSRV_ERROR_OUT_OF_MEMORY;
+            }
+            break;
+        }
+        case PVRSRV_HAP_SINGLE_PROCESS:
+        {
+            
+            
+            psLinuxMemArea = NewAllocPagesLinuxMemArea(ui32Size, ui32AllocFlags);
+            if(!psLinuxMemArea)
+            {
+                return PVRSRV_ERROR_OUT_OF_MEMORY;
+            }
+            PVRMMapRegisterArea(psLinuxMemArea);
+            break;
+        }
+
+        case PVRSRV_HAP_MULTI_PROCESS:
+        {
+            
+#if defined(VIVT_CACHE) || defined(__sh__)
+            
+            ui32AllocFlags &= ~PVRSRV_HAP_CACHED;
+#endif
+            psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
+            if(!psLinuxMemArea)
+            {
+                return PVRSRV_ERROR_OUT_OF_MEMORY;
+            }
+            PVRMMapRegisterArea(psLinuxMemArea);
+            break;
+        }
+        default:
+            PVR_DPF((PVR_DBG_ERROR, "OSAllocPages: invalid flags 0x%x\n", ui32AllocFlags));
+            *ppvCpuVAddr = NULL;
+            *phOSMemHandle = (IMG_HANDLE)0;
+            return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+    *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+    *phOSMemHandle = psLinuxMemArea;
+    
+    LinuxMemAreaRegister(psLinuxMemArea);
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+OSFreePages(IMG_UINT32 ui32AllocFlags, IMG_UINT32 ui32Bytes, IMG_VOID *pvCpuVAddr, IMG_HANDLE hOSMemHandle)
+{   
+    LinuxMemArea *psLinuxMemArea;
+    PVRSRV_ERROR eError;
+    
+    PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+    PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+    
+    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+    switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
+    {
+        case PVRSRV_HAP_KERNEL_ONLY:
+            break;
+        case PVRSRV_HAP_SINGLE_PROCESS:
+        case PVRSRV_HAP_MULTI_PROCESS:
+            eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+            if (eError != PVRSRV_OK)
+            {
+                PVR_DPF((PVR_DBG_ERROR,
+                         "OSFreePages(ui32AllocFlags=0x%08X, ui32Bytes=%d, "
+                                        "pvCpuVAddr=%p, hOSMemHandle=%p) FAILED!",
+                         ui32AllocFlags, ui32Bytes, pvCpuVAddr, hOSMemHandle));
+                return eError;
+            }
+            break;
+        default:
+            PVR_DPF((PVR_DBG_ERROR,"%s: invalid flags 0x%x\n",
+                    __FUNCTION__, ui32AllocFlags));
+            return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+    LinuxMemAreaDeepFree(psLinuxMemArea);
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
+                  IMG_UINT32 ui32ByteOffset,
+                  IMG_UINT32 ui32Bytes,
+                  IMG_UINT32 ui32Flags,
+                  IMG_HANDLE *phOSMemHandleRet)
+{
+    LinuxMemArea *psParentLinuxMemArea, *psLinuxMemArea;
+    PVRSRV_ERROR eError;
+
+    psParentLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+    
+    psLinuxMemArea = NewSubLinuxMemArea(psParentLinuxMemArea, ui32ByteOffset, ui32Bytes);
+    if(!psLinuxMemArea)
+    {
+        *phOSMemHandleRet = NULL;
+        return PVRSRV_ERROR_OUT_OF_MEMORY;
+    }
+    *phOSMemHandleRet = psLinuxMemArea;
+
+    
+    if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY)
+    {
+        return PVRSRV_OK;
+    }
+
+    eError = PVRMMapRegisterArea(psLinuxMemArea);
+    if(eError != PVRSRV_OK)
+    {
+        goto failed_register_area;
+    }
+
+    return PVRSRV_OK;
+
+failed_register_area:
+    *phOSMemHandleRet = NULL;
+    LinuxMemAreaDeepFree(psLinuxMemArea);
+    return eError;
+}
+
+PVRSRV_ERROR
+OSReleaseSubMemHandle(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32Flags)
+{
+    LinuxMemArea *psLinuxMemArea;
+    PVRSRV_ERROR eError;
+    
+    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
+    
+    if((ui32Flags & PVRSRV_HAP_KERNEL_ONLY) == 0)
+    {
+        eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+        if(eError != PVRSRV_OK)
+        {
+            return eError;
+        }
+    }
+    LinuxMemAreaDeepFree(psLinuxMemArea);
+
+    return PVRSRV_OK;
+}
+
+
+IMG_CPU_PHYADDR
+OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32ByteOffset)
+{
+    PVR_ASSERT(hOSMemHandle);
+
+    return LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset);
+}
+
+
+
+IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
+{
+#if defined(USE_UNOPTIMISED_MEMCPY)
+    IMG_UINT8 *Src,*Dst;
+    IMG_INT i;
+
+    Src=(IMG_UINT8 *)pvSrc;
+    Dst=(IMG_UINT8 *)pvDst;
+    for(i=0;i<ui32Size;i++)
+    {
+        Dst[i]=Src[i];
+    }
+#else
+    memcpy(pvDst, pvSrc, ui32Size);
+#endif
+}
+
+
+IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
+{
+#if defined(USE_UNOPTIMISED_MEMSET)
+    IMG_UINT8 *Buff;
+    IMG_INT i;
+
+    Buff=(IMG_UINT8 *)pvDest;
+    for(i=0;i<ui32Size;i++)
+    {
+        Buff[i]=ui8Value;
+    }
+#else
+    memset(pvDest, (IMG_INT) ui8Value, (size_t) ui32Size);
+#endif
+}
+
+
+IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc)
+{
+    return (strcpy(pszDest, pszSrc));
+}
+
+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_UINT32 ui32Size, const IMG_CHAR *pszFormat, ...)
+{
+    va_list argList;
+    IMG_INT32 iCount;
+
+    va_start(argList, pszFormat);
+    iCount = vsnprintf(pStr, (size_t)ui32Size, pszFormat, argList);
+    va_end(argList);
+
+    return iCount;
+}
+
+IMG_VOID OSBreakResourceLock (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
+{
+    volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
+
+    if(*pui32Access)
+    {
+        if(psResource->ui32ID == ui32ID)
+        {
+            psResource->ui32ID = 0;
+            *pui32Access = 0;
+        }
+        else
+        {
+            PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked for this process.")); 
+        }
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked"));
+    }
+}
+
+
+PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource)
+{
+    psResource->ui32ID = 0;
+    psResource->ui32Lock = 0;
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSDestroyResource (PVRSRV_RESOURCE *psResource)
+{
+    OSBreakResourceLock (psResource, psResource->ui32ID);
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData)
+{
+    ENV_DATA		*psEnvData;
+    PVRSRV_ERROR	eError;
+    
+    
+    eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), (IMG_VOID **)&psEnvData, IMG_NULL,
+        "Environment Data");
+    if (eError != PVRSRV_OK)
+    {
+        return eError;
+    }
+
+    eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, 
+                    &psEnvData->pvBridgeData, IMG_NULL,
+                    "Bridge Data");
+    if (eError != PVRSRV_OK)
+    {
+        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), psEnvData, IMG_NULL);
+		
+        return eError;
+    }
+
+
+    
+    psEnvData->bMISRInstalled = IMG_FALSE;
+    psEnvData->bLISRInstalled = IMG_FALSE;
+
+    
+    *ppvEnvSpecificData = psEnvData;
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData)
+{
+    ENV_DATA		*psEnvData = (ENV_DATA*)pvEnvSpecificData;
+
+    PVR_ASSERT(!psEnvData->bMISRInstalled);
+    PVR_ASSERT(!psEnvData->bLISRInstalled);
+
+    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, psEnvData->pvBridgeData, IMG_NULL);
+    psEnvData->pvBridgeData = IMG_NULL;
+
+    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), pvEnvSpecificData, IMG_NULL);
+	
+
+    return PVRSRV_OK;
+}
+
+
+ 
+IMG_VOID OSReleaseThreadQuanta(IMG_VOID)
+{
+    schedule();
+}
+
+
+ 
+IMG_UINT32 OSClockus(IMG_VOID)
+{
+    IMG_UINT32 time, j = jiffies;
+
+    time = j * (1000000 / HZ);
+
+    return time;
+}
+
+
+IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus)
+{
+    udelay(ui32Timeus);
+}
+
+
+IMG_VOID OSSleepms(IMG_UINT32 ui32Timems)
+{
+    msleep(ui32Timems);
+}
+
+
+ 
+IMG_HANDLE OSFuncHighResTimerCreate(IMG_VOID)
+{
+	
+	return (IMG_HANDLE) 1;
+}
+
+ 
+IMG_UINT32 OSFuncHighResTimerGetus(IMG_HANDLE hTimer)
+{
+	return (IMG_UINT32) jiffies_to_usecs(jiffies);
+}
+
+ 
+IMG_VOID OSFuncHighResTimerDestroy(IMG_HANDLE hTimer)
+{
+	PVR_UNREFERENCED_PARAMETER(hTimer);
+}
+
+IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID)
+{
+    if (in_interrupt())
+    {
+        return KERNEL_ID;
+    }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+    return (IMG_UINT32)current->pgrp;
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+    return (IMG_UINT32)task_tgid_nr(current);
+#else
+    return (IMG_UINT32)current->tgid;
+#endif
+#endif
+}
+
+
+IMG_UINT32 OSGetPageSize(IMG_VOID)
+{
+#if defined(__sh__)
+    IMG_UINT32 ui32ReturnValue = PAGE_SIZE;
+
+    return (ui32ReturnValue);
+#else
+    return PAGE_SIZE;
+#endif
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+static irqreturn_t DeviceISRWrapper(int irq, void *dev_id
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+        , struct pt_regs *regs
+#endif
+        )
+{
+    PVRSRV_DEVICE_NODE *psDeviceNode;
+    IMG_BOOL bStatus = IMG_FALSE;
+
+    PVR_UNREFERENCED_PARAMETER(irq);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+    PVR_UNREFERENCED_PARAMETER(regs);
+#endif	
+    psDeviceNode = (PVRSRV_DEVICE_NODE*)dev_id;
+    if(!psDeviceNode)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "DeviceISRWrapper: invalid params\n"));
+        goto out;
+    }
+
+    bStatus = PVRSRVDeviceLISR(psDeviceNode);
+
+    if (bStatus)
+    {
+		OSScheduleMISR((IMG_VOID *)psDeviceNode->psSysData);
+    }
+
+out:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+    return bStatus ? IRQ_HANDLED : IRQ_NONE;
+#endif
+}
+
+
+
+static irqreturn_t SystemISRWrapper(int irq, void *dev_id
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+        , struct pt_regs *regs
+#endif
+        )
+{
+    SYS_DATA *psSysData;
+    IMG_BOOL bStatus = IMG_FALSE;
+
+    PVR_UNREFERENCED_PARAMETER(irq);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+    PVR_UNREFERENCED_PARAMETER(regs);
+#endif
+    psSysData = (SYS_DATA *)dev_id;
+    if(!psSysData)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "SystemISRWrapper: invalid params\n"));
+        goto out;
+    }
+
+    bStatus = PVRSRVSystemLISR(psSysData);
+
+    if (bStatus)
+    {
+        OSScheduleMISR((IMG_VOID *)psSysData);
+    }
+
+out:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+    return bStatus ? IRQ_HANDLED : IRQ_NONE;
+#endif
+}
+PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData,
+                                    IMG_UINT32 ui32Irq,
+                                    IMG_CHAR *pszISRName,
+                                    IMG_VOID *pvDeviceNode)
+{
+    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+    if (psEnvData->bLISRInstalled)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSInstallDeviceLISR: An ISR has already been installed: IRQ %d cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+        return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+    }
+
+    PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %p", pszISRName, ui32Irq, pvDeviceNode));
+
+    if(request_irq(ui32Irq, DeviceISRWrapper,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
+        SA_SHIRQ
+#else
+        IRQF_SHARED
+#endif
+        , pszISRName, pvDeviceNode))
+    {
+        PVR_DPF((PVR_DBG_ERROR,"OSInstallDeviceLISR: Couldn't install device LISR on IRQ %d", ui32Irq));
+
+        return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
+    }
+
+    psEnvData->ui32IRQ = ui32Irq;
+    psEnvData->pvISRCookie = pvDeviceNode;
+    psEnvData->bLISRInstalled = IMG_TRUE;
+
+    return PVRSRV_OK;	
+}
+
+PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData)
+{
+    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+    if (!psEnvData->bLISRInstalled)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSUninstallDeviceLISR: No LISR has been installed"));
+        return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+    }
+        
+    PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ,  psEnvData->pvISRCookie));
+
+    free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
+
+    psEnvData->bLISRInstalled = IMG_FALSE;
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq)
+{
+    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+    if (psEnvData->bLISRInstalled)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSInstallSystemLISR: An LISR has already been installed: IRQ %d cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+        return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+    }
+
+    PVR_TRACE(("Installing system LISR on IRQ %d with cookie %p", ui32Irq, pvSysData));
+
+    if(request_irq(ui32Irq, SystemISRWrapper,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
+        SA_SHIRQ
+#else
+        IRQF_SHARED
+#endif
+        , PVRSRV_MODNAME, pvSysData))
+    {
+        PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Couldn't install system LISR on IRQ %d", ui32Irq));
+
+        return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
+    }
+
+    psEnvData->ui32IRQ = ui32Irq;
+    psEnvData->pvISRCookie = pvSysData;
+    psEnvData->bLISRInstalled = IMG_TRUE;
+
+    return PVRSRV_OK;	
+}
+
+
+PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData)
+{
+    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+    if (!psEnvData->bLISRInstalled)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSUninstallSystemLISR: No LISR has been installed"));
+        return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+    }
+
+    PVR_TRACE(("Uninstalling system LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+
+    free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
+
+    psEnvData->bLISRInstalled = IMG_FALSE;
+
+    return PVRSRV_OK;
+}
+
+#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+static void MISRWrapper(
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+			void *data
+#else
+			struct work_struct *data
+#endif
+)
+{
+	ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
+	SYS_DATA *psSysData  = (SYS_DATA *)psEnvData->pvMISRData;
+
+	PVRSRVMISR(psSysData);
+}
+
+
+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
+{
+	SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+	ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+	if (psEnvData->bMISRInstalled)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
+		return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+	}
+
+	PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
+
+	psEnvData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue");
+
+	if (psEnvData->psWorkQueue == IMG_NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: create_singlethreaded_workqueue failed"));
+		return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD;
+	}
+
+	INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+		, (void *)&psEnvData->sMISRWork
+#endif
+				);
+
+	psEnvData->pvMISRData = pvSysData;
+	psEnvData->bMISRInstalled = IMG_TRUE;
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
+{
+	SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+	ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+	if (!psEnvData->bMISRInstalled)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
+		return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+	}
+
+	PVR_TRACE(("Uninstalling MISR"));
+
+	destroy_workqueue(psEnvData->psWorkQueue);
+
+	psEnvData->bMISRInstalled = IMG_FALSE;
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
+{
+	SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+	ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
+
+	if (psEnvData->bMISRInstalled)
+	{
+		queue_work(psEnvData->psWorkQueue, &psEnvData->sMISRWork);
+	}
+
+	return PVRSRV_OK;	
+}
+#else	
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE)
+static void MISRWrapper(
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+			void *data
+#else
+			struct work_struct *data
+#endif
+)
+{
+	ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
+	SYS_DATA *psSysData  = (SYS_DATA *)psEnvData->pvMISRData;
+
+	PVRSRVMISR(psSysData);
+}
+
+
+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
+{
+	SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+	ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+	if (psEnvData->bMISRInstalled)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
+		return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+	}
+
+	PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
+
+	INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+		, (void *)&psEnvData->sMISRWork
+#endif
+				);
+
+	psEnvData->pvMISRData = pvSysData;
+	psEnvData->bMISRInstalled = IMG_TRUE;
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
+{
+	SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+	ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+	if (!psEnvData->bMISRInstalled)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
+		return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+	}
+
+	PVR_TRACE(("Uninstalling MISR"));
+
+	flush_scheduled_work();
+
+	psEnvData->bMISRInstalled = IMG_FALSE;
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
+{
+	SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+	ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
+
+	if (psEnvData->bMISRInstalled)
+	{
+		schedule_work(&psEnvData->sMISRWork);
+	}
+
+	return PVRSRV_OK;	
+}
+
+#else	
+
+
+static void MISRWrapper(unsigned long data)
+{
+    SYS_DATA *psSysData;
+
+    psSysData = (SYS_DATA *)data;
+    
+    PVRSRVMISR(psSysData);
+}
+
+
+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
+{
+    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+    if (psEnvData->bMISRInstalled)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
+        return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+    }
+
+    PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
+
+    tasklet_init(&psEnvData->sMISRTasklet, MISRWrapper, (unsigned long)pvSysData);
+
+    psEnvData->bMISRInstalled = IMG_TRUE;
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
+{
+    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+    if (!psEnvData->bMISRInstalled)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
+        return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+    }
+
+    PVR_TRACE(("Uninstalling MISR"));
+
+    tasklet_kill(&psEnvData->sMISRTasklet);
+
+    psEnvData->bMISRInstalled = IMG_FALSE;
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
+{
+    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+    ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
+
+    if (psEnvData->bMISRInstalled)
+    {
+        tasklet_schedule(&psEnvData->sMISRTasklet);
+    }
+
+    return PVRSRV_OK;	
+}
+
+#endif 
+#endif 
+
+#endif 
+
+IMG_VOID OSPanic(IMG_VOID)
+{
+	BUG();
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#define	OS_TAS(p)	xchg((p), 1)
+#else
+#define	OS_TAS(p)	tas(p)
+#endif
+PVRSRV_ERROR OSLockResource ( PVRSRV_RESOURCE 	*psResource,
+                                IMG_UINT32 			ui32ID)
+
+{
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+    if(!OS_TAS(&psResource->ui32Lock))
+        psResource->ui32ID = ui32ID;
+    else
+        eError = PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE;
+
+    return eError;
+}
+
+
+PVRSRV_ERROR OSUnlockResource (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
+{
+    volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+    if(*pui32Access)
+    {
+        if(psResource->ui32ID == ui32ID)
+        {
+            psResource->ui32ID = 0;
+            smp_mb();
+            *pui32Access = 0;
+        }
+        else
+        {
+            PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked with expected value.", psResource)); 
+            PVR_DPF((PVR_DBG_MESSAGE,"Should be %x is actually %x", ui32ID, psResource->ui32ID));
+            eError = PVRSRV_ERROR_INVALID_LOCK_ID;
+        }
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked", psResource));
+        eError = PVRSRV_ERROR_RESOURCE_NOT_LOCKED;
+    }
+    
+    return eError;
+}
+
+
+IMG_BOOL OSIsResourceLocked (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
+{
+    volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
+
+    return 	(*(volatile IMG_UINT32 *)pui32Access == 1) && (psResource->ui32ID == ui32ID)
+            ?	IMG_TRUE
+            :	IMG_FALSE;
+}
+
+
+#if !defined(SYS_CUSTOM_POWERLOCK_WRAP)
+PVRSRV_ERROR OSPowerLockWrap(IMG_BOOL bTryLock)
+{
+	PVR_UNREFERENCED_PARAMETER(bTryLock);	
+
+	return PVRSRV_OK;
+}
+
+IMG_VOID OSPowerLockUnwrap (IMG_VOID)
+{
+}
+#endif 
+
+
+IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_HANDLE hOSMemHandle,
+								  IMG_VOID *pvLinAddr)
+{
+    IMG_CPU_PHYADDR CpuPAddr;
+    LinuxMemArea *psLinuxMemArea;
+	IMG_UINTPTR_T uiByteOffset;
+	IMG_UINT32 ui32ByteOffset;
+
+	PVR_ASSERT(hOSMemHandle != IMG_NULL);
+
+	
+
+	psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+	uiByteOffset = (IMG_UINTPTR_T)pvLinAddr - (IMG_UINTPTR_T)LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+	ui32ByteOffset = (IMG_UINT32)uiByteOffset;
+
+	CpuPAddr = LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset);
+
+	return CpuPAddr;
+}
+
+
+IMG_VOID *
+OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr,
+               IMG_UINT32 ui32Bytes,
+               IMG_UINT32 ui32MappingFlags,
+               IMG_HANDLE *phOSMemHandle)
+{
+    if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
+    {
+	
+	if(phOSMemHandle == IMG_NULL)
+	{
+		IMG_VOID *pvIORemapCookie;
+		pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags);
+		if(pvIORemapCookie == IMG_NULL)
+		{
+		    return IMG_NULL;
+		}
+		return pvIORemapCookie;
+	}
+	else
+	{
+		LinuxMemArea *psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+
+		if(psLinuxMemArea == IMG_NULL)
+		{
+		    return IMG_NULL;
+		}
+
+		*phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
+		return LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+	}
+    }
+
+    PVR_DPF((PVR_DBG_ERROR,
+             "OSMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
+             " (Use OSReservePhys otherwise)"));
+
+    return IMG_NULL;
+}
+
+IMG_BOOL
+OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE hOSMemHandle)
+{
+    PVR_TRACE(("%s: unmapping %d bytes from %p", __FUNCTION__, ui32Bytes, pvLinAddr));
+
+    PVR_UNREFERENCED_PARAMETER(ui32Bytes);	
+
+    if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
+    {
+        if (hOSMemHandle == IMG_NULL)
+	{
+		IOUnmapWrapper(pvLinAddr);
+	}
+	else
+	{
+		LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+		PVR_ASSERT(LinuxMemAreaToCpuVAddr(psLinuxMemArea) == pvLinAddr);
+		
+		FreeIORemapLinuxMemArea(psLinuxMemArea);
+	}
+
+        return IMG_TRUE;
+    }
+
+    PVR_DPF((PVR_DBG_ERROR,
+                 "OSUnMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
+                 " (Use OSUnReservePhys otherwise)"));
+    return IMG_FALSE;
+}
+
+static PVRSRV_ERROR
+RegisterExternalMem(IMG_SYS_PHYADDR *pBasePAddr,
+          IMG_VOID *pvCPUVAddr,
+              IMG_UINT32 ui32Bytes,
+          IMG_BOOL bPhysContig,
+              IMG_UINT32 ui32MappingFlags,
+              IMG_HANDLE *phOSMemHandle)
+{
+    LinuxMemArea *psLinuxMemArea;
+
+    switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
+    {
+        case PVRSRV_HAP_KERNEL_ONLY:
+        {
+        psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
+        
+            if(!psLinuxMemArea)
+            {
+                return PVRSRV_ERROR_BAD_MAPPING;
+            }
+            break;
+        }
+        case PVRSRV_HAP_SINGLE_PROCESS:
+        {
+        psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
+
+            if(!psLinuxMemArea)
+            {
+                return PVRSRV_ERROR_BAD_MAPPING;
+            }
+            PVRMMapRegisterArea(psLinuxMemArea);
+            break;
+        }
+        case PVRSRV_HAP_MULTI_PROCESS:
+        {
+            
+#if defined(VIVT_CACHE) || defined(__sh__)
+            
+            ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
+#endif
+        psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
+
+            if(!psLinuxMemArea)
+            {
+                return PVRSRV_ERROR_BAD_MAPPING;
+            }
+            PVRMMapRegisterArea(psLinuxMemArea);
+            break;
+        }
+        default:
+            PVR_DPF((PVR_DBG_ERROR,"OSRegisterMem : invalid flags 0x%x\n", ui32MappingFlags));
+            *phOSMemHandle = (IMG_HANDLE)0;
+            return PVRSRV_ERROR_INVALID_FLAGS;
+    }
+    
+    *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
+
+    LinuxMemAreaRegister(psLinuxMemArea);
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
+              IMG_VOID *pvCPUVAddr,
+              IMG_UINT32 ui32Bytes,
+              IMG_UINT32 ui32MappingFlags,
+              IMG_HANDLE *phOSMemHandle)
+{
+    IMG_SYS_PHYADDR SysPAddr = SysCpuPAddrToSysPAddr(BasePAddr);
+
+    return RegisterExternalMem(&SysPAddr, pvCPUVAddr, ui32Bytes, IMG_TRUE, ui32MappingFlags, phOSMemHandle);
+}
+
+
+PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE *phOSMemHandle)
+{
+    return RegisterExternalMem(pBasePAddr, pvCPUVAddr, ui32Bytes, IMG_FALSE, ui32MappingFlags, phOSMemHandle);
+}
+
+
+PVRSRV_ERROR
+OSUnRegisterMem (IMG_VOID *pvCpuVAddr,
+                IMG_UINT32 ui32Bytes,
+                IMG_UINT32 ui32MappingFlags,
+                IMG_HANDLE hOSMemHandle)
+{
+    LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+    PVRSRV_ERROR eError;
+
+    PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+    PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+
+    switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
+    {
+        case PVRSRV_HAP_KERNEL_ONLY:
+            break;
+        case PVRSRV_HAP_SINGLE_PROCESS:
+        case PVRSRV_HAP_MULTI_PROCESS:
+        {
+            eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+            if (eError != PVRSRV_OK)
+            {
+                 PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
+                          __FUNCTION__, pvCpuVAddr, ui32Bytes,
+                          ui32MappingFlags, hOSMemHandle));
+                return eError;
+            }
+            break;
+        }
+        default:
+        {
+            PVR_DPF((PVR_DBG_ERROR, "OSUnRegisterMem : invalid flags 0x%x", ui32MappingFlags));
+            return PVRSRV_ERROR_INVALID_PARAMS;
+        }
+    }
+
+    LinuxMemAreaDeepFree(psLinuxMemArea);
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
+{
+    return OSUnRegisterMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
+}
+
+PVRSRV_ERROR
+OSReservePhys(IMG_CPU_PHYADDR BasePAddr,
+              IMG_UINT32 ui32Bytes,
+              IMG_UINT32 ui32MappingFlags,
+              IMG_VOID **ppvCpuVAddr,
+              IMG_HANDLE *phOSMemHandle)
+{
+    LinuxMemArea *psLinuxMemArea;
+
+#if 0
+    
+    if(ui32MappingFlags & PVRSRV_HAP_SINGLE_PROCESS)
+    {
+        ui32MappingFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
+        ui32MappingFlags |= PVRSRV_HAP_MULTI_PROCESS;
+    }
+#endif
+
+    switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
+    {
+        case PVRSRV_HAP_KERNEL_ONLY:
+        {
+            
+            psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+            if(!psLinuxMemArea)
+            {
+                return PVRSRV_ERROR_BAD_MAPPING;
+            }
+            break;
+        }
+        case PVRSRV_HAP_SINGLE_PROCESS:
+        {
+            
+            psLinuxMemArea = NewIOLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+            if(!psLinuxMemArea)
+            {
+                return PVRSRV_ERROR_BAD_MAPPING;
+            }
+            PVRMMapRegisterArea(psLinuxMemArea);
+            break;
+        }
+        case PVRSRV_HAP_MULTI_PROCESS:
+        {
+            
+#if defined(VIVT_CACHE) || defined(__sh__)
+            
+            ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
+#endif
+            psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+            if(!psLinuxMemArea)
+            {
+                return PVRSRV_ERROR_BAD_MAPPING;
+            }
+            PVRMMapRegisterArea(psLinuxMemArea);
+            break;
+        }
+        default:
+            PVR_DPF((PVR_DBG_ERROR,"OSMapPhysToLin : invalid flags 0x%x\n", ui32MappingFlags));
+            *ppvCpuVAddr = NULL;
+            *phOSMemHandle = (IMG_HANDLE)0;
+            return PVRSRV_ERROR_INVALID_FLAGS;
+    }
+
+    *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
+    *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+
+    LinuxMemAreaRegister(psLinuxMemArea);
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+OSUnReservePhys(IMG_VOID *pvCpuVAddr,
+                IMG_UINT32 ui32Bytes,
+                IMG_UINT32 ui32MappingFlags,
+                IMG_HANDLE hOSMemHandle)
+{
+    LinuxMemArea *psLinuxMemArea;
+    PVRSRV_ERROR eError;
+
+    PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+    PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+
+    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+    
+    switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
+    {
+        case PVRSRV_HAP_KERNEL_ONLY:
+            break;
+        case PVRSRV_HAP_SINGLE_PROCESS:
+        case PVRSRV_HAP_MULTI_PROCESS:
+        {
+            eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+            if (eError != PVRSRV_OK)
+            {
+                 PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
+                          __FUNCTION__, pvCpuVAddr, ui32Bytes,
+                          ui32MappingFlags, hOSMemHandle));
+                return eError;
+            }
+            break;
+        }
+        default:
+        {
+            PVR_DPF((PVR_DBG_ERROR, "OSUnMapPhysToLin : invalid flags 0x%x", ui32MappingFlags));
+            return PVRSRV_ERROR_INVALID_PARAMS;
+        }
+    }
+    
+    LinuxMemAreaDeepFree(psLinuxMemArea);
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSBaseAllocContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR *pvLinAddr, IMG_CPU_PHYADDR *psPhysAddr)
+{
+#if !defined(NO_HARDWARE)
+    PVR_UNREFERENCED_PARAMETER(ui32Size);
+    PVR_UNREFERENCED_PARAMETER(pvLinAddr);
+    PVR_UNREFERENCED_PARAMETER(psPhysAddr);
+    PVR_DPF((PVR_DBG_ERROR, "%s: Not available", __FUNCTION__));
+
+    return PVRSRV_ERROR_OUT_OF_MEMORY;
+#else
+    IMG_VOID *pvKernLinAddr;
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+    pvKernLinAddr = _KMallocWrapper(ui32Size, GFP_KERNEL, __FILE__, __LINE__);
+#else
+    pvKernLinAddr = KMallocWrapper(ui32Size, GFP_KERNEL);
+#endif
+    if (!pvKernLinAddr)
+    {
+    return PVRSRV_ERROR_OUT_OF_MEMORY;
+    }
+
+    *pvLinAddr = pvKernLinAddr;
+
+    psPhysAddr->uiAddr = virt_to_phys(pvKernLinAddr);
+
+    return PVRSRV_OK;
+#endif	
+}
+
+
+PVRSRV_ERROR OSBaseFreeContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR pvLinAddr, IMG_CPU_PHYADDR psPhysAddr)
+{
+#if !defined(NO_HARDWARE)
+    PVR_UNREFERENCED_PARAMETER(ui32Size);
+    PVR_UNREFERENCED_PARAMETER(pvLinAddr);
+    PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
+
+    PVR_DPF((PVR_DBG_WARNING, "%s: Not available", __FUNCTION__));
+#else
+    PVR_UNREFERENCED_PARAMETER(ui32Size);
+    PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
+
+    KFreeWrapper(pvLinAddr);
+#endif
+    return PVRSRV_OK;
+}
+
+IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
+{
+#if !defined(NO_HARDWARE)
+    return (IMG_UINT32) readl((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#else
+    return *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#endif
+}
+
+IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+#if !defined(NO_HARDWARE)
+    writel(ui32Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#else
+    *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset) = ui32Value;
+#endif
+}
+
+#if defined(CONFIG_PCI) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
+
+PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags)
+{
+    int err;
+    IMG_UINT32 i;
+    PVR_PCI_DEV *psPVRPCI;
+
+    PVR_TRACE(("OSPCISetDev"));
+
+    if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID **)&psPVRPCI, IMG_NULL,
+        "PCI Device") != PVRSRV_OK)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't allocate PVR PCI structure"));
+        return IMG_NULL;
+    }
+
+    psPVRPCI->psPCIDev = (struct pci_dev *)pvPCICookie;
+    psPVRPCI->ePCIFlags = eFlags;
+
+    err = pci_enable_device(psPVRPCI->psPCIDev);
+    if (err != 0)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't enable device (%d)", err));
+        return IMG_NULL;
+    }
+
+    if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)	 
+    {
+        pci_set_master(psPVRPCI->psPCIDev);
+    }
+
+    if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)		 
+    {
+#if defined(CONFIG_PCI_MSI)
+        err = pci_enable_msi(psPVRPCI->psPCIDev);
+        if (err != 0)
+        {
+            PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: Couldn't enable MSI (%d)", err));
+            psPVRPCI->ePCIFlags &= ~HOST_PCI_INIT_FLAG_MSI;	 
+        }
+#else
+        PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: MSI support not enabled in the kernel"));
+#endif
+    }
+
+    
+    for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+    {
+        psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
+    }
+
+    return (PVRSRV_PCI_DEV_HANDLE)psPVRPCI;
+}
+
+PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags)
+{
+    struct pci_dev *psPCIDev;
+
+    psPCIDev = pci_get_device(ui16VendorID, ui16DeviceID, NULL);
+    if (psPCIDev == NULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't acquire device"));
+        return IMG_NULL;
+    }
+
+    return OSPCISetDev((IMG_VOID *)psPCIDev, eFlags);
+}
+
+PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ)
+{
+    PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+
+    *pui32IRQ = psPVRPCI->psPCIDev->irq;
+
+    return PVRSRV_OK;
+}
+
+enum HOST_PCI_ADDR_RANGE_FUNC
+{
+    HOST_PCI_ADDR_RANGE_FUNC_LEN,
+    HOST_PCI_ADDR_RANGE_FUNC_START,
+    HOST_PCI_ADDR_RANGE_FUNC_END,
+    HOST_PCI_ADDR_RANGE_FUNC_REQUEST,
+    HOST_PCI_ADDR_RANGE_FUNC_RELEASE
+};
+
+static IMG_UINT32 OSPCIAddrRangeFunc(enum HOST_PCI_ADDR_RANGE_FUNC eFunc,
+                                     PVRSRV_PCI_DEV_HANDLE hPVRPCI,
+                                     IMG_UINT32 ui32Index)
+{
+    PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+
+    if (ui32Index >= DEVICE_COUNT_RESOURCE)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Index out of range"));
+        return 0;
+
+    }
+
+    switch (eFunc)
+    {
+        case HOST_PCI_ADDR_RANGE_FUNC_LEN:
+            return pci_resource_len(psPVRPCI->psPCIDev, ui32Index);
+        case HOST_PCI_ADDR_RANGE_FUNC_START:
+            return pci_resource_start(psPVRPCI->psPCIDev, ui32Index);
+        case HOST_PCI_ADDR_RANGE_FUNC_END:
+            return pci_resource_end(psPVRPCI->psPCIDev, ui32Index);
+        case HOST_PCI_ADDR_RANGE_FUNC_REQUEST:
+        {
+            int err;
+
+            err = pci_request_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index, PVRSRV_MODNAME);
+            if (err != 0)
+            {
+                PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: pci_request_region_failed (%d)", err));
+                return 0;
+            }
+            psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_TRUE;
+            return 1;
+        }
+        case HOST_PCI_ADDR_RANGE_FUNC_RELEASE:
+            if (psPVRPCI->abPCIResourceInUse[ui32Index])
+            {
+                pci_release_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index);
+                psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_FALSE;
+            }
+            return 1;
+        default:
+            PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Unknown function"));
+            break;
+    }
+
+    return 0;
+}
+
+IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index); 
+}
+
+IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index); 
+}
+
+IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index); 
+}
+
+PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI,
+                                   IMG_UINT32 ui32Index)
+{
+    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
+{
+    PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+    int i;
+
+    PVR_TRACE(("OSPCIReleaseDev"));
+
+    
+    for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+    {
+        if (psPVRPCI->abPCIResourceInUse[i])
+        {
+            PVR_TRACE(("OSPCIReleaseDev: Releasing Address range %d", i));
+            pci_release_region(psPVRPCI->psPCIDev, i);
+            psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
+        }
+    }
+
+#if defined(CONFIG_PCI_MSI)
+    if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)		 
+    {
+        pci_disable_msi(psPVRPCI->psPCIDev);
+    }
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+    if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)	 
+    {
+        pci_clear_master(psPVRPCI->psPCIDev);
+    }
+#endif
+    pci_disable_device(psPVRPCI->psPCIDev);
+
+    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)psPVRPCI, IMG_NULL);
+	
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_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 (psPVRPCI->abPCIResourceInUse[i])
+        {
+            pci_release_region(psPVRPCI->psPCIDev, i);
+        }
+    }
+
+    err = pci_save_state(psPVRPCI->psPCIDev);
+    if (err != 0)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_save_state_failed (%d)", err));
+        return PVRSRV_ERROR_PCI_CALL_FAILED;
+    }
+
+    pci_disable_device(psPVRPCI->psPCIDev);
+
+    err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_SUSPEND));
+    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(PVRSRV_PCI_DEV_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_choose_state(psPVRPCI->psPCIDev, PMSG_ON));
+    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_UNKNOWN_POWER_STATE;
+        default:
+            PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_set_power_state failed (%d)", err));
+            return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
+    }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
+    pci_restore_state(psPVRPCI->psPCIDev);
+#else
+    err = pci_restore_state(psPVRPCI->psPCIDev);
+    if (err != 0)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_restore_state failed (%d)", err));
+        return PVRSRV_ERROR_PCI_CALL_FAILED;
+    }
+#endif
+
+    err = pci_enable_device(psPVRPCI->psPCIDev);
+    if (err != 0)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: Couldn't enable device (%d)", err));
+        return PVRSRV_ERROR_PCI_CALL_FAILED;
+    }
+
+    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, PVRSRV_MODNAME);
+            if (err != 0)
+            {
+                PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err));
+            }
+        }
+
+    }
+
+    return PVRSRV_OK;
+}
+
+#endif 
+
+#define	OS_MAX_TIMERS	8
+
+typedef struct TIMER_CALLBACK_DATA_TAG
+{
+    IMG_BOOL			bInUse;
+    PFN_TIMER_FUNC		pfnTimerFunc;
+    IMG_VOID 			*pvData;	
+    struct timer_list		sTimer;
+    IMG_UINT32			ui32Delay;
+    IMG_BOOL			bActive;
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+    struct work_struct		sWork;
+#endif
+}TIMER_CALLBACK_DATA;
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+static struct workqueue_struct	*psTimerWorkQueue;
+#endif
+
+static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS];
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+DEFINE_MUTEX(sTimerStructLock);
+#else
+ 
+static spinlock_t sTimerStructLock = __SPIN_LOCK_UNLOCKED(sTimerStructLock);
+#endif
+
+static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData)
+{
+    if (!psTimerCBData->bActive)
+        return;
+
+    
+    psTimerCBData->pfnTimerFunc(psTimerCBData->pvData);
+    
+    
+    mod_timer(&psTimerCBData->sTimer, psTimerCBData->ui32Delay + jiffies);
+}
+
+
+static IMG_VOID OSTimerCallbackWrapper(IMG_UINT32 ui32Data)
+{
+    TIMER_CALLBACK_DATA	*psTimerCBData = (TIMER_CALLBACK_DATA*)ui32Data;
+    
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+    int res;
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+    res = queue_work(psTimerWorkQueue, &psTimerCBData->sWork);
+#else
+    res = schedule_work(&psTimerCBData->sWork);
+#endif
+    if (res == 0)
+    {
+        PVR_DPF((PVR_DBG_WARNING, "OSTimerCallbackWrapper: work already queued"));		
+    }
+#else
+    OSTimerCallbackBody(psTimerCBData);
+#endif
+}
+
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+static void OSTimerWorkQueueCallBack(struct work_struct *psWork)
+{
+    TIMER_CALLBACK_DATA *psTimerCBData = container_of(psWork, TIMER_CALLBACK_DATA, sWork);
+
+    OSTimerCallbackBody(psTimerCBData);
+}
+#endif
+
+IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout)
+{
+    TIMER_CALLBACK_DATA	*psTimerCBData;
+    IMG_UINT32		ui32i;
+#if !(defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE))
+    unsigned long		ulLockFlags;
+#endif
+
+    
+    if(!pfnTimerFunc)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback"));		
+        return IMG_NULL;		
+    }
+    
+    
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+    mutex_lock(&sTimerStructLock);
+#else
+    spin_lock_irqsave(&sTimerStructLock, ulLockFlags);
+#endif
+    for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
+    {
+        psTimerCBData = &sTimers[ui32i];
+        if (!psTimerCBData->bInUse)
+        {
+            psTimerCBData->bInUse = IMG_TRUE;
+            break;
+        }
+    }
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+    mutex_unlock(&sTimerStructLock);
+#else
+    spin_unlock_irqrestore(&sTimerStructLock, ulLockFlags);
+#endif
+    if (ui32i >= OS_MAX_TIMERS)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: all timers are in use"));		
+        return IMG_NULL;	
+    }
+
+    psTimerCBData->pfnTimerFunc = pfnTimerFunc;
+    psTimerCBData->pvData = pvData;
+    psTimerCBData->bActive = IMG_FALSE;
+    
+    
+
+
+    psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000)
+                                ?	1
+                                :	((HZ * ui32MsTimeout) / 1000);
+    
+    init_timer(&psTimerCBData->sTimer);
+    
+    
+     
+    psTimerCBData->sTimer.function = (IMG_VOID *)OSTimerCallbackWrapper;
+    psTimerCBData->sTimer.data = (IMG_UINT32)psTimerCBData;
+    
+    return (IMG_HANDLE)(ui32i + 1);
+}
+
+
+static inline TIMER_CALLBACK_DATA *GetTimerStructure(IMG_HANDLE hTimer)
+{
+    IMG_UINT32 ui32i = ((IMG_UINT32)hTimer) - 1;
+
+    PVR_ASSERT(ui32i < OS_MAX_TIMERS);
+
+    return &sTimers[ui32i];
+}
+
+PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer)
+{
+    TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+    PVR_ASSERT(psTimerCBData->bInUse);
+    PVR_ASSERT(!psTimerCBData->bActive);
+
+    
+    psTimerCBData->bInUse = IMG_FALSE;
+    
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer)
+{
+    TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+    PVR_ASSERT(psTimerCBData->bInUse);
+    PVR_ASSERT(!psTimerCBData->bActive);
+
+    
+    psTimerCBData->bActive = IMG_TRUE;
+
+    
+    psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies;
+
+    
+    add_timer(&psTimerCBData->sTimer);
+    
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer)
+{
+    TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+    PVR_ASSERT(psTimerCBData->bInUse);
+    PVR_ASSERT(psTimerCBData->bActive);
+
+    
+    psTimerCBData->bActive = IMG_FALSE;
+    smp_mb();
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+    flush_workqueue(psTimerWorkQueue);
+#endif
+#if defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+    flush_scheduled_work();
+#endif
+
+    
+    del_timer_sync(&psTimerCBData->sTimer);	
+    
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+    
+    flush_workqueue(psTimerWorkQueue);
+#endif
+#if defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+    flush_scheduled_work();
+#endif
+
+    return PVRSRV_OK;
+}
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT_KM *psEventObject)
+#else
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT *psEventObject)
+#endif
+{
+
+    PVRSRV_ERROR eError = PVRSRV_OK;
+    
+    if(psEventObject)
+    {
+        if(pszName)
+        {
+            
+            strncpy(psEventObject->szName, pszName, EVENTOBJNAME_MAXLENGTH);
+        }
+        else
+        {
+            	
+            static IMG_UINT16 ui16NameIndex = 0;			
+#if defined (SUPPORT_SID_INTERFACE)
+            snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_KM_%d", ui16NameIndex++);
+#else
+            snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_%d", ui16NameIndex++);
+#endif
+        }
+        
+        if(LinuxEventObjectListCreate(&psEventObject->hOSEventKM) != PVRSRV_OK)
+        {
+             eError = PVRSRV_ERROR_OUT_OF_MEMORY;	
+        }
+
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreateKM: psEventObject is not a valid pointer"));
+        eError = PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT;	
+    }
+    
+    return eError;
+
+}
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT_KM *psEventObject)
+#else
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT *psEventObject)
+#endif
+{
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+    if(psEventObject)
+    {
+        if(psEventObject->hOSEventKM)
+        {
+            LinuxEventObjectListDestroy(psEventObject->hOSEventKM);
+        }
+        else
+        {
+            PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: hOSEventKM is not a valid pointer"));
+            eError = PVRSRV_ERROR_INVALID_PARAMS;
+        }
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: psEventObject is not a valid pointer"));
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+    }
+    
+    return eError;
+}
+
+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM)
+{
+    PVRSRV_ERROR eError;
+    
+    if(hOSEventKM)
+    {
+        eError = LinuxEventObjectWait(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWaitKM: hOSEventKM is not a valid handle"));
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+    }
+    
+    return eError;
+}
+
+PVRSRV_ERROR OSEventObjectOpenKM(
+#if defined (SUPPORT_SID_INTERFACE)
+				 PVRSRV_EVENTOBJECT_KM *psEventObject,
+#else
+				 PVRSRV_EVENTOBJECT *psEventObject,
+#endif
+                                 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, "OSEventObjectCreateKM: psEventObject is not a valid pointer"));
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+    }
+    
+    return eError;
+}
+
+PVRSRV_ERROR OSEventObjectCloseKM(
+#if defined (SUPPORT_SID_INTERFACE)
+				  PVRSRV_EVENTOBJECT_KM *psEventObject,
+#else
+				  PVRSRV_EVENTOBJECT *psEventObject,
+#endif
+                                  IMG_HANDLE hOSEventKM)
+{
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+    if(psEventObject)
+    {
+        if(LinuxEventObjectDelete(psEventObject->hOSEventKM, hOSEventKM) != PVRSRV_OK)
+        {
+            PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectDelete: failed"));
+            eError = PVRSRV_ERROR_INVALID_PARAMS;
+        }
+
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: psEventObject is not a valid pointer"));
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+    }
+    
+    return eError;
+    
+}
+
+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM)
+{
+    PVRSRV_ERROR eError;
+    
+    if(hOSEventKM)
+    {
+        eError = LinuxEventObjectSignal(hOSEventKM);
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectSignalKM: hOSEventKM is not a valid handle"));
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+    }
+    
+    return eError;
+}
+
+IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID)
+{
+	/* Return true here so that we can run X as a non-root user. */
+	return IMG_TRUE;
+}
+
+PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, 
+                          IMG_VOID *pvDest, 
+                          IMG_VOID *pvSrc, 
+                          IMG_UINT32 ui32Bytes)
+{
+    PVR_UNREFERENCED_PARAMETER(pvProcess);
+
+    if (copy_to_user(pvDest, pvSrc, ui32Bytes) == 0)
+        return PVRSRV_OK;
+    else
+        return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
+}
+
+PVRSRV_ERROR OSCopyFromUser( IMG_PVOID pvProcess, 
+                             IMG_VOID *pvDest, 
+                             IMG_VOID *pvSrc, 
+                             IMG_UINT32 ui32Bytes)
+{
+    PVR_UNREFERENCED_PARAMETER(pvProcess);
+
+    if (copy_from_user(pvDest, pvSrc, ui32Bytes) == 0)
+        return PVRSRV_OK;
+    else
+        return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
+}
+
+IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_UINT32 ui32Bytes)
+{
+    if (eVerification == PVR_VERIFY_READ)
+    {
+	return access_ok(VERIFY_READ, pvUserPtr, ui32Bytes);
+    }
+    else
+    {
+        PVR_ASSERT(eVerification == PVR_VERIFY_WRITE);
+	return access_ok(VERIFY_WRITE, pvUserPtr, ui32Bytes);
+    }
+}
+
+typedef enum _eWrapMemType_
+{
+    WRAP_TYPE_NULL = 0,
+    WRAP_TYPE_GET_USER_PAGES,
+    WRAP_TYPE_FIND_VMA
+} eWrapMemType;
+
+typedef struct _sWrapMemInfo_
+{
+    eWrapMemType eType;
+    IMG_INT iNumPages;
+    IMG_INT iNumPagesMapped;
+    struct page **ppsPages;
+    IMG_SYS_PHYADDR *psPhysAddr;
+    IMG_INT iPageOffset;
+#if defined(DEBUG)
+    IMG_UINT32 ulStartAddr;
+    IMG_UINT32 ulBeyondEndAddr;
+    struct vm_area_struct *psVMArea;
+#endif
+} sWrapMemInfo;
+
+
+static IMG_BOOL CPUVAddrToPFN(struct vm_area_struct *psVMArea, IMG_UINT32 ulCPUVAddr, IMG_UINT32 *pulPFN, struct page **ppsPage)
+{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
+    pgd_t *psPGD;
+    pud_t *psPUD;
+    pmd_t *psPMD;
+    pte_t *psPTE;
+    struct mm_struct *psMM = psVMArea->vm_mm;
+    spinlock_t *psPTLock;
+    IMG_BOOL bRet = IMG_FALSE;
+
+    *pulPFN = 0;
+    *ppsPage = NULL;
+
+    psPGD = pgd_offset(psMM, ulCPUVAddr);
+    if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+        return bRet;
+
+    psPUD = pud_offset(psPGD, ulCPUVAddr);
+    if (pud_none(*psPUD) || pud_bad(*psPUD))
+        return bRet;
+
+    psPMD = pmd_offset(psPUD, ulCPUVAddr);
+    if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+        return bRet;
+
+    psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, ulCPUVAddr, &psPTLock);
+
+    if ((pte_none(*psPTE) == 0) && (pte_present(*psPTE) != 0) && (pte_write(*psPTE) != 0))
+    {
+        *pulPFN = pte_pfn(*psPTE);
+	bRet = IMG_TRUE;
+
+        if (pfn_valid(*pulPFN))
+        {
+            *ppsPage = pfn_to_page(*pulPFN);
+
+            get_page(*ppsPage);
+        }
+    }
+
+    pte_unmap_unlock(psPTE, psPTLock);
+
+    return bRet;
+#else
+    return IMG_FALSE;
+#endif
+}
+
+PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
+{
+    sWrapMemInfo *psInfo = (sWrapMemInfo *)hOSWrapMem;
+    IMG_INT i;
+
+    if (psInfo == IMG_NULL)
+    {
+        PVR_DPF((PVR_DBG_WARNING,
+            "OSReleasePhysPageAddr: called with null wrap handle"));
+	return PVRSRV_OK;
+    }
+
+    switch (psInfo->eType)
+    {
+	case WRAP_TYPE_NULL:
+	{
+            PVR_DPF((PVR_DBG_WARNING,
+                "OSReleasePhysPageAddr: called with wrap type WRAP_TYPE_NULL"));
+	    break;
+	}
+        case WRAP_TYPE_GET_USER_PAGES:
+        {
+            for (i = 0; i < psInfo->iNumPagesMapped; i++)
+            {
+                struct page *psPage = psInfo->ppsPages[i];
+
+		PVR_ASSERT(psPage != NULL);
+
+                
+		if (psInfo->iNumPagesMapped == psInfo->iNumPages)
+		{
+                    if (!PageReserved(psPage))
+                    {
+                        SetPageDirty(psPage);
+                    }
+	        }
+                page_cache_release(psPage);
+	    }
+            break;
+        }
+        case WRAP_TYPE_FIND_VMA:
+        {
+            for (i = 0; i < psInfo->iNumPages; i++)
+            {
+		if (psInfo->ppsPages[i] != IMG_NULL)
+		{
+                    put_page(psInfo->ppsPages[i]);
+		}
+            }
+            break;
+        }
+        default:
+        {
+            PVR_DPF((PVR_DBG_ERROR,
+                "OSReleasePhysPageAddr: Unknown wrap type (%d)", psInfo->eType));
+            return PVRSRV_ERROR_INVALID_WRAP_TYPE;
+        }
+    }
+
+    if (psInfo->ppsPages != IMG_NULL)
+    {
+        kfree(psInfo->ppsPages);
+    }
+
+    if (psInfo->psPhysAddr != IMG_NULL)
+    {
+        kfree(psInfo->psPhysAddr);
+    }
+
+    kfree(psInfo);
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID *pvCPUVAddr, 
+                                    IMG_UINT32 ui32Bytes, 
+                                    IMG_SYS_PHYADDR *psSysPAddr,
+                                    IMG_HANDLE *phOSWrapMem)
+{
+    IMG_UINT32 ulStartAddrOrig = (IMG_UINT32) pvCPUVAddr;
+    IMG_UINT32 ulAddrRangeOrig = (IMG_UINT32) ui32Bytes;
+    IMG_UINT32 ulBeyondEndAddrOrig = ulStartAddrOrig + ulAddrRangeOrig;
+    IMG_UINT32 ulStartAddr;
+    IMG_UINT32 ulAddrRange;
+    IMG_UINT32 ulBeyondEndAddr;
+    IMG_UINT32 ulAddr;
+    IMG_INT i;
+    struct vm_area_struct *psVMArea;
+    sWrapMemInfo *psInfo = NULL;
+    IMG_BOOL bHavePageStructs = IMG_FALSE;
+    IMG_BOOL bHaveNoPageStructs = IMG_FALSE;
+    IMG_BOOL bPFNMismatch = IMG_FALSE;
+    IMG_BOOL bMMapSemHeld = IMG_FALSE;
+    PVRSRV_ERROR eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+
+    
+    ulStartAddr = ulStartAddrOrig & PAGE_MASK;
+    ulBeyondEndAddr = PAGE_ALIGN(ulBeyondEndAddrOrig);
+    ulAddrRange = ulBeyondEndAddr - ulStartAddr;
+
+    
+    if (ulBeyondEndAddr <= ulStartAddr)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: Invalid address range (start %x, length %x)",
+		ulStartAddrOrig, ulAddrRangeOrig));
+        goto error;
+    }
+
+    
+    psInfo = kmalloc(sizeof(*psInfo), GFP_KERNEL);
+    if (psInfo == NULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: Couldn't allocate information structure"));
+        goto error;
+    }
+    memset(psInfo, 0, sizeof(*psInfo));
+
+#if defined(DEBUG)
+    psInfo->ulStartAddr = ulStartAddrOrig;
+    psInfo->ulBeyondEndAddr = ulBeyondEndAddrOrig;
+#endif
+
+    psInfo->iNumPages = (IMG_INT)(ulAddrRange >> PAGE_SHIFT);
+    psInfo->iPageOffset = (IMG_INT)(ulStartAddrOrig & ~PAGE_MASK);
+
+    
+    psInfo->psPhysAddr = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr), GFP_KERNEL);
+    if (psInfo->psPhysAddr == NULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: Couldn't allocate page array"));		
+        goto error;
+    }
+    memset(psInfo->psPhysAddr, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr));
+
+    
+    psInfo->ppsPages = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages),  GFP_KERNEL);
+    if (psInfo->ppsPages == NULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: Couldn't allocate page array"));		
+        goto error;
+    }
+    memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages));
+
+    
+    eError = PVRSRV_ERROR_BAD_MAPPING;
+
+    
+    psInfo->eType = WRAP_TYPE_GET_USER_PAGES;
+
+    
+    down_read(&current->mm->mmap_sem);
+    bMMapSemHeld = IMG_TRUE;
+
+    
+    psInfo->iNumPagesMapped = get_user_pages(current, current->mm, ulStartAddr, psInfo->iNumPages, 1, 0, psInfo->ppsPages, NULL);
+
+    if (psInfo->iNumPagesMapped >= 0)
+    {
+        
+        if (psInfo->iNumPagesMapped != psInfo->iNumPages)
+        {
+            PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't map all the pages needed (wanted: %d, got %d)", psInfo->iNumPages, psInfo->iNumPagesMapped));
+
+            goto error;
+        }
+
+        
+        for (i = 0; i < psInfo->iNumPages; i++)
+        {
+            IMG_CPU_PHYADDR CPUPhysAddr;
+	    IMG_UINT32 ulPFN;
+
+            ulPFN = page_to_pfn(psInfo->ppsPages[i]);
+            CPUPhysAddr.uiAddr = ulPFN << PAGE_SHIFT;
+	    if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ulPFN)
+	    {
+                PVR_DPF((PVR_DBG_ERROR,
+		    "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ulPFN));
+
+		    goto error;
+	    }
+            psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
+            psSysPAddr[i] = psInfo->psPhysAddr[i];
+            
+        }
+
+        goto exit;
+    }
+
+    PVR_DPF((PVR_DBG_MESSAGE, "OSAcquirePhysPageAddr: get_user_pages failed (%d), using CPU page table", psInfo->iNumPagesMapped));
+    
+    
+    psInfo->eType = WRAP_TYPE_NULL;
+    psInfo->iNumPagesMapped = 0;
+    memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages));
+
+    
+    
+    psInfo->eType = WRAP_TYPE_FIND_VMA;
+
+    psVMArea = find_vma(current->mm, ulStartAddrOrig);
+    if (psVMArea == NULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: Couldn't find memory region containing start address %x", ulStartAddrOrig));
+        
+        goto error;
+    }
+#if defined(DEBUG)
+    psInfo->psVMArea = psVMArea;
+#endif
+
+    
+    if (ulStartAddrOrig < psVMArea->vm_start)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: Start address %x is outside of the region returned by find_vma", ulStartAddrOrig));
+        goto error;
+    }
+
+    
+    if (ulBeyondEndAddrOrig > psVMArea->vm_end)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: End address %x is outside of the region returned by find_vma", ulBeyondEndAddrOrig));
+        goto error;
+    }
+
+    
+    if ((psVMArea->vm_flags & (VM_IO | VM_RESERVED)) != (VM_IO | VM_RESERVED))
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: Memory region does not represent memory mapped I/O (VMA flags: 0x%lx)", psVMArea->vm_flags));
+        goto error;
+    }
+
+    
+    if ((psVMArea->vm_flags & (VM_READ | VM_WRITE)) != (VM_READ | VM_WRITE))
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: No read/write access to memory region (VMA flags: 0x%lx)", psVMArea->vm_flags));
+        goto error;
+    }
+
+    for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++)
+    {
+	IMG_CPU_PHYADDR CPUPhysAddr;
+	IMG_UINT32 ulPFN = 0;
+
+	PVR_ASSERT(i < psInfo->iNumPages);
+
+	if (!CPUVAddrToPFN(psVMArea, ulAddr, &ulPFN, &psInfo->ppsPages[i]))
+	{
+            PVR_DPF((PVR_DBG_ERROR,
+	       "OSAcquirePhysPageAddr: Invalid CPU virtual address"));
+
+	    goto error;
+	}
+	if (psInfo->ppsPages[i] == NULL)
+	{
+
+	    bHaveNoPageStructs = IMG_TRUE;
+
+#if defined(VM_PFNMAP)
+	    if ((psVMArea->vm_flags & VM_PFNMAP) != 0)
+	    {
+	        IMG_UINT32 ulPFNRaw = ((ulAddr - psVMArea->vm_start) >> PAGE_SHIFT) + psVMArea->vm_pgoff;
+
+	        if (ulPFNRaw != ulPFN)
+	        {
+			bPFNMismatch = IMG_TRUE;
+	        }
+	    }
+#endif
+	}
+	else
+	{
+	    bHavePageStructs = IMG_TRUE;
+
+	    psInfo->iNumPagesMapped++;
+
+	    PVR_ASSERT(ulPFN == page_to_pfn(psInfo->ppsPages[i]));
+	}
+
+        CPUPhysAddr.uiAddr = ulPFN << PAGE_SHIFT;
+	if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ulPFN)
+	{
+                PVR_DPF((PVR_DBG_ERROR,
+		    "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ulPFN));
+
+		    goto error;
+	}
+
+	psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
+	psSysPAddr[i] = psInfo->psPhysAddr[i];
+    }
+    PVR_ASSERT(i ==  psInfo->iNumPages);
+
+#if defined(VM_MIXEDMAP)
+    if ((psVMArea->vm_flags & VM_MIXEDMAP) != 0)
+    {
+        goto exit;
+    }
+#endif
+
+    if (bHavePageStructs && bHaveNoPageStructs)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: Region is VM_MIXEDMAP, but isn't marked as such"));
+	goto error;
+    }
+
+    if (!bHaveNoPageStructs)
+    {
+	
+	goto exit;
+    }
+
+#if defined(VM_PFNMAP)
+    if ((psVMArea->vm_flags & VM_PFNMAP) == 0)
+#endif
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: Region is VM_PFNMAP, but isn't marked as such"));
+	goto error;
+    }
+
+    if (bPFNMismatch)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+            "OSAcquirePhysPageAddr: PFN calculation mismatch for VM_PFNMAP region"));
+	goto error;
+    }
+
+exit:
+    PVR_ASSERT(bMMapSemHeld);
+    up_read(&current->mm->mmap_sem);
+
+    
+    *phOSWrapMem = (IMG_HANDLE)psInfo;
+
+    if (bHaveNoPageStructs)
+    {
+        PVR_DPF((PVR_DBG_WARNING,
+            "OSAcquirePhysPageAddr: Region contains pages which can't be locked down (no page structures)"));
+    }
+
+    PVR_ASSERT(psInfo->eType != 0);
+
+#if 0
+    
+    
+    OSCleanCPUCacheRangeKM(pvCPUVAddr, (IMG_VOID *)((IMG_CHAR *)pvCPUVAddr + ui32Bytes));
+#endif
+
+    return PVRSRV_OK;
+
+error:
+    if (bMMapSemHeld)
+    {
+        up_read(&current->mm->mmap_sem);
+    }
+    OSReleasePhysPageAddr((IMG_HANDLE)psInfo);
+
+    PVR_ASSERT(eError != PVRSRV_OK);
+
+    return eError;
+}
+
+typedef void (*InnerCacheOp_t)(const void *pvStart, const void *pvEnd);
+typedef void (*OuterCacheOp_t)(unsigned long ulStart, unsigned long ulEnd);
+
+#if defined(CONFIG_OUTER_CACHE)
+
+typedef unsigned long (*MemAreaToPhys_t)(LinuxMemArea *psLinuxMemArea,
+										 IMG_VOID *pvRangeAddrStart,
+										 IMG_UINT32 ui32PageNumOffset,
+										 IMG_UINT32 ui32PageNum);
+
+static unsigned long VMallocAreaToPhys(LinuxMemArea *psLinuxMemArea,
+									   IMG_VOID *pvRangeAddrStart,
+									   IMG_UINT32 ui32PageNumOffset,
+									   IMG_UINT32 ui32PageNum)
+{
+	return vmalloc_to_pfn(pvRangeAddrStart + ui32PageNum * PAGE_SIZE) << PAGE_SHIFT;
+}
+
+static unsigned long ExternalKVAreaToPhys(LinuxMemArea *psLinuxMemArea,
+										  IMG_VOID *pvRangeAddrStart,
+										  IMG_UINT32 ui32PageNumOffset,
+										  IMG_UINT32 ui32PageNum)
+{
+	IMG_SYS_PHYADDR SysPAddr;
+	IMG_CPU_PHYADDR CpuPAddr;
+	SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageNumOffset + ui32PageNum];
+	CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr);
+	return CpuPAddr.uiAddr;
+}
+
+static unsigned long AllocPagesAreaToPhys(LinuxMemArea *psLinuxMemArea,
+										  IMG_VOID *pvRangeAddrStart,
+										  IMG_UINT32 ui32PageNumOffset,
+										  IMG_UINT32 ui32PageNum)
+{
+	struct page *pPage;
+	pPage = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageNumOffset + ui32PageNum];
+	return page_to_pfn(pPage) << PAGE_SHIFT;
+}
+
+#endif 
+
+#ifndef __mips__
+static
+IMG_VOID *FindMMapBaseVAddr(struct list_head *psMMapOffsetStructList,
+							IMG_VOID *pvRangeAddrStart, IMG_UINT32 ui32Length)
+{
+	PKV_OFFSET_STRUCT psOffsetStruct;
+	IMG_VOID *pvMinVAddr;
+
+	
+	list_for_each_entry(psOffsetStruct, psMMapOffsetStructList, sAreaItem)
+	{
+		if(OSGetCurrentProcessIDKM() != psOffsetStruct->ui32PID)
+			continue;
+
+		pvMinVAddr = (IMG_VOID *)psOffsetStruct->ui32UserVAddr;
+
+		
+		if(pvRangeAddrStart >= pvMinVAddr &&
+		   ui32Length <= psOffsetStruct->ui32RealByteSize)
+			return pvMinVAddr;
+	}
+
+	return IMG_NULL;
+}
+
+static
+IMG_BOOL CheckExecuteCacheOp(IMG_HANDLE hOSMemHandle,
+							 IMG_VOID *pvRangeAddrStart,
+							 IMG_UINT32 ui32Length,
+							 InnerCacheOp_t pfnInnerCacheOp,
+							 OuterCacheOp_t pfnOuterCacheOp)
+{
+	LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+	IMG_UINT32 ui32AreaLength, ui32AreaOffset = 0;
+	struct list_head *psMMapOffsetStructList;
+	IMG_VOID *pvMinVAddr;
+
+#if defined(CONFIG_OUTER_CACHE)
+	MemAreaToPhys_t pfnMemAreaToPhys = IMG_NULL;
+	IMG_UINT32 ui32PageNumOffset = 0;
+#endif
+
+	PVR_ASSERT(psLinuxMemArea != IMG_NULL);
+
+	ui32AreaLength = psLinuxMemArea->ui32ByteSize;
+	psMMapOffsetStructList = &psLinuxMemArea->sMMapOffsetStructList;
+
+	PVR_ASSERT(ui32Length <= ui32AreaLength);
+
+	if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
+	{
+		ui32AreaOffset = psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset;
+		psLinuxMemArea = psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
+	}
+
+	
+	PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
+
+	switch(psLinuxMemArea->eAreaType)
+	{
+		case LINUX_MEM_AREA_VMALLOC:
+		{
+			if(is_vmalloc_addr(pvRangeAddrStart))
+			{
+				pvMinVAddr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress + ui32AreaOffset;
+
+				
+				if(pvRangeAddrStart < pvMinVAddr)
+					goto err_blocked;
+
+				pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+			}
+			else
+			{
+				
+				
+
+				pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+											   pvRangeAddrStart, ui32Length);
+				if(!pvMinVAddr)
+					goto err_blocked;
+
+				pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+
+#if defined(CONFIG_OUTER_CACHE)
+				
+				pvRangeAddrStart = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress +
+								   (ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr);
+			}
+
+			pfnMemAreaToPhys = VMallocAreaToPhys;
+#else 
+			}
+#endif 
+			break;
+		}
+
+		case LINUX_MEM_AREA_EXTERNAL_KV:
+		{
+			
+			if (psLinuxMemArea->uData.sExternalKV.bPhysContig == IMG_TRUE)
+			{
+				PVR_DPF((PVR_DBG_WARNING, "%s: Attempt to flush contiguous external memory", __func__));
+
+				goto err_blocked;
+			}
+
+			
+			if (psLinuxMemArea->uData.sExternalKV.pvExternalKV != IMG_NULL)
+			{
+				PVR_DPF((PVR_DBG_WARNING, "%s: Attempt to flush external memory with a kernel virtual address", __func__));
+
+				goto err_blocked;
+			}
+
+			
+
+			pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+										   pvRangeAddrStart, ui32Length);
+			if(!pvMinVAddr)
+				goto err_blocked;
+
+			pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+
+#if defined(CONFIG_OUTER_CACHE)
+			ui32PageNumOffset = ((ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
+			pfnMemAreaToPhys = ExternalKVAreaToPhys;
+#endif
+			break;
+		}
+
+		case LINUX_MEM_AREA_ALLOC_PAGES:
+		{
+			pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+										   pvRangeAddrStart, ui32Length);
+			if(!pvMinVAddr)
+				goto err_blocked;
+
+			pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+
+#if defined(CONFIG_OUTER_CACHE)
+			ui32PageNumOffset = ((ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
+			pfnMemAreaToPhys = AllocPagesAreaToPhys;
+#endif
+			break;
+		}
+
+		default:
+			PVR_DBG_BREAK;
+	}
+
+#if defined(CONFIG_OUTER_CACHE)
+	PVR_ASSERT(pfnMemAreaToPhys != IMG_NULL);
+
+	
+	{
+		unsigned long ulStart, ulEnd, ulLength, ulStartOffset, ulEndOffset;
+		IMG_UINT32 i, ui32NumPages;
+
+		
+		ulLength = (unsigned long)ui32Length;
+		ulStartOffset = ((unsigned long)pvRangeAddrStart) & (PAGE_SIZE - 1);
+		ulEndOffset = ((unsigned long)pvRangeAddrStart + ulLength) & (PAGE_SIZE - 1);
+
+		
+		ui32NumPages = (ulStartOffset + ulLength + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+		for(i = 0; i < ui32NumPages; i++)
+		{
+			ulStart = pfnMemAreaToPhys(psLinuxMemArea, pvRangeAddrStart,
+									   ui32PageNumOffset, i);
+			ulEnd = ulStart + PAGE_SIZE;
+
+			if(i == ui32NumPages - 1 && ulEndOffset != 0)
+				ulEnd = ulStart + ulEndOffset;
+
+			if(i == 0)
+				ulStart += ulStartOffset;
+
+			pfnOuterCacheOp(ulStart, ulEnd);
+		}
+	}
+#endif
+
+	return IMG_TRUE;
+
+err_blocked:
+	PVR_DPF((PVR_DBG_WARNING, "%s: Blocked cache op on virtual range "
+							  "%p-%p (type %d)", __func__,
+			 pvRangeAddrStart, pvRangeAddrStart + ui32Length,
+			 psLinuxMemArea->eAreaType));
+	return IMG_FALSE;
+}
+
+#endif
+
+#if defined(__i386__)
+
+#define ROUND_UP(x,a) (((x) + (a) - 1) & ~((a) - 1))
+
+static void per_cpu_cache_flush(void *arg)
+{
+    PVR_UNREFERENCED_PARAMETER(arg);
+    wbinvd();
+}
+
+static void x86_flush_cache_range(const void *pvStart, const void *pvEnd)
+{
+	IMG_BYTE *pbStart = (IMG_BYTE *)pvStart;
+	IMG_BYTE *pbEnd = (IMG_BYTE *)pvEnd;
+	IMG_BYTE *pbBase;
+
+	pbEnd = (IMG_BYTE *)ROUND_UP((IMG_UINTPTR_T)pbEnd,
+								 boot_cpu_data.x86_clflush_size);
+
+	mb();
+	for(pbBase = pbStart; pbBase < pbEnd; pbBase += boot_cpu_data.x86_clflush_size)
+		clflush(pbBase);
+	mb();
+}
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
+{
+	
+	ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+}
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
+{
+	ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+}
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+								IMG_VOID *pvRangeAddrStart,
+								IMG_UINT32 ui32Length)
+{
+	
+	return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+							   x86_flush_cache_range, IMG_NULL);
+}
+
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+								IMG_VOID *pvRangeAddrStart,
+								IMG_UINT32 ui32Length)
+{
+	
+	return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+							   x86_flush_cache_range, IMG_NULL);
+}
+
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+									 IMG_VOID *pvRangeAddrStart,
+									 IMG_UINT32 ui32Length)
+{
+	
+	return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+							   x86_flush_cache_range, IMG_NULL);
+}
+
+#else 
+
+#if defined(__arm__)
+
+static void per_cpu_cache_flush(void *arg)
+{
+	PVR_UNREFERENCED_PARAMETER(arg);
+	flush_cache_all();
+}
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
+{
+	
+	ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+#if defined(CONFIG_OUTER_CACHE) && !defined(PVR_NO_FULL_CACHE_OPS)
+	outer_clean_all();
+#endif
+}
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
+{
+	ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+#if defined(CONFIG_OUTER_CACHE) && !defined(PVR_NO_FULL_CACHE_OPS)
+	outer_flush_all();
+#endif
+}
+
+static inline size_t pvr_dmac_range_len(const void *pvStart, const void *pvEnd)
+{
+	return (size_t)((char *)pvEnd - (char *)pvStart);
+}
+
+static void pvr_dmac_inv_range(const void *pvStart, const void *pvEnd)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
+	dmac_inv_range(pvStart, pvEnd);
+#else
+	dmac_map_area(pvStart, pvr_dmac_range_len(pvStart, pvEnd), DMA_FROM_DEVICE);
+#endif
+}
+
+static void pvr_dmac_clean_range(const void *pvStart, const void *pvEnd)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
+	dmac_clean_range(pvStart, pvEnd);
+#else
+	dmac_map_area(pvStart, pvr_dmac_range_len(pvStart, pvEnd), DMA_TO_DEVICE);
+#endif
+}
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+								IMG_VOID *pvRangeAddrStart,
+								IMG_UINT32 ui32Length)
+{
+	return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+							   dmac_flush_range, outer_flush_range);
+}
+
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+								IMG_VOID *pvRangeAddrStart,
+								IMG_UINT32 ui32Length)
+{
+	return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+							   pvr_dmac_clean_range, outer_clean_range);
+}
+
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+									 IMG_VOID *pvRangeAddrStart,
+									 IMG_UINT32 ui32Length)
+{
+	return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+							   pvr_dmac_inv_range, outer_inv_range);
+}
+
+#else 
+
+#if defined(__mips__)
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
+{
+	
+	dma_cache_wback(0, 0x100000);
+}
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
+{
+	
+	dma_cache_wback_inv(0, 0x100000);
+}
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+								IMG_VOID *pvRangeAddrStart,
+								IMG_UINT32 ui32Length)
+{
+	if (ui32Length)
+		dma_cache_wback_inv((IMG_UINTPTR_T)pvRangeAddrStart, ui32Length);	
+	return IMG_TRUE;
+}
+
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+								IMG_VOID *pvRangeAddrStart,
+								IMG_UINT32 ui32Length)
+{
+	if (ui32Length)
+		dma_cache_wback((IMG_UINTPTR_T)pvRangeAddrStart, ui32Length);
+	return IMG_TRUE;
+}
+
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+									 IMG_VOID *pvRangeAddrStart,
+									 IMG_UINT32 ui32Length)
+{
+	if (ui32Length)
+		dma_cache_inv((IMG_UINTPTR_T)pvRangeAddrStart, ui32Length);
+	return IMG_TRUE;
+}
+
+#else 
+
+#error "Implement CPU cache flush/clean/invalidate primitives for this CPU!"
+
+#endif 
+
+#endif 
+
+#endif 
+
+PVRSRV_ERROR PVROSFuncInit(IMG_VOID)
+{
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+    {
+        psTimerWorkQueue = create_workqueue("pvr_timer");
+        if (psTimerWorkQueue == NULL)
+        {
+	    PVR_DPF((PVR_DBG_ERROR, "%s: couldn't create timer workqueue", __FUNCTION__));		
+	    return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD;
+
+        }
+    }
+#endif
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+    {
+	IMG_UINT32 ui32i;
+
+        for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
+        {
+            TIMER_CALLBACK_DATA *psTimerCBData = &sTimers[ui32i];
+
+	    INIT_WORK(&psTimerCBData->sWork, OSTimerWorkQueueCallBack);
+        }
+    }
+#endif
+    return PVRSRV_OK;
+}
+
+IMG_VOID PVROSFuncDeInit(IMG_VOID)
+{
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+    if (psTimerWorkQueue != NULL)
+    {
+	destroy_workqueue(psTimerWorkQueue);
+    }
+#endif
+}
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/osperproc.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/osperproc.c
new file mode 100644
index 0000000..6b57dfc
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/osperproc.c
@@ -0,0 +1,113 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "osperproc.h"
+
+#include "env_perproc.h"
+#include "proc.h"
+
+extern IMG_UINT32 gui32ReleasePID;
+
+PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData)
+{
+	PVRSRV_ERROR eError;
+	IMG_HANDLE hBlockAlloc;
+	PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+
+	eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
+				phOsPrivateData,
+				&hBlockAlloc,
+				"Environment per Process Data");
+
+	if (eError != PVRSRV_OK)
+	{
+		*phOsPrivateData = IMG_NULL;
+
+		PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed (%d)", __FUNCTION__, eError));
+		return eError;
+	}
+
+	psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)*phOsPrivateData;
+	OSMemSet(psEnvPerProc, 0, sizeof(*psEnvPerProc));
+
+	psEnvPerProc->hBlockAlloc = hBlockAlloc;
+
+	
+	LinuxMMapPerProcessConnect(psEnvPerProc);
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+	
+	INIT_LIST_HEAD(&psEnvPerProc->sDRMAuthListHead);
+#endif
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+
+	if (hOsPrivateData == IMG_NULL)
+	{
+		return PVRSRV_OK;
+	}
+
+	psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)hOsPrivateData;
+
+	
+	LinuxMMapPerProcessDisconnect(psEnvPerProc);
+
+	
+	RemovePerProcessProcDir(psEnvPerProc);
+
+	eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+				sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
+				hOsPrivateData,
+				psEnvPerProc->hBlockAlloc);
+	
+
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: OSFreeMem failed (%d)", __FUNCTION__, eError));
+	}
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
+{
+	return LinuxMMapPerProcessHandleOptions(psHandleBase);
+}
+
+IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID)
+{
+	if(!gui32ReleasePID)
+		return NULL;
+	return PVRSRVPerProcessPrivateData(gui32ReleasePID);
+}
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pdump.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pdump.c
new file mode 100644
index 0000000..13d9b0d
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pdump.c
@@ -0,0 +1,628 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if defined (SUPPORT_SGX) || defined (SUPPORT_VGX)
+#if defined (PDUMP)
+
+#include <asm/atomic.h>
+#include <stdarg.h>
+#if defined (SUPPORT_SGX)
+#include "sgxdefs.h" 
+#endif
+#include "services_headers.h"
+
+#include "pvrversion.h"
+#include "pvr_debug.h"
+
+#include "dbgdrvif.h"
+#if defined (SUPPORT_SGX)
+#include "sgxmmu.h"
+#endif
+#include "mm.h"
+#include "pdump_km.h"
+#include "pdump_int.h"
+
+#include <linux/kernel.h> 
+#include <linux/string.h> 
+
+static IMG_BOOL PDumpWriteString2		(IMG_CHAR * pszString, IMG_UINT32 ui32Flags);
+static IMG_BOOL PDumpWriteILock			(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags);
+static IMG_VOID DbgSetFrame				(PDBG_STREAM psStream, IMG_UINT32 ui32Frame);
+static IMG_VOID DbgSetMarker			(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+
+#define PDUMP_DATAMASTER_PIXEL		(1)
+#define PDUMP_DATAMASTER_EDM		(3)
+
+#define MAX_FILE_SIZE	0x40000000
+
+static atomic_t gsPDumpSuspended = ATOMIC_INIT(0);
+
+static PDBGKM_SERVICE_TABLE gpfnDbgDrv = IMG_NULL;
+
+
+
+IMG_CHAR *pszStreamName[PDUMP_NUM_STREAMS] = {	"ParamStream2",
+												"ScriptStream2",
+												"DriverInfoStream"};
+typedef struct PDBG_PDUMP_STATE_TAG
+{
+	PDBG_STREAM psStream[PDUMP_NUM_STREAMS];
+	IMG_UINT32 ui32ParamFileNum;
+
+	IMG_CHAR *pszMsg;
+	IMG_CHAR *pszScript;
+	IMG_CHAR *pszFile;
+
+} PDBG_PDUMP_STATE;
+
+static PDBG_PDUMP_STATE gsDBGPdumpState = {{IMG_NULL}, 0, IMG_NULL, IMG_NULL, IMG_NULL};
+
+#define SZ_MSG_SIZE_MAX			PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
+#define SZ_SCRIPT_SIZE_MAX		PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
+#define SZ_FILENAME_SIZE_MAX	PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
+
+
+
+
+IMG_VOID DBGDrvGetServiceTable(IMG_VOID **fn_table);
+
+static inline IMG_BOOL PDumpSuspended(IMG_VOID)
+{
+	return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE;
+}
+
+PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript,
+									IMG_UINT32 *pui32MaxLen)
+{
+	*phScript = (IMG_HANDLE)gsDBGPdumpState.pszScript;
+	*pui32MaxLen = SZ_SCRIPT_SIZE_MAX;
+	if ((!*phScript) || PDumpSuspended())
+	{
+		return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+	}
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg,
+									 IMG_UINT32 *pui32MaxLen)
+{
+	*ppszMsg = gsDBGPdumpState.pszMsg;
+	*pui32MaxLen = SZ_MSG_SIZE_MAX;
+	if ((!*ppszMsg) || PDumpSuspended())
+	{
+		return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+	}
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile,
+									 IMG_UINT32 *pui32MaxLen)
+{
+	*ppszFile = gsDBGPdumpState.pszFile;
+	*pui32MaxLen = SZ_FILENAME_SIZE_MAX;
+	if ((!*ppszFile) || PDumpSuspended())
+	{
+		return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+	}
+	return PVRSRV_OK;
+}
+
+IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags)
+{
+	return PDumpWriteString2(hScript, ui32Flags);
+}
+
+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...)
+{
+	IMG_CHAR* pszBuf = hBuf;
+	IMG_INT32 n;
+	va_list	vaArgs;
+
+	va_start(vaArgs, pszFormat);
+
+	n = vsnprintf(pszBuf, ui32ScriptSizeMax, pszFormat, vaArgs);
+
+	va_end(vaArgs);
+
+	if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1)	
+	{
+		PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+		return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+	}
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+	g_ui32EveryLineCounter++;
+#endif
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs)
+{
+	IMG_INT32 n;
+
+	n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
+
+	if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1)	
+	{
+		PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+		return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+	}
+
+	return PVRSRV_OK;
+}
+
+IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...)
+{
+	PVR_UNREFERENCED_PARAMETER(pszFormat);
+
+	
+}
+
+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...)
+{
+	IMG_INT32 n;
+	va_list	vaArgs;
+
+	va_start(vaArgs, pszFormat);
+
+	n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
+
+	va_end(vaArgs);
+
+	if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1)	
+	{
+		PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+		return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+	}
+
+	return PVRSRV_OK;
+}
+
+IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
+{
+	IMG_CHAR* pszBuf = hBuffer;
+	IMG_UINT32 ui32Count = 0;
+
+	while ((pszBuf[ui32Count]!=0) && (ui32Count<ui32BufferSizeMax) )
+	{
+		ui32Count++;
+	}
+	return(ui32Count);
+}
+
+IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
+{
+	IMG_UINT32 ui32Count;
+	IMG_CHAR* pszBuf = hBuffer;
+
+	
+	ui32Count = PDumpOSBuflen(hBuffer, ui32BufferSizeMax);
+
+	
+	if ((ui32Count >= 1) && (pszBuf[ui32Count-1] != '\n') && (ui32Count<ui32BufferSizeMax))
+	{
+		pszBuf[ui32Count] = '\n';
+		ui32Count++;
+		pszBuf[ui32Count] = '\0';
+	}
+	if ((ui32Count >= 2) && (pszBuf[ui32Count-2] != '\r') && (ui32Count<ui32BufferSizeMax))
+	{
+		pszBuf[ui32Count-1] = '\r';
+		pszBuf[ui32Count] = '\n';
+		ui32Count++;
+		pszBuf[ui32Count] = '\0';
+	}
+}
+
+IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream)
+{
+	return (IMG_HANDLE)gsDBGPdumpState.psStream[ePDumpStream];
+}
+
+IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream)
+{
+	PDBG_STREAM psStream = gsDBGPdumpState.psStream[ePDumpStream];
+	return gpfnDbgDrv->pfnGetStreamOffset(psStream);
+}
+
+IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID)
+{
+	return gsDBGPdumpState.ui32ParamFileNum;
+}
+
+IMG_BOOL PDumpOSWriteString(IMG_HANDLE hStream,
+		IMG_UINT8 *psui8Data,
+		IMG_UINT32 ui32Size,
+		IMG_UINT32 ui32Flags)
+{
+	PDBG_STREAM psStream = (PDBG_STREAM)hStream;
+	return PDumpWriteILock(psStream,
+					psui8Data,
+					ui32Size,
+					ui32Flags);
+}
+
+IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags)
+{
+	
+	PVR_UNREFERENCED_PARAMETER(hStream);
+	PVR_UNREFERENCED_PARAMETER(ui32Size);
+	PVR_UNREFERENCED_PARAMETER(ui32Flags);
+}
+
+IMG_BOOL PDumpOSJTInitialised(IMG_VOID)
+{
+	if(gpfnDbgDrv)
+	{
+		return IMG_TRUE;
+	}
+	return IMG_FALSE;
+}
+
+inline IMG_BOOL PDumpOSIsSuspended(IMG_VOID)
+{
+	return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE;
+}
+
+IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
+        IMG_HANDLE hOSMemHandle,
+		IMG_UINT32 ui32Offset,
+		IMG_UINT8 *pui8LinAddr,
+		IMG_UINT32 ui32PageSize,
+		IMG_DEV_PHYADDR *psDevPAddr)
+{
+	IMG_CPU_PHYADDR	sCpuPAddr;
+
+	PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
+	PVR_UNREFERENCED_PARAMETER(ui32PageSize);   
+
+	
+	   
+	PVR_ASSERT (hOSMemHandle != IMG_NULL);
+	
+	sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
+	PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0);
+
+	
+	*psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
+}
+
+IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
+		IMG_UINT32 ui32Offset,
+		IMG_PUINT8 pui8LinAddr,
+		IMG_UINT32 ui32DataPageMask,
+		IMG_UINT32 *pui32PageOffset)
+{
+	if(hOSMemHandle)
+	{
+		
+		IMG_CPU_PHYADDR     sCpuPAddr;
+
+		PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
+
+		sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
+	    *pui32PageOffset = sCpuPAddr.uiAddr & ui32DataPageMask;
+	}
+	else
+	{
+		PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+		PVR_UNREFERENCED_PARAMETER(ui32Offset);
+
+		*pui32PageOffset = ((IMG_UINT32)pui8LinAddr & ui32DataPageMask);
+	}
+}
+
+IMG_UINT32 PDumpOSDebugDriverWrite( PDBG_STREAM psStream,
+									PDUMP_DDWMODE eDbgDrvWriteMode,
+									IMG_UINT8 *pui8Data,
+									IMG_UINT32 ui32BCount,
+									IMG_UINT32 ui32Level,
+									IMG_UINT32 ui32DbgDrvFlags)
+{
+	switch(eDbgDrvWriteMode)
+	{
+		case PDUMP_WRITE_MODE_CONTINUOUS:
+			PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+			return gpfnDbgDrv->pfnDBGDrivWrite2(psStream, pui8Data, ui32BCount, ui32Level);
+		case PDUMP_WRITE_MODE_LASTFRAME:
+			return gpfnDbgDrv->pfnWriteLF(psStream, pui8Data, ui32BCount, ui32Level, ui32DbgDrvFlags);
+		case PDUMP_WRITE_MODE_BINCM:
+			PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+			return gpfnDbgDrv->pfnWriteBINCM(psStream, pui8Data, ui32BCount, ui32Level);
+		case PDUMP_WRITE_MODE_PERSISTENT:
+			PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+			return gpfnDbgDrv->pfnWritePersist(psStream, pui8Data, ui32BCount, ui32Level);
+		default:
+			PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+			break;
+	}
+	return 0xFFFFFFFFU;
+}
+
+IMG_VOID PDumpOSReleaseExecution(IMG_VOID)
+{
+	OSReleaseThreadQuanta();
+}
+
+IMG_VOID PDumpInit(IMG_VOID)
+{
+	IMG_UINT32 i;
+	DBGKM_CONNECT_NOTIFIER sConnectNotifier;
+
+	
+	if (!gpfnDbgDrv)
+	{
+		DBGDrvGetServiceTable((IMG_VOID **)&gpfnDbgDrv);
+
+
+		
+		if (gpfnDbgDrv == IMG_NULL)
+		{
+			return;
+		}
+		
+		
+		sConnectNotifier.pfnConnectNotifier = &PDumpConnectionNotify;
+		gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
+
+		if(!gsDBGPdumpState.pszFile)
+		{
+			if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszFile, 0,
+				"Filename string") != PVRSRV_OK)
+			{
+				goto init_failed;
+			}
+		}
+
+		if(!gsDBGPdumpState.pszMsg)
+		{
+			if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszMsg, 0,
+				"Message string") != PVRSRV_OK)
+			{
+				goto init_failed;
+			}
+		}
+
+		if(!gsDBGPdumpState.pszScript)
+		{
+			if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszScript, 0,
+				"Script string") != PVRSRV_OK)
+			{
+				goto init_failed;
+			}
+		}
+
+		for(i=0; i < PDUMP_NUM_STREAMS; i++)
+		{
+			gsDBGPdumpState.psStream[i] = gpfnDbgDrv->pfnCreateStream(pszStreamName[i],
+														DEBUG_CAPMODE_FRAMED,
+														DEBUG_OUTMODE_STREAMENABLE,
+														0,
+														10);
+
+			gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState.psStream[i],DEBUG_CAPMODE_FRAMED,0xFFFFFFFF, 0xFFFFFFFF, 1);
+			gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i],0);
+		}
+
+		PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME);
+		PDUMPCOMMENT("Driver Product Version: %s (%s)", PVRVERSION_STRING, PVRVERSION_FAMILY);
+		PDUMPCOMMENT("Start of Init Phase");
+	}
+
+	return;
+
+init_failed:
+
+	if(gsDBGPdumpState.pszFile)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0);
+		gsDBGPdumpState.pszFile = IMG_NULL;
+	}
+
+	if(gsDBGPdumpState.pszScript)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0);
+		gsDBGPdumpState.pszScript = IMG_NULL;
+	}
+
+	if(gsDBGPdumpState.pszMsg)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0);
+		gsDBGPdumpState.pszMsg = IMG_NULL;
+	}
+
+	
+	sConnectNotifier.pfnConnectNotifier = 0;
+	gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
+
+	gpfnDbgDrv = IMG_NULL;
+}
+
+
+IMG_VOID PDumpDeInit(IMG_VOID)
+{
+	IMG_UINT32 i;
+	DBGKM_CONNECT_NOTIFIER sConnectNotifier;
+
+	for(i=0; i < PDUMP_NUM_STREAMS; i++)
+	{
+		gpfnDbgDrv->pfnDestroyStream(gsDBGPdumpState.psStream[i]);
+	}
+
+	if(gsDBGPdumpState.pszFile)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0);
+		gsDBGPdumpState.pszFile = IMG_NULL;
+	}
+
+	if(gsDBGPdumpState.pszScript)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0);
+		gsDBGPdumpState.pszScript = IMG_NULL;
+	}
+
+	if(gsDBGPdumpState.pszMsg)
+	{
+		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0);
+		gsDBGPdumpState.pszMsg = IMG_NULL;
+	}
+
+	
+	sConnectNotifier.pfnConnectNotifier = 0;
+	gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
+
+	gpfnDbgDrv = IMG_NULL;
+}
+
+PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID)
+{
+	IMG_UINT32 i;
+
+	if (gpfnDbgDrv)
+	{
+		PDUMPCOMMENT("Start Init Phase");
+		for(i=0; i < PDUMP_NUM_STREAMS; i++)
+		{
+			gpfnDbgDrv->pfnStartInitPhase(gsDBGPdumpState.psStream[i]);
+		}
+	}
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID)
+{
+	IMG_UINT32 i;
+
+	if (gpfnDbgDrv)
+	{
+		PDUMPCOMMENT("Stop Init Phase");
+
+		for(i=0; i < PDUMP_NUM_STREAMS; i++)
+		{
+			gpfnDbgDrv->pfnStopInitPhase(gsDBGPdumpState.psStream[i]);
+		}
+	}
+	return PVRSRV_OK;
+}
+
+IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID)
+{
+	return gpfnDbgDrv->pfnIsLastCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]);
+}
+
+
+IMG_BOOL PDumpOSIsCaptureFrameKM(IMG_VOID)
+{
+	if (PDumpSuspended())
+	{
+		return IMG_FALSE;
+	}
+	return gpfnDbgDrv->pfnIsCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], IMG_FALSE);
+}
+
+PVRSRV_ERROR PDumpOSSetFrameKM(IMG_UINT32 ui32Frame)
+{
+	IMG_UINT32	ui32Stream;
+
+	for	(ui32Stream = 0; ui32Stream < PDUMP_NUM_STREAMS; ui32Stream++)
+	{
+		if	(gsDBGPdumpState.psStream[ui32Stream])
+		{
+			DbgSetFrame(gsDBGPdumpState.psStream[ui32Stream], ui32Frame);
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static IMG_BOOL PDumpWriteString2(IMG_CHAR * pszString, IMG_UINT32 ui32Flags)
+{
+	return PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], (IMG_UINT8 *) pszString, strlen(pszString), ui32Flags);
+}
+
+
+static IMG_BOOL PDumpWriteILock(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags)
+{
+	IMG_UINT32 ui32Written = 0;
+	if ((psStream == IMG_NULL) || PDumpSuspended() || ((ui32Flags & PDUMP_FLAGS_NEVER) != 0))
+	{
+		PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteILock: Failed to write 0x%x bytes to stream 0x%x", ui32Count, (IMG_UINT32)psStream));
+		return IMG_TRUE;
+	}
+
+
+	
+
+	if (psStream == gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2])
+	{
+		IMG_UINT32 ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]);
+
+		if (ui32ParamOutPos + ui32Count > MAX_FILE_SIZE)
+		{
+			if ((gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2] && PDumpWriteString2("\r\n-- Splitting pdump output file\r\n\r\n", ui32Flags)))
+			{
+				DbgSetMarker(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], ui32ParamOutPos);
+				gsDBGPdumpState.ui32ParamFileNum++;
+			}
+		}
+	}
+
+	ui32Written = DbgWrite(psStream, pui8Data, ui32Count, ui32Flags);
+
+	if (ui32Written == 0xFFFFFFFF)
+	{
+		return IMG_FALSE;
+	}
+
+	return IMG_TRUE;
+}
+
+static IMG_VOID DbgSetFrame(PDBG_STREAM psStream, IMG_UINT32 ui32Frame)
+{
+	gpfnDbgDrv->pfnSetFrame(psStream, ui32Frame);
+}
+
+static IMG_VOID DbgSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+	gpfnDbgDrv->pfnSetMarker(psStream, ui32Marker);
+}
+
+IMG_VOID PDumpSuspendKM(IMG_VOID)
+{
+	atomic_inc(&gsPDumpSuspended);
+}
+
+IMG_VOID PDumpResumeKM(IMG_VOID)
+{
+	atomic_dec(&gsPDumpSuspended);
+}
+
+#endif 
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/private_data.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/private_data.h
new file mode 100644
index 0000000..b8751d3
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/private_data.h
@@ -0,0 +1,69 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __INCLUDED_PRIVATE_DATA_H_
+#define __INCLUDED_PRIVATE_DATA_H_
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+#include <linux/list.h>
+#include <drm/drmP.h>
+#endif
+
+typedef struct
+{
+	
+	IMG_UINT32 ui32OpenPID;
+
+	
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID hKernelMemInfo;
+#else
+	IMG_HANDLE hKernelMemInfo;
+#endif
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+	
+	struct list_head sDRMAuthListItem;
+
+	struct drm_file *psDRMFile;
+#endif
+
+#if defined(SUPPORT_MEMINFO_IDS)
+	
+	IMG_UINT64 ui64Stamp;
+#endif 
+
+	
+	IMG_HANDLE hBlockAlloc;
+
+#if defined(SUPPORT_DRI_DRM_EXT)
+	IMG_PVOID pPriv;	
+#endif
+}
+PVRSRV_FILE_PRIVATE_DATA;
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/proc.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/proc.c
new file mode 100644
index 0000000..1df8aff
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/proc.c
@@ -0,0 +1,835 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include "services_headers.h"
+
+#include "queue.h"
+#include "resman.h"
+#include "pvrmmap.h"
+#include "pvr_debug.h"
+#include "pvrversion.h"
+#include "proc.h"
+#include "perproc.h"
+#include "env_perproc.h"
+#include "linkage.h"
+
+#include "lists.h"
+
+static struct proc_dir_entry * dir;
+
+static const IMG_CHAR PVRProcDirRoot[] = "pvr";
+
+static IMG_INT pvr_proc_open(struct inode *inode,struct file *file);
+static void *pvr_proc_seq_start (struct seq_file *m, loff_t *pos);
+static void pvr_proc_seq_stop (struct seq_file *m, void *v);
+static void *pvr_proc_seq_next (struct seq_file *m, void *v, loff_t *pos);
+static int pvr_proc_seq_show (struct seq_file *m, void *v);
+static ssize_t pvr_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
+
+static struct file_operations pvr_proc_operations =
+{
+	.open		= pvr_proc_open,
+	.read		= seq_read,
+	.write		= pvr_proc_write,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+static struct seq_operations pvr_proc_seq_operations =
+{
+	.start =	pvr_proc_seq_start,
+	.next =		pvr_proc_seq_next,
+	.stop =		pvr_proc_seq_stop,
+	.show =		pvr_proc_seq_show,
+};
+
+static struct proc_dir_entry* g_pProcQueue;
+static struct proc_dir_entry* g_pProcVersion;
+static struct proc_dir_entry* g_pProcSysNodes;
+
+#ifdef DEBUG
+static struct proc_dir_entry* g_pProcDebugLevel;
+#endif
+
+#ifdef PVR_MANUAL_POWER_CONTROL
+static struct proc_dir_entry* g_pProcPowerLevel;
+#endif
+
+
+static void ProcSeqShowVersion(struct seq_file *sfile,void* el);
+
+static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off);
+
+off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
+{
+    IMG_INT n;
+    size_t space = size - (size_t)off;
+    va_list ap;
+
+    va_start (ap, format);
+
+    n = vsnprintf (buffer+off, space, format, ap);
+
+    va_end (ap);
+    
+    if (n >= (IMG_INT)space || n < 0)
+    {
+	
+        buffer[size - 1] = 0;
+        return (off_t)(size - 1);
+    }
+    else
+    {
+        return (off + (off_t)n);
+    }
+}
+
+
+void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
+{
+	PVR_UNREFERENCED_PARAMETER(sfile);
+	
+	if(!off)
+		return (void*)2;
+	return NULL;
+}
+
+
+void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off)
+{
+	PVR_UNREFERENCED_PARAMETER(sfile);
+
+	if(!off)
+	{
+		return PVR_PROC_SEQ_START_TOKEN;
+	}
+
+	
+	if(off == 1)
+		return (void*)2;
+
+	return NULL;
+}
+
+
+static IMG_INT pvr_proc_open(struct inode *inode,struct file *file)
+{
+	IMG_INT ret = seq_open(file, &pvr_proc_seq_operations);
+
+	struct seq_file *seq = (struct seq_file*)file->private_data;
+	struct proc_dir_entry* pvr_proc_entry = PDE(inode);
+
+	
+	seq->private = pvr_proc_entry->data;
+	return ret;
+}
+
+static ssize_t pvr_proc_write(struct file *file, const char __user *buffer,
+		size_t count, loff_t *ppos)
+{
+	struct inode *inode = file->f_path.dentry->d_inode;
+	struct proc_dir_entry * dp;
+
+	PVR_UNREFERENCED_PARAMETER(ppos);
+	dp = PDE(inode);
+
+	if (!dp->write_proc)
+		return -EIO;
+
+	return dp->write_proc(file, buffer, count, dp->data);
+}
+
+
+static void *pvr_proc_seq_start (struct seq_file *proc_seq_file, loff_t *pos)
+{
+	PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+	if(handlers->startstop != NULL)
+		handlers->startstop(proc_seq_file, IMG_TRUE);
+	return handlers->off2element(proc_seq_file, *pos);
+}
+
+static void pvr_proc_seq_stop (struct seq_file *proc_seq_file, void *v)
+{
+	PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+	PVR_UNREFERENCED_PARAMETER(v);
+
+	if(handlers->startstop != NULL)
+		handlers->startstop(proc_seq_file, IMG_FALSE);
+}
+
+static void *pvr_proc_seq_next (struct seq_file *proc_seq_file, void *v, loff_t *pos)
+{
+	PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+	(*pos)++;
+	if( handlers->next != NULL)
+		return handlers->next( proc_seq_file, v, *pos );
+	return handlers->off2element(proc_seq_file, *pos);
+}
+
+static int pvr_proc_seq_show (struct seq_file *proc_seq_file, void *v)
+{
+	PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+	handlers->show( proc_seq_file,v );
+    return 0;
+}
+
+
+
+static struct proc_dir_entry* CreateProcEntryInDirSeq(
+									   struct proc_dir_entry *pdir,
+									   const IMG_CHAR * name,
+    								   IMG_VOID* data,
+									   pvr_next_proc_seq_t next_handler,
+									   pvr_show_proc_seq_t show_handler,
+									   pvr_off2element_proc_seq_t off2element_handler,
+									   pvr_startstop_proc_seq_t startstop_handler,
+									   write_proc_t whandler
+									   )
+{
+
+    struct proc_dir_entry * file;
+	mode_t mode;
+
+    if (!dir)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
+        return NULL;
+    }
+
+	mode = S_IFREG;
+
+    if (show_handler)
+    {
+		mode |= S_IRUGO;
+    }
+
+    if (whandler)
+    {
+		mode |= S_IWUSR;
+    }
+
+	file=create_proc_entry(name, mode, pdir);
+
+    if (file)
+    {
+		PVR_PROC_SEQ_HANDLERS *seq_handlers;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+        file->owner = THIS_MODULE;
+#endif
+
+		file->proc_fops = &pvr_proc_operations;
+		file->write_proc = whandler;
+
+		
+		file->data =  kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL);
+		if(file->data)
+		{
+			seq_handlers = (PVR_PROC_SEQ_HANDLERS*)file->data;
+			seq_handlers->next = next_handler;
+			seq_handlers->show = show_handler;
+			seq_handlers->off2element = off2element_handler;
+			seq_handlers->startstop = startstop_handler;
+			seq_handlers->data = data;
+
+        	return file;
+		}
+    }
+
+    PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
+    return NULL;
+}
+
+
+struct proc_dir_entry* CreateProcReadEntrySeq (
+								const IMG_CHAR * name,
+								IMG_VOID* data,
+								pvr_next_proc_seq_t next_handler,
+								pvr_show_proc_seq_t show_handler,
+								pvr_off2element_proc_seq_t off2element_handler,
+								pvr_startstop_proc_seq_t startstop_handler
+							   )
+{
+	return CreateProcEntrySeq(name,
+							  data,
+							  next_handler,
+							  show_handler,
+							  off2element_handler,
+							  startstop_handler,
+							  NULL);
+}
+
+struct proc_dir_entry* CreateProcEntrySeq (
+											const IMG_CHAR * name,
+											IMG_VOID* data,
+											pvr_next_proc_seq_t next_handler,
+											pvr_show_proc_seq_t show_handler,
+											pvr_off2element_proc_seq_t off2element_handler,
+											pvr_startstop_proc_seq_t startstop_handler,
+											write_proc_t whandler
+										  )
+{
+	return CreateProcEntryInDirSeq(
+								   dir,
+								   name,
+								   data,
+								   next_handler,
+								   show_handler,
+								   off2element_handler,
+								   startstop_handler,
+								   whandler
+								  );
+}
+
+
+
+struct proc_dir_entry* CreatePerProcessProcEntrySeq (
+									  const IMG_CHAR * name,
+    								  IMG_VOID* data,
+									  pvr_next_proc_seq_t next_handler,
+									  pvr_show_proc_seq_t show_handler,
+									  pvr_off2element_proc_seq_t off2element_handler,
+									  pvr_startstop_proc_seq_t startstop_handler,
+									  write_proc_t whandler
+									 )
+{
+    PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+    IMG_UINT32 ui32PID;
+
+    if (!dir)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: /proc/%s doesn't exist", PVRProcDirRoot));
+        return NULL;
+    }
+
+    ui32PID = OSGetCurrentProcessIDKM();
+
+    psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
+    if (!psPerProc)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: no per process data"));
+
+        return NULL;
+    }
+
+    if (!psPerProc->psProcDir)
+    {
+        IMG_CHAR dirname[16];
+        IMG_INT ret;
+
+        ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
+
+		if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
+			return NULL;
+		}
+		else
+		{
+			psPerProc->psProcDir = proc_mkdir(dirname, dir);
+			if (!psPerProc->psProcDir)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u",
+						PVRProcDirRoot, ui32PID));
+				return NULL;
+			}
+		}
+    }
+
+    return CreateProcEntryInDirSeq(psPerProc->psProcDir, name, data, next_handler,
+								   show_handler,off2element_handler,startstop_handler,whandler);
+}
+
+
+IMG_VOID RemoveProcEntrySeq( struct proc_dir_entry* proc_entry )
+{
+    if (dir)
+    {
+		void* data = proc_entry->data ;
+        PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, proc_entry->name));
+
+        remove_proc_entry(proc_entry->name, dir);
+		if( data)
+			kfree( data );
+
+    }
+}
+
+IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry)
+{
+    PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+
+    psPerProc = LinuxTerminatingProcessPrivateData();
+    if (!psPerProc)
+    {
+        psPerProc = PVRSRVFindPerProcessPrivateData();
+        if (!psPerProc)
+        {
+            PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
+                                    "remove %s, no per process data", proc_entry->name));
+            return;
+        }
+    }
+
+    if (psPerProc->psProcDir)
+    {
+		void* data = proc_entry->data ;
+        PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", proc_entry->name, psPerProc->psProcDir->name));
+
+        remove_proc_entry(proc_entry->name, psPerProc->psProcDir);
+		if(data)
+			kfree( data );
+    }
+}
+
+static IMG_INT pvr_read_proc(IMG_CHAR *page, IMG_CHAR **start, off_t off,
+                         IMG_INT count, IMG_INT *eof, IMG_VOID *data)
+{
+	 
+    pvr_read_proc_t *pprn = (pvr_read_proc_t *)data;
+
+    off_t len = pprn (page, (size_t)count, off);
+
+    if (len == END_OF_FILE)
+    {
+        len  = 0;
+        *eof = 1;
+    }
+    else if (!len)             
+    {
+        *start = (IMG_CHAR *) 0;   
+    }
+    else
+    {
+        *start = (IMG_CHAR *) 1;
+    }
+
+    return len;
+}
+
+
+static IMG_INT CreateProcEntryInDir(struct proc_dir_entry *pdir, const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
+{
+    struct proc_dir_entry * file;
+    mode_t mode;
+
+    if (!pdir)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDir: parent directory doesn't exist"));
+
+        return -ENOMEM;
+    }
+
+    mode = S_IFREG;
+
+    if (rhandler)
+    {
+	mode |= S_IRUGO;
+    }
+
+    if (whandler)
+    {
+	mode |= S_IWUSR;
+    }
+
+    file = create_proc_entry(name, mode, pdir);
+
+    if (file)
+    {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+        file->owner = THIS_MODULE;
+#endif
+		file->read_proc = rhandler;
+		file->write_proc = whandler;
+		file->data = data;
+
+		PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, pdir->name));
+
+        return 0;
+    }
+
+    PVR_DPF((PVR_DBG_ERROR, "CreateProcEntry: cannot create proc entry %s in %s", name, pdir->name));
+
+    return -ENOMEM;
+}
+
+
+IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
+{
+    return CreateProcEntryInDir(dir, name, rhandler, whandler, data);
+}
+
+
+IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
+{
+    PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+    IMG_UINT32 ui32PID;
+
+    if (!dir)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: /proc/%s doesn't exist", PVRProcDirRoot));
+
+        return -ENOMEM;
+    }
+
+    ui32PID = OSGetCurrentProcessIDKM();
+
+    psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
+    if (!psPerProc)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: no per process data"));
+
+        return -ENOMEM;
+    }
+
+    if (!psPerProc->psProcDir)
+    {
+        IMG_CHAR dirname[16];
+        IMG_INT ret;
+
+        ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
+
+		if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
+		{
+			PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
+
+					return -ENOMEM;
+		}
+		else
+		{
+			psPerProc->psProcDir = proc_mkdir(dirname, dir);
+			if (!psPerProc->psProcDir)
+			{
+			PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u", PVRProcDirRoot, ui32PID));
+
+			return -ENOMEM;
+			}
+		}
+    }
+
+    return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler, whandler, data);
+}
+
+
+IMG_INT CreateProcReadEntry(const IMG_CHAR * name, pvr_read_proc_t handler)
+{
+    struct proc_dir_entry * file;
+
+    if (!dir)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
+
+        return -ENOMEM;
+    }
+
+	 
+    file = create_proc_read_entry (name, S_IFREG | S_IRUGO, dir, pvr_read_proc, (IMG_VOID *)handler);
+
+    if (file)
+    {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+        file->owner = THIS_MODULE;
+#endif
+        return 0;
+    }
+
+    PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
+
+    return -ENOMEM;
+}
+
+
+IMG_INT CreateProcEntries(IMG_VOID)
+{
+    dir = proc_mkdir (PVRProcDirRoot, NULL);
+
+    if (!dir)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: cannot make /proc/%s directory", PVRProcDirRoot));
+
+        return -ENOMEM;
+    }
+
+	g_pProcQueue = CreateProcReadEntrySeq("queue", NULL, NULL, ProcSeqShowQueue, ProcSeqOff2ElementQueue, NULL);
+	g_pProcVersion = CreateProcReadEntrySeq("version", NULL, NULL, ProcSeqShowVersion, ProcSeq1ElementHeaderOff2Element, NULL);
+	g_pProcSysNodes = CreateProcReadEntrySeq("nodes", NULL, NULL, ProcSeqShowSysNodes, ProcSeqOff2ElementSysNodes, NULL);
+
+	if(!g_pProcQueue || !g_pProcVersion || !g_pProcSysNodes)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s files", PVRProcDirRoot));
+
+        return -ENOMEM;
+    }
+
+
+#ifdef DEBUG
+
+	g_pProcDebugLevel = CreateProcEntrySeq("debug_level", NULL, NULL,
+											ProcSeqShowDebugLevel,
+											ProcSeq1ElementOff2Element, NULL,
+										    (IMG_VOID*)PVRDebugProcSetLevel);
+	if(!g_pProcDebugLevel)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/debug_level", PVRProcDirRoot));
+
+        return -ENOMEM;
+    }
+
+#ifdef PVR_MANUAL_POWER_CONTROL
+	g_pProcPowerLevel = CreateProcEntrySeq("power_control", NULL, NULL,
+											ProcSeqShowPowerLevel,
+											ProcSeq1ElementOff2Element, NULL,
+										    PVRProcSetPowerLevel);
+	if(!g_pProcPowerLevel)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/power_control", PVRProcDirRoot));
+
+        return -ENOMEM;
+    }
+#endif
+#endif
+
+    return 0;
+}
+
+
+IMG_VOID RemoveProcEntry(const IMG_CHAR * name)
+{
+    if (dir)
+    {
+        remove_proc_entry(name, dir);
+        PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, name));
+    }
+}
+
+
+IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name)
+{
+    PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+
+    psPerProc = LinuxTerminatingProcessPrivateData();
+    if (!psPerProc)
+    {
+        psPerProc = PVRSRVFindPerProcessPrivateData();
+        if (!psPerProc)
+        {
+            PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
+                                    "remove %s, no per process data", name));
+            return;
+        }
+    }
+
+    if (psPerProc->psProcDir)
+    {
+        remove_proc_entry(name, psPerProc->psProcDir);
+
+        PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", name, psPerProc->psProcDir->name));
+    }
+}
+
+
+IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc)
+{
+    if (psPerProc->psProcDir)
+    {
+        while (psPerProc->psProcDir->subdir)
+        {
+            PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s/%s", PVRProcDirRoot, psPerProc->psProcDir->name, psPerProc->psProcDir->subdir->name));
+
+            RemoveProcEntry(psPerProc->psProcDir->subdir->name);
+        }
+        RemoveProcEntry(psPerProc->psProcDir->name);
+    }
+}
+
+IMG_VOID RemoveProcEntries(IMG_VOID)
+{
+#ifdef DEBUG
+	RemoveProcEntrySeq( g_pProcDebugLevel );
+#ifdef PVR_MANUAL_POWER_CONTROL
+	RemoveProcEntrySeq( g_pProcPowerLevel );
+#endif 
+#endif
+
+	RemoveProcEntrySeq(g_pProcQueue);
+	RemoveProcEntrySeq(g_pProcVersion);
+	RemoveProcEntrySeq(g_pProcSysNodes);
+
+	while (dir->subdir)
+	{
+		PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s", PVRProcDirRoot, dir->subdir->name));
+
+		RemoveProcEntry(dir->subdir->name);
+	}
+
+	remove_proc_entry(PVRProcDirRoot, NULL);
+}
+
+static void ProcSeqShowVersion(struct seq_file *sfile,void* el)
+{
+	SYS_DATA *psSysData;
+	IMG_CHAR *pszSystemVersionString = "None";
+
+	if(el == PVR_PROC_SEQ_START_TOKEN)
+	{
+		seq_printf(sfile,
+				"Version %s (%s) %s\n",
+				PVRVERSION_STRING,
+				PVR_BUILD_TYPE, PVR_BUILD_DIR);
+		return;
+	}
+
+	psSysData = SysAcquireDataNoCheck();
+	if(psSysData != IMG_NULL && psSysData->pszVersionString != IMG_NULL)
+	{
+		pszSystemVersionString = psSysData->pszVersionString;
+	}
+
+	seq_printf( sfile, "System Version String: %s\n", pszSystemVersionString);
+}
+
+static const IMG_CHAR *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType)
+{
+    switch (deviceType)
+    {
+        default:
+        {
+            static IMG_CHAR text[10];
+
+            sprintf(text, "?%x", (IMG_UINT)deviceType);
+
+            return text;
+        }
+    }
+}
+
+
+static const IMG_CHAR *deviceClassToString(PVRSRV_DEVICE_CLASS deviceClass)
+{
+    switch (deviceClass)
+    {
+	case PVRSRV_DEVICE_CLASS_3D:
+	{
+	    return "3D";
+	}
+	case PVRSRV_DEVICE_CLASS_DISPLAY:
+	{
+	    return "display";
+	}
+	case PVRSRV_DEVICE_CLASS_BUFFER:
+	{
+	    return "buffer";
+	}
+	default:
+	{
+	    static IMG_CHAR text[10];
+
+	    sprintf(text, "?%x", (IMG_UINT)deviceClass);
+	    return text;
+	}
+    }
+}
+
+static IMG_VOID* DecOffPsDev_AnyVaCb(PVRSRV_DEVICE_NODE *psNode, va_list va)
+{
+	off_t *pOff = va_arg(va, off_t*);
+	if (--(*pOff))
+	{
+		return IMG_NULL;
+	}
+	else
+	{
+		return psNode;
+	}
+}
+
+static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el)
+{
+	PVRSRV_DEVICE_NODE *psDevNode;
+
+	if(el == PVR_PROC_SEQ_START_TOKEN)
+	{
+		seq_printf( sfile,
+						"Registered nodes\n"
+						"Addr     Type     Class    Index Ref pvDev     Size Res\n");
+		return;
+	}
+
+	psDevNode = (PVRSRV_DEVICE_NODE*)el;
+
+	seq_printf( sfile,
+			  "%p %-8s %-8s %4d  %2u  %p  %3u  %p\n",
+			  psDevNode,
+			  deviceTypeToString(psDevNode->sDevId.eDeviceType),
+			  deviceClassToString(psDevNode->sDevId.eDeviceClass),
+			  psDevNode->sDevId.eDeviceClass,
+			  psDevNode->ui32RefCount,
+			  psDevNode->pvDevice,
+			  psDevNode->ui32pvDeviceSize,
+			  psDevNode->hResManContext);
+}
+
+static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off)
+{
+    SYS_DATA *psSysData;
+    PVRSRV_DEVICE_NODE*psDevNode = IMG_NULL;
+    
+    PVR_UNREFERENCED_PARAMETER(sfile);
+    
+    if(!off)
+    {
+	return PVR_PROC_SEQ_START_TOKEN;
+    }
+
+    psSysData = SysAcquireDataNoCheck();
+    if (psSysData != IMG_NULL)
+    {
+	
+	psDevNode = (PVRSRV_DEVICE_NODE*)
+			List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+													DecOffPsDev_AnyVaCb,
+													&off);
+    }
+
+    
+    return (void*)psDevNode;
+}
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/proc.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/proc.h
new file mode 100644
index 0000000..2066d71
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/proc.h
@@ -0,0 +1,108 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __SERVICES_PROC_H__
+#define __SERVICES_PROC_H__
+
+#include <asm/system.h>		
+#include <linux/proc_fs.h>	
+#include <linux/seq_file.h> 
+
+#define END_OF_FILE (off_t) -1
+
+typedef off_t (pvr_read_proc_t)(IMG_CHAR *, size_t, off_t);
+
+
+#define PVR_PROC_SEQ_START_TOKEN (void*)1
+typedef void* (pvr_next_proc_seq_t)(struct seq_file *,void*,loff_t);
+typedef void* (pvr_off2element_proc_seq_t)(struct seq_file *, loff_t);
+typedef void (pvr_show_proc_seq_t)(struct seq_file *,void*);
+typedef void (pvr_startstop_proc_seq_t)(struct seq_file *, IMG_BOOL start);
+
+typedef struct _PVR_PROC_SEQ_HANDLERS_ {
+	pvr_next_proc_seq_t *next;	
+	pvr_show_proc_seq_t *show;	
+	pvr_off2element_proc_seq_t *off2element;
+	pvr_startstop_proc_seq_t *startstop;
+	IMG_VOID *data;
+} PVR_PROC_SEQ_HANDLERS;
+
+
+void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off);
+
+void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off);
+
+off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
+	__attribute__((format(printf, 4, 5)));
+
+IMG_INT CreateProcEntries(IMG_VOID);
+
+IMG_INT CreateProcReadEntry (const IMG_CHAR * name, pvr_read_proc_t handler);
+
+IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data);
+
+IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data);
+
+IMG_VOID RemoveProcEntry(const IMG_CHAR * name);
+
+IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR * name);
+
+IMG_VOID RemoveProcEntries(IMG_VOID);
+
+struct proc_dir_entry* CreateProcReadEntrySeq (
+								const IMG_CHAR* name, 
+								IMG_VOID* data,
+								pvr_next_proc_seq_t next_handler, 
+								pvr_show_proc_seq_t show_handler,
+								pvr_off2element_proc_seq_t off2element_handler,
+								pvr_startstop_proc_seq_t startstop_handler
+							   );
+
+struct proc_dir_entry* CreateProcEntrySeq (
+								const IMG_CHAR* name, 
+								IMG_VOID* data,
+								pvr_next_proc_seq_t next_handler, 
+								pvr_show_proc_seq_t show_handler,
+								pvr_off2element_proc_seq_t off2element_handler,
+								pvr_startstop_proc_seq_t startstop_handler,
+								write_proc_t whandler
+							   );
+
+struct proc_dir_entry* CreatePerProcessProcEntrySeq (
+								const IMG_CHAR* name, 
+								IMG_VOID* data,
+								pvr_next_proc_seq_t next_handler, 
+								pvr_show_proc_seq_t show_handler,
+								pvr_off2element_proc_seq_t off2element_handler,
+								pvr_startstop_proc_seq_t startstop_handler,
+								write_proc_t whandler
+							   );
+
+
+IMG_VOID RemoveProcEntrySeq(struct proc_dir_entry* proc_entry);
+IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry);
+
+#endif
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_bridge_k.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_bridge_k.c
new file mode 100644
index 0000000..4b8eb4c
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_bridge_k.c
@@ -0,0 +1,435 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "img_defs.h"
+#include "services.h"
+#include "pvr_bridge.h"
+#include "perproc.h"
+#include "mutex.h"
+#include "syscommon.h"
+#include "pvr_debug.h"
+#include "proc.h"
+#include "private_data.h"
+#include "linkage.h"
+#include "pvr_bridge_km.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#include "pvr_drm.h"
+#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
+#include "env_perproc.h"
+#endif
+#endif
+
+#if defined(SUPPORT_VGX)
+#include "vgx_bridge.h"
+#endif
+
+#if defined(SUPPORT_SGX)
+#include "sgx_bridge.h"
+#endif
+
+#include "bridged_pvr_bridge.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#define	PRIVATE_DATA(pFile) ((pFile)->driver_priv)
+#else
+#define	PRIVATE_DATA(pFile) ((pFile)->private_data)
+#endif
+
+#if defined(DEBUG_BRIDGE_KM)
+
+static struct proc_dir_entry *g_ProcBridgeStats =0;
+static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off);
+static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementBridgeStats(struct seq_file * sfile, loff_t off);
+static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start);
+
+#endif
+
+extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
+
+#if defined(SUPPORT_MEMINFO_IDS)
+static IMG_UINT64 ui64Stamp;
+#endif 
+
+PVRSRV_ERROR
+LinuxBridgeInit(IMG_VOID)
+{
+#if defined(DEBUG_BRIDGE_KM)
+	{
+		g_ProcBridgeStats = CreateProcReadEntrySeq(
+												  "bridge_stats", 
+												  NULL,
+												  ProcSeqNextBridgeStats,
+												  ProcSeqShowBridgeStats,
+												  ProcSeqOff2ElementBridgeStats,
+												  ProcSeqStartstopBridgeStats
+						  						 );
+		if(!g_ProcBridgeStats)
+		{
+			return PVRSRV_ERROR_OUT_OF_MEMORY;
+		}
+	}
+#endif
+	return CommonBridgeInit();
+}
+
+IMG_VOID
+LinuxBridgeDeInit(IMG_VOID)
+{
+#if defined(DEBUG_BRIDGE_KM)
+    RemoveProcEntrySeq(g_ProcBridgeStats);
+#endif
+}
+
+#if defined(DEBUG_BRIDGE_KM)
+
+static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start) 
+{
+	if(start) 
+	{
+		LinuxLockMutex(&gPVRSRVLock);
+	}
+	else
+	{
+		LinuxUnLockMutex(&gPVRSRVLock);
+	}
+}
+
+
+static void* ProcSeqOff2ElementBridgeStats(struct seq_file *sfile, loff_t off)
+{
+	if(!off) 
+	{
+		return PVR_PROC_SEQ_START_TOKEN;
+	}
+
+	if(off > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
+	{
+		return (void*)0;
+	}
+
+
+	return (void*)&g_BridgeDispatchTable[off-1];
+}
+
+static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off)
+{
+	return ProcSeqOff2ElementBridgeStats(sfile,off);
+}
+
+
+static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el)
+{
+	PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = (	PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY*)el;
+
+	if(el == PVR_PROC_SEQ_START_TOKEN) 
+	{
+		seq_printf(sfile,
+						  "Total ioctl call count = %u\n"
+						  "Total number of bytes copied via copy_from_user = %u\n"
+						  "Total number of bytes copied via copy_to_user = %u\n"
+						  "Total number of bytes copied via copy_*_user = %u\n\n"
+						  "%-45s | %-40s | %10s | %20s | %10s\n",
+						  g_BridgeGlobalStats.ui32IOCTLCount,
+						  g_BridgeGlobalStats.ui32TotalCopyFromUserBytes,
+						  g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
+						  g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
+						  "Bridge Name",
+						  "Wrapper Function",
+						  "Call Count",
+						  "copy_from_user Bytes",
+						  "copy_to_user Bytes"
+						 );
+		return;
+	}
+
+	seq_printf(sfile,
+				   "%-45s   %-40s   %-10u   %-20u   %-10u\n",
+				   psEntry->pszIOCName,
+				   psEntry->pszFunctionName,
+				   psEntry->ui32CallCount,
+				   psEntry->ui32CopyFromUserTotalBytes,
+				   psEntry->ui32CopyToUserTotalBytes);
+}
+
+#endif 
+
+
+#if defined(SUPPORT_DRI_DRM)
+int
+PVRSRV_BridgeDispatchKM(struct drm_device unref__ *dev, void *arg, struct drm_file *pFile)
+#else
+long
+PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsigned long arg)
+#endif
+{
+	IMG_UINT32 cmd;
+#if !defined(SUPPORT_DRI_DRM)
+	PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg;
+	PVRSRV_BRIDGE_PACKAGE sBridgePackageKM;
+#endif
+	PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM;
+	IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+	PVRSRV_PER_PROCESS_DATA *psPerProc;
+	IMG_INT err = -EFAULT;
+
+	LinuxLockMutex(&gPVRSRVLock);
+
+#if defined(SUPPORT_DRI_DRM)
+	psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg;
+	PVR_ASSERT(psBridgePackageKM != IMG_NULL);
+#else
+	psBridgePackageKM = &sBridgePackageKM;
+
+	if(!OSAccessOK(PVR_VERIFY_WRITE,
+				   psBridgePackageUM,
+				   sizeof(PVRSRV_BRIDGE_PACKAGE)))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
+				 __FUNCTION__));
+
+		goto unlock_and_return;
+	}
+	
+	
+	if(OSCopyFromUser(IMG_NULL,
+					  psBridgePackageKM,
+					  psBridgePackageUM,
+					  sizeof(PVRSRV_BRIDGE_PACKAGE))
+	  != PVRSRV_OK)
+	{
+		goto unlock_and_return;
+	}
+#endif
+
+	cmd = psBridgePackageKM->ui32BridgeID;
+	
+	if(cmd != PVRSRV_BRIDGE_CONNECT_SERVICES)
+	{
+		PVRSRV_ERROR eError;
+
+		eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+									(IMG_PVOID *)&psPerProc,
+									psBridgePackageKM->hKernelServices,
+									PVRSRV_HANDLE_TYPE_PERPROC_DATA);
+		if(eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "%s: Invalid kernel services handle (%d)",
+					 __FUNCTION__, eError));
+			goto unlock_and_return;
+		}
+
+		if(psPerProc->ui32PID != ui32PID)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "%s: Process %d tried to access data "
+					 "belonging to process %d", __FUNCTION__, ui32PID,
+					 psPerProc->ui32PID));
+			goto unlock_and_return;
+		}
+	}
+	else
+	{
+		
+		psPerProc = PVRSRVPerProcessData(ui32PID);
+		if(psPerProc == IMG_NULL)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BridgeDispatchKM: "
+					 "Couldn't create per-process data area"));
+			goto unlock_and_return;
+		}
+	}
+
+	psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
+
+	switch(cmd)
+	{
+		case PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2:
+		{
+			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+			if(psPrivateData->hKernelMemInfo)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: Can only export one MemInfo "
+						 "per file descriptor", __FUNCTION__));
+				err = -EINVAL;
+				goto unlock_and_return;
+			}
+			break;
+		}
+
+		case PVRSRV_BRIDGE_MAP_DEV_MEMORY_2:
+		{
+			PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN =
+				(PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamIn;
+			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+			if(!psPrivateData->hKernelMemInfo)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: File descriptor has no "
+						 "associated MemInfo handle", __FUNCTION__));
+				err = -EINVAL;
+				goto unlock_and_return;
+			}
+
+			if (put_user(psPrivateData->hKernelMemInfo, &psMapDevMemIN->hKernelMemInfo) != 0)
+			{
+				err = -EFAULT;
+				goto unlock_and_return;
+			}
+			break;
+		}
+
+		default:
+		{
+			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+			if(psPrivateData->hKernelMemInfo)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: Import/Export handle tried "
+						 "to use privileged service", __FUNCTION__));
+				goto unlock_and_return;
+			}
+			break;
+		}
+	}
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+	switch(cmd)
+	{
+		case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
+		case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
+		{
+			PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+			int authenticated = pFile->authenticated;
+			PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+
+			if (authenticated)
+			{
+				break;
+			}
+
+			
+			psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc);
+			if (psEnvPerProc == IMG_NULL)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: Process private data not allocated", __FUNCTION__));
+				err = -EFAULT;
+				goto unlock_and_return;
+			}
+
+			list_for_each_entry(psPrivateData, &psEnvPerProc->sDRMAuthListHead, sDRMAuthListItem)
+			{
+				struct drm_file *psDRMFile = psPrivateData->psDRMFile;
+
+				if (pFile->master == psDRMFile->master)
+				{
+					authenticated |= psDRMFile->authenticated;
+					if (authenticated)
+					{
+						break;
+					}
+				}
+			}
+
+			if (!authenticated)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: Not authenticated for mapping device or device class memory", __FUNCTION__));
+				err = -EPERM;
+				goto unlock_and_return;
+			}
+			break;
+		}
+		default:
+			break;
+	}
+#endif 
+
+	err = BridgedDispatchKM(psPerProc, psBridgePackageKM);
+	if(err != PVRSRV_OK)
+		goto unlock_and_return;
+
+	switch(cmd)
+	{
+		case PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2:
+		{
+			PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT =
+				(PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)psBridgePackageKM->pvParamOut;
+			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+			if (get_user(psPrivateData->hKernelMemInfo, &psExportDeviceMemOUT->hMemInfo) != 0)
+			{
+				err = -EFAULT;
+				goto unlock_and_return;
+			}
+#if defined(SUPPORT_MEMINFO_IDS)
+			psPrivateData->ui64Stamp = ++ui64Stamp;
+
+			if (put_user(psPrivateData->ui64Stamp, &psExportDeviceMemOUT->ui64Stamp) != 0)
+			{
+				err = -EFAULT;
+				goto unlock_and_return;
+			}
+#endif
+			break;
+		}
+
+#if defined(SUPPORT_MEMINFO_IDS)
+		case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
+		{
+			PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDeviceMemoryOUT =
+				(PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamOut;
+			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+			if (put_user(psPrivateData->ui64Stamp, &psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp) != 0)
+			{
+				err = -EFAULT;
+				goto unlock_and_return;
+			}
+			break;
+		}
+
+		case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
+		{
+			PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psDeviceClassMemoryOUT =
+				(PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *)psBridgePackageKM->pvParamOut;
+			if (put_user(++ui64Stamp, &psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp) != 0)
+			{
+				err = -EFAULT;
+				goto unlock_and_return;
+			}
+			break;
+		}
+#endif 
+
+		default:
+			break;
+	}
+
+unlock_and_return:
+	LinuxUnLockMutex(&gPVRSRVLock);
+	return err;
+}
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_debug.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_debug.c
new file mode 100644
index 0000000..b2b0273
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_debug.c
@@ -0,0 +1,424 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/hardirq.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>			
+#include <stdarg.h>
+#include "img_types.h"
+#include "servicesext.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "proc.h"
+#include "mutex.h"
+#include "linkage.h"
+
+static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
+						 const IMG_CHAR* pszFormat, va_list VArgs)
+						 IMG_FORMAT_PRINTF(3, 0);
+
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+#define PVR_MAX_FILEPATH_LEN 256
+
+static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
+						const IMG_CHAR *pszFormat, ...)
+						IMG_FORMAT_PRINTF(3, 4);
+
+IMG_UINT32 gPVRDebugLevel =
+	(DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
+
+#endif 
+
+#define	PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
+
+static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
+
+static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
+
+static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ;
+
+ 
+static spinlock_t gsDebugLockIRQ = __SPIN_LOCK_UNLOCKED(gsDebugLockIRQ);
+
+#if !defined (USE_SPIN_LOCK)  
+#define	USE_SPIN_LOCK (in_interrupt() || !preemptible())
+#endif
+
+static inline void GetBufferLock(unsigned long *pulLockFlags)
+{
+	if (USE_SPIN_LOCK)
+	{
+		spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
+	}
+	else
+	{
+		LinuxLockMutex(&gsDebugMutexNonIRQ);
+	}
+}
+
+static inline void ReleaseBufferLock(unsigned long ulLockFlags)
+{
+	if (USE_SPIN_LOCK)
+	{
+		spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
+	}
+	else
+	{
+		LinuxUnLockMutex(&gsDebugMutexNonIRQ);
+	}
+}
+
+static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
+{
+	if (USE_SPIN_LOCK)
+	{
+		*ppszBuf = gszBufferIRQ;
+		*pui32BufSiz = sizeof(gszBufferIRQ);
+	}
+	else
+	{
+		*ppszBuf = gszBufferNonIRQ;
+		*pui32BufSiz = sizeof(gszBufferNonIRQ);
+	}
+}
+
+static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs)
+{
+	IMG_UINT32 ui32Used;
+	IMG_UINT32 ui32Space;
+	IMG_INT32 i32Len;
+
+	ui32Used = strlen(pszBuf);
+	BUG_ON(ui32Used >= ui32BufSiz);
+	ui32Space = ui32BufSiz - ui32Used;
+
+	i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs);
+	pszBuf[ui32BufSiz - 1] = 0;
+
+	
+	return (i32Len < 0 || i32Len >= (IMG_INT32)ui32Space) ? IMG_TRUE : IMG_FALSE;
+}
+
+IMG_VOID PVRDPFInit(IMG_VOID)
+{
+    LinuxInitMutex(&gsDebugMutexNonIRQ);
+}
+
+IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
+{
+	va_list vaArgs;
+	unsigned long ulLockFlags = 0;
+	IMG_CHAR *pszBuf;
+	IMG_UINT32 ui32BufSiz;
+
+	SelectBuffer(&pszBuf, &ui32BufSiz);
+
+	va_start(vaArgs, pszFormat);
+
+	GetBufferLock(&ulLockFlags);
+	strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
+
+	if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
+	{
+		printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+	}
+	else
+	{
+		printk(KERN_INFO "%s\n", pszBuf);
+	}
+
+	ReleaseBufferLock(ulLockFlags);
+	va_end(vaArgs);
+
+}
+
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+
+IMG_VOID PVRSRVDebugAssertFail(const IMG_CHAR* pszFile, IMG_UINT32 uLine)
+{
+	PVRSRVDebugPrintf(DBGPRIV_FATAL, pszFile, uLine, "Debug assertion failed!");
+	BUG();
+}
+
+#endif 
+
+#if defined(PVRSRV_NEED_PVR_TRACE)
+
+IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...)
+{
+	va_list VArgs;
+	unsigned long ulLockFlags = 0;
+	IMG_CHAR *pszBuf;
+	IMG_UINT32 ui32BufSiz;
+
+	SelectBuffer(&pszBuf, &ui32BufSiz);
+
+	va_start(VArgs, pszFormat);
+
+	GetBufferLock(&ulLockFlags);
+
+	strncpy(pszBuf, "PVR: ", (ui32BufSiz -1));
+
+	if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
+	{
+		printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+	}
+	else
+	{
+		printk(KERN_INFO "%s\n", pszBuf);
+	}
+
+	ReleaseBufferLock(ulLockFlags);
+
+	va_end(VArgs);
+}
+
+#endif 
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...)
+{
+	va_list VArgs;
+	IMG_BOOL bTrunc;
+
+	va_start (VArgs, pszFormat);
+
+	bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs);
+
+	va_end (VArgs);
+
+	return bTrunc;
+}
+
+IMG_VOID PVRSRVDebugPrintf	(
+						IMG_UINT32	ui32DebugLevel,
+						const IMG_CHAR*	pszFullFileName,
+						IMG_UINT32	ui32Line,
+						const IMG_CHAR*	pszFormat,
+						...
+					)
+{
+	IMG_BOOL bTrace;
+	const IMG_CHAR *pszFileName = pszFullFileName;
+	IMG_CHAR *pszLeafName;
+
+
+	bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
+
+	if (gPVRDebugLevel & ui32DebugLevel)
+	{
+		va_list vaArgs;
+		unsigned long ulLockFlags = 0;
+		IMG_CHAR *pszBuf;
+		IMG_UINT32 ui32BufSiz;
+
+		SelectBuffer(&pszBuf, &ui32BufSiz);
+
+		va_start(vaArgs, pszFormat);
+
+		GetBufferLock(&ulLockFlags);
+
+		
+		if (bTrace == IMG_FALSE)
+		{
+			switch(ui32DebugLevel)
+			{
+				case DBGPRIV_FATAL:
+				{
+					strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1));
+					break;
+				}
+				case DBGPRIV_ERROR:
+				{
+					strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1));
+					break;
+				}
+				case DBGPRIV_WARNING:
+				{
+					strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1));
+					break;
+				}
+				case DBGPRIV_MESSAGE:
+				{
+					strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1));
+					break;
+				}
+				case DBGPRIV_VERBOSE:
+				{
+					strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1));
+					break;
+				}
+				default:
+				{
+					strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1));
+					break;
+				}
+			}
+		}
+		else
+		{
+			strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
+		}
+
+		if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
+		{
+			printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+		}
+		else
+		{
+			
+			if (bTrace == IMG_FALSE)
+			{
+#ifdef DEBUG_LOG_PATH_TRUNCATE
+				
+				static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
+
+   				IMG_CHAR* pszTruncIter;
+				IMG_CHAR* pszTruncBackInter;
+
+				
+				if (strlen(pszFullFileName) > strlen(DEBUG_LOG_PATH_TRUNCATE)+1)
+					pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
+
+				
+				strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
+
+				if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) {
+					IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED";
+					strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage);
+				}
+
+				pszTruncIter = szFileNameRewrite;
+				while(*pszTruncIter++ != 0)
+				{
+					IMG_CHAR* pszNextStartPoint;
+					
+					if(
+					   !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) &&
+						 ( *(pszTruncIter-1) == '.') &&
+						 ( *(pszTruncIter-2) == '.') &&
+						 ( *(pszTruncIter-3) == '/') )
+					   ) continue;
+
+					
+					pszTruncBackInter = pszTruncIter - 3;
+					while(*(--pszTruncBackInter) != '/')
+					{
+						if(pszTruncBackInter <= szFileNameRewrite) break;
+					}
+					pszNextStartPoint = pszTruncBackInter;
+
+					
+					while(*pszTruncIter != 0)
+					{
+						*pszTruncBackInter++ = *pszTruncIter++;
+					}
+					*pszTruncBackInter = 0;
+
+					
+					pszTruncIter = pszNextStartPoint;
+				}
+
+				pszFileName = szFileNameRewrite;
+				
+				if(*pszFileName == '/') pszFileName++;
+#endif
+
+#if !defined(__sh__)
+				pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
+
+				if (pszLeafName)
+				{
+					pszFileName = pszLeafName;
+		       	}
+#endif 
+
+				if (BAppend(pszBuf, ui32BufSiz, " [%u, %s]", ui32Line, pszFileName))
+				{
+					printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+				}
+				else
+				{
+					printk(KERN_INFO "%s\n", pszBuf);
+				}
+			}
+			else
+			{
+				printk(KERN_INFO "%s\n", pszBuf);
+			}
+		}
+
+		ReleaseBufferLock(ulLockFlags);
+
+		va_end (vaArgs);
+	}
+}
+
+#endif 
+
+#if defined(DEBUG)
+
+IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
+{
+#define	_PROC_SET_BUFFER_SZ		2
+	IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
+
+	if (count != _PROC_SET_BUFFER_SZ)
+	{
+		return -EINVAL;
+	}
+	else
+	{
+		if (copy_from_user(data_buffer, buffer, count))
+			return -EINVAL;
+		if (data_buffer[count - 1] != '\n')
+			return -EINVAL;
+		gPVRDebugLevel = data_buffer[0] - '0';
+	}
+	return (count);
+}
+
+void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)
+{
+	seq_printf(sfile, "%u\n", gPVRDebugLevel);
+}
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_drm.c b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_drm.c
new file mode 100644
index 0000000..4291bd1
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_drm.c
@@ -0,0 +1,479 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if defined(SUPPORT_DRI_DRM)
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <asm/ioctl.h>
+#include <drm/drmP.h>
+#include <drm/drm.h>
+
+#include "img_defs.h"
+#include "services.h"
+#include "kerneldisplay.h"
+#include "kernelbuffer.h"
+#include "syscommon.h"
+#include "pvrmmap.h"
+#include "mm.h"
+#include "mmap.h"
+#include "mutex.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "perproc.h"
+#include "handle.h"
+#include "pvr_bridge_km.h"
+#include "pvr_bridge.h"
+#include "proc.h"
+#include "pvrmodule.h"
+#include "pvrversion.h"
+#include "lock.h"
+#include "linkage.h"
+#include "pvr_drm.h"
+
+#if defined(PVR_DRI_DRM_NOT_PCI)
+#include "pvr_drm_mod.h"
+#endif
+
+#define PVR_DRM_NAME	PVRSRV_MODNAME
+#define PVR_DRM_DESC	"Imagination Technologies PVR DRM"
+
+DECLARE_WAIT_QUEUE_HEAD(sWaitForInit);
+
+IMG_BOOL bInitComplete;
+IMG_BOOL bInitFailed;
+
+#if !defined(PVR_DRI_DRM_NOT_PCI)
+#if defined(PVR_DRI_DRM_PLATFORM_DEV)
+struct platform_device *gpsPVRLDMDev;
+#else
+struct pci_dev *gpsPVRLDMDev;
+#endif
+#endif
+
+struct drm_device *gpsPVRDRMDev;
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24))
+#error "Linux kernel version 2.6.25 or later required for PVR DRM support"
+#endif
+
+#define PVR_DRM_FILE struct drm_file *
+
+#if !defined(SUPPORT_DRI_DRM_EXT)
+#if defined(PVR_DRI_DRM_PLATFORM_DEV)
+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED)
+static struct platform_device_id asPlatIdList[] = {
+	{SYS_SGX_DEV_NAME, 0},
+	{}
+};
+#endif
+#else	
+static struct pci_device_id asPciIdList[] = {
+#if defined(PVR_DRI_DRM_NOT_PCI)
+	{1, 1, 1, 1, 0, 0, 0},
+#else	
+	{SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#if defined(SYS_SGX_DEV1_DEVICE_ID)
+	{SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif	
+#endif	
+	{0}
+};
+#endif	
+#endif	
+
+DRI_DRM_STATIC int
+PVRSRVDrmLoad(struct drm_device *dev, unsigned long flags)
+{
+	int iRes = 0;
+
+	PVR_TRACE(("PVRSRVDrmLoad"));
+
+	gpsPVRDRMDev = dev;
+#if !defined(PVR_DRI_DRM_NOT_PCI)
+#if defined(PVR_DRI_DRM_PLATFORM_DEV)
+	gpsPVRLDMDev = dev->platformdev;
+#else
+	gpsPVRLDMDev = dev->pdev;
+#endif
+#endif
+
+#if defined(PDUMP)
+	iRes = dbgdrv_init();
+	if (iRes != 0)
+	{
+		goto exit;
+	}
+#endif
+	
+	iRes = PVRCore_Init();
+	if (iRes != 0)
+	{
+		goto exit_dbgdrv_cleanup;
+	}
+
+#if defined(DISPLAY_CONTROLLER)
+	iRes = PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(dev);
+	if (iRes != 0)
+	{
+		goto exit_pvrcore_cleanup;
+	}
+#endif
+	goto exit;
+
+#if defined(DISPLAY_CONTROLLER)
+exit_pvrcore_cleanup:
+	PVRCore_Cleanup();
+#endif
+exit_dbgdrv_cleanup:
+#if defined(PDUMP)
+	dbgdrv_cleanup();
+#endif
+exit:
+	if (iRes != 0)
+	{
+		bInitFailed = IMG_TRUE;
+	}
+	bInitComplete = IMG_TRUE;
+
+	wake_up_interruptible(&sWaitForInit);
+
+	return iRes;
+}
+
+DRI_DRM_STATIC int
+PVRSRVDrmUnload(struct drm_device *dev)
+{
+	PVR_TRACE(("PVRSRVDrmUnload"));
+
+#if defined(DISPLAY_CONTROLLER)
+	PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(dev);
+#endif
+
+	PVRCore_Cleanup();
+
+#if defined(PDUMP)
+	dbgdrv_cleanup();
+#endif
+
+	return 0;
+}
+
+DRI_DRM_STATIC int
+PVRSRVDrmOpen(struct drm_device *dev, struct drm_file *file)
+{
+	while (!bInitComplete)
+	{
+		DEFINE_WAIT(sWait);
+
+		prepare_to_wait(&sWaitForInit, &sWait, TASK_INTERRUPTIBLE);
+
+		if (!bInitComplete)
+		{
+			PVR_TRACE(("%s: Waiting for module initialisation to complete", __FUNCTION__));
+
+			schedule();
+		}
+
+		finish_wait(&sWaitForInit, &sWait);
+
+		if (signal_pending(current))
+		{
+			return -ERESTARTSYS;
+		}
+	}
+
+	if (bInitFailed)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Module initialisation failed", __FUNCTION__));
+		return -EINVAL;
+	}
+
+	return PVRSRVOpen(dev, file);
+}
+
+#if defined(SUPPORT_DRI_DRM_EXT) && !defined(PVR_LINUX_USING_WORKQUEUES)
+DRI_DRM_STATIC void
+PVRSRVDrmPostClose(struct drm_device *dev, struct drm_file *file)
+{
+	PVRSRVRelease(file->driver_priv);
+
+	file->driver_priv = NULL;
+}
+#else
+DRI_DRM_STATIC int
+PVRSRVDrmRelease(struct inode *inode, struct file *filp)
+{
+	struct drm_file *file_priv = filp->private_data;
+	void *psDriverPriv = file_priv->driver_priv;
+	int ret;
+
+	ret = drm_release(inode, filp);
+
+	if (ret != 0)
+	{
+		
+		PVR_DPF((PVR_DBG_ERROR, "%s : drm_release failed: %d",
+			__FUNCTION__, ret));
+	}
+
+	PVRSRVRelease(psDriverPriv);
+
+	return 0;
+}
+#endif
+
+DRI_DRM_STATIC int
+PVRDRMIsMaster(struct drm_device *dev, void *arg, struct drm_file *pFile)
+{
+	return 0;
+}
+
+#if defined(SUPPORT_DRI_DRM_EXT)
+int
+PVRDRM_Dummy_ioctl(struct drm_device *dev, void *arg, struct drm_file *pFile)
+{
+	return 0;
+}
+#endif
+
+DRI_DRM_STATIC int
+PVRDRMUnprivCmd(struct drm_device *dev, void *arg, struct drm_file *pFile)
+{
+	int ret = 0;
+
+	LinuxLockMutex(&gPVRSRVLock);
+
+	if (arg == NULL)
+	{
+		ret = -EFAULT;
+	}
+	else
+	{
+		IMG_UINT32 *pui32Args = (IMG_UINT32 *)arg;
+		IMG_UINT32 ui32Cmd = pui32Args[0];
+		IMG_UINT32 *pui32OutArg = (IMG_UINT32 *)arg;
+
+		switch (ui32Cmd)
+		{
+			case PVR_DRM_UNPRIV_INIT_SUCCESFUL:
+				*pui32OutArg = PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL) ? 1 : 0;
+				break;
+
+			default:
+				ret = -EFAULT;
+		}
+
+	}
+
+	LinuxUnLockMutex(&gPVRSRVLock);
+
+	return ret;
+}
+
+#if defined(DISPLAY_CONTROLLER) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL)
+static int
+PVRDRM_Display_ioctl(struct drm_device *dev, void *arg, struct drm_file *pFile)
+{
+	int res;
+
+	LinuxLockMutex(&gPVRSRVLock);
+
+	res = PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(dev, arg, pFile);
+
+	LinuxUnLockMutex(&gPVRSRVLock);
+
+	return res;
+}
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+#define	PVR_DRM_FOPS_IOCTL	.unlocked_ioctl
+#define	PVR_DRM_UNLOCKED	DRM_UNLOCKED
+#else
+#define	PVR_DRM_FOPS_IOCTL	.ioctl
+#define	PVR_DRM_UNLOCKED	0
+#endif
+
+#if !defined(SUPPORT_DRI_DRM_EXT)
+
+#if defined(DRM_IOCTL_DEF)
+#define	PVR_DRM_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(DRM_##ioctl, _func, _flags)
+#else
+#define	PVR_DRM_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF_DRV(ioctl, _func, _flags)
+#endif
+
+struct drm_ioctl_desc sPVRDrmIoctls[] = {
+	PVR_DRM_IOCTL_DEF(PVR_SRVKM, PVRSRV_BridgeDispatchKM, PVR_DRM_UNLOCKED),
+	PVR_DRM_IOCTL_DEF(PVR_IS_MASTER, PVRDRMIsMaster, DRM_MASTER | PVR_DRM_UNLOCKED),
+	PVR_DRM_IOCTL_DEF(PVR_UNPRIV, PVRDRMUnprivCmd, PVR_DRM_UNLOCKED),
+#if defined(PDUMP)
+	PVR_DRM_IOCTL_DEF(PVR_DBGDRV, dbgdrv_ioctl, PVR_DRM_UNLOCKED),
+#endif
+#if defined(DISPLAY_CONTROLLER) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL)
+	PVR_DRM_IOCTL_DEF(PVR_DISP, PVRDRM_Display_ioctl, DRM_MASTER | PVR_DRM_UNLOCKED)
+#endif
+};
+
+static int pvr_max_ioctl = DRM_ARRAY_SIZE(sPVRDrmIoctls);
+
+#if defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_EXT)
+static int PVRSRVDrmProbe(struct platform_device *pDevice);
+static int PVRSRVDrmRemove(struct platform_device *pDevice);
+#endif	
+
+static struct drm_driver sPVRDrmDriver = 
+{
+#if defined(PVR_DRI_DRM_PLATFORM_DEV)
+	.driver_features = DRIVER_USE_PLATFORM_DEVICE,
+#else
+	.driver_features = 0,
+#endif
+	.dev_priv_size = 0,
+	.load = PVRSRVDrmLoad,
+	.unload = PVRSRVDrmUnload,
+	.open = PVRSRVDrmOpen,
+#if !defined(PVR_DRI_DRM_PLATFORM_DEV)
+	.suspend = PVRSRVDriverSuspend,
+	.resume = PVRSRVDriverResume,
+#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37))
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+#endif
+	.ioctls = sPVRDrmIoctls,
+	.fops = 
+	{
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = PVRSRVDrmRelease,
+		PVR_DRM_FOPS_IOCTL = drm_ioctl,
+		.mmap = PVRMMap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+	},
+#if defined(PVR_DRI_DRM_PLATFORM_DEV)
+	.platform_driver =
+	{
+		.id_table = asPlatIdList,
+		.driver =
+		{
+			.name = PVR_DRM_NAME,
+		},
+		.probe = PVRSRVDrmProbe,
+		.remove = PVRSRVDrmRemove,
+		.suspend = PVRSRVDriverSuspend,
+		.resume = PVRSRVDriverResume,
+		.shutdown = PVRSRVDriverShutdown,
+	},
+#else
+	.pci_driver = 
+	{
+		.name = PVR_DRM_NAME,
+		.id_table = asPciIdList,
+	},
+#endif
+	.name = PVR_DRM_NAME,
+	.desc = PVR_DRM_DESC,
+	.date = PVR_BUILD_DATE,
+	.major = PVRVERSION_MAJ,
+	.minor = PVRVERSION_MIN,
+	.patchlevel = PVRVERSION_BUILD,
+};
+
+#if defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_EXT)
+static int
+PVRSRVDrmProbe(struct platform_device *pDevice)
+{
+	PVR_TRACE(("PVRSRVDrmProbe"));
+
+	return drm_get_platform_dev(pDevice, &sPVRDrmDriver);
+}
+
+static int
+PVRSRVDrmRemove(struct platform_device *pDevice)
+{
+	PVR_TRACE(("PVRSRVDrmRemove"));
+
+	drm_put_dev(gpsPVRDRMDev);
+
+	return 0;
+}
+
+#endif	
+static int __init PVRSRVDrmInit(void)
+{
+	int iRes;
+	sPVRDrmDriver.num_ioctls = pvr_max_ioctl;
+
+	
+	PVRDPFInit();
+
+#if defined(PVR_DRI_DRM_NOT_PCI)
+	iRes = drm_pvr_dev_add();
+	if (iRes != 0)
+	{
+		return iRes;
+	}
+#endif
+
+	iRes = drm_init(&sPVRDrmDriver);
+#if defined(PVR_DRI_DRM_NOT_PCI)
+	if (iRes != 0)
+	{
+		drm_pvr_dev_remove();
+	}
+#endif
+	return iRes;
+}
+	
+static void __exit PVRSRVDrmExit(void)
+{
+	drm_exit(&sPVRDrmDriver);
+
+#if defined(PVR_DRI_DRM_NOT_PCI)
+	drm_pvr_dev_remove();
+#endif
+}
+
+module_init(PVRSRVDrmInit);
+module_exit(PVRSRVDrmExit);
+#endif	
+#endif	
+
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_drm.h b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_drm.h
new file mode 100644
index 0000000..9bd5540
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/env/linux/pvr_drm.h
@@ -0,0 +1,107 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined(__PVR_DRM_H__)
+#define __PVR_DRM_H__
+
+#include "pvr_drm_shared.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#define	PVR_DRM_MAKENAME_HELPER(x, y) x ## y
+#define	PVR_DRM_MAKENAME(x, y) PVR_DRM_MAKENAME_HELPER(x, y)
+
+#if defined(PVR_DRI_DRM_PLATFORM_DEV)
+#define	LDM_DEV	struct platform_device
+#endif
+
+int PVRCore_Init(void);
+void PVRCore_Cleanup(void);
+int PVRSRVOpen(struct drm_device *dev, struct drm_file *pFile);
+void PVRSRVRelease(void *pvPrivData);
+
+#if defined(PVR_DRI_DRM_PLATFORM_DEV)
+void PVRSRVDriverShutdown(LDM_DEV *pDevice);
+int PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state);
+int PVRSRVDriverResume(LDM_DEV *pDevice);
+#else
+int PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state);
+int PVRSRVDriverResume(struct drm_device *pDevice);
+#endif
+
+int PVRSRV_BridgeDispatchKM(struct drm_device *dev, void *arg, struct drm_file *pFile);
+
+#if defined(SUPPORT_DRI_DRM_EXT)
+#define	DRI_DRM_STATIC
+int PVRSRVDrmLoad(struct drm_device *dev, unsigned long flags);
+int PVRSRVDrmUnload(struct drm_device *dev);
+int PVRSRVDrmOpen(struct drm_device *dev, struct drm_file *file);
+#if defined(PVR_LINUX_USING_WORKQUEUES)
+DRI_DRM_STATIC int PVRSRVDrmRelease(struct inode *inode, struct file *filp);
+#else
+void PVRSRVDrmPostClose(struct drm_device *dev, struct drm_file *file);
+#endif
+int PVRDRMIsMaster(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+int PVRDRMUnprivCmd(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+int PVRDRM_Dummy_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+#else
+#define	DRI_DRM_STATIC	static
+#endif	
+
+#if defined(DISPLAY_CONTROLLER)
+extern int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device *);
+extern void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device *);
+extern int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Suspend)(struct drm_device *);
+extern int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Resume)(struct drm_device *);
+#if defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL)
+extern int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(struct drm_device *dev, void *arg, struct drm_file *pFile);
+#endif
+#endif
+
+#if defined(PDUMP)
+int dbgdrv_init(void);
+void dbgdrv_cleanup(void);
+IMG_INT dbgdrv_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+#endif
+
+#if !defined(SUPPORT_DRI_DRM_EXT)
+#define	DRM_PVR_SRVKM		PVR_DRM_SRVKM_CMD
+#define	DRM_PVR_IS_MASTER	PVR_DRM_IS_MASTER_CMD
+#define	DRM_PVR_UNPRIV		PVR_DRM_UNPRIV_CMD
+#define	DRM_PVR_DBGDRV		PVR_DRM_DBGDRV_CMD
+#define	DRM_PVR_DISP		PVR_DRM_DISP_CMD
+
+#define	DRM_IOCTL_PVR_SRVKM		_IO(0, DRM_PVR_SRVKM)
+#define	DRM_IOCTL_PVR_IS_MASTER 	_IO(0, DRM_PVR_IS_MASTER)
+#define	DRM_IOCTL_PVR_UNPRIV		_IO(0, DRM_PVR_UNPRIV)
+#define	DRM_IOCTL_PVR_DBGDRV		_IO(0, DRM_PVR_DBGDRV)
+#define	DRM_IOCTL_PVR_DISP		_IO(0, DRM_PVR_DISP)
+#endif	
+
+#endif	
+
+#endif 
+
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/mnemedefs.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/mnemedefs.h
new file mode 100755
index 0000000..905081d
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/mnemedefs.h
@@ -0,0 +1,94 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _MNEMEDEFS_KM_H_
+#define _MNEMEDEFS_KM_H_
+
+#define MNE_CR_CTRL                         0x0D00
+#define MNE_CR_CTRL_BYP_CC_N_MASK           0x00010000U
+#define MNE_CR_CTRL_BYP_CC_N_SHIFT          16
+#define MNE_CR_CTRL_BYP_CC_N_SIGNED         0
+#define MNE_CR_CTRL_BYP_CC_MASK             0x00008000U
+#define MNE_CR_CTRL_BYP_CC_SHIFT            15
+#define MNE_CR_CTRL_BYP_CC_SIGNED           0
+#define MNE_CR_CTRL_USE_INVAL_REQ_MASK      0x00007800U
+#define MNE_CR_CTRL_USE_INVAL_REQ_SHIFT     11
+#define MNE_CR_CTRL_USE_INVAL_REQ_SIGNED    0
+#define MNE_CR_CTRL_BYPASS_ALL_MASK         0x00000400U
+#define MNE_CR_CTRL_BYPASS_ALL_SHIFT        10
+#define MNE_CR_CTRL_BYPASS_ALL_SIGNED       0
+#define MNE_CR_CTRL_BYPASS_MASK             0x000003E0U
+#define MNE_CR_CTRL_BYPASS_SHIFT            5
+#define MNE_CR_CTRL_BYPASS_SIGNED           0
+#define MNE_CR_CTRL_PAUSE_MASK              0x00000010U
+#define MNE_CR_CTRL_PAUSE_SHIFT             4
+#define MNE_CR_CTRL_PAUSE_SIGNED            0
+#define MNE_CR_USE_INVAL                    0x0D04
+#define MNE_CR_USE_INVAL_ADDR_MASK          0xFFFFFFFFU
+#define MNE_CR_USE_INVAL_ADDR_SHIFT         0
+#define MNE_CR_USE_INVAL_ADDR_SIGNED        0
+#define MNE_CR_STAT                         0x0D08
+#define MNE_CR_STAT_PAUSED_MASK             0x00000400U
+#define MNE_CR_STAT_PAUSED_SHIFT            10
+#define MNE_CR_STAT_PAUSED_SIGNED           0
+#define MNE_CR_STAT_READS_MASK              0x000003FFU
+#define MNE_CR_STAT_READS_SHIFT             0
+#define MNE_CR_STAT_READS_SIGNED            0
+#define MNE_CR_STAT_STATS                   0x0D0C
+#define MNE_CR_STAT_STATS_RST_MASK          0x000FFFF0U
+#define MNE_CR_STAT_STATS_RST_SHIFT         4
+#define MNE_CR_STAT_STATS_RST_SIGNED        0
+#define MNE_CR_STAT_STATS_SEL_MASK          0x0000000FU
+#define MNE_CR_STAT_STATS_SEL_SHIFT         0
+#define MNE_CR_STAT_STATS_SEL_SIGNED        0
+#define MNE_CR_STAT_STATS_OUT               0x0D10
+#define MNE_CR_STAT_STATS_OUT_VALUE_MASK    0xFFFFFFFFU
+#define MNE_CR_STAT_STATS_OUT_VALUE_SHIFT   0
+#define MNE_CR_STAT_STATS_OUT_VALUE_SIGNED  0
+#define MNE_CR_EVENT_STATUS                 0x0D14
+#define MNE_CR_EVENT_STATUS_INVAL_MASK      0x00000001U
+#define MNE_CR_EVENT_STATUS_INVAL_SHIFT     0
+#define MNE_CR_EVENT_STATUS_INVAL_SIGNED    0
+#define MNE_CR_EVENT_CLEAR                  0x0D18
+#define MNE_CR_EVENT_CLEAR_INVAL_MASK       0x00000001U
+#define MNE_CR_EVENT_CLEAR_INVAL_SHIFT      0
+#define MNE_CR_EVENT_CLEAR_INVAL_SIGNED     0
+#define MNE_CR_CTRL_INVAL                   0x0D20
+#define MNE_CR_CTRL_INVAL_PREQ_PDS_MASK     0x00000008U
+#define MNE_CR_CTRL_INVAL_PREQ_PDS_SHIFT    3
+#define MNE_CR_CTRL_INVAL_PREQ_PDS_SIGNED   0
+#define MNE_CR_CTRL_INVAL_PREQ_USEC_MASK    0x00000004U
+#define MNE_CR_CTRL_INVAL_PREQ_USEC_SHIFT   2
+#define MNE_CR_CTRL_INVAL_PREQ_USEC_SIGNED  0
+#define MNE_CR_CTRL_INVAL_PREQ_CACHE_MASK   0x00000002U
+#define MNE_CR_CTRL_INVAL_PREQ_CACHE_SHIFT  1
+#define MNE_CR_CTRL_INVAL_PREQ_CACHE_SIGNED 0
+#define MNE_CR_CTRL_INVAL_ALL_MASK          0x00000001U
+#define MNE_CR_CTRL_INVAL_ALL_SHIFT         0
+#define MNE_CR_CTRL_INVAL_ALL_SIGNED        0
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx535defs.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx535defs.h
new file mode 100644
index 0000000..66f2166
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx535defs.h
@@ -0,0 +1,650 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SGX535DEFS_KM_H_
+#define _SGX535DEFS_KM_H_
+
+#define EUR_CR_CLKGATECTL                   0x0000
+#define EUR_CR_CLKGATECTL_2D_CLKG_MASK      0x00000003U
+#define EUR_CR_CLKGATECTL_2D_CLKG_SHIFT     0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK     0x00000030U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT    4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK     0x00000300U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT    8
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK      0x00003000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT     12
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK     0x00030000U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT    16
+#define EUR_CR_CLKGATECTL_USE_CLKG_MASK     0x00300000U
+#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT    20
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATESTATUS                0x0004
+#define EUR_CR_CLKGATESTATUS_2D_CLKS_MASK   0x00000001
+#define EUR_CR_CLKGATESTATUS_2D_CLKS_SHIFT  0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK  0x00000010U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK  0x00000100U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK   0x00001000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT  12
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK  0x00010000U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK  0x00100000U
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR                0x0008
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_MASK   0x00000003U
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_SHIFT  0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK  0x00000030U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK  0x00000300U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK   0x00003000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT  12
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK  0x00030000U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK  0x00300000U
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20
+#define EUR_CR_CORE_ID                      0x0010
+#define EUR_CR_CORE_ID_CONFIG_MASK          0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT         0
+#define EUR_CR_CORE_ID_ID_MASK              0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT             16
+#define EUR_CR_CORE_REVISION                0x0014
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK     0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT    8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK     0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT    16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK  0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_DESIGNER_REV_FIELD1          0x0018
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2          0x001C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_SOFT_RESET                   0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK    0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT   0
+#define EUR_CR_SOFT_RESET_TWOD_RESET_MASK   0x00000002U
+#define EUR_CR_SOFT_RESET_TWOD_RESET_SHIFT  1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK    0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT   2
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK     0x00000008U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT    3
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK    0x00000010U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT   4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK    0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT   5
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK    0x00000040U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT   6
+#define EUR_CR_EVENT_HOST_ENABLE2           0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_BIF_REQUESTER_FAULT_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_BIF_REQUESTER_FAULT_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2            0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_BIF_REQUESTER_FAULT_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_BIF_REQUESTER_FAULT_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2                0x0118U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK   0x00000080U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT  7
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK   0x00000040U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT  6
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK   0x00000020U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT  5
+#define EUR_CR_EVENT_STATUS2_BIF_REQUESTER_FAULT_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_BIF_REQUESTER_FAULT_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS                 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK      0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT     29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK   0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT  20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK   0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT  17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK   0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT  14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK  0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK  0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE            0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR             0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK  0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_PDS_EXEC_BASE                0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK      0xFFF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT     20
+#define EUR_CR_EVENT_KICKER                 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK    0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT   4
+#define EUR_CR_EVENT_KICK                   0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK          0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT         0
+#define EUR_CR_EVENT_TIMER                  0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK      0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT     24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK       0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT      0
+#define EUR_CR_PDS_INV0                     0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT           0
+#define EUR_CR_PDS_INV1                     0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT           0
+#define EUR_CR_PDS_INV2                     0x0AD8
+#define EUR_CR_PDS_INV2_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV2_DSC_SHIFT           0
+#define EUR_CR_PDS_INV3                     0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT           0
+#define EUR_CR_PDS_INV_CSC                  0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK        0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT       0
+#define EUR_CR_PDS_PC_BASE                  0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK     0x3FFFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT    0
+#define EUR_CR_BIF_CTRL                     0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK      0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT     0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK          0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT         1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK          0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT         2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK        0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT       3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK    0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT   4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK  0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_MASK 0x00000800U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_SHIFT 11
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK 0x00010000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_SHIFT 16
+#define EUR_CR_BIF_INT_STAT                 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK      0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT     0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK    0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT   14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+#define EUR_CR_BIF_FAULT                    0x0C08
+#define EUR_CR_BIF_FAULT_ADDR_MASK          0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT         12
+#define EUR_CR_BIF_TILE0                    0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE0_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE1                    0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE1_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE2                    0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE2_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE3                    0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE3_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE4                    0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE4_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE5                    0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE5_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE6                    0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE6_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE7                    0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE7_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE8                    0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE8_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE9                    0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE9_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT          24
+#define EUR_CR_BIF_DIR_LIST_BASE1           0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE2           0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE3           0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE4           0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE5           0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE6           0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE7           0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE8           0x0C54
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE9           0x0C58
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE10          0x0C5C
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE11          0x0C60
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE12          0x0C64
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE13          0x0C68
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE14          0x0C6C
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE15          0x0C70
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_SHIFT 12
+#define EUR_CR_BIF_BANK_SET                 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_MASK     0x000003FFU
+#define EUR_CR_BIF_BANK_SET_SELECT_SHIFT    0
+#define EUR_CR_BIF_BANK0                    0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK     0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT    0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK      0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT     4
+#define EUR_CR_BIF_BANK0_INDEX_HOST_MASK    0x00000F00U
+#define EUR_CR_BIF_BANK0_INDEX_HOST_SHIFT   8
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK      0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT     12
+#define EUR_CR_BIF_BANK0_INDEX_2D_MASK      0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_2D_SHIFT     16
+#define EUR_CR_BIF_BANK1                    0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK     0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT    0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK      0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT     4
+#define EUR_CR_BIF_BANK1_INDEX_HOST_MASK    0x00000F00U
+#define EUR_CR_BIF_BANK1_INDEX_HOST_SHIFT   8
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK      0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT     12
+#define EUR_CR_BIF_BANK1_INDEX_2D_MASK      0x000F0000U
+#define EUR_CR_BIF_BANK1_INDEX_2D_SHIFT     16
+#define EUR_CR_BIF_ADT_TTE                  0x0C80
+#define EUR_CR_BIF_ADT_TTE_VALUE_MASK       0x000000FFU
+#define EUR_CR_BIF_ADT_TTE_VALUE_SHIFT      0
+#define EUR_CR_BIF_DIR_LIST_BASE0           0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_TWOD_REQ_BASE            0x0C88
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK  0xFFF00000U
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_TA_REQ_BASE              0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK    0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1      0x0C94
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_MMU_MASK 0x00000007U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_MMU_SHIFT 0
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_CACHE_MASK 0x00000038U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_CACHE_SHIFT 3
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_VDM_MASK 0x000001C0U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_VDM_SHIFT 6
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TE_MASK 0x00000E00U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TE_SHIFT 9
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TWOD_MASK 0x00007000U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TWOD_SHIFT 12
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_PBE_MASK 0x00038000U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_PBE_SHIFT 15
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2      0x0C98
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_HOST_MASK 0x00000007U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_HOST_SHIFT 0
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_USE_MASK 0x00000038U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_USE_SHIFT 3
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_ISP_MASK 0x000001C0U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_ISP_SHIFT 6
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_TSPP_MASK 0x00000E00U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_TSPP_SHIFT 9
+#define EUR_CR_BIF_MEM_ARB_CONFIG           0x0CA0
+#define EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_MASK 0x0000000FU
+#define EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT 0
+#define EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_MASK 0x00000FF0U
+#define EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT 4
+#define EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_MASK 0x00FFF000U
+#define EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT 12
+#define EUR_CR_BIF_MEM_REQ_STAT             0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK  0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_3D_REQ_BASE              0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK    0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_ZLS_REQ_BASE             0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK   0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT  20
+#define EUR_CR_BIF_BANK_STATUS              0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+#define EUR_CR_2D_BLIT_STATUS               0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK     0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT    24
+#define EUR_CR_2D_VIRTUAL_FIFO_0            0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1            0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_2D_SOCIF                     0x0E18
+#define EUR_CR_2D_SOCIF_FREESPACE_MASK      0x000000FFU
+#define EUR_CR_2D_SOCIF_FREESPACE_SHIFT     0
+#define EUR_CR_2D_ALPHA                     0x0E1C
+#define EUR_CR_2D_ALPHA_COMPONENT_ONE_MASK  0x0000FF00U
+#define EUR_CR_2D_ALPHA_COMPONENT_ONE_SHIFT 8
+#define EUR_CR_2D_ALPHA_COMPONENT_ZERO_MASK 0x000000FFU
+#define EUR_CR_2D_ALPHA_COMPONENT_ZERO_SHIFT 0
+#define EUR_CR_USE_CODE_BASE(X)     (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK      0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT     0
+#define EUR_CR_USE_CODE_BASE_DM_MASK        0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT       25
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx540defs.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx540defs.h
new file mode 100644
index 0000000..c09aa26
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx540defs.h
@@ -0,0 +1,547 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SGX540DEFS_KM_H_
+#define _SGX540DEFS_KM_H_
+
+#define EUR_CR_CLKGATECTL                   0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK     0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT    0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK    0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT   2
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK     0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT    4
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK      0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT     6
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK     0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT    8
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK     0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT    10
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK     0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT    12
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK     0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT    14
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK      0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT     18
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK  0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+#define EUR_CR_CLKGATECTL2                  0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK    0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT   0
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK   0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT  6
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK   0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT  8
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK   0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT  10
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK  0x00003000U
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK   0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT  14
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK   0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT  16
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK   0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT  18
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK  0x00300000U
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20
+#define EUR_CR_CLKGATESTATUS                0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK  0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK  0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK   0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT  3
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK  0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK  0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK  0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK  0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK  0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000U
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000U
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK   0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT  20
+#define EUR_CR_CLKGATECTLOVR                0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK  0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK  0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK   0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT  6
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK  0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK  0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK  0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK  0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK   0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT  18
+#define EUR_CR_POWER                        0x001C
+#define EUR_CR_POWER_PIPE_DISABLE_MASK      0x00000001U
+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT     0
+#define EUR_CR_CORE_ID                      0x0020
+#define EUR_CR_CORE_ID_CONFIG_MASK          0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT         0
+#define EUR_CR_CORE_ID_ID_MASK              0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT             16
+#define EUR_CR_CORE_REVISION                0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK     0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT    8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK     0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT    16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK  0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_DESIGNER_REV_FIELD1          0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2          0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_SOFT_RESET                   0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK    0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT   0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK    0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT   1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK    0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT   2
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK     0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT    3
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK    0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT   4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK    0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT   5
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK   0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT  6
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK    0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT   7
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK    0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT   8
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK    0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT   9
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_MADD_RESET_MASK   0x00001000U
+#define EUR_CR_SOFT_RESET_MADD_RESET_SHIFT  12
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK    0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT   13
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK    0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT   14
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK    0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT   15
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK     0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT    17
+#define EUR_CR_EVENT_HOST_ENABLE2           0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2            0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2                0x0118
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK   0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT  4
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK   0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT  3
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK   0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT  2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS                 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK      0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT     29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK   0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT  20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK   0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT  17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK   0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT  14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK  0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK  0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE            0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR             0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK  0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_TIMER                        0x0144
+#define EUR_CR_TIMER_VALUE_MASK             0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT            0
+#define EUR_CR_EVENT_KICK1                  0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK         0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT        0
+#define EUR_CR_PDS_EXEC_BASE                0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK      0x0FF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT     20
+#define EUR_CR_EVENT_KICK2                  0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK         0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICKER                 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK    0x0FFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT   4
+#define EUR_CR_EVENT_KICK                   0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK          0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT         0
+#define EUR_CR_EVENT_TIMER                  0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK      0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT     24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK       0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT      0
+#define EUR_CR_PDS_INV0                     0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT           0
+#define EUR_CR_PDS_INV1                     0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT           0
+#define EUR_CR_EVENT_KICK3                  0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK         0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT        0
+#define EUR_CR_PDS_INV3                     0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT           0
+#define EUR_CR_PDS_INV_CSC                  0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK        0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT       0
+#define EUR_CR_PDS_PC_BASE                  0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK     0x00FFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT    0
+#define EUR_CR_BIF_CTRL                     0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK      0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT     0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK          0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT         1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK          0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT         2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK        0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT       3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK    0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT   4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK  0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_INT_STAT                 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK      0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT     0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK    0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT   14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+#define EUR_CR_BIF_FAULT                    0x0C08
+#define EUR_CR_BIF_FAULT_SB_MASK            0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT           4
+#define EUR_CR_BIF_FAULT_ADDR_MASK          0x0FFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT         12
+#define EUR_CR_BIF_DIR_LIST_BASE0           0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_TA_REQ_BASE              0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK    0x0FF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_MEM_REQ_STAT             0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK  0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_3D_REQ_BASE              0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK    0x0FF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_ZLS_REQ_BASE             0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK   0x0FF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT  20
+#define EUR_CR_2D_BLIT_STATUS               0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK     0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT    24
+#define EUR_CR_2D_VIRTUAL_FIFO_0            0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1            0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_USE_CODE_BASE(X)     (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK      0x00FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT     0
+#define EUR_CR_USE_CODE_BASE_DM_MASK        0x03000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT       24
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx543_v1.164defs.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx543_v1.164defs.h
new file mode 100755
index 0000000..23bd4d4
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx543_v1.164defs.h
@@ -0,0 +1,1284 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SGX543DEFS_KM_H_
+#define _SGX543DEFS_KM_H_
+
+#define EUR_CR_CLKGATECTL                   0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK     0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT    0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK    0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT   2
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SIGNED  0
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK     0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT    4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK      0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT     6
+#define EUR_CR_CLKGATECTL_TE_CLKG_SIGNED    0
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK     0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT    8
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK     0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT    10
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK     0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT    12
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK     0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT    14
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK      0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT     18
+#define EUR_CR_CLKGATECTL_TA_CLKG_SIGNED    0
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SIGNED 0
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK  0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2                  0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK    0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT   0
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SIGNED  0
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK   0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT  6
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK   0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT  8
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK   0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT  10
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK   0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT  14
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK   0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT  16
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK   0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT  18
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_MASK 0x00C00000U
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SHIFT 22
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_MASK 0x03000000U
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SHIFT 24
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_MASK 0x0C000000U
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SHIFT 26
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATESTATUS                0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK  0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK  0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK   0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT  3
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK  0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK  0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK  0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK  0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK  0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK   0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT  20
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_MASK 0x00200000U
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SHIFT 21
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_MASK 0x00400000U
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SHIFT 22
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_MASK 0x00800000U
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SHIFT 23
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_MASK 0x01000000U
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SHIFT 24
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR                0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK  0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK  0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK   0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT  6
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK  0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK  0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK  0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK  0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK   0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT  18
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SIGNED 0
+#define EUR_CR_POWER                        0x001C
+#define EUR_CR_POWER_PIPE_DISABLE_MASK      0x00000001U
+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT     0
+#define EUR_CR_POWER_PIPE_DISABLE_SIGNED    0
+#define EUR_CR_CORE_ID                      0x0020
+#define EUR_CR_CORE_ID_CONFIG_MULTI_MASK    0x00000001U
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SHIFT   0
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SIGNED  0
+#define EUR_CR_CORE_ID_CONFIG_BASE_MASK     0x00000002U
+#define EUR_CR_CORE_ID_CONFIG_BASE_SHIFT    1
+#define EUR_CR_CORE_ID_CONFIG_BASE_SIGNED   0
+#define EUR_CR_CORE_ID_CONFIG_MASK          0x000000FCU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT         2
+#define EUR_CR_CORE_ID_CONFIG_SIGNED        0
+#define EUR_CR_CORE_ID_CONFIG_CORES_MASK    0x00000F00U
+#define EUR_CR_CORE_ID_CONFIG_CORES_SHIFT   8
+#define EUR_CR_CORE_ID_CONFIG_CORES_SIGNED  0
+#define EUR_CR_CORE_ID_CONFIG_SLC_MASK      0x0000F000U
+#define EUR_CR_CORE_ID_CONFIG_SLC_SHIFT     12
+#define EUR_CR_CORE_ID_CONFIG_SLC_SIGNED    0
+#define EUR_CR_CORE_ID_ID_MASK              0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT             16
+#define EUR_CR_CORE_ID_ID_SIGNED            0
+#define EUR_CR_CORE_REVISION                0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SIGNED 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK     0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT    8
+#define EUR_CR_CORE_REVISION_MINOR_SIGNED   0
+#define EUR_CR_CORE_REVISION_MAJOR_MASK     0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT    16
+#define EUR_CR_CORE_REVISION_MAJOR_SIGNED   0
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK  0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_CORE_REVISION_DESIGNER_SIGNED 0
+#define EUR_CR_DESIGNER_REV_FIELD1          0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SIGNED 0
+#define EUR_CR_DESIGNER_REV_FIELD2          0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SIGNED 0
+#define EUR_CR_SOFT_RESET                   0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK    0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT   0
+#define EUR_CR_SOFT_RESET_BIF_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK    0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT   1
+#define EUR_CR_SOFT_RESET_VDM_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK    0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT   2
+#define EUR_CR_SOFT_RESET_DPM_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK     0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT    3
+#define EUR_CR_SOFT_RESET_TE_RESET_SIGNED   0
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK    0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT   4
+#define EUR_CR_SOFT_RESET_MTE_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK    0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT   5
+#define EUR_CR_SOFT_RESET_ISP_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK   0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT  6
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK    0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT   7
+#define EUR_CR_SOFT_RESET_TSP_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK    0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT   8
+#define EUR_CR_SOFT_RESET_PDS_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK    0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT   9
+#define EUR_CR_SOFT_RESET_PBE_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK    0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT   13
+#define EUR_CR_SOFT_RESET_ITR_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK    0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT   14
+#define EUR_CR_SOFT_RESET_TEX_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK    0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT   15
+#define EUR_CR_SOFT_RESET_USE_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK     0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT    17
+#define EUR_CR_SOFT_RESET_TA_RESET_SIGNED   0
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK 0x00040000U
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SHIFT 18
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK 0x00080000U
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SHIFT 19
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2           0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2            0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2                0x0118
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK   0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT  4
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK   0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT  3
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK   0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT  2
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS                 0x012C
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TIMER_MASK      0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT     29
+#define EUR_CR_EVENT_STATUS_TIMER_SIGNED    0
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK   0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT  20
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK   0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT  14
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK  0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK  0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE            0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR             0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK  0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SIGNED 0
+#define EUR_CR_TIMER                        0x0144
+#define EUR_CR_TIMER_VALUE_MASK             0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT            0
+#define EUR_CR_TIMER_VALUE_SIGNED           0
+#define EUR_CR_EVENT_KICK1                  0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK         0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICK1_NOW_SIGNED       0
+#define EUR_CR_EVENT_KICK2                  0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK         0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICK2_NOW_SIGNED       0
+#define EUR_CR_EVENT_KICKER                 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK    0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT   4
+#define EUR_CR_EVENT_KICKER_ADDRESS_SIGNED  0
+#define EUR_CR_EVENT_KICK                   0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK          0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT         0
+#define EUR_CR_EVENT_KICK_NOW_SIGNED        0
+#define EUR_CR_EVENT_TIMER                  0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK      0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT     24
+#define EUR_CR_EVENT_TIMER_ENABLE_SIGNED    0
+#define EUR_CR_EVENT_TIMER_VALUE_MASK       0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT      0
+#define EUR_CR_EVENT_TIMER_VALUE_SIGNED     0
+#define EUR_CR_PDS_INV0                     0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT           0
+#define EUR_CR_PDS_INV0_DSC_SIGNED          0
+#define EUR_CR_PDS_INV1                     0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT           0
+#define EUR_CR_PDS_INV1_DSC_SIGNED          0
+#define EUR_CR_EVENT_KICK3                  0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK         0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICK3_NOW_SIGNED       0
+#define EUR_CR_PDS_INV3                     0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT           0
+#define EUR_CR_PDS_INV3_DSC_SIGNED          0
+#define EUR_CR_PDS_INV_CSC                  0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK        0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT       0
+#define EUR_CR_PDS_INV_CSC_KICK_SIGNED      0
+#define EUR_CR_BIF_CTRL                     0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK      0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT     0
+#define EUR_CR_BIF_CTRL_NOREORDER_SIGNED    0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK          0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT         1
+#define EUR_CR_BIF_CTRL_PAUSE_SIGNED        0
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK    0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT   4
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SIGNED  0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_MASK  0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_MASK 0x00010000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SHIFT 16
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_MASK 0x00020000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SHIFT 17
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_MASK 0x00040000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SHIFT 18
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_MASK 0x00080000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SHIFT 19
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SIGNED 0
+#define EUR_CR_BIF_INT_STAT                 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK  0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_MASK 0x00070000U
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SHIFT 16
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00080000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 19
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SIGNED 0
+#define EUR_CR_BIF_FAULT                    0x0C08
+#define EUR_CR_BIF_FAULT_CID_MASK           0x0000000FU
+#define EUR_CR_BIF_FAULT_CID_SHIFT          0
+#define EUR_CR_BIF_FAULT_CID_SIGNED         0
+#define EUR_CR_BIF_FAULT_SB_MASK            0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT           4
+#define EUR_CR_BIF_FAULT_SB_SIGNED          0
+#define EUR_CR_BIF_FAULT_ADDR_MASK          0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT         12
+#define EUR_CR_BIF_FAULT_ADDR_SIGNED        0
+#define EUR_CR_BIF_TILE0                    0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE0_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE1                    0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE1_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE2                    0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE2_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE3                    0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE3_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE4                    0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE4_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE5                    0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE5_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE6                    0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE6_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE7                    0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE7_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE8                    0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE8_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE9                    0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE9_CFG_SIGNED         0
+#define EUR_CR_BIF_CTRL_INVAL               0x0C34
+#define EUR_CR_BIF_CTRL_INVAL_PTE_MASK      0x00000004U
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SHIFT     2
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SIGNED    0
+#define EUR_CR_BIF_CTRL_INVAL_ALL_MASK      0x00000008U
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SHIFT     3
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SIGNED    0
+#define EUR_CR_BIF_DIR_LIST_BASE1           0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE2           0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE3           0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE4           0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE5           0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE6           0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE7           0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SIGNED 0
+#define EUR_CR_BIF_BANK_SET                 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_MASK  0x00000001U
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SHIFT 0
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_MASK  0x0000000CU
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SHIFT 2
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_MASK 0x00000010U
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SHIFT 4
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_MASK  0x000000C0U
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SHIFT 6
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_MASK 0x00000100U
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SHIFT 8
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_MASK 0x00000200U
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SHIFT 9
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SIGNED 0
+#define EUR_CR_BIF_BANK0                    0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK     0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT    0
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SIGNED   0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK      0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT     4
+#define EUR_CR_BIF_BANK0_INDEX_TA_SIGNED    0
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK      0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT     12
+#define EUR_CR_BIF_BANK0_INDEX_3D_SIGNED    0
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_MASK    0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SHIFT   16
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SIGNED  0
+#define EUR_CR_BIF_BANK1                    0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK     0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT    0
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SIGNED   0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK      0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT     4
+#define EUR_CR_BIF_BANK1_INDEX_TA_SIGNED    0
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK      0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT     12
+#define EUR_CR_BIF_BANK1_INDEX_3D_SIGNED    0
+#define EUR_CR_BIF_DIR_LIST_BASE0           0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SIGNED 0
+#define EUR_CR_BIF_TA_REQ_BASE              0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK    0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SIGNED  0
+#define EUR_CR_BIF_MEM_REQ_STAT             0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK  0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SIGNED 0
+#define EUR_CR_BIF_3D_REQ_BASE              0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK    0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SIGNED  0
+#define EUR_CR_BIF_ZLS_REQ_BASE             0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK   0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT  20
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS              0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL                 0x0CD0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK 0x00000001U
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SHIFT 0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_MASK 0x00000006U
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT 1
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_MASK 0x00000008U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SHIFT 3
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK 0x00000010U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SHIFT 4
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SIGNED 0
+#define EUR_CR_2D_BLIT_STATUS               0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SIGNED 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK     0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT    24
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SIGNED   0
+#define EUR_CR_2D_VIRTUAL_FIFO_0            0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1            0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SIGNED 0
+#define EUR_CR_BREAKPOINT0_START            0x0F44
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT0_END              0x0F48
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT0                  0x0F4C
+#define EUR_CR_BREAKPOINT0_MASK_DM_MASK     0x00000038U
+#define EUR_CR_BREAKPOINT0_MASK_DM_SHIFT    3
+#define EUR_CR_BREAKPOINT0_MASK_DM_SIGNED   0
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_START            0x0F50
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT1_END              0x0F54
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT1                  0x0F58
+#define EUR_CR_BREAKPOINT1_MASK_DM_MASK     0x00000038U
+#define EUR_CR_BREAKPOINT1_MASK_DM_SHIFT    3
+#define EUR_CR_BREAKPOINT1_MASK_DM_SIGNED   0
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_START            0x0F5C
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT2_END              0x0F60
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT2                  0x0F64
+#define EUR_CR_BREAKPOINT2_MASK_DM_MASK     0x00000038U
+#define EUR_CR_BREAKPOINT2_MASK_DM_SHIFT    3
+#define EUR_CR_BREAKPOINT2_MASK_DM_SIGNED   0
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_START            0x0F68
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT3_END              0x0F6C
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT3                  0x0F70
+#define EUR_CR_BREAKPOINT3_MASK_DM_MASK     0x00000038U
+#define EUR_CR_BREAKPOINT3_MASK_DM_SHIFT    3
+#define EUR_CR_BREAKPOINT3_MASK_DM_SIGNED   0
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT_READ              0x0F74
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP              0x0F78
+#define EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+#define EUR_CR_BREAKPOINT                   0x0F7C
+#define EUR_CR_BREAKPOINT_MODULE_ID_MASK    0x000003C0U
+#define EUR_CR_BREAKPOINT_MODULE_ID_SHIFT   6
+#define EUR_CR_BREAKPOINT_MODULE_ID_SIGNED  0
+#define EUR_CR_BREAKPOINT_ID_MASK           0x00000030U
+#define EUR_CR_BREAKPOINT_ID_SHIFT          4
+#define EUR_CR_BREAKPOINT_ID_SIGNED         0
+#define EUR_CR_BREAKPOINT_UNTRAPPED_MASK    0x00000008U
+#define EUR_CR_BREAKPOINT_UNTRAPPED_SHIFT   3
+#define EUR_CR_BREAKPOINT_UNTRAPPED_SIGNED  0
+#define EUR_CR_BREAKPOINT_TRAPPED_MASK      0x00000004U
+#define EUR_CR_BREAKPOINT_TRAPPED_SHIFT     2
+#define EUR_CR_BREAKPOINT_TRAPPED_SIGNED    0
+#define EUR_CR_BREAKPOINT_TRAP_INFO0        0x0F80
+#define EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1        0x0F84
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_0              0x0A0C
+#define EUR_CR_USE_CODE_BASE_ADDR_00_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_00_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_00_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_00_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_1              0x0A10
+#define EUR_CR_USE_CODE_BASE_ADDR_01_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_01_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_01_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_01_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_2              0x0A14
+#define EUR_CR_USE_CODE_BASE_ADDR_02_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_02_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_02_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_02_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_3              0x0A18
+#define EUR_CR_USE_CODE_BASE_ADDR_03_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_03_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_03_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_03_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_4              0x0A1C
+#define EUR_CR_USE_CODE_BASE_ADDR_04_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_04_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_04_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_04_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_5              0x0A20
+#define EUR_CR_USE_CODE_BASE_ADDR_05_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_05_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_05_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_05_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_6              0x0A24
+#define EUR_CR_USE_CODE_BASE_ADDR_06_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_06_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_06_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_06_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_7              0x0A28
+#define EUR_CR_USE_CODE_BASE_ADDR_07_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_07_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_07_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_07_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_8              0x0A2C
+#define EUR_CR_USE_CODE_BASE_ADDR_08_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_08_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_08_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_08_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_9              0x0A30
+#define EUR_CR_USE_CODE_BASE_ADDR_09_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_09_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_09_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_09_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_10             0x0A34
+#define EUR_CR_USE_CODE_BASE_ADDR_10_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_10_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_10_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_10_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_11             0x0A38
+#define EUR_CR_USE_CODE_BASE_ADDR_11_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_11_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_11_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_11_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_12             0x0A3C
+#define EUR_CR_USE_CODE_BASE_ADDR_12_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_12_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_12_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_12_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_13             0x0A40
+#define EUR_CR_USE_CODE_BASE_ADDR_13_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_13_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_13_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_13_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_14             0x0A44
+#define EUR_CR_USE_CODE_BASE_ADDR_14_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_14_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_14_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_14_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_15             0x0A48
+#define EUR_CR_USE_CODE_BASE_ADDR_15_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_15_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_15_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_15_SIGNED   0
+#define EUR_CR_USE_CODE_BASE(X)     (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK      0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT     0
+#define EUR_CR_USE_CODE_BASE_ADDR_SIGNED    0
+#define EUR_CR_USE_CODE_BASE_DM_MASK        0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT       26
+#define EUR_CR_USE_CODE_BASE_DM_SIGNED      0
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx544defs.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx544defs.h
new file mode 100755
index 0000000..c18b8ad
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx544defs.h
@@ -0,0 +1,1367 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SGX544DEFS_KM_H_
+#define _SGX544DEFS_KM_H_
+
+#define EUR_CR_CLKGATECTL                   0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK     0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT    0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK    0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT   2
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SIGNED  0
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK     0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT    4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK      0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT     6
+#define EUR_CR_CLKGATECTL_TE_CLKG_SIGNED    0
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK     0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT    8
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK     0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT    10
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK     0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT    12
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK     0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT    14
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK      0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT     18
+#define EUR_CR_CLKGATECTL_TA_CLKG_SIGNED    0
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SIGNED 0
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK  0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2                  0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK    0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT   0
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SIGNED  0
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK   0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT  6
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK   0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT  8
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK   0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT  10
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK   0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT  14
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK   0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT  16
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK   0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT  18
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_MASK 0x00C00000U
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SHIFT 22
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_MASK 0x03000000U
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SHIFT 24
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_MASK 0x0C000000U
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SHIFT 26
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATESTATUS                0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK  0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK  0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK   0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT  3
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK  0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK  0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK  0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK  0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK  0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK   0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT  20
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_MASK 0x00200000U
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SHIFT 21
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_MASK 0x00400000U
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SHIFT 22
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_MASK 0x00800000U
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SHIFT 23
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_MASK 0x01000000U
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SHIFT 24
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR                0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK  0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK  0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK   0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT  6
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK  0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK  0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK  0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK  0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK   0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT  18
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SIGNED 0
+#define EUR_CR_POWER                        0x001C
+#define EUR_CR_POWER_PIPE_DISABLE_MASK      0x00000001U
+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT     0
+#define EUR_CR_POWER_PIPE_DISABLE_SIGNED    0
+#define EUR_CR_CORE_ID                      0x0020
+#define EUR_CR_CORE_ID_CONFIG_MULTI_MASK    0x00000001U
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SHIFT   0
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SIGNED  0
+#define EUR_CR_CORE_ID_CONFIG_BASE_MASK     0x00000002U
+#define EUR_CR_CORE_ID_CONFIG_BASE_SHIFT    1
+#define EUR_CR_CORE_ID_CONFIG_BASE_SIGNED   0
+#define EUR_CR_CORE_ID_CONFIG_MASK          0x000000FCU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT         2
+#define EUR_CR_CORE_ID_CONFIG_SIGNED        0
+#define EUR_CR_CORE_ID_CONFIG_CORES_MASK    0x00000F00U
+#define EUR_CR_CORE_ID_CONFIG_CORES_SHIFT   8
+#define EUR_CR_CORE_ID_CONFIG_CORES_SIGNED  0
+#define EUR_CR_CORE_ID_CONFIG_SLC_MASK      0x0000F000U
+#define EUR_CR_CORE_ID_CONFIG_SLC_SHIFT     12
+#define EUR_CR_CORE_ID_CONFIG_SLC_SIGNED    0
+#define EUR_CR_CORE_ID_ID_MASK              0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT             16
+#define EUR_CR_CORE_ID_ID_SIGNED            0
+#define EUR_CR_CORE_REVISION                0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SIGNED 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK     0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT    8
+#define EUR_CR_CORE_REVISION_MINOR_SIGNED   0
+#define EUR_CR_CORE_REVISION_MAJOR_MASK     0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT    16
+#define EUR_CR_CORE_REVISION_MAJOR_SIGNED   0
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK  0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_CORE_REVISION_DESIGNER_SIGNED 0
+#define EUR_CR_DESIGNER_REV_FIELD1          0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SIGNED 0
+#define EUR_CR_DESIGNER_REV_FIELD2          0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SIGNED 0
+#define EUR_CR_SOFT_RESET                   0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK    0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT   0
+#define EUR_CR_SOFT_RESET_BIF_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK    0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT   1
+#define EUR_CR_SOFT_RESET_VDM_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK    0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT   2
+#define EUR_CR_SOFT_RESET_DPM_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK     0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT    3
+#define EUR_CR_SOFT_RESET_TE_RESET_SIGNED   0
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK    0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT   4
+#define EUR_CR_SOFT_RESET_MTE_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK    0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT   5
+#define EUR_CR_SOFT_RESET_ISP_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK   0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT  6
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK    0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT   7
+#define EUR_CR_SOFT_RESET_TSP_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK    0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT   8
+#define EUR_CR_SOFT_RESET_PDS_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK    0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT   9
+#define EUR_CR_SOFT_RESET_PBE_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK    0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT   13
+#define EUR_CR_SOFT_RESET_ITR_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK    0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT   14
+#define EUR_CR_SOFT_RESET_TEX_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK    0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT   15
+#define EUR_CR_SOFT_RESET_USE_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK     0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT    17
+#define EUR_CR_SOFT_RESET_TA_RESET_SIGNED   0
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK 0x00040000U
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SHIFT 18
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK 0x00080000U
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SHIFT 19
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2           0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2            0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2                0x0118
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK   0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT  4
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK   0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT  3
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK   0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT  2
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS                 0x012C
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TIMER_MASK      0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT     29
+#define EUR_CR_EVENT_STATUS_TIMER_SIGNED    0
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK   0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT  20
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK   0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT  14
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK  0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK  0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE            0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR             0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK  0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SIGNED 0
+#define EUR_CR_TIMER                        0x0144
+#define EUR_CR_TIMER_VALUE_MASK             0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT            0
+#define EUR_CR_TIMER_VALUE_SIGNED           0
+#define EUR_CR_EVENT_KICK1                  0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK         0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICK1_NOW_SIGNED       0
+#define EUR_CR_EVENT_KICK2                  0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK         0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICK2_NOW_SIGNED       0
+#define EUR_CR_EVENT_KICKER                 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK    0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT   4
+#define EUR_CR_EVENT_KICKER_ADDRESS_SIGNED  0
+#define EUR_CR_EVENT_KICK                   0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK          0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT         0
+#define EUR_CR_EVENT_KICK_NOW_SIGNED        0
+#define EUR_CR_EVENT_TIMER                  0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK      0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT     24
+#define EUR_CR_EVENT_TIMER_ENABLE_SIGNED    0
+#define EUR_CR_EVENT_TIMER_VALUE_MASK       0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT      0
+#define EUR_CR_EVENT_TIMER_VALUE_SIGNED     0
+#define EUR_CR_PDS_INV0                     0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT           0
+#define EUR_CR_PDS_INV0_DSC_SIGNED          0
+#define EUR_CR_PDS_INV1                     0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT           0
+#define EUR_CR_PDS_INV1_DSC_SIGNED          0
+#define EUR_CR_EVENT_KICK3                  0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK         0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICK3_NOW_SIGNED       0
+#define EUR_CR_PDS_INV3                     0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT           0
+#define EUR_CR_PDS_INV3_DSC_SIGNED          0
+#define EUR_CR_PDS_INV_CSC                  0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK        0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT       0
+#define EUR_CR_PDS_INV_CSC_KICK_SIGNED      0
+#define EUR_CR_BIF_CTRL                     0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK      0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT     0
+#define EUR_CR_BIF_CTRL_NOREORDER_SIGNED    0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK          0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT         1
+#define EUR_CR_BIF_CTRL_PAUSE_SIGNED        0
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK    0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT   4
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SIGNED  0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_MASK  0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_MASK 0x00010000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SHIFT 16
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_MASK 0x00020000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SHIFT 17
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_MASK 0x00040000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SHIFT 18
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_MASK 0x00080000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SHIFT 19
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SIGNED 0
+#define EUR_CR_BIF_INT_STAT                 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK  0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_MASK 0x00070000U
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SHIFT 16
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00080000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 19
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SIGNED 0
+#define EUR_CR_BIF_FAULT                    0x0C08
+#define EUR_CR_BIF_FAULT_CID_MASK           0x0000000FU
+#define EUR_CR_BIF_FAULT_CID_SHIFT          0
+#define EUR_CR_BIF_FAULT_CID_SIGNED         0
+#define EUR_CR_BIF_FAULT_SB_MASK            0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT           4
+#define EUR_CR_BIF_FAULT_SB_SIGNED          0
+#define EUR_CR_BIF_FAULT_ADDR_MASK          0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT         12
+#define EUR_CR_BIF_FAULT_ADDR_SIGNED        0
+#define EUR_CR_BIF_TILE0                    0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE0_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE1                    0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE1_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE2                    0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE2_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE3                    0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE3_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE4                    0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE4_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE5                    0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE5_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE6                    0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE6_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE7                    0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE7_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE8                    0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE8_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE9                    0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE9_CFG_SIGNED         0
+#define EUR_CR_BIF_CTRL_INVAL               0x0C34
+#define EUR_CR_BIF_CTRL_INVAL_PTE_MASK      0x00000004U
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SHIFT     2
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SIGNED    0
+#define EUR_CR_BIF_CTRL_INVAL_ALL_MASK      0x00000008U
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SHIFT     3
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SIGNED    0
+#define EUR_CR_BIF_DIR_LIST_BASE1           0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE2           0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE3           0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE4           0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE5           0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE6           0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE7           0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SIGNED 0
+#define EUR_CR_BIF_BANK_SET                 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_MASK  0x00000001U
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SHIFT 0
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_MASK  0x0000000CU
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SHIFT 2
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_MASK 0x00000010U
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SHIFT 4
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_MASK  0x000000C0U
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SHIFT 6
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_MASK 0x00000100U
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SHIFT 8
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_MASK 0x00000200U
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SHIFT 9
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SIGNED 0
+#define EUR_CR_BIF_BANK0                    0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK     0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT    0
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SIGNED   0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK      0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT     4
+#define EUR_CR_BIF_BANK0_INDEX_TA_SIGNED    0
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK      0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT     12
+#define EUR_CR_BIF_BANK0_INDEX_3D_SIGNED    0
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_MASK    0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SHIFT   16
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SIGNED  0
+#define EUR_CR_BIF_BANK1                    0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK     0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT    0
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SIGNED   0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK      0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT     4
+#define EUR_CR_BIF_BANK1_INDEX_TA_SIGNED    0
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK      0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT     12
+#define EUR_CR_BIF_BANK1_INDEX_3D_SIGNED    0
+#define EUR_CR_BIF_DIR_LIST_BASE0           0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SIGNED 0
+#define EUR_CR_BIF_TA_REQ_BASE              0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK    0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SIGNED  0
+#define EUR_CR_BIF_MEM_REQ_STAT             0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK  0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SIGNED 0
+#define EUR_CR_BIF_3D_REQ_BASE              0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK    0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SIGNED  0
+#define EUR_CR_BIF_ZLS_REQ_BASE             0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK   0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT  20
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS              0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL                 0x0CD0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK 0x00000001U
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SHIFT 0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_MASK 0x00000006U
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT 1
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_MASK 0x00000008U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SHIFT 3
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK 0x00000010U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SHIFT 4
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_MASK 0x00000020U
+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_SHIFT 5
+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_SIGNED 0
+#define EUR_CR_2D_BLIT_STATUS               0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SIGNED 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK     0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT    24
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SIGNED   0
+#define EUR_CR_2D_VIRTUAL_FIFO_0            0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1            0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SIGNED 0
+#define EUR_CR_BREAKPOINT0_START            0x0F44
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT0_END              0x0F48
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT0                  0x0F4C
+#define EUR_CR_BREAKPOINT0_MASK_DM_MASK     0x00000038U
+#define EUR_CR_BREAKPOINT0_MASK_DM_SHIFT    3
+#define EUR_CR_BREAKPOINT0_MASK_DM_SIGNED   0
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_START            0x0F50
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT1_END              0x0F54
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT1                  0x0F58
+#define EUR_CR_BREAKPOINT1_MASK_DM_MASK     0x00000038U
+#define EUR_CR_BREAKPOINT1_MASK_DM_SHIFT    3
+#define EUR_CR_BREAKPOINT1_MASK_DM_SIGNED   0
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_START            0x0F5C
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT2_END              0x0F60
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT2                  0x0F64
+#define EUR_CR_BREAKPOINT2_MASK_DM_MASK     0x00000038U
+#define EUR_CR_BREAKPOINT2_MASK_DM_SHIFT    3
+#define EUR_CR_BREAKPOINT2_MASK_DM_SIGNED   0
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_START            0x0F68
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT3_END              0x0F6C
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SIGNED 0
+#define EUR_CR_BREAKPOINT3                  0x0F70
+#define EUR_CR_BREAKPOINT3_MASK_DM_MASK     0x00000038U
+#define EUR_CR_BREAKPOINT3_MASK_DM_SHIFT    3
+#define EUR_CR_BREAKPOINT3_MASK_DM_SIGNED   0
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT_READ              0x0F74
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP    0x0F78
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT         0x0F7C
+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_ID_MASK 0x00000030U
+#define EUR_CR_PARTITION_BREAKPOINT_ID_SHIFT 4
+#define EUR_CR_PARTITION_BREAKPOINT_ID_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0 0x0F80
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1 0x0F84
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_0              0x0A0C
+#define EUR_CR_USE_CODE_BASE_ADDR_00_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_00_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_00_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_00_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_1              0x0A10
+#define EUR_CR_USE_CODE_BASE_ADDR_01_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_01_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_01_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_01_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_2              0x0A14
+#define EUR_CR_USE_CODE_BASE_ADDR_02_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_02_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_02_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_02_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_3              0x0A18
+#define EUR_CR_USE_CODE_BASE_ADDR_03_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_03_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_03_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_03_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_4              0x0A1C
+#define EUR_CR_USE_CODE_BASE_ADDR_04_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_04_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_04_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_04_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_5              0x0A20
+#define EUR_CR_USE_CODE_BASE_ADDR_05_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_05_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_05_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_05_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_6              0x0A24
+#define EUR_CR_USE_CODE_BASE_ADDR_06_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_06_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_06_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_06_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_7              0x0A28
+#define EUR_CR_USE_CODE_BASE_ADDR_07_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_07_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_07_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_07_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_8              0x0A2C
+#define EUR_CR_USE_CODE_BASE_ADDR_08_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_08_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_08_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_08_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_9              0x0A30
+#define EUR_CR_USE_CODE_BASE_ADDR_09_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_09_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_09_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_09_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_10             0x0A34
+#define EUR_CR_USE_CODE_BASE_ADDR_10_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_10_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_10_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_10_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_11             0x0A38
+#define EUR_CR_USE_CODE_BASE_ADDR_11_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_11_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_11_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_11_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_12             0x0A3C
+#define EUR_CR_USE_CODE_BASE_ADDR_12_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_12_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_12_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_12_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_13             0x0A40
+#define EUR_CR_USE_CODE_BASE_ADDR_13_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_13_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_13_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_13_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_14             0x0A44
+#define EUR_CR_USE_CODE_BASE_ADDR_14_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_14_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_14_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_14_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_15             0x0A48
+#define EUR_CR_USE_CODE_BASE_ADDR_15_MASK   0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_15_MASK     0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_15_SHIFT    26
+#define EUR_CR_USE_CODE_BASE_DM_15_SIGNED   0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP        0x0F88
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT             0x0F8C
+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_ID_MASK     0x00000030U
+#define EUR_CR_PIPE0_BREAKPOINT_ID_SHIFT    4
+#define EUR_CR_PIPE0_BREAKPOINT_ID_SIGNED   0
+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0  0x0F90
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1  0x0F94
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP        0x0F98
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT             0x0F9C
+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_ID_MASK     0x00000030U
+#define EUR_CR_PIPE1_BREAKPOINT_ID_SHIFT    4
+#define EUR_CR_PIPE1_BREAKPOINT_ID_SIGNED   0
+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0  0x0FA0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1  0x0FA4
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+#define EUR_CR_USE_CODE_BASE(X)     (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK      0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT     0
+#define EUR_CR_USE_CODE_BASE_ADDR_SIGNED    0
+#define EUR_CR_USE_CODE_BASE_DM_MASK        0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT       26
+#define EUR_CR_USE_CODE_BASE_DM_SIGNED      0
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx545defs.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx545defs.h
new file mode 100644
index 0000000..4dc7f3c
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgx545defs.h
@@ -0,0 +1,1180 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SGX545DEFS_KM_H_
+#define _SGX545DEFS_KM_H_
+
+#define EUR_CR_CLKGATECTL                   0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK     0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT    0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK    0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT   2
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SIGNED  0
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK     0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT    4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK      0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT     6
+#define EUR_CR_CLKGATECTL_TE_CLKG_SIGNED    0
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK     0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT    8
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK     0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT    10
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK     0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT    12
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SIGNED   0
+#define EUR_CR_CLKGATECTL_PDS0_CLKG_MASK    0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS0_CLKG_SHIFT   14
+#define EUR_CR_CLKGATECTL_PDS0_CLKG_SIGNED  0
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SIGNED 0
+#define EUR_CR_CLKGATECTL2                  0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK    0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT   0
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SIGNED  0
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK   0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT  6
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK   0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT  8
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK   0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT  10
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK  0x00003000U
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK   0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT  14
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK   0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT  16
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK   0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT  18
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK  0x00300000U
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_PDS1_CLKG_MASK   0x00C00000U
+#define EUR_CR_CLKGATECTL2_PDS1_CLKG_SHIFT  22
+#define EUR_CR_CLKGATECTL2_PDS1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATESTATUS                0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK  0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK  0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK   0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT  3
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK  0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK  0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK  0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PDS0_CLKS_MASK 0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS0_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PDS0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK  0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000U
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000U
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PDS1_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_PDS1_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_PDS1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR                0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK  0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK  0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK   0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT  6
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK  0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK  0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK  0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_PDS0_CLKO_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS0_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_PDS0_CLKO_SIGNED 0
+#define EUR_CR_CORE_ID                      0x001C
+#define EUR_CR_CORE_ID_CONFIG_MASK          0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT         0
+#define EUR_CR_CORE_ID_CONFIG_SIGNED        0
+#define EUR_CR_CORE_ID_ID_MASK              0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT             16
+#define EUR_CR_CORE_ID_ID_SIGNED            0
+#define EUR_CR_CORE_REVISION                0x0020
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SIGNED 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK     0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT    8
+#define EUR_CR_CORE_REVISION_MINOR_SIGNED   0
+#define EUR_CR_CORE_REVISION_MAJOR_MASK     0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT    16
+#define EUR_CR_CORE_REVISION_MAJOR_SIGNED   0
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK  0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_CORE_REVISION_DESIGNER_SIGNED 0
+#define EUR_CR_DESIGNER_REV_FIELD1          0x0024
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SIGNED 0
+#define EUR_CR_DESIGNER_REV_FIELD2          0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SIGNED 0
+#define EUR_CR_SOFT_RESET                   0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK    0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT   0
+#define EUR_CR_SOFT_RESET_BIF_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK    0x00000002U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT   1
+#define EUR_CR_SOFT_RESET_DPM_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK     0x00000004U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT    2
+#define EUR_CR_SOFT_RESET_TA_RESET_SIGNED   0
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK    0x00000008U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT   3
+#define EUR_CR_SOFT_RESET_USE_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK    0x00000010U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT   4
+#define EUR_CR_SOFT_RESET_ISP_RESET_SIGNED  0
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK    0x00000020U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT   5
+#define EUR_CR_SOFT_RESET_TSP_RESET_SIGNED  0
+#define EUR_CR_EVENT_HOST_ENABLE2           0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_CONTEXT_LOAD_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_CONTEXT_LOAD_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_CONTEXT_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_TASK_KICKED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_TASK_KICKED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_TASK_KICKED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_MEM_CLEARED_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_MEM_CLEARED_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_MEM_CLEARED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_FLUSHED_INV_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_FLUSHED_INV_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_FLUSHED_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_FLUSHED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_FLUSHED_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_LOADED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_LOADED_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2            0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_CONTEXT_LOAD_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_CONTEXT_LOAD_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_CONTEXT_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_TASK_KICKED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_TASK_KICKED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_TASK_KICKED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_MEM_CLEARED_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_MEM_CLEARED_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_MEM_CLEARED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_FLUSHED_INV_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_FLUSHED_INV_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_FLUSHED_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_FLUSHED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_FLUSHED_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_LOADED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_LOADED_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2                0x0118
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SHIFT 15
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_VDM_CONTEXT_LOAD_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS2_VDM_CONTEXT_LOAD_SHIFT 14
+#define EUR_CR_EVENT_STATUS2_VDM_CONTEXT_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_VDM_TASK_KICKED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS2_VDM_TASK_KICKED_SHIFT 13
+#define EUR_CR_EVENT_STATUS2_VDM_TASK_KICKED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_OTPM_MEM_CLEARED_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS2_OTPM_MEM_CLEARED_SHIFT 12
+#define EUR_CR_EVENT_STATUS2_OTPM_MEM_CLEARED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_OTPM_FLUSHED_INV_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS2_OTPM_FLUSHED_INV_SHIFT 11
+#define EUR_CR_EVENT_STATUS2_OTPM_FLUSHED_INV_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SHIFT 10
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_GSG_FLUSHED_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS2_GSG_FLUSHED_SHIFT 9
+#define EUR_CR_EVENT_STATUS2_GSG_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_GSG_LOADED_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS2_GSG_LOADED_SHIFT 8
+#define EUR_CR_EVENT_STATUS2_GSG_LOADED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK   0x00000080U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT  7
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK   0x00000040U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT  6
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK   0x00000020U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT  5
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS                 0x012C
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TIMER_MASK      0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT     29
+#define EUR_CR_EVENT_STATUS_TIMER_SIGNED    0
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP2_ZLS_CSW_FINISHED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_ISP2_ZLS_CSW_FINISHED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK   0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT  20
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SIGNED 0
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK   0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT  14
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK  0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK  0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE            0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP2_ZLS_CSW_FINISHED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP2_ZLS_CSW_FINISHED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR             0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK  0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP2_ZLS_CSW_FINISHED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP2_ZLS_CSW_FINISHED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SIGNED 0
+#define EUR_CR_TIMER                        0x0144
+#define EUR_CR_TIMER_VALUE_MASK             0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT            0
+#define EUR_CR_TIMER_VALUE_SIGNED           0
+#define EUR_CR_USE_CODE_BASE_0              0x0A0C
+#define EUR_CR_USE_CODE_BASE_ADDR_00_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_00_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_00_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_00_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_1              0x0A10
+#define EUR_CR_USE_CODE_BASE_ADDR_01_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_01_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_01_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_01_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_2              0x0A14
+#define EUR_CR_USE_CODE_BASE_ADDR_02_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_02_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_02_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_02_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_3              0x0A18
+#define EUR_CR_USE_CODE_BASE_ADDR_03_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_03_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_03_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_03_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_4              0x0A1C
+#define EUR_CR_USE_CODE_BASE_ADDR_04_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_04_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_04_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_04_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_5              0x0A20
+#define EUR_CR_USE_CODE_BASE_ADDR_05_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_05_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_05_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_05_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_6              0x0A24
+#define EUR_CR_USE_CODE_BASE_ADDR_06_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_06_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_06_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_06_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_7              0x0A28
+#define EUR_CR_USE_CODE_BASE_ADDR_07_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_07_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_07_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_07_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_8              0x0A2C
+#define EUR_CR_USE_CODE_BASE_ADDR_08_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_08_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_08_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_08_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_9              0x0A30
+#define EUR_CR_USE_CODE_BASE_ADDR_09_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_09_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_09_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_09_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_10             0x0A34
+#define EUR_CR_USE_CODE_BASE_ADDR_10_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_10_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_10_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_10_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_11             0x0A38
+#define EUR_CR_USE_CODE_BASE_ADDR_11_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_11_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_11_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_11_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_12             0x0A3C
+#define EUR_CR_USE_CODE_BASE_ADDR_12_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_12_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_12_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_12_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_13             0x0A40
+#define EUR_CR_USE_CODE_BASE_ADDR_13_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_13_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_13_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_13_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_14             0x0A44
+#define EUR_CR_USE_CODE_BASE_ADDR_14_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_14_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_14_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_14_SIGNED   0
+#define EUR_CR_USE_CODE_BASE_15             0x0A48
+#define EUR_CR_USE_CODE_BASE_ADDR_15_MASK   0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SHIFT  0
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_15_MASK     0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_15_SHIFT    25
+#define EUR_CR_USE_CODE_BASE_DM_15_SIGNED   0
+#define EUR_CR_PDS_EXEC_BASE                0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK      0xFFF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT     20
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SIGNED    0
+#define EUR_CR_EVENT_KICKER                 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK    0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT   4
+#define EUR_CR_EVENT_KICKER_ADDRESS_SIGNED  0
+#define EUR_CR_EVENT_KICK                   0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK          0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT         0
+#define EUR_CR_EVENT_KICK_NOW_SIGNED        0
+#define EUR_CR_EVENT_TIMER                  0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK      0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT     24
+#define EUR_CR_EVENT_TIMER_ENABLE_SIGNED    0
+#define EUR_CR_EVENT_TIMER_VALUE_MASK       0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT      0
+#define EUR_CR_EVENT_TIMER_VALUE_SIGNED     0
+#define EUR_CR_PDS_INV0                     0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT           0
+#define EUR_CR_PDS_INV0_DSC_SIGNED          0
+#define EUR_CR_PDS_INV1                     0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT           0
+#define EUR_CR_PDS_INV1_DSC_SIGNED          0
+#define EUR_CR_PDS_INV3                     0x0AD8
+#define EUR_CR_PDS_INV3_DSC_MASK            0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT           0
+#define EUR_CR_PDS_INV3_DSC_SIGNED          0
+#define EUR_CR_PDS_INV_CSC                  0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK        0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT       0
+#define EUR_CR_PDS_INV_CSC_KICK_SIGNED      0
+#define EUR_CR_EVENT_KICK1                  0x0AE4
+#define EUR_CR_EVENT_KICK1_NOW_MASK         0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICK1_NOW_SIGNED       0
+#define EUR_CR_EVENT_KICK2                  0x0AE8
+#define EUR_CR_EVENT_KICK2_NOW_MASK         0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICK2_NOW_SIGNED       0
+#define EUR_CR_EVENT_KICK3                  0x0AEC
+#define EUR_CR_EVENT_KICK3_NOW_MASK         0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT        0
+#define EUR_CR_EVENT_KICK3_NOW_SIGNED       0
+#define EUR_CR_BIF_CTRL                     0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK      0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT     0
+#define EUR_CR_BIF_CTRL_NOREORDER_SIGNED    0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK          0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT         1
+#define EUR_CR_BIF_CTRL_PAUSE_SIGNED        0
+#define EUR_CR_BIF_CTRL_FLUSH_MASK          0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT         2
+#define EUR_CR_BIF_CTRL_FLUSH_SIGNED        0
+#define EUR_CR_BIF_CTRL_INVALDC_MASK        0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT       3
+#define EUR_CR_BIF_CTRL_INVALDC_SIGNED      0
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK    0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT   4
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SIGNED  0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK  0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00000800U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 11
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_SIGNED 0
+#define EUR_CR_BIF_INT_STAT                 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK  0x0000FFFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_MASK 0x00070000U
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SHIFT 16
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00080000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 19
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SIGNED 0
+#define EUR_CR_BIF_FAULT                    0x0C08
+#define EUR_CR_BIF_FAULT_CID_MASK           0x0000000FU
+#define EUR_CR_BIF_FAULT_CID_SHIFT          0
+#define EUR_CR_BIF_FAULT_CID_SIGNED         0
+#define EUR_CR_BIF_FAULT_SB_MASK            0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT           4
+#define EUR_CR_BIF_FAULT_SB_SIGNED          0
+#define EUR_CR_BIF_FAULT_ADDR_MASK          0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT         12
+#define EUR_CR_BIF_FAULT_ADDR_SIGNED        0
+#define EUR_CR_BIF_TILE0                    0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE0_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE1                    0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE1_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE2                    0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE2_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE3                    0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE3_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE4                    0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE4_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE5                    0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE5_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE6                    0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE6_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE7                    0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE7_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE8                    0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE8_CFG_SIGNED         0
+#define EUR_CR_BIF_TILE9                    0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK   0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT  0
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK   0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT  12
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_CFG_MASK           0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT          24
+#define EUR_CR_BIF_TILE9_CFG_SIGNED         0
+#define EUR_CR_BIF_DIR_LIST_BASE1           0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE2           0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE3           0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE4           0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE5           0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE6           0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE7           0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE8           0x0C54
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE9           0x0C58
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE10          0x0C5C
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE11          0x0C60
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE12          0x0C64
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE13          0x0C68
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE14          0x0C6C
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_SIGNED 0
+#define EUR_CR_BIF_DIR_LIST_BASE15          0x0C70
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_SIGNED 0
+#define EUR_CR_BIF_BANK_SET                 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_MASK  0x00000001U
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SHIFT 0
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_MASK  0x0000000CU
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SHIFT 2
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_MASK 0x00000010U
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SHIFT 4
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_MASK  0x000000C0U
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SHIFT 6
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_MASK 0x00000100U
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SHIFT 8
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_MASK 0x00000200U
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SHIFT 9
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SIGNED 0
+#define EUR_CR_BIF_BANK0                    0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK     0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT    0
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SIGNED   0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK      0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT     4
+#define EUR_CR_BIF_BANK0_INDEX_TA_SIGNED    0
+#define EUR_CR_BIF_BANK0_INDEX_HOST_MASK    0x00000F00U
+#define EUR_CR_BIF_BANK0_INDEX_HOST_SHIFT   8
+#define EUR_CR_BIF_BANK0_INDEX_HOST_SIGNED  0
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK      0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT     12
+#define EUR_CR_BIF_BANK0_INDEX_3D_SIGNED    0
+#define EUR_CR_BIF_BANK0_INDEX_2D_MASK      0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_2D_SHIFT     16
+#define EUR_CR_BIF_BANK0_INDEX_2D_SIGNED    0
+#define EUR_CR_BIF_BANK1                    0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK     0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT    0
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SIGNED   0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK      0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT     4
+#define EUR_CR_BIF_BANK1_INDEX_TA_SIGNED    0
+#define EUR_CR_BIF_BANK1_INDEX_HOST_MASK    0x00000F00U
+#define EUR_CR_BIF_BANK1_INDEX_HOST_SHIFT   8
+#define EUR_CR_BIF_BANK1_INDEX_HOST_SIGNED  0
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK      0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT     12
+#define EUR_CR_BIF_BANK1_INDEX_3D_SIGNED    0
+#define EUR_CR_BIF_BANK1_INDEX_2D_MASK      0x000F0000U
+#define EUR_CR_BIF_BANK1_INDEX_2D_SHIFT     16
+#define EUR_CR_BIF_BANK1_INDEX_2D_SIGNED    0
+#define EUR_CR_BIF_DIR_LIST_BASE0           0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SIGNED 0
+#define EUR_CR_BIF_TA_REQ_BASE              0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK    0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SIGNED  0
+#define EUR_CR_BIF_MEM_REQ_STAT             0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK  0x000007FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SIGNED 0
+#define EUR_CR_BIF_3D_REQ_BASE              0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK    0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT   20
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SIGNED  0
+#define EUR_CR_BIF_ZLS_REQ_BASE             0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK   0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT  20
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS              0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_36BIT_ADDRESSING         0x0CCC
+#define EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK 0x00000001U
+#define EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_SHIFT 0
+#define EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_SIGNED 0
+#define EUR_CR_BIF_TILE0_ADDR_EXT           0x0CD0
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_TILE1_ADDR_EXT           0x0CD4
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_TILE2_ADDR_EXT           0x0CD8
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_TILE3_ADDR_EXT           0x0CDC
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_TILE4_ADDR_EXT           0x0CE0
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_TILE5_ADDR_EXT           0x0CE4
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_TILE6_ADDR_EXT           0x0CE8
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_TILE7_ADDR_EXT           0x0CEC
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_TILE8_ADDR_EXT           0x0CF0
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_TILE9_ADDR_EXT           0x0CF4
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MIN_MASK  0x000000FFU
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MAX_MASK  0x0000FF00U
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MAX_SIGNED 0
+#define EUR_CR_BIF_CTRL_RDATA               0x0CF8
+#define EUR_CR_BIF_CTRL_RDATA_LIMIT_MASK    0x000003FFU
+#define EUR_CR_BIF_CTRL_RDATA_LIMIT_SHIFT   0
+#define EUR_CR_BIF_CTRL_RDATA_LIMIT_SIGNED  0
+#define EUR_CR_USE_CODE_BASE(X)     (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK      0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT     0
+#define EUR_CR_USE_CODE_BASE_ADDR_SIGNED    0
+#define EUR_CR_USE_CODE_BASE_DM_MASK        0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT       25
+#define EUR_CR_USE_CODE_BASE_DM_SIGNED      0
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxdefs.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxdefs.h
new file mode 100644
index 0000000..b3a2583
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxdefs.h
@@ -0,0 +1,90 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SGXDEFS_H_
+#define	_SGXDEFS_H_
+
+#include "sgxerrata.h"
+#include "sgxfeaturedefs.h"
+
+#if defined(SGX520)
+#include "sgx520defs.h"
+#else
+#if defined(SGX530)
+#include "sgx530defs.h"
+#else
+#if defined(SGX535)
+#include "sgx535defs.h"
+#else
+#if defined(SGX535_V1_1)
+#include "sgx535defs.h"
+#else
+#if defined(SGX540)
+#include "sgx540defs.h"
+#else
+#if defined(SGX543)
+#if defined(FIX_HW_BRN_29954)
+#include "sgx543_v1.164defs.h"
+#else
+#include "sgx543defs.h"
+#endif
+#else
+#if defined(SGX544)
+#include "sgx544defs.h"
+#else
+#if defined(SGX545)
+#include "sgx545defs.h"
+#else
+#if defined(SGX531)
+#include "sgx531defs.h"
+#else
+#if defined(SGX554)
+#include "sgx554defs.h"
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX554)
+#include "sgxmpplusdefs.h"
+#else
+#include "sgxmpdefs.h"
+#endif 
+#else 
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+#include "mnemedefs.h"
+#endif
+#endif 
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxerrata.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxerrata.h
new file mode 100644
index 0000000..b698acc
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxerrata.h
@@ -0,0 +1,694 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SGXERRATA_KM_H_
+#define _SGXERRATA_KM_H_
+
+#if defined(SGX520) && !defined(SGX_CORE_DEFINED)
+	
+	#define SGX_CORE_REV_HEAD	0
+	#if defined(USE_SGX_CORE_REV_HEAD)
+		
+		#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+	#endif
+
+	#if SGX_CORE_REV == 100
+		#define FIX_HW_BRN_28889
+	#else
+	#if SGX_CORE_REV == 111
+		#define FIX_HW_BRN_28889
+	#else
+	#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+		
+	#else
+		#error "sgxerrata.h: SGX520 Core Revision unspecified"
+	#endif
+	#endif
+	#endif
+	
+	#define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX530) && !defined(SGX_CORE_DEFINED)
+	
+	#define SGX_CORE_REV_HEAD	0
+	#if defined(USE_SGX_CORE_REV_HEAD)
+		
+		#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+	#endif
+
+	#if SGX_CORE_REV == 110
+		#define FIX_HW_BRN_22934
+		#define FIX_HW_BRN_28889
+	#else
+	#if SGX_CORE_REV == 111
+		#define FIX_HW_BRN_22934	
+		#define FIX_HW_BRN_28889
+	#else
+	#if SGX_CORE_REV == 1111
+		#define FIX_HW_BRN_22934	
+		#define FIX_HW_BRN_28889
+	#else
+	#if SGX_CORE_REV == 120
+		#define FIX_HW_BRN_22934	
+		#define FIX_HW_BRN_28889
+	#else
+	#if SGX_CORE_REV == 121
+		#define FIX_HW_BRN_22934	
+		#define FIX_HW_BRN_28889
+	#else
+	#if SGX_CORE_REV == 125
+		#define FIX_HW_BRN_22934	
+		#define FIX_HW_BRN_28889
+	#else
+	#if SGX_CORE_REV == 130
+		#define FIX_HW_BRN_22934	
+		#define FIX_HW_BRN_28889
+	#else
+	#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+		
+	#else
+		#error "sgxerrata.h: SGX530 Core Revision unspecified"
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+#endif
+        #endif
+	
+	#define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX531) && !defined(SGX_CORE_DEFINED)
+	
+	#define SGX_CORE_REV_HEAD	0
+	#if defined(USE_SGX_CORE_REV_HEAD)
+		
+		#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+	#endif
+
+	#if SGX_CORE_REV == 101
+		#define FIX_HW_BRN_26620
+		#define FIX_HW_BRN_28011
+		#define FIX_HW_BRN_34028
+	#else
+	#if SGX_CORE_REV == 110
+		#define FIX_HW_BRN_34028
+	#else
+	#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+		
+	#else
+		#error "sgxerrata.h: SGX531 Core Revision unspecified"
+	#endif
+	#endif
+	#endif
+	
+	#define SGX_CORE_DEFINED
+#endif
+
+#if (defined(SGX535) || defined(SGX535_V1_1)) && !defined(SGX_CORE_DEFINED)
+	
+	#define SGX_CORE_REV_HEAD	0
+	#if defined(USE_SGX_CORE_REV_HEAD)
+		
+		#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+	#endif
+
+	#if SGX_CORE_REV == 112
+		#define FIX_HW_BRN_23281
+		#define FIX_HW_BRN_23410 
+		#define FIX_HW_BRN_22693
+		#define FIX_HW_BRN_22934	
+		#define FIX_HW_BRN_22997
+		#define FIX_HW_BRN_23030
+	#else
+	#if SGX_CORE_REV == 113
+		#define FIX_HW_BRN_22934	
+		#define FIX_HW_BRN_23281
+		#define FIX_HW_BRN_23944
+		#define FIX_HW_BRN_23410
+	#else
+	#if SGX_CORE_REV == 121
+		#define FIX_HW_BRN_22934	
+		#define FIX_HW_BRN_23944
+		#define FIX_HW_BRN_23410
+	#else
+	#if SGX_CORE_REV == 126
+		#define FIX_HW_BRN_22934	
+	#else	
+	#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+		
+	#else
+		#error "sgxerrata.h: SGX535 Core Revision unspecified"
+
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	
+	#define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX540) && !defined(SGX_CORE_DEFINED)
+	
+	#define SGX_CORE_REV_HEAD	0
+	#if defined(USE_SGX_CORE_REV_HEAD)
+		
+		#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+	#endif
+
+	#if SGX_CORE_REV == 101
+		#define FIX_HW_BRN_25499
+		#define FIX_HW_BRN_25503
+		#define FIX_HW_BRN_26620
+		#define FIX_HW_BRN_28011
+		#define FIX_HW_BRN_34028
+	#else
+	#if SGX_CORE_REV == 110
+		#define FIX_HW_BRN_25503
+		#define FIX_HW_BRN_26620
+		#define FIX_HW_BRN_28011
+		#define FIX_HW_BRN_34028
+	#else
+	#if SGX_CORE_REV == 120
+		#define FIX_HW_BRN_26620
+		#define FIX_HW_BRN_28011
+		#define FIX_HW_BRN_34028
+	#else
+	#if SGX_CORE_REV == 121
+		#define FIX_HW_BRN_28011
+		#define FIX_HW_BRN_34028
+	#else
+	#if SGX_CORE_REV == 130
+		#define FIX_HW_BRN_34028
+	#else
+	#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+		
+	#else
+		#error "sgxerrata.h: SGX540 Core Revision unspecified"
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	
+	#define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX541) && !defined(SGX_CORE_DEFINED)
+	#if defined(SGX_FEATURE_MP)
+		
+		#define SGX_CORE_REV_HEAD	0
+		#if defined(USE_SGX_CORE_REV_HEAD)
+			
+			#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+		#endif
+
+		#if SGX_CORE_REV == 100
+			#define FIX_HW_BRN_27270
+			#define FIX_HW_BRN_28011
+			#define FIX_HW_BRN_27510
+			
+		#else
+		#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+			
+		#else
+			#error "sgxerrata.h: SGX541 Core Revision unspecified"
+		#endif
+		#endif
+		
+		#define SGX_CORE_DEFINED
+	#else 
+		#error "sgxerrata.h: SGX541 only supports MP configs (SGX_FEATURE_MP)"
+	#endif 
+#endif
+
+#if defined(SGX543) && !defined(SGX_CORE_DEFINED)
+	
+	#define SGX_CORE_REV_HEAD	0
+	#if defined(USE_SGX_CORE_REV_HEAD)
+		
+		#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+	#endif
+
+	#if SGX_CORE_REV == 113
+		#define FIX_HW_BRN_29954
+		#define FIX_HW_BRN_29997
+		#define FIX_HW_BRN_30954
+		#define FIX_HW_BRN_31093
+		#define FIX_HW_BRN_31195
+		#define FIX_HW_BRN_31272
+		#define FIX_HW_BRN_31278
+ 		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31620
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_31542
+		#define FIX_HW_BRN_32044 
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+	#else
+	#if SGX_CORE_REV == 122
+		#define FIX_HW_BRN_29954
+		#define FIX_HW_BRN_29997
+		#define FIX_HW_BRN_30954
+		#define FIX_HW_BRN_31093
+		#define FIX_HW_BRN_31195
+		#define FIX_HW_BRN_31272
+		#define FIX_HW_BRN_31278
+ 		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31620
+		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_31542
+		#define FIX_HW_BRN_32044 
+		#define FIX_HW_BRN_32085 
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+			
+	#else
+	#if SGX_CORE_REV == 1221
+		#define FIX_HW_BRN_29954
+        #define FIX_HW_BRN_31195
+		#define FIX_HW_BRN_31272
+		#define FIX_HW_BRN_31278
+ 		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31542
+		#define FIX_HW_BRN_31671		
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_32044
+		#define FIX_HW_BRN_32085 
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+			
+	#else
+	#if SGX_CORE_REV == 140
+		#define FIX_HW_BRN_29954
+		#define FIX_HW_BRN_30954
+		#define FIX_HW_BRN_31093
+		#define FIX_HW_BRN_31195
+		#define FIX_HW_BRN_31272
+		#define FIX_HW_BRN_31278
+ 		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31620
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_31542
+		#define FIX_HW_BRN_32044 
+		#define FIX_HW_BRN_32085 
+		#define FIX_HW_BRN_33920
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+			
+	#else
+	#if SGX_CORE_REV == 1401
+		#define FIX_HW_BRN_29954
+		#define FIX_HW_BRN_30954
+		#define FIX_HW_BRN_31195
+		#define FIX_HW_BRN_31272
+		#define FIX_HW_BRN_31278
+ 		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31620
+		#define FIX_HW_BRN_31542
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_32044 
+		#define FIX_HW_BRN_32085 
+		#define FIX_HW_BRN_33920
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+			
+	#else
+	#if SGX_CORE_REV == 141
+		#define FIX_HW_BRN_29954
+ 		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31671 
+ 		#define FIX_HW_BRN_31780
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+			
+	#else
+	#if SGX_CORE_REV == 142
+		#define FIX_HW_BRN_29954
+ 		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31671 
+ 		#define FIX_HW_BRN_31780
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+			
+	#else
+	#if SGX_CORE_REV == 211
+		#define FIX_HW_BRN_31093
+		#define FIX_HW_BRN_31195
+		#define FIX_HW_BRN_31272
+		#define FIX_HW_BRN_31278
+ 		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31620
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_31542
+		#define FIX_HW_BRN_32044 
+		#define FIX_HW_BRN_32085 
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+			
+	#else
+	#if SGX_CORE_REV == 2111
+		#define FIX_HW_BRN_30982 
+		#define FIX_HW_BRN_31093
+		#define FIX_HW_BRN_31195
+		#define FIX_HW_BRN_31272
+		#define FIX_HW_BRN_31278
+ 		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31620
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_31542
+		#define FIX_HW_BRN_32044 
+		#define FIX_HW_BRN_32085 
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+			
+	#else
+	#if SGX_CORE_REV == 213
+		#define FIX_HW_BRN_31272
+		#if defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_31425
+		#endif
+		#define FIX_HW_BRN_31671 
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_32085 
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+			
+	#else
+	#if SGX_CORE_REV == 216
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+	#else
+	#if SGX_CORE_REV == 302
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+	#else
+	#if SGX_CORE_REV == 303
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+	#else
+	#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+	#else
+		#error "sgxerrata.h: SGX543 Core Revision unspecified"
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	
+	#define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX544) && !defined(SGX_CORE_DEFINED)
+	
+	#define SGX_CORE_REV_HEAD	0
+	#if defined(USE_SGX_CORE_REV_HEAD)
+		
+		#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+	#endif
+
+	#if SGX_CORE_REV == 100
+ 		#if defined(SGX_FEATURE_MP)
+ 			#define FIX_HW_BRN_31425
+ 		#endif
+	#else
+	#if SGX_CORE_REV == 102
+		#define FIX_HW_BRN_29954
+		#define FIX_HW_BRN_31272
+ 		#if defined(SGX_FEATURE_MP)
+ 			#define FIX_HW_BRN_31425
+ 		#endif
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_32085 
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+	#else
+	#if SGX_CORE_REV == 103
+		#define FIX_HW_BRN_29954
+		#define FIX_HW_BRN_31272
+ 		#if defined(SGX_FEATURE_MP)
+ 			#define FIX_HW_BRN_31425
+ 		#endif
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_32085 
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+	#else
+	#if SGX_CORE_REV == 104
+		#define FIX_HW_BRN_29954
+		#define FIX_HW_BRN_31093
+		#define FIX_HW_BRN_31195
+		#define FIX_HW_BRN_31272
+		#define FIX_HW_BRN_31278
+ 		#if defined(SGX_FEATURE_MP)
+ 			#define FIX_HW_BRN_31425
+ 		#endif
+		#define FIX_HW_BRN_31542 
+ 		#define FIX_HW_BRN_31620
+		#define FIX_HW_BRN_31671 
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_32044 
+		#define FIX_HW_BRN_32085 
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+	#else	
+	#if SGX_CORE_REV == 105
+ 		#if defined(SGX_FEATURE_MP)
+ 			#define FIX_HW_BRN_31425
+ 		#endif
+ 		#define FIX_HW_BRN_31780
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+	#else
+	#if SGX_CORE_REV == 106
+		#define FIX_HW_BRN_31272
+ 		#define FIX_HW_BRN_31780
+		#define FIX_HW_BRN_33920
+	#else
+	#if SGX_CORE_REV == 110
+		#define FIX_HW_BRN_31272
+ 		#if defined(SGX_FEATURE_MP)
+ 			#define FIX_HW_BRN_31425
+ 		#endif
+ 		#define FIX_HW_BRN_31780
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		#define FIX_HW_BRN_33920
+	#else
+	#if SGX_CORE_REV == 112
+		#define FIX_HW_BRN_31272
+		#define FIX_HW_BRN_33920
+	#else
+	#if SGX_CORE_REV == 114
+ 		#if defined(SGX_FEATURE_MP)
+ 			#define FIX_HW_BRN_31425
+ 		#endif
+ 		#define FIX_HW_BRN_31780
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+	#else
+	#if SGX_CORE_REV == 115
+ 		#if defined(SGX_FEATURE_MP)
+ 			#define FIX_HW_BRN_31425
+ 		#endif
+ 		#define FIX_HW_BRN_31780
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+	#else
+	#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+	#else
+		#error "sgxerrata.h: SGX544 Core Revision unspecified"
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	
+	#define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX545) && !defined(SGX_CORE_DEFINED)
+	
+	#define SGX_CORE_REV_HEAD	0
+	#if defined(USE_SGX_CORE_REV_HEAD)
+		
+		#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+	#endif
+
+	#if SGX_CORE_REV == 100
+		#define FIX_HW_BRN_26620
+		#define FIX_HW_BRN_27266
+		#define FIX_HW_BRN_27456
+		#define FIX_HW_BRN_29702
+		#define FIX_HW_BRN_29823
+	#else
+	#if SGX_CORE_REV == 109
+		#define FIX_HW_BRN_29702
+		#define FIX_HW_BRN_29823
+		#define FIX_HW_BRN_31939
+	#else
+	#if SGX_CORE_REV == 1012
+		#define FIX_HW_BRN_31939
+	#else
+	#if SGX_CORE_REV == 1013
+		#define FIX_HW_BRN_31939
+		#define FIX_HW_BRN_SAMPLE_CACHE
+	#else
+	#if SGX_CORE_REV == 10131
+		#define FIX_HW_BRN_SAMPLE_CACHE
+	#else
+	#if SGX_CORE_REV == 1014
+		#define FIX_HW_BRN_SAMPLE_CACHE
+	#else
+	#if SGX_CORE_REV == 10141
+		#define FIX_HW_BRN_SAMPLE_CACHE
+	#else
+	#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+		
+	#else
+		#error "sgxerrata.h: SGX545 Core Revision unspecified"
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	#endif
+	
+	#define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX554) && !defined(SGX_CORE_DEFINED)
+	
+	#define SGX_CORE_REV_HEAD	0
+	#if defined(USE_SGX_CORE_REV_HEAD)
+		
+		#define SGX_CORE_REV	SGX_CORE_REV_HEAD
+	#endif
+
+	#if SGX_CORE_REV == 1251
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+		
+	#else	
+	#if SGX_CORE_REV == SGX_CORE_REV_HEAD
+		#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+			#define FIX_HW_BRN_33657
+		#endif
+	#else
+		#error "sgxerrata.h: SGX554 Core Revision unspecified"
+	#endif
+	#endif
+	
+	#define SGX_CORE_DEFINED
+#endif
+
+#if !defined(SGX_CORE_DEFINED)
+#if defined (__GNUC__)
+	#warning "sgxerrata.h: SGX Core Version unspecified"
+#else
+	#pragma message("sgxerrata.h: SGX Core Version unspecified")
+#endif
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h
new file mode 100644
index 0000000..6427e7e
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h
@@ -0,0 +1,247 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#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_NUM_USE_PIPES						(1)
+	#define SGX_FEATURE_AUTOCLOCKGATING
+#else
+#if defined(SGX530)
+	#define SGX_CORE_FRIENDLY_NAME							"SGX530"
+	#define SGX_CORE_ID										SGX_CORE_ID_530
+	#define SGX_FEATURE_ADDRESS_SPACE_SIZE					(28)
+	#define SGX_FEATURE_NUM_USE_PIPES						(2)
+	#define SGX_FEATURE_AUTOCLOCKGATING
+#else
+#if defined(SGX531)
+	#define SGX_CORE_FRIENDLY_NAME							"SGX531"
+	#define SGX_CORE_ID										SGX_CORE_ID_531
+	#define SGX_FEATURE_ADDRESS_SPACE_SIZE					(28)
+	#define SGX_FEATURE_NUM_USE_PIPES						(2)
+	#define SGX_FEATURE_AUTOCLOCKGATING
+	#define SGX_FEATURE_MULTI_EVENT_KICK
+#else
+#if defined(SGX535)
+	#define SGX_CORE_FRIENDLY_NAME							"SGX535"
+	#define SGX_CORE_ID										SGX_CORE_ID_535
+	#define SGX_FEATURE_ADDRESS_SPACE_SIZE					(32)
+	#define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+	#define SGX_FEATURE_BIF_NUM_DIRLISTS					(16)
+	#define SGX_FEATURE_2D_HARDWARE
+	#define SGX_FEATURE_NUM_USE_PIPES						(2)
+	#define SGX_FEATURE_AUTOCLOCKGATING
+	#define SUPPORT_SGX_GENERAL_MAPPING_HEAP
+	#define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+#else
+#if defined(SGX540)
+	#define SGX_CORE_FRIENDLY_NAME							"SGX540"
+	#define SGX_CORE_ID										SGX_CORE_ID_540
+	#define SGX_FEATURE_ADDRESS_SPACE_SIZE					(28)
+	#define SGX_FEATURE_NUM_USE_PIPES						(4)
+	#define SGX_FEATURE_AUTOCLOCKGATING
+	#define SGX_FEATURE_MULTI_EVENT_KICK
+#else
+#if defined(SGX543)
+	#define SGX_CORE_FRIENDLY_NAME							"SGX543"
+	#define SGX_CORE_ID										SGX_CORE_ID_543
+	#define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
+	#define SGX_FEATURE_USE_UNLIMITED_PHASES
+	#define SGX_FEATURE_ADDRESS_SPACE_SIZE					(32)
+	#define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+	#define SGX_FEATURE_BIF_NUM_DIRLISTS					(8)
+	#define SGX_FEATURE_NUM_USE_PIPES						(4)
+	#define SGX_FEATURE_AUTOCLOCKGATING
+	#define SGX_FEATURE_MONOLITHIC_UKERNEL
+	#define SGX_FEATURE_MULTI_EVENT_KICK
+	#define SGX_FEATURE_DATA_BREAKPOINTS
+    #define SGX_FEATURE_PERPIPE_BKPT_REGS
+    #define SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES          (2)
+	#define SGX_FEATURE_2D_HARDWARE
+	#define SGX_FEATURE_PTLA
+	#define SGX_FEATURE_EXTENDED_PERF_COUNTERS
+	#define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+	#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+		#if defined(SGX_FEATURE_MP)
+		#define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH
+		#endif
+		#define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH
+		#define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+	#endif
+#else
+#if defined(SGX544)
+	#define SGX_CORE_FRIENDLY_NAME							"SGX544"
+	#define SGX_CORE_ID										SGX_CORE_ID_544
+	#define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
+	#define SGX_FEATURE_USE_UNLIMITED_PHASES
+	#define SGX_FEATURE_ADDRESS_SPACE_SIZE					(32)
+	#define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+	#define SGX_FEATURE_BIF_NUM_DIRLISTS					(8)
+	#define SGX_FEATURE_NUM_USE_PIPES						(4)
+	#define SGX_FEATURE_AUTOCLOCKGATING
+	#define SGX_FEATURE_MONOLITHIC_UKERNEL
+	#define SGX_FEATURE_MULTI_EVENT_KICK
+	#define SGX_FEATURE_EXTENDED_PERF_COUNTERS
+	#define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+	#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+		#if defined(SGX_FEATURE_MP)
+		#define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH
+		#endif
+		#define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH
+		#define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+	#endif
+#else
+#if defined(SGX545)
+	#define SGX_CORE_FRIENDLY_NAME							"SGX545"
+	#define SGX_CORE_ID										SGX_CORE_ID_545
+	#define SGX_FEATURE_ADDRESS_SPACE_SIZE					(32)
+	#define SGX_FEATURE_AUTOCLOCKGATING
+	#define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
+	#define SGX_FEATURE_USE_UNLIMITED_PHASES
+	#define SGX_FEATURE_VOLUME_TEXTURES
+	#define SGX_FEATURE_HOST_ALLOC_FROM_DPM
+	#define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+	#define SGX_FEATURE_BIF_NUM_DIRLISTS				(16)
+	#define SGX_FEATURE_NUM_USE_PIPES					(4)
+	#define	SGX_FEATURE_TEXTURESTRIDE_EXTENSION
+	#define SGX_FEATURE_PDS_DATA_INTERLEAVE_2DWORDS
+	#define SGX_FEATURE_MONOLITHIC_UKERNEL
+	#define SGX_FEATURE_ZLS_EXTERNALZ
+	#define SGX_FEATURE_NUM_PDS_PIPES					(2)
+	#define SGX_FEATURE_NATIVE_BACKWARD_BLIT
+	#define SGX_FEATURE_MAX_TA_RENDER_TARGETS				(512)
+	#define SGX_FEATURE_SECONDARY_REQUIRES_USE_KICK
+	#define SGX_FEATURE_WRITEBACK_DCU
+	
+	
+	#define SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS
+	#define SGX_FEATURE_MULTI_EVENT_KICK
+	#define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+	#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+		#define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+	#endif
+#else
+#if defined(SGX554)
+	#define SGX_CORE_FRIENDLY_NAME							"SGX554"
+	#define SGX_CORE_ID										SGX_CORE_ID_554
+	#define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
+	#define SGX_FEATURE_USE_UNLIMITED_PHASES
+	#define SGX_FEATURE_ADDRESS_SPACE_SIZE					(32)
+	#define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+	#define SGX_FEATURE_BIF_NUM_DIRLISTS					(8)
+	#define SGX_FEATURE_NUM_USE_PIPES						(8)
+	#define SGX_FEATURE_AUTOCLOCKGATING
+	#define SGX_FEATURE_MONOLITHIC_UKERNEL
+	#define SGX_FEATURE_MULTI_EVENT_KICK
+	#define SGX_FEATURE_2D_HARDWARE
+	#define SGX_FEATURE_PTLA
+	#define SGX_FEATURE_EXTENDED_PERF_COUNTERS
+	#define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+	#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+		#if defined(SGX_FEATURE_MP)
+		#define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH
+		#endif
+		#define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH
+		#define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+	#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if defined(SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH) \
+	|| defined(SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH)
+#define SGX_FEATURE_VDM_CONTEXT_SWITCH
+#endif
+
+#if defined(FIX_HW_BRN_22693)
+#undef SGX_FEATURE_AUTOCLOCKGATING
+#endif
+
+#if defined(FIX_HW_BRN_27266)
+#undef SGX_FEATURE_36BIT_MMU
+#endif
+
+#if defined(FIX_HW_BRN_27456)
+#undef SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS
+#endif
+
+#if defined(FIX_HW_BRN_22934)	\
+	|| defined(FIX_HW_BRN_25499)
+#undef SGX_FEATURE_MULTI_EVENT_KICK
+#endif
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+	#if defined(SGX_FEATURE_36BIT_MMU)
+		#error SGX_FEATURE_SYSTEM_CACHE is incompatible with SGX_FEATURE_36BIT_MMU
+	#endif
+	#if defined(FIX_HW_BRN_26620) && !defined(SGX_FEATURE_MULTI_EVENT_KICK)
+		#define SGX_BYPASS_SYSTEM_CACHE
+	#endif
+#endif
+
+#if defined(FIX_HW_BRN_29954)
+#undef SGX_FEATURE_PERPIPE_BKPT_REGS
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+#undef SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+#undef SGX_FEATURE_BIF_NUM_DIRLISTS
+#endif
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_MP_CORE_COUNT_TA) && defined(SGX_FEATURE_MP_CORE_COUNT_3D)
+#if (SGX_FEATURE_MP_CORE_COUNT_TA > SGX_FEATURE_MP_CORE_COUNT_3D)
+#error Number of TA cores larger than number of 3D cores not supported in current driver
+#endif 
+#else
+#if defined(SGX_FEATURE_MP_CORE_COUNT)
+#define SGX_FEATURE_MP_CORE_COUNT_TA		(SGX_FEATURE_MP_CORE_COUNT)
+#define SGX_FEATURE_MP_CORE_COUNT_3D		(SGX_FEATURE_MP_CORE_COUNT)
+#else
+#error Either SGX_FEATURE_MP_CORE_COUNT or \
+both SGX_FEATURE_MP_CORE_COUNT_TA and SGX_FEATURE_MP_CORE_COUNT_3D \
+must be defined when SGX_FEATURE_MP is defined
+#endif 
+#endif 
+#else
+#define SGX_FEATURE_MP_CORE_COUNT		(1)
+#define SGX_FEATURE_MP_CORE_COUNT_TA	(1)
+#define SGX_FEATURE_MP_CORE_COUNT_3D	(1)
+#endif 
+
+#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && !defined(SUPPORT_SGX_PRIORITY_SCHEDULING)
+#define SUPPORT_SGX_PRIORITY_SCHEDULING
+#endif
+
+#include "img_types.h"
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxmmu.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxmmu.h
new file mode 100644
index 0000000..1b265f1
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxmmu.h
@@ -0,0 +1,72 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined(__SGXMMU_KM_H__)
+#define __SGXMMU_KM_H__
+
+#define SGX_MMU_PAGE_SHIFT				(12)
+#define SGX_MMU_PAGE_SIZE				(1U<<SGX_MMU_PAGE_SHIFT)
+#define SGX_MMU_PAGE_MASK				(SGX_MMU_PAGE_SIZE - 1U)
+
+#define SGX_MMU_PD_SHIFT				(10)
+#define SGX_MMU_PD_SIZE					(1U<<SGX_MMU_PD_SHIFT)
+#define SGX_MMU_PD_MASK					(0xFFC00000U)
+
+#if defined(SGX_FEATURE_36BIT_MMU)
+	#define SGX_MMU_PDE_ADDR_MASK			(0xFFFFFF00U)
+	#define SGX_MMU_PDE_ADDR_ALIGNSHIFT		(4)
+#else
+	#define SGX_MMU_PDE_ADDR_MASK			(0xFFFFF000U)
+	#define SGX_MMU_PDE_ADDR_ALIGNSHIFT		(0)
+#endif
+#define SGX_MMU_PDE_VALID				(0x00000001U)
+#define SGX_MMU_PDE_PAGE_SIZE_4K		(0x00000000U)
+#define SGX_MMU_PDE_PAGE_SIZE_16K		(0x00000002U)
+#define SGX_MMU_PDE_PAGE_SIZE_64K		(0x00000004U)
+#define SGX_MMU_PDE_PAGE_SIZE_256K		(0x00000006U)
+#define SGX_MMU_PDE_PAGE_SIZE_1M		(0x00000008U)
+#define SGX_MMU_PDE_PAGE_SIZE_4M		(0x0000000AU)
+#define SGX_MMU_PDE_PAGE_SIZE_MASK		(0x0000000EU)
+
+#define SGX_MMU_PT_SHIFT				(10)
+#define SGX_MMU_PT_SIZE					(1U<<SGX_MMU_PT_SHIFT)
+#define SGX_MMU_PT_MASK					(0x003FF000U)
+
+#if defined(SGX_FEATURE_36BIT_MMU)
+	#define SGX_MMU_PTE_ADDR_MASK			(0xFFFFFF00U)
+	#define SGX_MMU_PTE_ADDR_ALIGNSHIFT		(4)
+#else
+	#define SGX_MMU_PTE_ADDR_MASK			(0xFFFFF000U)
+	#define SGX_MMU_PTE_ADDR_ALIGNSHIFT		(0)
+#endif
+#define SGX_MMU_PTE_VALID				(0x00000001U)
+#define SGX_MMU_PTE_WRITEONLY			(0x00000002U)
+#define SGX_MMU_PTE_READONLY			(0x00000004U)
+#define SGX_MMU_PTE_CACHECONSISTENT		(0x00000008U)
+#define SGX_MMU_PTE_EDMPROTECT			(0x00000010U)
+
+#endif	
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxmpdefs.h b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxmpdefs.h
new file mode 100755
index 0000000..e34561a
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/hwdefs/sgxmpdefs.h
@@ -0,0 +1,332 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SGXMPDEFS_H_
+#define _SGXMPDEFS_H_
+
+#define EUR_CR_MASTER_BIF_CTRL              0x4C00
+#define EUR_CR_MASTER_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_MASTER_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_MASTER_BIF_CTRL_NOREORDER_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_PAUSE_MASK   0x00000002U
+#define EUR_CR_MASTER_BIF_CTRL_PAUSE_SHIFT  1
+#define EUR_CR_MASTER_BIF_CTRL_PAUSE_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_MASTER_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_MASTER_BIF_CTRL_CLEAR_FAULT_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_PTLA_MASK 0x00010000U
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_PTLA_SHIFT 16
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_PTLA_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_VDM_MASK 0x00020000U
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SHIFT 17
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_IPF_MASK 0x00040000U
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SHIFT 18
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_DPM_MASK 0x00080000U
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SHIFT 19
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_INVAL        0x4C34
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_PTE_MASK 0x00000004U
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_PTE_SHIFT 2
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_PTE_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_ALL_MASK 0x00000008U
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_ALL_SHIFT 3
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_ALL_SIGNED 0
+#define EUR_CR_MASTER_BIF_MMU_CTRL          0x4CD0
+#define EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_MASK 0x00000001U
+#define EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_SHIFT 0
+#define EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_SIGNED 0
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_MASK 0x00000006U
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT 1
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SIGNED 0
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK 0x00000010U
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_SHIFT 4
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL              0x4D00
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_MASK 0x00800000U
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_SHIFT 23
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_BURST_EXP_MASK 0x00400000U
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_BURST_EXP_SHIFT 22
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_BURST_EXP_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ3_MASK 0x00200000U
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ3_SHIFT 21
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ3_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ2_MASK 0x00100000U
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ2_SHIFT 20
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ2_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ1_MASK 0x00080000U
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ1_SHIFT 19
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ1_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK 0x00040000U
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_SHIFT 18
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_DM_REF_SET_ALL_MASK 0x00010000U
+#define EUR_CR_MASTER_SLC_CTRL_DM_REF_SET_ALL_SHIFT 16
+#define EUR_CR_MASTER_SLC_CTRL_DM_REF_SET_ALL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_MASK 0x0000F000U
+#define EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT 12
+#define EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_MASK 0x00000E00U
+#define EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT 9
+#define EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_PAUSE_MASK   0x00000100U
+#define EUR_CR_MASTER_SLC_CTRL_PAUSE_SHIFT  8
+#define EUR_CR_MASTER_SLC_CTRL_PAUSE_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS       0x4D04
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_N_MASK 0x08000000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_N_SHIFT 27
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_N_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK 0x04000000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_SHIFT 26
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE4_MASK 0x02000000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE4_SHIFT 25
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE4_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE3_MASK 0x01000000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE3_SHIFT 24
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE3_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE2_MASK 0x00800000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE2_SHIFT 23
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE2_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE1_MASK 0x00400000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE1_SHIFT 22
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE1_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE0_MASK 0x00200000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE0_SHIFT 21
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE0_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PTLA_MASK 0x00100000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PTLA_SHIFT 20
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PTLA_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ISP2_RCIF_MASK 0x00080000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ISP2_RCIF_SHIFT 19
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ISP2_RCIF_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ZLS_MASK 0x00040000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ZLS_SHIFT 18
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ZLS_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PBE_MASK 0x00020000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PBE_SHIFT 17
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PBE_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_VDM_MASK 0x00010000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_VDM_SHIFT 16
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_VDM_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_MASK 0x00008000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_SHIFT 15
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PDS_MASK 0x00004000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PDS_SHIFT 14
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PDS_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USEC_MASK 0x00002000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USEC_SHIFT 13
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USEC_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_MASK 0x00001000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_SHIFT 12
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_MASK 0x00000800U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_SHIFT 11
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_MASK 0x00000400U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_SHIFT 10
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_MASK 0x00000200U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_SHIFT 9
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_OBJ_MASK 0x00000100U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_OBJ_SHIFT 8
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_OBJ_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TPF_MASK 0x00000080U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TPF_SHIFT 7
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TPF_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_MASK 0x00000040U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_SHIFT 6
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_CACHE_MASK 0x00000020U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_CACHE_SHIFT 5
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_CACHE_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_MASK 0x00000010U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_SHIFT 4
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_EVENT_MASK 0x00000008U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_EVENT_SHIFT 3
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_EVENT_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_PIXEL_MASK 0x00000004U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_PIXEL_SHIFT 2
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_PIXEL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_VERTEX_MASK 0x00000002U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_VERTEX_SHIFT 1
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_VERTEX_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_MASK 0x00000001U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_SHIFT 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL   0x4D08
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_ADDR_MASK 0xFFFFFFFFU
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_ADDR_SHIFT 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_ADDR_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_INVAL        0x4D28
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_EVENT_MASK 0x00000008U
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_EVENT_SHIFT 3
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_EVENT_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_PIXEL_MASK 0x00000004U
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_PIXEL_SHIFT 2
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_PIXEL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_VERTEX_MASK 0x00000002U
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_VERTEX_SHIFT 1
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_VERTEX_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_ALL_MASK 0x00000001U
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_ALL_SHIFT 0
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_ALL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH        0x4D2C
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_EVENT_MASK 0x00000080U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_EVENT_SHIFT 7
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_EVENT_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_PIXEL_MASK 0x00000040U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_PIXEL_SHIFT 6
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_PIXEL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_VERTEX_MASK 0x00000020U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_VERTEX_SHIFT 5
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_VERTEX_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_ALL_MASK 0x00000010U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_ALL_SHIFT 4
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_ALL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV    0x4D34
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_EVENT_MASK 0x00000080U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_EVENT_SHIFT 7
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_EVENT_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_PIXEL_MASK 0x00000040U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_PIXEL_SHIFT 6
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_PIXEL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_VERTEX_MASK 0x00000020U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_VERTEX_SHIFT 5
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_VERTEX_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_ALL_MASK 0x00000010U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_ALL_SHIFT 4
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_ALL_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_READ       0x4F18
+#define EUR_CR_MASTER_BREAKPOINT_READ_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_MASTER_BREAKPOINT_READ_ADDRESS_SHIFT 4
+#define EUR_CR_MASTER_BREAKPOINT_READ_ADDRESS_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP       0x4F1C
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT            0x4F20
+#define EUR_CR_MASTER_BREAKPOINT_ID_MASK    0x00000030U
+#define EUR_CR_MASTER_BREAKPOINT_ID_SHIFT   4
+#define EUR_CR_MASTER_BREAKPOINT_ID_SIGNED  0
+#define EUR_CR_MASTER_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_MASTER_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_MASTER_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_MASTER_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_MASTER_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0 0x4F24
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1 0x4F28
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+#define EUR_CR_MASTER_CORE                  0x4000
+#define EUR_CR_MASTER_CORE_ENABLE_MASK      0x00000003U
+#define EUR_CR_MASTER_CORE_ENABLE_SHIFT     0
+#define EUR_CR_MASTER_CORE_ENABLE_SIGNED    0
+#define EUR_CR_MASTER_CORE_ID               0x4010
+#define EUR_CR_MASTER_CORE_ID_CONFIG_MULTI_MASK 0x00000001U
+#define EUR_CR_MASTER_CORE_ID_CONFIG_MULTI_SHIFT 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_MULTI_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_BASE_MASK 0x00000002U
+#define EUR_CR_MASTER_CORE_ID_CONFIG_BASE_SHIFT 1
+#define EUR_CR_MASTER_CORE_ID_CONFIG_BASE_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_MASK   0x000000FCU
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SHIFT  2
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_CORES_MASK 0x00000F00U
+#define EUR_CR_MASTER_CORE_ID_CONFIG_CORES_SHIFT 8
+#define EUR_CR_MASTER_CORE_ID_CONFIG_CORES_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SLC_MASK 0x0000F000U
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SLC_SHIFT 12
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SLC_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_ID_MASK       0xFFFF0000U
+#define EUR_CR_MASTER_CORE_ID_ID_SHIFT      16
+#define EUR_CR_MASTER_CORE_ID_ID_SIGNED     0
+#define EUR_CR_MASTER_CORE_REVISION         0x4014
+#define EUR_CR_MASTER_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_MASTER_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_MASTER_CORE_REVISION_MAINTENANCE_SIGNED 0
+#define EUR_CR_MASTER_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_MASTER_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_MASTER_CORE_REVISION_MINOR_SIGNED 0
+#define EUR_CR_MASTER_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_MASTER_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_MASTER_CORE_REVISION_MAJOR_SIGNED 0
+#define EUR_CR_MASTER_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_MASTER_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_MASTER_CORE_REVISION_DESIGNER_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET            0x4080
+#define EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(i) (0x00000001U << (0 + ((i) * 1)))
+#define EUR_CR_MASTER_SOFT_RESET_CORE_RESET_SHIFT(i) (0 + ((i) * 1))
+#define EUR_CR_MASTER_SOFT_RESET_CORE_RESET_REGNUM(i) 0x4080
+#define EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK 0x00000010U
+#define EUR_CR_MASTER_SOFT_RESET_IPF_RESET_SHIFT 4
+#define EUR_CR_MASTER_SOFT_RESET_IPF_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK 0x00000020U
+#define EUR_CR_MASTER_SOFT_RESET_DPM_RESET_SHIFT 5
+#define EUR_CR_MASTER_SOFT_RESET_DPM_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK 0x00000040U
+#define EUR_CR_MASTER_SOFT_RESET_VDM_RESET_SHIFT 6
+#define EUR_CR_MASTER_SOFT_RESET_VDM_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK 0x00000080U
+#define EUR_CR_MASTER_SOFT_RESET_SLC_RESET_SHIFT 7
+#define EUR_CR_MASTER_SOFT_RESET_SLC_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK 0x00000100U
+#define EUR_CR_MASTER_SOFT_RESET_BIF_RESET_SHIFT 8
+#define EUR_CR_MASTER_SOFT_RESET_BIF_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_MCI_RESET_MASK 0x00000200U
+#define EUR_CR_MASTER_SOFT_RESET_MCI_RESET_SHIFT 9
+#define EUR_CR_MASTER_SOFT_RESET_MCI_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_MASK 0x00000400U
+#define EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_SHIFT 10
+#define EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_SIGNED 0
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/buffer_manager.h b/drivers/staging/cdv/pvr/services4/srvkm/include/buffer_manager.h
new file mode 100644
index 0000000..bba12a7
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/buffer_manager.h
@@ -0,0 +1,219 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _BUFFER_MANAGER_H_
+#define _BUFFER_MANAGER_H_
+
+#include "img_types.h"
+#include "ra.h"
+#include "perproc.h"
+
+#if defined(__cplusplus)
+extern "C"{
+#endif
+
+typedef struct _BM_HEAP_ BM_HEAP;
+
+struct _BM_MAPPING_
+{
+	enum
+	{
+		hm_wrapped = 1,		
+		hm_wrapped_scatter,	
+		hm_wrapped_virtaddr, 
+		hm_wrapped_scatter_virtaddr, 
+		hm_env,				
+		hm_contiguous		
+	} eCpuMemoryOrigin;
+
+	BM_HEAP				*pBMHeap;	
+	RA_ARENA			*pArena;	
+
+	IMG_CPU_VIRTADDR	CpuVAddr;
+	IMG_CPU_PHYADDR		CpuPAddr;
+	IMG_DEV_VIRTADDR	DevVAddr;
+	IMG_SYS_PHYADDR		*psSysAddr;
+	IMG_SIZE_T			uSize;
+    IMG_HANDLE          hOSMemHandle;
+	IMG_UINT32			ui32Flags;
+};
+
+typedef struct _BM_BUF_
+{
+	IMG_CPU_VIRTADDR	*CpuVAddr;
+    IMG_VOID            *hOSMemHandle;
+	IMG_CPU_PHYADDR		CpuPAddr;
+	IMG_DEV_VIRTADDR	DevVAddr;
+
+	BM_MAPPING			*pMapping;
+	IMG_UINT32			ui32RefCount;
+	IMG_UINT32			ui32ExportCount;
+} BM_BUF;
+
+struct _BM_HEAP_
+{
+	IMG_UINT32				ui32Attribs;
+	BM_CONTEXT				*pBMContext;
+	RA_ARENA				*pImportArena;
+	RA_ARENA				*pLocalDevMemArena;
+	RA_ARENA				*pVMArena;
+	DEV_ARENA_DESCRIPTOR	sDevArena;
+	MMU_HEAP				*pMMUHeap;
+	PDUMP_MMU_ATTRIB 		*psMMUAttrib;
+	
+	struct _BM_HEAP_ 		*psNext;
+	struct _BM_HEAP_ 		**ppsThis;
+};
+
+struct _BM_CONTEXT_
+{
+	MMU_CONTEXT	*psMMUContext;
+
+	
+	 BM_HEAP *psBMHeap;
+
+	
+	 BM_HEAP *psBMSharedHeap;
+
+	PVRSRV_DEVICE_NODE *psDeviceNode;
+
+	
+	HASH_TABLE *pBufferHash;
+
+	
+	IMG_HANDLE hResItem;
+
+	IMG_UINT32 ui32RefCount;
+
+	
+
+	struct _BM_CONTEXT_ *psNext;
+	struct _BM_CONTEXT_ **ppsThis;
+};
+
+
+
+typedef IMG_VOID *BM_HANDLE;
+
+#define BP_POOL_MASK         0x7
+
+#define BP_CONTIGUOUS			(1 << 3)
+#define BP_PARAMBUFFER			(1 << 4)
+
+#define BM_MAX_DEVMEM_ARENAS  2
+
+IMG_HANDLE
+BM_CreateContext(PVRSRV_DEVICE_NODE			*psDeviceNode,
+				 IMG_DEV_PHYADDR			*psPDDevPAddr,
+				 PVRSRV_PER_PROCESS_DATA	*psPerProc,
+				 IMG_BOOL					*pbCreated);
+
+
+PVRSRV_ERROR
+BM_DestroyContext (IMG_HANDLE hBMContext,
+					IMG_BOOL *pbCreated);
+
+
+IMG_HANDLE
+BM_CreateHeap (IMG_HANDLE hBMContext,
+				DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo);
+
+IMG_VOID
+BM_DestroyHeap (IMG_HANDLE hDevMemHeap);
+
+
+IMG_BOOL
+BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_BOOL
+BM_Alloc (IMG_HANDLE			hDevMemHeap,
+			IMG_DEV_VIRTADDR	*psDevVAddr,
+			IMG_SIZE_T			uSize,
+			IMG_UINT32			*pui32Flags,
+			IMG_UINT32			uDevVAddrAlignment,
+			BM_HANDLE			*phBuf);
+
+IMG_BOOL
+BM_Wrap (	IMG_HANDLE hDevMemHeap,
+		    IMG_SIZE_T ui32Size,
+			IMG_SIZE_T ui32Offset,
+			IMG_BOOL bPhysContig,
+			IMG_SYS_PHYADDR *psSysAddr,
+			IMG_VOID *pvCPUVAddr,
+			IMG_UINT32 *pui32Flags,
+			BM_HANDLE *phBuf);
+
+IMG_VOID
+BM_Free (BM_HANDLE hBuf,
+		IMG_UINT32 ui32Flags);
+
+
+IMG_CPU_VIRTADDR
+BM_HandleToCpuVaddr (BM_HANDLE hBuf);
+
+IMG_DEV_VIRTADDR
+BM_HandleToDevVaddr (BM_HANDLE hBuf);
+
+IMG_SYS_PHYADDR
+BM_HandleToSysPaddr (BM_HANDLE hBuf);
+
+IMG_HANDLE
+BM_HandleToOSMemHandle (BM_HANDLE hBuf);
+
+IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+								IMG_DEV_VIRTADDR sDevVPageAddr,
+								IMG_DEV_PHYADDR *psDevPAddr);
+
+MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap);
+
+MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext);
+
+IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap);
+
+PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext);
+
+
+IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_VOID BM_Export(BM_HANDLE hBuf);
+
+IMG_VOID BM_FreeExport(BM_HANDLE hBuf, IMG_UINT32 ui32Flags);
+
+PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index);
+PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index);
+PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index);
+
+PVRSRV_ERROR BM_XProcWorkaroundShareInit(void);
+void BM_XProcWorkaroundShareDestroy(void);
+
+IMG_UINT32 BM_XProcWorkaroundGetRefCount(IMG_UINT32 ui32Index);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/device.h b/drivers/staging/cdv/pvr/services4/srvkm/include/device.h
new file mode 100644
index 0000000..9df2c73
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/device.h
@@ -0,0 +1,323 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __DEVICE_H__
+#define __DEVICE_H__
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+	
+#include "ra.h"  		
+#include "resman.h"		
+
+typedef struct _BM_CONTEXT_ BM_CONTEXT;
+
+typedef struct _MMU_HEAP_ MMU_HEAP;
+typedef struct _MMU_CONTEXT_ MMU_CONTEXT;
+
+#define PVRSRV_BACKINGSTORE_SYSMEM_CONTIG		(1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+0))
+#define PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG	(1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+1))
+#define PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG		(1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+2))
+#define PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG	(1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+3))
+
+typedef IMG_UINT32 DEVICE_MEMORY_HEAP_TYPE;
+#define DEVICE_MEMORY_HEAP_PERCONTEXT		0
+#define DEVICE_MEMORY_HEAP_KERNEL			1
+#define DEVICE_MEMORY_HEAP_SHARED			2
+#define DEVICE_MEMORY_HEAP_SHARED_EXPORTED	3
+
+#define PVRSRV_DEVICE_NODE_FLAGS_PORT80DISPLAY	1
+#define PVRSRV_DEVICE_NODE_FLAGS_MMU_OPT_INV	2	
+
+typedef struct _DEVICE_MEMORY_HEAP_INFO_
+{
+	
+	IMG_UINT32				ui32HeapID;
+
+	
+	IMG_CHAR				*pszName;
+
+	
+	IMG_CHAR				*pszBSName;
+	
+	
+	IMG_DEV_VIRTADDR		sDevVAddrBase;
+
+	
+	IMG_UINT32				ui32HeapSize;
+
+	
+	IMG_UINT32				ui32Attribs;
+
+	
+	DEVICE_MEMORY_HEAP_TYPE	DevMemHeapType;
+	
+	
+	IMG_HANDLE				hDevMemHeap;
+	
+	
+	RA_ARENA				*psLocalDevMemArena;
+
+	
+	IMG_UINT32				ui32DataPageSize;
+
+	IMG_UINT32				ui32XTileStride;
+
+} DEVICE_MEMORY_HEAP_INFO;
+
+typedef struct _DEVICE_MEMORY_INFO_
+{
+	
+	IMG_UINT32				ui32AddressSpaceSizeLog2;
+
+	
+
+
+	IMG_UINT32				ui32Flags;
+
+	
+	IMG_UINT32				ui32HeapCount;
+	
+	
+	IMG_UINT32				ui32SyncHeapID;
+	
+	
+	IMG_UINT32				ui32MappingHeapID;
+
+	
+	DEVICE_MEMORY_HEAP_INFO	*psDeviceMemoryHeap;
+
+	
+    BM_CONTEXT				*pBMKernelContext;
+
+	
+    BM_CONTEXT				*pBMContext;
+
+} DEVICE_MEMORY_INFO;
+
+
+typedef struct DEV_ARENA_DESCRIPTOR_TAG
+{
+	IMG_UINT32				ui32HeapID;		
+
+	IMG_CHAR				*pszName;		
+
+	IMG_DEV_VIRTADDR		BaseDevVAddr;	
+
+	IMG_UINT32 				ui32Size;		
+
+	DEVICE_MEMORY_HEAP_TYPE	DevMemHeapType;
+
+	
+	IMG_UINT32				ui32DataPageSize;
+
+	DEVICE_MEMORY_HEAP_INFO	*psDeviceMemoryHeapInfo;
+
+} DEV_ARENA_DESCRIPTOR;
+
+
+typedef struct _PDUMP_MMU_ATTRIB_
+{
+	PVRSRV_DEVICE_IDENTIFIER	sDevId;
+	
+	IMG_CHAR	*pszPDRegRegion;
+	
+	
+	IMG_UINT32 ui32DataPageMask;
+
+	
+	IMG_UINT32 ui32PTEValid;
+	IMG_UINT32 ui32PTSize;
+	IMG_UINT32 ui32PTEAlignShift;
+
+	
+	IMG_UINT32 ui32PDEMask;
+	IMG_UINT32 ui32PDEAlignShift;
+
+} PDUMP_MMU_ATTRIB;
+
+typedef struct _SYS_DATA_TAG_ *PSYS_DATA;
+
+typedef struct _PVRSRV_DEVICE_NODE_
+{
+	PVRSRV_DEVICE_IDENTIFIER	sDevId;
+	IMG_UINT32					ui32RefCount;
+
+	
+
+	
+	PVRSRV_ERROR			(*pfnInitDevice) (IMG_VOID*);
+	
+	PVRSRV_ERROR			(*pfnDeInitDevice) (IMG_VOID*);
+
+	
+	PVRSRV_ERROR			(*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*);
+
+	
+	PVRSRV_ERROR			(*pfnMMUInitialise)(struct _PVRSRV_DEVICE_NODE_*, MMU_CONTEXT**, IMG_DEV_PHYADDR*);
+	IMG_VOID				(*pfnMMUFinalise)(MMU_CONTEXT*);
+	IMG_VOID				(*pfnMMUInsertHeap)(MMU_CONTEXT*, MMU_HEAP*);
+	MMU_HEAP*				(*pfnMMUCreate)(MMU_CONTEXT*,DEV_ARENA_DESCRIPTOR*,RA_ARENA**,PDUMP_MMU_ATTRIB **ppsMMUAttrib);
+	IMG_VOID				(*pfnMMUDelete)(MMU_HEAP*);
+	IMG_BOOL				(*pfnMMUAlloc)(MMU_HEAP*pMMU,
+										   IMG_SIZE_T uSize,
+										   IMG_SIZE_T *pActualSize,
+										   IMG_UINT32 uFlags,
+										   IMG_UINT32 uDevVAddrAlignment,
+										   IMG_DEV_VIRTADDR *pDevVAddr);
+	IMG_VOID				(*pfnMMUFree)(MMU_HEAP*,IMG_DEV_VIRTADDR,IMG_UINT32);
+	IMG_VOID 				(*pfnMMUEnable)(MMU_HEAP*);
+	IMG_VOID				(*pfnMMUDisable)(MMU_HEAP*);
+	IMG_VOID				(*pfnMMUMapPages)(MMU_HEAP *pMMU,
+											  IMG_DEV_VIRTADDR devVAddr,
+											  IMG_SYS_PHYADDR SysPAddr,
+											  IMG_SIZE_T uSize,
+											  IMG_UINT32 ui32MemFlags,
+											  IMG_HANDLE hUniqueTag);
+	IMG_VOID				(*pfnMMUMapShadow)(MMU_HEAP            *pMMU,
+											   IMG_DEV_VIRTADDR    MapBaseDevVAddr,
+											   IMG_SIZE_T          uSize, 
+											   IMG_CPU_VIRTADDR    CpuVAddr,
+											   IMG_HANDLE          hOSMemHandle,
+											   IMG_DEV_VIRTADDR    *pDevVAddr,
+											   IMG_UINT32 ui32MemFlags,
+											   IMG_HANDLE hUniqueTag);
+	IMG_VOID				(*pfnMMUUnmapPages)(MMU_HEAP *pMMU,
+												IMG_DEV_VIRTADDR dev_vaddr,
+												IMG_UINT32 ui32PageCount,
+												IMG_HANDLE hUniqueTag);
+
+	IMG_VOID				(*pfnMMUMapScatter)(MMU_HEAP *pMMU,
+												IMG_DEV_VIRTADDR DevVAddr,
+												IMG_SYS_PHYADDR *psSysAddr,
+												IMG_SIZE_T uSize,
+												IMG_UINT32 ui32MemFlags,
+												IMG_HANDLE hUniqueTag);
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	IMG_BOOL				(*pfnMMUIsHeapShared)(MMU_HEAP *);
+#endif
+	IMG_DEV_PHYADDR			(*pfnMMUGetPhysPageAddr)(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
+	IMG_DEV_PHYADDR			(*pfnMMUGetPDDevPAddr)(MMU_CONTEXT *pMMUContext);
+	IMG_VOID				(*pfnMMUGetCacheFlushRange)(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask);
+	IMG_VOID				(*pfnMMUGetPDPhysAddr)(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr);
+
+	
+	PVRSRV_ERROR			(*pfnAllocMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+														PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+														IMG_UINT32 ui32TilingStride,
+														IMG_UINT32 *pui32RangeIndex);
+	PVRSRV_ERROR			(*pfnFreeMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+														IMG_UINT32 ui32RangeIndex);
+
+	
+	IMG_BOOL				(*pfnDeviceISR)(IMG_VOID*);
+	
+	IMG_VOID				*pvISRData;
+	
+	IMG_UINT32 				ui32SOCInterruptBit;
+	
+	IMG_VOID				(*pfnDeviceMISR)(IMG_VOID*);
+
+	
+	IMG_VOID				(*pfnDeviceCommandComplete)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+	
+	IMG_BOOL				bReProcessDeviceCommandComplete;
+
+	IMG_VOID				(*pfnCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+
+	
+	DEVICE_MEMORY_INFO		sDevMemoryInfo;
+
+	
+	IMG_VOID				*pvDevice;
+	IMG_UINT32				ui32pvDeviceSize; 
+		
+	
+	PRESMAN_CONTEXT			hResManContext;
+	
+	
+	PSYS_DATA				psSysData;
+	
+	
+	RA_ARENA				*psLocalDevMemArena;
+	
+	IMG_UINT32				ui32Flags;
+	
+	struct _PVRSRV_DEVICE_NODE_	*psNext;
+	struct _PVRSRV_DEVICE_NODE_	**ppsThis;
+	
+#if defined(PDUMP)
+	
+	PVRSRV_ERROR			(*pfnPDumpInitDevice)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+	
+	IMG_UINT32				(*pfnMMUGetContextID)(IMG_HANDLE hDevMemContext);
+#endif
+} PVRSRV_DEVICE_NODE;
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
+											  PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
+											  IMG_UINT32 ui32SOCInterruptBit,
+			 								  IMG_UINT32 *pui32DeviceIndex );
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice(IMG_UINT32 ui32DevIndex);
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful);
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex);
+
+#if !defined(USE_CODE)
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PollForValueKM(volatile IMG_UINT32*	pui32LinMemAddr,
+													IMG_UINT32				ui32Value,
+													IMG_UINT32				ui32Mask,
+													IMG_UINT32				ui32Timeoutus,
+													IMG_UINT32				ui32PollPeriodus,
+													IMG_BOOL				bAllowPreemption);
+
+#endif 
+
+
+#if defined (USING_ISR_INTERRUPTS)
+PVRSRV_ERROR IMG_CALLCONV PollForInterruptKM(IMG_UINT32 ui32Value,
+								IMG_UINT32 ui32Mask,
+								IMG_UINT32 ui32Waitus,
+								IMG_UINT32 ui32Tries);
+#endif 
+
+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)
+}
+#endif
+	
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/handle.h b/drivers/staging/cdv/pvr/services4/srvkm/include/handle.h
new file mode 100644
index 0000000..536fa56
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/handle.h
@@ -0,0 +1,404 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __HANDLE_H__
+#define __HANDLE_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_types.h"
+#include "hash.h"
+#include "resman.h"
+
+typedef enum
+{
+	PVRSRV_HANDLE_TYPE_NONE = 0,
+	PVRSRV_HANDLE_TYPE_PERPROC_DATA,
+	PVRSRV_HANDLE_TYPE_DEV_NODE,
+	PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
+	PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+	PVRSRV_HANDLE_TYPE_MEM_INFO,
+	PVRSRV_HANDLE_TYPE_SYNC_INFO,
+	PVRSRV_HANDLE_TYPE_DISP_INFO,
+	PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
+	PVRSRV_HANDLE_TYPE_BUF_INFO,
+	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_EVENT_OBJECT_CONNECT,
+	PVRSRV_HANDLE_TYPE_MMAP_INFO,
+	PVRSRV_HANDLE_TYPE_SOC_TIMER,
+	PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ,
+	PVRSRV_HANDLE_TYPE_RESITEM_INFO
+} PVRSRV_HANDLE_TYPE;
+
+typedef enum
+{
+	
+	PVRSRV_HANDLE_ALLOC_FLAG_NONE = 		0,
+	
+	PVRSRV_HANDLE_ALLOC_FLAG_SHARED = 		0x01,
+	
+	PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 		0x02,
+	
+	PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 		0x04
+} PVRSRV_HANDLE_ALLOC_FLAG;
+
+struct _PVRSRV_HANDLE_BASE_;
+typedef struct _PVRSRV_HANDLE_BASE_ PVRSRV_HANDLE_BASE;
+
+#if defined (PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase;
+
+#define	KERNEL_HANDLE_BASE (gpsKernelHandleBase)
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag);
+
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent);
+
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_SID hHandle);
+
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType, IMG_SID hAncestor);
+
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phParent, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+#else
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag);
+
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
+
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle);
+
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor);
+
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+#endif 
+
+PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize);
+
+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase);
+
+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle);
+
+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase);
+
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID);
+
+PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID);
+
+#else	
+
+#define KERNEL_HANDLE_BASE IMG_NULL
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVAllocHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
+{
+	PVR_UNREFERENCED_PARAMETER(eType);
+	PVR_UNREFERENCED_PARAMETER(eFlag);
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	*phHandle = pvData;
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVAllocSubHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
+{
+	PVR_UNREFERENCED_PARAMETER(eType);
+	PVR_UNREFERENCED_PARAMETER(eFlag);
+	PVR_UNREFERENCED_PARAMETER(hParent);
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	*phHandle = pvData;
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVFindHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
+{
+	PVR_UNREFERENCED_PARAMETER(eType);
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	*phHandle = pvData;
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVLookupHandleAnyType)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+	
+	*peType = PVRSRV_HANDLE_TYPE_NONE;
+
+	*ppvData = hHandle;
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVLookupHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+	PVR_UNREFERENCED_PARAMETER(eType);
+
+	*ppvData = hHandle;
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVLookupSubHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+	PVR_UNREFERENCED_PARAMETER(eType);
+	PVR_UNREFERENCED_PARAMETER(hAncestor);
+
+	*ppvData = hHandle;
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVGetParentHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+	PVR_UNREFERENCED_PARAMETER(eType);
+	PVR_UNREFERENCED_PARAMETER(hHandle);
+
+	*phParent = IMG_NULL;
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVLookupAndReleaseHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+{
+	PVR_UNREFERENCED_PARAMETER(eType);
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	*ppvData = hHandle;
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVReleaseHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+{
+	PVR_UNREFERENCED_PARAMETER(hHandle);
+	PVR_UNREFERENCED_PARAMETER(eType);
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVNewHandleBatch)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+	PVR_UNREFERENCED_PARAMETER(ui32BatchSize);
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVCommitHandleBatch)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVReleaseHandleBatch)
+#endif
+static INLINE
+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSetMaxHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+	PVR_UNREFERENCED_PARAMETER(ui32MaxHandle);
+
+	return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVGetMaxHandle)
+#endif
+static INLINE
+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	return 0;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVEnableHandlePurging)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPurgeHandles)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVAllocHandleBase)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
+{
+	*ppsBase = IMG_NULL;
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVFreeHandleBase)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
+{
+	PVR_UNREFERENCED_PARAMETER(psBase);
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVHandleInit)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID)
+{
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVHandleDeInit)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID)
+{
+	return PVRSRV_OK;
+}
+
+#endif	
+
+#define PVRSRVAllocHandleNR(psBase, phHandle, pvData, eType, eFlag) \
+	(IMG_VOID)PVRSRVAllocHandle(psBase, phHandle, pvData, eType, eFlag)
+
+#define PVRSRVAllocSubHandleNR(psBase, phHandle, pvData, eType, eFlag, hParent) \
+	(IMG_VOID)PVRSRVAllocSubHandle(psBase, phHandle, pvData, eType, eFlag, hParent)
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/hash.h b/drivers/staging/cdv/pvr/services4/srvkm/include/hash.h
new file mode 100644
index 0000000..3662089
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/hash.h
@@ -0,0 +1,80 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _HASH_H_
+#define _HASH_H_
+
+#include "img_types.h"
+#include "osfunc.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+typedef IMG_UINT32 HASH_FUNC(IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
+typedef IMG_BOOL HASH_KEY_COMP(IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
+
+typedef struct _HASH_TABLE_ HASH_TABLE;
+
+typedef PVRSRV_ERROR (*HASH_pfnCallback) (
+	IMG_UINTPTR_T k,
+	IMG_UINTPTR_T v
+);
+
+IMG_UINT32 HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
+
+IMG_BOOL HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
+
+HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp);
+
+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen);
+
+IMG_VOID HASH_Delete (HASH_TABLE *pHash);
+
+IMG_BOOL HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v);
+
+IMG_BOOL HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v);
+
+IMG_UINTPTR_T HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey);
+
+IMG_UINTPTR_T HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k);
+
+IMG_UINTPTR_T HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey);
+
+IMG_UINTPTR_T HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k);
+
+PVRSRV_ERROR HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback);
+
+#ifdef HASH_TRACE
+IMG_VOID HASH_Dump (HASH_TABLE *pHash);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/lists.h b/drivers/staging/cdv/pvr/services4/srvkm/include/lists.h
new file mode 100644
index 0000000..a02307a
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/lists.h
@@ -0,0 +1,244 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __LISTS_UTILS__
+#define __LISTS_UTILS__
+
+#include <stdarg.h>
+#include "img_types.h"
+
+#define DECLARE_LIST_FOR_EACH(TYPE) \
+IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_FOR_EACH(TYPE) \
+IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))\
+{\
+	while(psHead)\
+	{\
+		pfnCallBack(psHead);\
+		psHead = psHead->psNext;\
+	}\
+}
+
+
+#define DECLARE_LIST_FOR_EACH_VA(TYPE) \
+IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...)
+
+#define IMPLEMENT_LIST_FOR_EACH_VA(TYPE) \
+IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...) \
+{\
+	va_list ap;\
+	while(psHead)\
+	{\
+		va_start(ap, pfnCallBack);\
+		pfnCallBack(psHead, ap);\
+		psHead = psHead->psNext;\
+		va_end(ap);\
+	}\
+}
+
+
+#define DECLARE_LIST_ANY(TYPE) \
+IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_ANY(TYPE) \
+IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))\
+{ \
+	IMG_VOID *pResult;\
+	TYPE *psNextNode;\
+	pResult = IMG_NULL;\
+	psNextNode = psHead;\
+	while(psHead && !pResult)\
+	{\
+		psNextNode = psNextNode->psNext;\
+		pResult = pfnCallBack(psHead);\
+		psHead = psNextNode;\
+	}\
+	return pResult;\
+}
+
+
+#define DECLARE_LIST_ANY_VA(TYPE) \
+IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)
+
+#define IMPLEMENT_LIST_ANY_VA(TYPE) \
+IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
+{\
+	va_list ap;\
+	TYPE *psNextNode;\
+	IMG_VOID* pResult = IMG_NULL;\
+	while(psHead && !pResult)\
+	{\
+		psNextNode = psHead->psNext;\
+		va_start(ap, pfnCallBack);\
+		pResult = pfnCallBack(psHead, ap);\
+		va_end(ap);\
+		psHead = psNextNode;\
+	}\
+	return pResult;\
+}
+
+#define DECLARE_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))\
+{ \
+	RTYPE result;\
+	TYPE *psNextNode;\
+	result = CONTINUE;\
+	psNextNode = psHead;\
+	while(psHead && result == CONTINUE)\
+	{\
+		psNextNode = psNextNode->psNext;\
+		result = pfnCallBack(psHead);\
+		psHead = psNextNode;\
+	}\
+	return result;\
+}
+
+
+#define DECLARE_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)
+
+#define IMPLEMENT_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
+{\
+	va_list ap;\
+	TYPE *psNextNode;\
+	RTYPE result = CONTINUE;\
+	while(psHead && result == CONTINUE)\
+	{\
+		psNextNode = psHead->psNext;\
+		va_start(ap, pfnCallBack);\
+		result = pfnCallBack(psHead, ap);\
+		va_end(ap);\
+		psHead = psNextNode;\
+	}\
+	return result;\
+}
+
+
+#define DECLARE_LIST_REMOVE(TYPE) \
+IMG_VOID List_##TYPE##_Remove(TYPE *psNode)
+
+#define IMPLEMENT_LIST_REMOVE(TYPE) \
+IMG_VOID List_##TYPE##_Remove(TYPE *psNode)\
+{\
+	(*psNode->ppsThis)=psNode->psNext;\
+	if(psNode->psNext)\
+	{\
+		psNode->psNext->ppsThis = psNode->ppsThis;\
+	}\
+}
+
+#define DECLARE_LIST_INSERT(TYPE) \
+IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)
+
+#define IMPLEMENT_LIST_INSERT(TYPE) \
+IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)\
+{\
+	psNewNode->ppsThis = ppsHead;\
+	psNewNode->psNext = *ppsHead;\
+	*ppsHead = psNewNode;\
+	if(psNewNode->psNext)\
+	{\
+		psNewNode->psNext->ppsThis = &(psNewNode->psNext);\
+	}\
+}
+
+#define DECLARE_LIST_REVERSE(TYPE) \
+IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead)
+
+#define IMPLEMENT_LIST_REVERSE(TYPE) \
+IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead)\
+{\
+    TYPE *psTmpNode1; \
+    TYPE *psTmpNode2; \
+    TYPE *psCurNode; \
+	psTmpNode1 = IMG_NULL; \
+	psCurNode = *ppsHead; \
+	while(psCurNode) { \
+    	psTmpNode2 = psCurNode->psNext; \
+        psCurNode->psNext = psTmpNode1; \
+		psTmpNode1 = psCurNode; \
+		psCurNode = psTmpNode2; \
+		if(psCurNode) \
+		{ \
+			psTmpNode1->ppsThis = &(psCurNode->psNext); \
+		} \
+		else \
+		{ \
+			psTmpNode1->ppsThis = ppsHead;		\
+		} \
+	} \
+	*ppsHead = psTmpNode1; \
+}
+
+#define IS_LAST_ELEMENT(x) ((x)->psNext == IMG_NULL)
+
+#include "services_headers.h"
+
+DECLARE_LIST_ANY_VA(BM_HEAP);
+DECLARE_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_FOR_EACH_VA(BM_HEAP);
+DECLARE_LIST_REMOVE(BM_HEAP);
+DECLARE_LIST_INSERT(BM_HEAP);
+
+DECLARE_LIST_ANY_VA(BM_CONTEXT);
+DECLARE_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL);
+DECLARE_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_FOR_EACH(BM_CONTEXT);
+DECLARE_LIST_REMOVE(BM_CONTEXT);
+DECLARE_LIST_INSERT(BM_CONTEXT);
+
+DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_INSERT(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_REMOVE(PVRSRV_DEVICE_NODE);
+
+DECLARE_LIST_ANY_VA(PVRSRV_POWER_DEV);
+DECLARE_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_INSERT(PVRSRV_POWER_DEV);
+DECLARE_LIST_REMOVE(PVRSRV_POWER_DEV);
+
+#undef DECLARE_LIST_ANY_2
+#undef DECLARE_LIST_ANY_VA
+#undef DECLARE_LIST_ANY_VA_2
+#undef DECLARE_LIST_FOR_EACH
+#undef DECLARE_LIST_FOR_EACH_VA
+#undef DECLARE_LIST_INSERT
+#undef DECLARE_LIST_REMOVE
+
+IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va);
+IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va);
+
+#endif
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/metrics.h b/drivers/staging/cdv/pvr/services4/srvkm/include/metrics.h
new file mode 100644
index 0000000..69e1b3d
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/metrics.h
@@ -0,0 +1,130 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _METRICS_
+#define _METRICS_
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+#if defined(DEBUG) || defined(TIMING)
+
+
+typedef struct 
+{
+	IMG_UINT32 ui32Start;
+	IMG_UINT32 ui32Stop;
+	IMG_UINT32 ui32Total;
+	IMG_UINT32 ui32Count;
+} Temporal_Data;
+
+extern Temporal_Data asTimers[]; 
+
+extern IMG_UINT32 PVRSRVTimeNow(IMG_VOID);
+extern IMG_VOID   PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo);
+extern IMG_VOID   PVRSRVOutputMetricTotals(IMG_VOID);
+
+
+#define PVRSRV_TIMER_DUMMY				0
+
+#define PVRSRV_TIMER_EXAMPLE_1			1
+#define PVRSRV_TIMER_EXAMPLE_2			2
+
+
+#define PVRSRV_NUM_TIMERS		(PVRSRV_TIMER_EXAMPLE_2 + 1)
+
+#define PVRSRV_TIME_START(X)	{ \
+									asTimers[X].ui32Count += 1; \
+									asTimers[X].ui32Count |= 0x80000000L; \
+									asTimers[X].ui32Start = PVRSRVTimeNow(); \
+									asTimers[X].ui32Stop  = 0; \
+								}
+
+#define PVRSRV_TIME_SUSPEND(X)	{ \
+									asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \
+								}
+
+#define PVRSRV_TIME_RESUME(X)	{ \
+									asTimers[X].ui32Start = PVRSRVTimeNow(); \
+								}
+
+#define PVRSRV_TIME_STOP(X)		{ \
+									asTimers[X].ui32Stop  += PVRSRVTimeNow() - asTimers[X].ui32Start; \
+									asTimers[X].ui32Total += asTimers[X].ui32Stop; \
+									asTimers[X].ui32Count &= 0x7FFFFFFFL; \
+								}
+
+#define PVRSRV_TIME_RESET(X)	{ \
+									asTimers[X].ui32Start = 0; \
+									asTimers[X].ui32Stop  = 0; \
+									asTimers[X].ui32Total = 0; \
+									asTimers[X].ui32Count = 0; \
+								}
+
+
+#if defined(__sh__)
+
+#define TST_REG   ((volatile IMG_UINT8 *) (psDevInfo->pvSOCRegsBaseKM)) 	
+
+#define TCOR_2    ((volatile IMG_UINT *)  (psDevInfo->pvSOCRegsBaseKM+28))	
+#define TCNT_2    ((volatile IMG_UINT *)  (psDevInfo->pvSOCRegsBaseKM+32))	
+#define TCR_2     ((volatile IMG_UINT16 *)(psDevInfo->pvSOCRegsBaseKM+36))	
+
+#define TIMER_DIVISOR  4
+
+#endif 
+
+
+
+
+
+#else 
+
+
+
+#define PVRSRV_TIME_START(X)
+#define PVRSRV_TIME_SUSPEND(X)
+#define PVRSRV_TIME_RESUME(X)
+#define PVRSRV_TIME_STOP(X)
+#define PVRSRV_TIME_RESET(X)
+
+#define PVRSRVSetupMetricTimers(X)
+#define PVRSRVOutputMetricTotals()
+
+
+
+#endif 
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/osfunc.h b/drivers/staging/cdv/pvr/services4/srvkm/include/osfunc.h
new file mode 100644
index 0000000..b76cefd
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/osfunc.h
@@ -0,0 +1,606 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifdef DEBUG_RELEASE_BUILD
+#pragma optimize( "", off )
+#define DEBUG		1
+#endif
+
+#ifndef __OSFUNC_H__
+#define __OSFUNC_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__linux__) && defined(__KERNEL__)
+#include <linux/hardirq.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#if defined(__arm__)
+#include <asm/memory.h>
+#endif
+#endif
+
+
+	
+	#define PVRSRV_PAGEABLE_SELECT		PVRSRV_OS_PAGEABLE_HEAP
+
+#define KERNEL_ID			0xffffffffL
+#define POWER_MANAGER_ID	0xfffffffeL
+#define ISR_ID				0xfffffffdL
+#define TIMER_ID			0xfffffffcL
+
+
+#define HOST_PAGESIZE			OSGetPageSize
+#define HOST_PAGEMASK			(HOST_PAGESIZE()-1)
+#define HOST_PAGEALIGN(addr)	(((addr) + HOST_PAGEMASK) & ~HOST_PAGEMASK)
+
+#define PVRSRV_OS_HEAP_MASK			0xf 
+#define PVRSRV_OS_PAGEABLE_HEAP		0x1 
+#define PVRSRV_OS_NON_PAGEABLE_HEAP	0x2 
+
+
+IMG_UINT32 OSClockus(IMG_VOID);
+IMG_SIZE_T OSGetPageSize(IMG_VOID);
+PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData,
+								 IMG_UINT32 ui32Irq,
+								 IMG_CHAR *pszISRName,
+								 IMG_VOID *pvDeviceNode);
+PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData);
+PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq);
+PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData);
+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData);
+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData);
+IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_HANDLE, IMG_VOID* pvLinAddr);
+IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_SIZE_T ui32Size);
+IMG_VOID *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle);
+IMG_BOOL OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
+
+PVRSRV_ERROR OSReservePhys(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle);
+PVRSRV_ERROR OSUnReservePhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
+
+#if defined(__linux__) && defined(__KERNEL__)
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID);
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID);
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+								IMG_VOID *pvRangeAddrStart,
+								IMG_UINT32 ui32Length);
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+								IMG_VOID *pvRangeAddrStart,
+								IMG_UINT32 ui32Length);
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+									 IMG_VOID *pvRangeAddrStart,
+									 IMG_UINT32 ui32Length);
+
+#else 
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSFlushCPUCacheKM)
+#endif
+static INLINE IMG_VOID OSFlushCPUCacheKM(IMG_VOID) {}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSCleanCPUCacheKM)
+#endif
+static INLINE IMG_VOID OSCleanCPUCacheKM(IMG_VOID) {}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSFlushCPUCacheRangeKM)
+#endif
+static INLINE IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+											  IMG_VOID *pvRangeAddrStart,
+											  IMG_UINT32 ui32Length)
+{
+	PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+	PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
+	PVR_UNREFERENCED_PARAMETER(ui32Length);
+	return IMG_FALSE;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSCleanCPUCacheRangeKM)
+#endif
+static INLINE IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+											  IMG_VOID *pvRangeAddrStart,
+											  IMG_UINT32 ui32Length)
+{
+	PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+	PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
+	PVR_UNREFERENCED_PARAMETER(ui32Length);
+	return IMG_FALSE;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSInvalidateCPUCacheRangeKM)
+#endif
+static INLINE IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+												   IMG_VOID *pvRangeAddrStart,
+												   IMG_UINT32 ui32Length)
+{
+	PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+	PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
+	PVR_UNREFERENCED_PARAMETER(ui32Length);
+	return IMG_FALSE;
+}
+
+#endif 
+
+#if (defined(__linux__) || defined(__QNXNTO__))
+PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
+									IMG_VOID *pvCpuVAddr, 
+									IMG_SIZE_T ui32Bytes,
+									IMG_UINT32 ui32Flags, 
+									IMG_HANDLE *phOSMemHandle);
+PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr,
+									IMG_SIZE_T ui32Bytes,
+									IMG_UINT32 ui32Flags,
+									IMG_HANDLE hOSMemHandle);
+#else	
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSRegisterDiscontigMem)
+#endif
+static INLINE PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
+													IMG_VOID *pvCpuVAddr,
+													IMG_SIZE_T ui32Bytes,
+													IMG_UINT32 ui32Flags,
+													IMG_HANDLE *phOSMemHandle)
+{
+	PVR_UNREFERENCED_PARAMETER(pBasePAddr);
+	PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+	PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+	PVR_UNREFERENCED_PARAMETER(ui32Flags);
+	PVR_UNREFERENCED_PARAMETER(phOSMemHandle);
+
+	return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSUnRegisterDiscontigMem)
+#endif
+static INLINE PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr,
+													IMG_SIZE_T ui32Bytes,
+													IMG_UINT32 ui32Flags,
+													IMG_HANDLE hOSMemHandle)
+{
+	PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+	PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+	PVR_UNREFERENCED_PARAMETER(ui32Flags);
+	PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+
+	return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+#endif	
+
+
+#if (defined(__linux__) || defined(__QNXNTO__))
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReserveDiscontigPhys)
+#endif
+static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle)
+{
+#if defined(__linux__) || defined(__QNXNTO__) 
+	*ppvCpuVAddr = IMG_NULL;
+	return OSRegisterDiscontigMem(pBasePAddr, *ppvCpuVAddr, ui32Bytes, ui32Flags, phOSMemHandle);	
+#else
+	extern IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr(IMG_SYS_PHYADDR SysPAddr);
+
+	
+	return OSReservePhys(SysSysPAddrToCpuPAddr(pBasePAddr[0]), ui32Bytes, ui32Flags, ppvCpuVAddr, phOSMemHandle);
+#endif	
+}
+
+static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
+{
+#if defined(__linux__) || defined(__QNXNTO__) 
+	OSUnRegisterDiscontigMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
+#endif
+	
+	return PVRSRV_OK;
+}
+#else	
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReserveDiscontigPhys)
+#endif
+static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle)
+{
+	PVR_UNREFERENCED_PARAMETER(pBasePAddr);
+	PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+	PVR_UNREFERENCED_PARAMETER(ui32Flags);
+	PVR_UNREFERENCED_PARAMETER(ppvCpuVAddr);
+	PVR_UNREFERENCED_PARAMETER(phOSMemHandle);
+
+	return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSUnReserveDiscontigPhys)
+#endif
+static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
+{
+	PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+	PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+	PVR_UNREFERENCED_PARAMETER(ui32Flags);
+	PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+
+	return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+#endif	
+
+PVRSRV_ERROR OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
+							IMG_VOID *pvCpuVAddr,
+							IMG_SIZE_T ui32Bytes,
+							IMG_UINT32 ui32Flags,
+							IMG_HANDLE *phOSMemHandle);
+PVRSRV_ERROR OSUnRegisterMem(IMG_VOID *pvCpuVAddr,
+							IMG_SIZE_T ui32Bytes,
+							IMG_UINT32 ui32Flags,
+							IMG_HANDLE hOSMemHandle);
+
+
+
+#if defined(__linux__) || defined(__QNXNTO__)
+PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
+							   IMG_UINTPTR_T ui32ByteOffset,
+							   IMG_SIZE_T ui32Bytes,
+							   IMG_UINT32 ui32Flags,
+							   IMG_HANDLE *phOSMemHandleRet);
+PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSGetSubMemHandle)
+#endif
+static INLINE PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
+											 IMG_UINTPTR_T ui32ByteOffset,
+											 IMG_SIZE_T ui32Bytes,
+											 IMG_UINT32 ui32Flags,
+											 IMG_HANDLE *phOSMemHandleRet)
+{
+	PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
+	PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+	PVR_UNREFERENCED_PARAMETER(ui32Flags);
+
+	*phOSMemHandleRet = hOSMemHandle;
+	return PVRSRV_OK;
+}
+
+static INLINE PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags)
+{
+	PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+	PVR_UNREFERENCED_PARAMETER(ui32Flags);
+	return PVRSRV_OK;
+}
+#endif
+
+IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID);
+IMG_UINTPTR_T OSGetCurrentThreadID( IMG_VOID );
+IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
+
+PVRSRV_ERROR OSAllocPages_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_UINT32 ui32PageSize, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phPageAlloc);
+PVRSRV_ERROR OSFreePages(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hPageAlloc);
+
+
+#ifdef PVRSRV_LOG_MEMORY_ALLOCS
+	#define OSAllocMem(flags, size, linAddr, blockAlloc, logStr) \
+		(PVR_TRACE(("OSAllocMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): " logStr " (size = 0x%lx)", size)), \
+			OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
+
+	#define OSAllocPages(flags, size, pageSize, linAddr, pageAlloc) \
+		(PVR_TRACE(("OSAllocPages(" #flags ", " #size ", " #pageSize ", " #linAddr ", " #pageAlloc "): (size = 0x%lx)", size)), \
+			OSAllocPages_Impl(flags, size, pageSize, linAddr, pageAlloc))
+		
+	#define OSFreeMem(flags, size, linAddr, blockAlloc) \
+		(PVR_TRACE(("OSFreeMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): (pointer = 0x%X)", linAddr)), \
+			OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
+#else
+	#define OSAllocMem(flags, size, linAddr, blockAlloc, logString) \
+		OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
+	
+	#define OSAllocPages OSAllocPages_Impl
+	
+	#define OSFreeMem(flags, size, linAddr, blockAlloc) \
+			OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
+#endif
+ 
+#ifdef PVRSRV_DEBUG_OS_MEMORY
+
+	PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+										IMG_UINT32 ui32Size,
+										IMG_PVOID *ppvCpuVAddr,
+										IMG_HANDLE *phBlockAlloc,
+										IMG_CHAR *pszFilename,
+										IMG_UINT32 ui32Line);
+	
+	PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+									 IMG_UINT32 ui32Size,
+									 IMG_PVOID pvCpuVAddr,
+									 IMG_HANDLE hBlockAlloc,
+									 IMG_CHAR *pszFilename,
+									 IMG_UINT32 ui32Line);
+
+
+	typedef struct
+	{	
+		IMG_UINT8 sGuardRegionBefore[8];
+		IMG_CHAR sFileName[128];
+		IMG_UINT32 uLineNo;
+		IMG_SIZE_T uSize;
+		IMG_SIZE_T uSizeParityCheck;
+		enum valid_tag
+		{	isFree = 0x277260FF,
+			isAllocated = 0x260511AA
+		} eValid;
+	} OSMEM_DEBUG_INFO;
+	
+	#define TEST_BUFFER_PADDING_STATUS (sizeof(OSMEM_DEBUG_INFO)) 
+	#define TEST_BUFFER_PADDING_AFTER  (8) 
+	#define TEST_BUFFER_PADDING (TEST_BUFFER_PADDING_STATUS + TEST_BUFFER_PADDING_AFTER)
+#else
+	#define OSAllocMem_Debug_Wrapper OSAllocMem_Debug_Linux_Memory_Allocations
+	#define OSFreeMem_Debug_Wrapper OSFreeMem_Debug_Linux_Memory_Allocations
+#endif
+ 
+#if (defined(__linux__) || defined(__QNXNTO__)) && defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+	PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
+	PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
+	
+	#define OSAllocMem_Debug_Linux_Memory_Allocations OSAllocMem_Impl
+	#define OSFreeMem_Debug_Linux_Memory_Allocations OSFreeMem_Impl
+#else
+	PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc);
+	PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc);
+	
+	#define OSAllocMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
+		OSAllocMem_Impl(flags, size, addr, blockAlloc)
+	#define OSFreeMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
+		OSFreeMem_Impl(flags, size, addr, blockAlloc)
+#endif
+
+
+#if defined(__linux__) || defined(__QNXNTO__)
+IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_SIZE_T ui32ByteOffset);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSMemHandleToCpuPAddr)
+#endif
+static INLINE IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_HANDLE hOSMemHandle, IMG_SIZE_T ui32ByteOffset)
+{
+	IMG_CPU_PHYADDR sCpuPAddr;
+	PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+	PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
+	sCpuPAddr.uiAddr = 0;
+	return sCpuPAddr;
+}
+#endif
+PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData);
+PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData);
+IMG_CHAR* OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc);
+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_SIZE_T ui32Size, const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+#define OSStringLength(pszString) strlen(pszString)
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName,
+								 PVRSRV_EVENTOBJECT_KM *psEventObject);
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT_KM *psEventObject);
+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+											IMG_HANDLE *phOSEvent);
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+											IMG_HANDLE hOSEventKM);
+#else
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName,
+								 PVRSRV_EVENTOBJECT *psEventObject);
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT *psEventObject);
+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT *psEventObject,
+											IMG_HANDLE *phOSEvent);
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT *psEventObject,
+											IMG_HANDLE hOSEventKM);
+#endif 
+
+
+PVRSRV_ERROR OSBaseAllocContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR *pLinAddr, IMG_CPU_PHYADDR *pPhysAddr);
+PVRSRV_ERROR OSBaseFreeContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr);
+
+IMG_PVOID MapUserFromKernel(IMG_PVOID pvLinAddrKM,IMG_SIZE_T ui32Size,IMG_HANDLE *phMemBlock);
+IMG_PVOID OSMapHWRegsIntoUserSpace(IMG_HANDLE hDevCookie, IMG_SYS_PHYADDR sRegAddr, IMG_UINT32 ulSize, IMG_PVOID *ppvProcess);
+IMG_VOID  OSUnmapHWRegsFromUserSpace(IMG_HANDLE hDevCookie, IMG_PVOID pvUserAddr, IMG_PVOID pvProcess);
+
+IMG_VOID  UnmapUserFromKernel(IMG_PVOID pvLinAddrUM, IMG_SIZE_T ui32Size, IMG_HANDLE hMemBlock);
+
+PVRSRV_ERROR OSMapPhysToUserSpace(IMG_HANDLE hDevCookie,
+								  IMG_SYS_PHYADDR sCPUPhysAddr,
+								  IMG_SIZE_T uiSizeInBytes,
+								  IMG_UINT32 ui32CacheFlags,
+								  IMG_PVOID *ppvUserAddr,
+								  IMG_SIZE_T *puiActualSize,
+								  IMG_HANDLE hMappingHandle);
+
+PVRSRV_ERROR OSUnmapPhysToUserSpace(IMG_HANDLE hDevCookie,
+									IMG_PVOID pvUserAddr,
+									IMG_PVOID pvProcess);
+
+PVRSRV_ERROR OSLockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
+PVRSRV_ERROR OSUnlockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
+IMG_BOOL OSIsResourceLocked(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
+PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource);
+PVRSRV_ERROR OSDestroyResource(PVRSRV_RESOURCE *psResource);
+IMG_VOID OSBreakResourceLock(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
+
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
+#define OSPowerLockWrap SysPowerLockWrap
+#define OSPowerLockUnwrap SysPowerLockUnwrap
+#else
+PVRSRV_ERROR OSPowerLockWrap(IMG_BOOL bTryLock);
+
+IMG_VOID OSPowerLockUnwrap(IMG_VOID);
+#endif 
+
+ 
+IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus);
+
+ 
+IMG_VOID OSSleepms(IMG_UINT32 ui32Timems);
+
+IMG_HANDLE OSFuncHighResTimerCreate(IMG_VOID);
+IMG_UINT32 OSFuncHighResTimerGetus(IMG_HANDLE hTimer);
+IMG_VOID OSFuncHighResTimerDestroy(IMG_HANDLE hTimer);
+IMG_VOID OSReleaseThreadQuanta(IMG_VOID);
+IMG_UINT32 OSPCIReadDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg);
+IMG_VOID OSPCIWriteDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Value);
+
+#ifndef OSReadHWReg
+IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+#endif
+#ifndef OSWriteHWReg
+IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
+#endif
+
+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_SIZE_T *pui32Bytes);
+
+typedef enum _HOST_PCI_INIT_FLAGS_
+{
+	HOST_PCI_INIT_FLAG_BUS_MASTER	= 0x00000001,
+	HOST_PCI_INIT_FLAG_MSI		= 0x00000002,
+	HOST_PCI_INIT_FLAG_FORCE_I32 	= 0x7fffffff
+} HOST_PCI_INIT_FLAGS;
+
+struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_;
+typedef struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_ *PVRSRV_PCI_DEV_HANDLE;
+
+PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags);
+PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags);
+PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
+PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ);
+IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
+PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
+
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData);
+
+IMG_VOID OSPanic(IMG_VOID);
+
+IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID);
+
+typedef enum _img_verify_test
+{
+	PVR_VERIFY_WRITE = 0,
+	PVR_VERIFY_READ
+} IMG_VERIFY_TEST;
+
+IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_SIZE_T ui32Bytes);
+
+PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
+PVRSRV_ERROR OSCopyFromUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
+
+#if (defined(__linux__) || defined(__QNXNTO__))
+PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, 
+									IMG_SIZE_T ui32Bytes, 
+									IMG_SYS_PHYADDR *psSysPAddr,
+									IMG_HANDLE *phOSWrapMem);
+PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSAcquirePhysPageAddr)
+#endif
+static INLINE PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, 
+												IMG_SIZE_T ui32Bytes, 
+												IMG_SYS_PHYADDR *psSysPAddr,
+												IMG_HANDLE *phOSWrapMem)
+{
+	PVR_UNREFERENCED_PARAMETER(pvCPUVAddr);
+	PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+	PVR_UNREFERENCED_PARAMETER(psSysPAddr);
+	PVR_UNREFERENCED_PARAMETER(phOSWrapMem);
+	return PVRSRV_OK;	
+}
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReleasePhysPageAddr)
+#endif
+static INLINE PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
+{
+	PVR_UNREFERENCED_PARAMETER(hOSWrapMem);
+	return PVRSRV_OK;	
+}
+#endif
+									
+#if defined(__linux__) && defined(__KERNEL__)
+
+#define	OS_SUPPORTS_IN_LISR
+
+static inline IMG_BOOL OSInLISR(IMG_VOID unref__ *pvSysData)
+{
+	PVR_UNREFERENCED_PARAMETER(pvSysData);
+	return (in_irq()) ? IMG_TRUE : IMG_FALSE;
+}
+
+static inline IMG_VOID OSWriteMemoryBarrier(IMG_VOID)
+{
+	wmb();
+}
+
+static inline IMG_VOID OSMemoryBarrier(IMG_VOID)
+{
+	mb();
+}
+
+#else 
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSWriteMemoryBarrier)
+#endif
+static INLINE IMG_VOID OSWriteMemoryBarrier(IMG_VOID) { }
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSMemoryBarrier)
+#endif
+static INLINE IMG_VOID OSMemoryBarrier(IMG_VOID) { }
+
+#endif 
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/osperproc.h b/drivers/staging/cdv/pvr/services4/srvkm/include/osperproc.h
new file mode 100644
index 0000000..e5c81da
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/osperproc.h
@@ -0,0 +1,76 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __OSPERPROC_H__
+#define __OSPERPROC_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__linux__) || defined(__QNXNTO__)
+PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData);
+PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData);
+
+PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
+#else	
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSPerProcessPrivateDataInit)
+#endif
+static INLINE PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData)
+{
+	PVR_UNREFERENCED_PARAMETER(phOsPrivateData);
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSPerProcessPrivateDataDeInit)
+#endif
+static INLINE PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
+{
+	PVR_UNREFERENCED_PARAMETER(hOsPrivateData);
+
+	return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSPerProcessSetHandleOptions)
+#endif
+static INLINE PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
+{
+	PVR_UNREFERENCED_PARAMETER(psHandleBase);
+
+	return PVRSRV_OK;
+}
+#endif	
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/pdump_int.h b/drivers/staging/cdv/pvr/services4/srvkm/include/pdump_int.h
new file mode 100644
index 0000000..9f68549
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/pdump_int.h
@@ -0,0 +1,67 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __PDUMP_INT_H__
+#define __PDUMP_INT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if !defined(_UITRON)
+#include "dbgdrvif.h"
+
+IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID);
+
+#endif 
+
+typedef enum
+{
+	
+	PDUMP_WRITE_MODE_CONTINUOUS = 0,
+	
+	PDUMP_WRITE_MODE_LASTFRAME,
+	
+	PDUMP_WRITE_MODE_BINCM,
+	
+	PDUMP_WRITE_MODE_PERSISTENT
+} PDUMP_DDWMODE;
+
+
+IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags);
+
+IMG_UINT32 PDumpOSDebugDriverWrite(	PDBG_STREAM psStream,
+									PDUMP_DDWMODE eDbgDrvWriteMode,
+									IMG_UINT8 *pui8Data,
+									IMG_UINT32 ui32BCount,
+									IMG_UINT32 ui32Level,
+									IMG_UINT32 ui32DbgDrvFlags);
+
+#if defined (__cplusplus)
+}
+#endif
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/pdump_km.h b/drivers/staging/cdv/pvr/services4/srvkm/include/pdump_km.h
new file mode 100644
index 0000000..418c6d7
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/pdump_km.h
@@ -0,0 +1,414 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _PDUMP_KM_H_
+#define _PDUMP_KM_H_
+
+
+#include "pdump_osfunc.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "pdump.h"
+
+#define PDUMP_PD_UNIQUETAG			(IMG_HANDLE)0
+#define PDUMP_PT_UNIQUETAG			(IMG_HANDLE)0
+
+#define PDUMP_STREAM_PARAM2			0
+#define PDUMP_STREAM_SCRIPT2		1
+#define PDUMP_STREAM_DRIVERINFO		2
+#define PDUMP_NUM_STREAMS			3
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+extern IMG_UINT32 g_ui32EveryLineCounter;
+#endif
+
+#ifndef PDUMP
+#define MAKEUNIQUETAG(hMemInfo)	(0)
+#endif
+
+#ifdef PDUMP
+
+#define MAKEUNIQUETAG(hMemInfo)	(((BM_BUF *)(((PVRSRV_KERNEL_MEM_INFO *)(hMemInfo))->sMemBlk.hBuffer))->pMapping)
+
+	IMG_IMPORT PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+										  IMG_UINT32			ui32Offset,
+										  IMG_UINT32			ui32Value,
+										  IMG_UINT32			ui32Mask,
+										  PDUMP_POLL_OPERATOR	eOperator,
+										  IMG_UINT32			ui32Flags,
+										  IMG_HANDLE			hUniqueTag);
+
+	IMG_IMPORT PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psProcData,
+									   IMG_PVOID			pvAltLinAddr,
+									   IMG_PVOID			pvLinAddr,
+									   PVRSRV_KERNEL_MEM_INFO	*psMemInfo,
+									   IMG_UINT32			ui32Offset,
+									   IMG_UINT32			ui32Bytes,
+									   IMG_UINT32			ui32Flags,
+									   IMG_HANDLE			hUniqueTag);
+
+	IMG_IMPORT PVRSRV_ERROR PDumpMemKM(IMG_PVOID			pvAltLinAddr,
+									   PVRSRV_KERNEL_MEM_INFO	*psMemInfo,
+									   IMG_UINT32			ui32Offset,
+									   IMG_UINT32			ui32Bytes,
+									   IMG_UINT32			ui32Flags,
+									   IMG_HANDLE			hUniqueTag);
+	PVRSRV_ERROR PDumpMemPagesKM(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+								 IMG_DEV_PHYADDR		*pPages,
+								 IMG_UINT32			ui32NumPages,
+								 IMG_DEV_VIRTADDR	sDevAddr,
+								 IMG_UINT32			ui32Start,
+								 IMG_UINT32			ui32Length,
+								 IMG_UINT32			ui32Flags,
+								 IMG_HANDLE			hUniqueTag);
+
+	PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+									 IMG_HANDLE hOSMemHandle,
+							 		 IMG_CPU_VIRTADDR pvLinAddr,
+							 		 IMG_UINT32 ui32Bytes,
+							 		 IMG_UINT32 ui32Flags,
+							 		 IMG_BOOL bInitialisePages,
+							 		 IMG_HANDLE hUniqueTag1,
+							 		 IMG_HANDLE hUniqueTag2);
+							 
+	PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+									 IMG_HANDLE         hOSMemHandle,
+									 IMG_CPU_VIRTADDR	pvLinAddr,
+									 IMG_UINT32			ui32Bytes,
+									 IMG_UINT32			ui32Flags,
+									 IMG_BOOL			bInitialisePages,
+									 IMG_HANDLE			hUniqueTag1,
+									 IMG_HANDLE			hUniqueTag2);
+	IMG_VOID PDumpInitCommon(IMG_VOID);
+	IMG_VOID PDumpDeInitCommon(IMG_VOID);
+	IMG_VOID PDumpInit(IMG_VOID);
+	IMG_VOID PDumpDeInit(IMG_VOID);
+	IMG_BOOL PDumpIsSuspended(IMG_VOID);
+	PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID);
+	PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID);
+	IMG_IMPORT PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame);
+	IMG_IMPORT PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags);
+
+
+	IMG_IMPORT PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags);
+
+	PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+									 IMG_UINT32 ui32RegAddr,
+									 IMG_UINT32 ui32RegValue,
+									 IMG_UINT32 ui32Flags);
+	PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+										IMG_UINT32 ui32RegAddr,
+										IMG_UINT32 ui32RegValue,
+										IMG_UINT32 ui32Mask,
+										IMG_UINT32 ui32Flags,
+										PDUMP_POLL_OPERATOR	eOperator);
+	PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName,
+								IMG_UINT32 ui32RegAddr,
+								IMG_UINT32 ui32RegValue,
+								IMG_UINT32 ui32Mask,
+								PDUMP_POLL_OPERATOR	eOperator);
+
+	IMG_IMPORT PVRSRV_ERROR PDumpBitmapKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+										  IMG_CHAR *pszFileName,
+										  IMG_UINT32 ui32FileOffset,
+										  IMG_UINT32 ui32Width,
+										  IMG_UINT32 ui32Height,
+										  IMG_UINT32 ui32StrideInBytes,
+										  IMG_DEV_VIRTADDR sDevBaseAddr,
+										  IMG_HANDLE hDevMemContext,
+										  IMG_UINT32 ui32Size,
+										  PDUMP_PIXEL_FORMAT ePixelFormat,
+										  PDUMP_MEM_FORMAT eMemFormat,
+										  IMG_UINT32 ui32PDumpFlags);
+	IMG_IMPORT PVRSRV_ERROR PDumpReadRegKM(IMG_CHAR *pszPDumpRegName,
+										   IMG_CHAR *pszFileName,
+										   IMG_UINT32 ui32FileOffset,
+										   IMG_UINT32 ui32Address,
+										   IMG_UINT32 ui32Size,
+										   IMG_UINT32 ui32PDumpFlags);
+
+	PVRSRV_ERROR PDumpRegKM(IMG_CHAR* pszPDumpRegName,
+							IMG_UINT32 dwReg,
+							IMG_UINT32 dwData);
+
+	PVRSRV_ERROR PDumpComment(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+	PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32	ui32Flags,
+									   IMG_CHAR*	pszFormat,
+									   ...) IMG_FORMAT_PRINTF(2, 3);
+
+	PVRSRV_ERROR PDumpPDReg(PDUMP_MMU_ATTRIB *psMMUAttrib,
+							IMG_UINT32	ui32Reg,
+							IMG_UINT32	ui32dwData,
+							IMG_HANDLE	hUniqueTag);
+	PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
+									 IMG_UINT32		ui32Reg,
+									 IMG_UINT32		ui32Data,
+									 IMG_UINT32		ui32Flags,
+									 IMG_HANDLE		hUniqueTag);
+
+	IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID);
+	IMG_IMPORT IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID);
+
+	IMG_VOID PDumpMallocPagesPhys(PVRSRV_DEVICE_IDENTIFIER	*psDevID,
+								  IMG_UINT32			ui32DevVAddr,
+								  IMG_PUINT32			pui32PhysPages,
+								  IMG_UINT32			ui32NumPages,
+								  IMG_HANDLE			hUniqueTag);
+	PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+									IMG_CHAR *pszMemSpace,
+									IMG_UINT32 *pui32MMUContextID,
+									IMG_UINT32 ui32MMUType,
+									IMG_HANDLE hUniqueTag1,
+									IMG_HANDLE hOSMemHandle,
+									IMG_VOID *pvPDCPUAddr);
+	PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+									IMG_CHAR *pszMemSpace,
+									IMG_UINT32 ui32MMUContextID,
+									IMG_UINT32 ui32MMUType);
+
+	PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+								   IMG_UINT32 ui32Offset,
+								   IMG_DEV_PHYADDR sPDDevPAddr,
+								   IMG_HANDLE hUniqueTag1,
+								   IMG_HANDLE hUniqueTag2);
+
+	IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame);
+
+	PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+							 	 IMG_CHAR			*pszFileName,
+								 IMG_UINT32			ui32FileOffset,
+								 IMG_DEV_VIRTADDR	sDevBaseAddr,
+								 IMG_UINT32 		ui32Size,
+								 IMG_UINT32 		ui32DataMaster,
+								 IMG_UINT32 		ui32PDumpFlags);
+
+	PVRSRV_ERROR PDumpTASignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+								   IMG_UINT32	ui32DumpFrameNum,
+								   IMG_UINT32	ui32TAKickCount,
+								   IMG_BOOL		bLastFrame,
+								   IMG_UINT32 *pui32Registers,
+								   IMG_UINT32 ui32NumRegisters);
+
+	PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+											IMG_UINT32 ui32DumpFrameNum,
+											IMG_BOOL bLastFrame,
+											IMG_UINT32 *pui32Registers,
+											IMG_UINT32 ui32NumRegisters);
+
+	PVRSRV_ERROR PDumpCounterRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+					IMG_UINT32 ui32DumpFrameNum,
+					IMG_BOOL		bLastFrame,
+					IMG_UINT32 *pui32Registers,
+					IMG_UINT32 ui32NumRegisters);
+
+	PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
+								const IMG_UINT32 dwRegOffset,
+								IMG_UINT32	ui32Flags);
+
+	PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+										const IMG_UINT32 dwRegOffset,
+										IMG_BOOL bLastFrame);
+
+	PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags);
+	PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks);
+
+	PVRSRV_ERROR PDumpMallocPages(PVRSRV_DEVICE_IDENTIFIER	*psDevID,
+								  IMG_UINT32				ui32DevVAddr,
+								  IMG_CPU_VIRTADDR			pvLinAddr,
+								  IMG_HANDLE				hOSMemHandle,
+								  IMG_UINT32				ui32NumBytes,
+								  IMG_UINT32				ui32PageSize,
+		                          IMG_BOOL			  		bShared,
+								  IMG_HANDLE				hUniqueTag);
+	PVRSRV_ERROR PDumpMallocPageTable(PVRSRV_DEVICE_IDENTIFIER	*psDevId,
+									  IMG_HANDLE            hOSMemHandle,
+									  IMG_UINT32            ui32Offset,
+									  IMG_CPU_VIRTADDR		pvLinAddr,
+									  IMG_UINT32			ui32NumBytes,
+									  IMG_UINT32			ui32Flags,
+									  IMG_HANDLE			hUniqueTag);
+	PVRSRV_ERROR PDumpFreePages(struct _BM_HEAP_	*psBMHeap,
+							IMG_DEV_VIRTADDR	sDevVAddr,
+							IMG_UINT32			ui32NumBytes,
+							IMG_UINT32			ui32PageSize,
+							IMG_HANDLE      	hUniqueTag,
+							IMG_BOOL			bInterleaved);
+	PVRSRV_ERROR PDumpFreePageTable(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+									IMG_HANDLE          hOSMemHandle,
+									IMG_CPU_VIRTADDR	pvLinAddr,
+									IMG_UINT32			ui32NumBytes,
+									IMG_UINT32			ui32Flags,
+									IMG_HANDLE			hUniqueTag);
+
+	IMG_IMPORT PVRSRV_ERROR PDumpHWPerfCBKM(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+										IMG_CHAR			*pszFileName,
+										IMG_UINT32			ui32FileOffset,
+										IMG_DEV_VIRTADDR	sDevBaseAddr,
+										IMG_UINT32 			ui32Size,
+										IMG_UINT32			ui32MMUContextID,
+										IMG_UINT32 			ui32PDumpFlags);
+
+	PVRSRV_ERROR PDumpSignatureBuffer(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+									  IMG_CHAR			*pszFileName,
+									  IMG_CHAR			*pszBufferType,
+									  IMG_UINT32		ui32FileOffset,
+									  IMG_DEV_VIRTADDR	sDevBaseAddr,
+									  IMG_UINT32 		ui32Size,
+									  IMG_UINT32		ui32MMUContextID,
+									  IMG_UINT32 		ui32PDumpFlags);
+
+	PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO	psROffMemInfo,
+				  IMG_UINT32				ui32ROffOffset,
+				  IMG_UINT32				ui32WPosVal,
+				  IMG_UINT32				ui32PacketSize,
+				  IMG_UINT32				ui32BufferSize,
+				  IMG_UINT32				ui32Flags,
+				  IMG_HANDLE				hUniqueTag);
+
+	PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR		*pszPDumpRegName,
+								  IMG_UINT32	ui32RegOffset,
+								  IMG_UINT32	ui32WPosVal,
+								  IMG_UINT32	ui32PacketSize,
+								  IMG_UINT32	ui32BufferSize,
+								  IMG_UINT32	ui32Flags);
+
+	IMG_VOID PDumpVGXMemToFile(IMG_CHAR *pszFileName,
+							   IMG_UINT32 ui32FileOffset, 
+							   PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+							   IMG_UINT32 uiAddr, 
+							   IMG_UINT32 ui32Size,
+							   IMG_UINT32 ui32PDumpFlags,
+							   IMG_HANDLE hUniqueTag);
+
+	IMG_VOID PDumpSuspendKM(IMG_VOID);
+	IMG_VOID PDumpResumeKM(IMG_VOID);
+
+	
+	PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
+							         IMG_CHAR *pszFileName,
+									 IMG_UINT32 ui32FileOffset, 
+									 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+									 IMG_UINT32 uiAddr, 
+									 IMG_UINT32 ui32Size,
+									 IMG_UINT32 ui32PDumpFlags,
+									 IMG_HANDLE hUniqueTag);
+
+	#define PDUMPMEMPOL				PDumpMemPolKM
+	#define PDUMPMEM				PDumpMemKM
+	#define PDUMPMEMPTENTRIES		PDumpMemPTEntriesKM
+	#define PDUMPPDENTRIES			PDumpMemPDEntriesKM
+	#define PDUMPMEMUM				PDumpMemUM
+	#define PDUMPINIT				PDumpInitCommon
+	#define PDUMPDEINIT				PDumpDeInitCommon
+	#define PDUMPISLASTFRAME		PDumpIsLastCaptureFrameKM
+	#define PDUMPTESTFRAME			PDumpIsCaptureFrameKM
+	#define PDUMPTESTNEXTFRAME		PDumpTestNextFrame
+	#define PDUMPREGWITHFLAGS		PDumpRegWithFlagsKM
+	#define PDUMPREG				PDumpRegKM
+	#define PDUMPCOMMENT			PDumpComment
+	#define PDUMPCOMMENTWITHFLAGS	PDumpCommentWithFlags
+	#define PDUMPREGPOL				PDumpRegPolKM
+	#define PDUMPREGPOLWITHFLAGS	PDumpRegPolWithFlagsKM
+	#define PDUMPMALLOCPAGES		PDumpMallocPages
+	#define PDUMPMALLOCPAGETABLE	PDumpMallocPageTable
+	#define PDUMPSETMMUCONTEXT		PDumpSetMMUContext
+	#define PDUMPCLEARMMUCONTEXT	PDumpClearMMUContext
+    #define PDUMPPDDEVPADDR         PDumpPDDevPAddrKM
+	#define PDUMPFREEPAGES			PDumpFreePages
+	#define PDUMPFREEPAGETABLE		PDumpFreePageTable
+	#define PDUMPPDREG				PDumpPDReg
+	#define PDUMPPDREGWITHFLAGS		PDumpPDRegWithFlags
+	#define PDUMPCBP				PDumpCBP
+	#define PDUMPREGBASEDCBP		PDumpRegBasedCBP
+	#define PDUMPMALLOCPAGESPHYS	PDumpMallocPagesPhys
+	#define PDUMPENDINITPHASE		PDumpStopInitPhaseKM
+	#define PDUMPBITMAPKM			PDumpBitmapKM
+	#define PDUMPDRIVERINFO			PDumpDriverInfoKM
+	#define PDUMPIDLWITHFLAGS		PDumpIDLWithFlags
+	#define PDUMPIDL				PDumpIDL
+	#define PDUMPSUSPEND			PDumpSuspendKM
+	#define PDUMPRESUME				PDumpResumeKM
+
+#else
+        #if (((defined(LINUX) || defined(__QNXNTO__)) || defined(GCC_IA32)) || defined(GCC_ARM))
+			#define PDUMPMEMPOL(args...)
+			#define PDUMPMEM(args...)
+			#define PDUMPMEMPTENTRIES(args...)
+			#define PDUMPPDENTRIES(args...)
+			#define PDUMPMEMUM(args...)
+			#define PDUMPINIT(args...)
+			#define PDUMPDEINIT(args...)
+			#define PDUMPISLASTFRAME(args...)
+			#define PDUMPTESTFRAME(args...)
+			#define PDUMPTESTNEXTFRAME(args...)
+			#define PDUMPREGWITHFLAGS(args...)
+			#define PDUMPREG(args...)
+			#define PDUMPCOMMENT(args...)
+			#define PDUMPREGPOL(args...)
+			#define PDUMPREGPOLWITHFLAGS(args...)
+			#define PDUMPMALLOCPAGES(args...)
+			#define PDUMPMALLOCPAGETABLE(args...)
+			#define PDUMPSETMMUCONTEXT(args...)
+			#define PDUMPCLEARMMUCONTEXT(args...)
+            #define PDUMPPDDEVPADDR(args...)
+			#define PDUMPFREEPAGES(args...)
+			#define PDUMPFREEPAGETABLE(args...)
+			#define PDUMPPDREG(args...)
+			#define PDUMPPDREGWITHFLAGS(args...)
+			#define PDUMPSYNC(args...)
+			#define PDUMPCOPYTOMEM(args...)
+			#define PDUMPWRITE(args...)
+			#define PDUMPCBP(args...)
+			#define PDUMPREGBASEDCBP(args...)
+			#define PDUMPCOMMENTWITHFLAGS(args...)
+			#define PDUMPMALLOCPAGESPHYS(args...)
+			#define PDUMPENDINITPHASE(args...)
+			#define PDUMPMSVDXREG(args...)
+			#define PDUMPMSVDXREGWRITE(args...)
+			#define PDUMPMSVDXREGREAD(args...)
+			#define PDUMPMSVDXPOLEQ(args...)
+			#define PDUMPMSVDXPOL(args...)
+			#define PDUMPBITMAPKM(args...)
+			#define PDUMPDRIVERINFO(args...)
+			#define PDUMPIDLWITHFLAGS(args...)
+			#define PDUMPIDL(args...)
+			#define PDUMPSUSPEND(args...)
+			#define PDUMPRESUME(args...)
+			#define PDUMPMSVDXWRITEREF(args...)
+		#else
+			#error Compiler not specified
+		#endif
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/pdump_osfunc.h b/drivers/staging/cdv/pvr/services4/srvkm/include/pdump_osfunc.h
new file mode 100644
index 0000000..f3ed914
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/pdump_osfunc.h
@@ -0,0 +1,142 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stdarg.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#define MAX_PDUMP_STRING_LENGTH (256)
+
+
+
+
+	
+#define PDUMP_GET_SCRIPT_STRING()				\
+	IMG_HANDLE hScript;							\
+	IMG_UINT32	ui32MaxLen;						\
+	PVRSRV_ERROR eError;						\
+	eError = PDumpOSGetScriptString(&hScript, &ui32MaxLen);\
+	if(eError != PVRSRV_OK) return eError;
+
+#define PDUMP_GET_MSG_STRING()					\
+	IMG_CHAR *pszMsg;							\
+	IMG_UINT32	ui32MaxLen;						\
+	PVRSRV_ERROR eError;						\
+	eError = PDumpOSGetMessageString(&pszMsg, &ui32MaxLen);\
+	if(eError != PVRSRV_OK) return eError;
+
+#define PDUMP_GET_FILE_STRING()				\
+	IMG_CHAR *pszFileName;					\
+	IMG_UINT32	ui32MaxLen;					\
+	PVRSRV_ERROR eError;					\
+	eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLen);\
+	if(eError != PVRSRV_OK) return eError;
+
+#define PDUMP_GET_SCRIPT_AND_FILE_STRING()		\
+	IMG_HANDLE hScript;							\
+	IMG_CHAR *pszFileName;						\
+	IMG_UINT32	ui32MaxLenScript;				\
+	IMG_UINT32	ui32MaxLenFileName;				\
+	PVRSRV_ERROR eError;						\
+	eError = PDumpOSGetScriptString(&hScript, &ui32MaxLenScript);\
+	if(eError != PVRSRV_OK) return eError;		\
+	eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLenFileName);\
+	if(eError != PVRSRV_OK) return eError;
+
+	
+	PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript, IMG_UINT32 *pui32MaxLen);
+
+	
+	PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg, IMG_UINT32 *pui32MaxLen);
+
+	
+	PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile, IMG_UINT32 *pui32MaxLen);
+
+
+
+
+#define PDUMP_va_list	va_list
+#define PDUMP_va_start	va_start
+#define PDUMP_va_end	va_end
+
+
+
+IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream);
+
+IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream);
+
+IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID);
+
+IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags);
+
+IMG_BOOL PDumpOSIsSuspended(IMG_VOID);
+
+IMG_BOOL PDumpOSJTInitialised(IMG_VOID);
+
+IMG_BOOL PDumpOSWriteString(IMG_HANDLE hDbgStream,
+		IMG_UINT8 *psui8Data,
+		IMG_UINT32 ui32Size,
+		IMG_UINT32 ui32Flags);
+
+IMG_BOOL PDumpOSWriteString2(IMG_HANDLE	hScript, IMG_UINT32 ui32Flags);
+
+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+
+IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+
+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+
+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszMsg, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs) IMG_FORMAT_PRINTF(3, 0);
+
+IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
+
+IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
+
+IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
+        IMG_HANDLE hOSMemHandle,
+		IMG_UINT32 ui32Offset,
+		IMG_UINT8 *pui8LinAddr,
+		IMG_UINT32 ui32PageSize,
+		IMG_DEV_PHYADDR *psDevPAddr);
+
+IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
+		IMG_UINT32 ui32Offset,
+		IMG_PUINT8 pui8LinAddr,
+		IMG_UINT32 ui32DataPageMask,
+		IMG_UINT32 *pui32PageOffset);
+
+IMG_VOID PDumpOSReleaseExecution(IMG_VOID);
+
+IMG_BOOL PDumpOSIsCaptureFrameKM(IMG_VOID);
+
+PVRSRV_ERROR PDumpOSSetFrameKM(IMG_UINT32 ui32Frame);
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/perproc.h b/drivers/staging/cdv/pvr/services4/srvkm/include/perproc.h
new file mode 100644
index 0000000..842680c
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/perproc.h
@@ -0,0 +1,126 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __PERPROC_H__
+#define __PERPROC_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_types.h"
+#include "resman.h"
+
+#include "handle.h"
+
+typedef struct _PVRSRV_PER_PROCESS_DATA_
+{
+	IMG_UINT32		ui32PID;
+	IMG_HANDLE		hBlockAlloc;
+	PRESMAN_CONTEXT 	hResManContext;
+#if defined (SUPPORT_SID_INTERFACE)
+	IMG_SID			hPerProcData;
+#else
+	IMG_HANDLE		hPerProcData;
+#endif
+	PVRSRV_HANDLE_BASE 	*psHandleBase;
+#if defined (SUPPORT_SID_INTERFACE)
+	
+	IMG_BOOL		bHandlesBatched;
+#else
+#if defined (PVR_SECURE_HANDLES)
+	
+	IMG_BOOL		bHandlesBatched;
+#endif  
+#endif 
+	IMG_UINT32		ui32RefCount;
+
+	
+	IMG_BOOL		bInitProcess;
+#if defined(PDUMP)
+	
+	IMG_BOOL		bPDumpPersistent;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+	
+	IMG_BOOL		bPDumpActive;
+#endif 
+#endif
+	
+	IMG_HANDLE		hOsPrivateData;
+} PVRSRV_PER_PROCESS_DATA;
+
+PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID);
+
+PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32	ui32PID, IMG_UINT32 ui32Flags);
+IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32	ui32PID);
+
+PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID);
+PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID);
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVFindPerProcessData)
+#endif
+static INLINE
+PVRSRV_PER_PROCESS_DATA *PVRSRVFindPerProcessData(IMG_VOID)
+{
+	return PVRSRVPerProcessData(OSGetCurrentProcessIDKM());
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVProcessPrivateData)
+#endif
+static INLINE
+IMG_HANDLE PVRSRVProcessPrivateData(PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+	return (psPerProc != IMG_NULL) ? psPerProc->hOsPrivateData : IMG_NULL;
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPerProcessPrivateData)
+#endif
+static INLINE
+IMG_HANDLE PVRSRVPerProcessPrivateData(IMG_UINT32 ui32PID)
+{
+	return PVRSRVProcessPrivateData(PVRSRVPerProcessData(ui32PID));
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVFindPerProcessPrivateData)
+#endif
+static INLINE
+IMG_HANDLE PVRSRVFindPerProcessPrivateData(IMG_VOID)
+{
+	return PVRSRVProcessPrivateData(PVRSRVFindPerProcessData());
+}
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/power.h b/drivers/staging/cdv/pvr/services4/srvkm/include/power.h
new file mode 100644
index 0000000..9e3dcc40
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/power.h
@@ -0,0 +1,120 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef POWER_H
+#define POWER_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+ 
+typedef struct _PVRSRV_POWER_DEV_TAG_
+{
+	PFN_PRE_POWER					pfnPrePower;
+	PFN_POST_POWER					pfnPostPower;
+	PFN_PRE_CLOCKSPEED_CHANGE		pfnPreClockSpeedChange;
+	PFN_POST_CLOCKSPEED_CHANGE		pfnPostClockSpeedChange;
+	IMG_HANDLE						hDevCookie;
+	IMG_UINT32						ui32DeviceIndex;
+	PVRSRV_DEV_POWER_STATE 			eDefaultPowerState;
+	PVRSRV_DEV_POWER_STATE 			eCurrentPowerState;
+	struct _PVRSRV_POWER_DEV_TAG_	*psNext;
+	struct _PVRSRV_POWER_DEV_TAG_	**ppsThis;
+
+} PVRSRV_POWER_DEV;
+
+typedef enum _PVRSRV_INIT_SERVER_STATE_
+{
+	PVRSRV_INIT_SERVER_Unspecified		= -1,	
+	PVRSRV_INIT_SERVER_RUNNING			= 0,	
+	PVRSRV_INIT_SERVER_RAN				= 1,	
+	PVRSRV_INIT_SERVER_SUCCESSFUL		= 2,	
+	PVRSRV_INIT_SERVER_NUM				= 3,	
+	PVRSRV_INIT_SERVER_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_INIT_SERVER_STATE, *PPVRSRV_INIT_SERVER_STATE;
+
+IMG_IMPORT
+IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE	eInitServerState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE	eInitServerState, IMG_BOOL bState);
+
+
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32	ui32CallerID,
+							 IMG_BOOL	bSystemPowerEvent);
+IMG_IMPORT
+IMG_VOID PVRSRVPowerUnlock(IMG_UINT32	ui32CallerID);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32				ui32DeviceIndex,
+										 PVRSRV_DEV_POWER_STATE	eNewPowerState,
+										 IMG_UINT32				ui32CallerID,
+										 IMG_BOOL				bRetainMutex);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetPowerStateKM (PVRSRV_SYS_POWER_STATE ePVRState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32					ui32DeviceIndex,
+									   PFN_PRE_POWER				pfnPrePower,
+									   PFN_POST_POWER				pfnPostPower,
+									   PFN_PRE_CLOCKSPEED_CHANGE	pfnPreClockSpeedChange,
+									   PFN_POST_CLOCKSPEED_CHANGE	pfnPostClockSpeedChange,
+									   IMG_HANDLE					hDevCookie,
+									   PVRSRV_DEV_POWER_STATE		eCurrentPowerState,
+									   PVRSRV_DEV_POWER_STATE		eDefaultPowerState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex);
+
+IMG_IMPORT
+IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32	ui32DeviceIndex,
+											 IMG_BOOL	bIdleDevice,
+											 IMG_VOID	*pvInfo);
+
+IMG_IMPORT
+IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32	ui32DeviceIndex,
+										  IMG_BOOL		bIdleDevice,
+										  IMG_VOID		*pvInfo);
+
+#if defined (__cplusplus)
+}
+#endif
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/queue.h b/drivers/staging/cdv/pvr/services4/srvkm/include/queue.h
new file mode 100644
index 0000000..ab89527
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/queue.h
@@ -0,0 +1,110 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define UPDATE_QUEUE_ROFF(psQueue, ui32Size)						\
+	(psQueue)->ui32ReadOffset = ((psQueue)->ui32ReadOffset + (ui32Size))	\
+	& ((psQueue)->ui32QueueSize - 1);
+
+ typedef struct _COMMAND_COMPLETE_DATA_
+ {
+	IMG_BOOL			bInUse;
+		
+	IMG_UINT32			ui32DstSyncCount;	
+	IMG_UINT32			ui32SrcSyncCount;	
+	PVRSRV_SYNC_OBJECT	*psDstSync;			
+	PVRSRV_SYNC_OBJECT	*psSrcSync;			
+	IMG_UINT32			ui32AllocSize;		
+ }COMMAND_COMPLETE_DATA, *PCOMMAND_COMPLETE_DATA;
+
+#if !defined(USE_CODE)
+IMG_VOID QueueDumpDebugInfo(IMG_VOID);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVProcessQueues (IMG_BOOL		bFlush);
+
+#if defined(__linux__) && defined(__KERNEL__) 
+#include <linux/types.h>
+#include <linux/seq_file.h>
+void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off);
+void ProcSeqShowQueue(struct seq_file *sfile,void* el);
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
+													 PVRSRV_QUEUE_INFO **ppsQueueInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO	*psQueue,
+												PVRSRV_COMMAND		**ppsCommand,
+												IMG_UINT32			ui32DevIndex,
+												IMG_UINT16			CommandType,
+												IMG_UINT32			ui32DstSyncCount,
+												PVRSRV_KERNEL_SYNC_INFO	*apsDstSync[],
+												IMG_UINT32			ui32SrcSyncCount,
+												PVRSRV_KERNEL_SYNC_INFO	*apsSrcSync[],
+												IMG_SIZE_T			ui32DataByteSize );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
+												IMG_SIZE_T ui32ParamSize,
+												IMG_VOID **ppvSpace);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
+												PVRSRV_COMMAND *psCommand);
+
+IMG_IMPORT
+IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, IMG_BOOL bScheduleMISR);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32		ui32DevIndex,
+										 PFN_CMD_PROC	*ppfnCmdProcList,
+										 IMG_UINT32		ui32MaxSyncsPerCmd[][2],
+										 IMG_UINT32		ui32CmdCount);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32	ui32DevIndex,
+									   IMG_UINT32	ui32CmdCount);
+
+#endif 
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/ra.h b/drivers/staging/cdv/pvr/services4/srvkm/include/ra.h
new file mode 100644
index 0000000..db141f6
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/ra.h
@@ -0,0 +1,159 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _RA_H_
+#define _RA_H_
+
+#include "img_types.h"
+#include "hash.h"
+#include "osfunc.h"
+
+typedef struct _RA_ARENA_ RA_ARENA;			
+typedef struct _BM_MAPPING_ BM_MAPPING;
+
+
+
+#define RA_STATS 
+
+
+struct _RA_STATISTICS_
+{
+    
+    IMG_SIZE_T uSpanCount;
+
+    
+    IMG_SIZE_T uLiveSegmentCount;
+
+    
+    IMG_SIZE_T uFreeSegmentCount;
+
+    
+    IMG_SIZE_T uTotalResourceCount;
+    
+    
+    IMG_SIZE_T uFreeResourceCount;
+
+    
+    IMG_SIZE_T uCumulativeAllocs;
+
+    
+    IMG_SIZE_T uCumulativeFrees;
+
+    
+    IMG_SIZE_T uImportCount;
+
+    
+    IMG_SIZE_T uExportCount;
+};
+typedef struct _RA_STATISTICS_ RA_STATISTICS;
+
+struct _RA_SEGMENT_DETAILS_
+{
+	IMG_SIZE_T      uiSize;
+	IMG_CPU_PHYADDR sCpuPhyAddr;
+	IMG_HANDLE      hSegment;
+};
+typedef struct _RA_SEGMENT_DETAILS_ RA_SEGMENT_DETAILS;
+
+RA_ARENA *
+RA_Create (IMG_CHAR *name,
+           IMG_UINTPTR_T base,
+           IMG_SIZE_T uSize,
+           BM_MAPPING *psMapping,
+           IMG_SIZE_T uQuantum, 
+           IMG_BOOL (*imp_alloc)(IMG_VOID *_h,
+                                IMG_SIZE_T uSize,
+                                IMG_SIZE_T *pActualSize,
+                                BM_MAPPING **ppsMapping,
+                                IMG_UINT32 uFlags,
+                                IMG_UINTPTR_T *pBase),
+           IMG_VOID (*imp_free) (IMG_VOID *,
+                                IMG_UINTPTR_T,
+                                BM_MAPPING *),
+           IMG_VOID (*backingstore_free) (IMG_VOID *,
+                                          IMG_SIZE_T,
+                                          IMG_SIZE_T,
+                                          IMG_HANDLE),
+           IMG_VOID *import_handle);
+
+IMG_VOID
+RA_Delete (RA_ARENA *pArena);
+
+IMG_BOOL
+RA_TestDelete (RA_ARENA *pArena);
+
+IMG_BOOL
+RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize);
+
+IMG_BOOL
+RA_Alloc (RA_ARENA *pArena, 
+          IMG_SIZE_T uSize,
+          IMG_SIZE_T *pActualSize,
+          BM_MAPPING **ppsMapping, 
+          IMG_UINT32 uFlags,
+          IMG_UINT32 uAlignment,
+		  IMG_UINT32 uAlignmentOffset,
+          IMG_UINTPTR_T *pBase);
+
+IMG_VOID 
+RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore);
+
+
+#ifdef RA_STATS
+
+#define CHECK_SPACE(total)					\
+{											\
+	if((total)<100) 							\
+		return PVRSRV_ERROR_INVALID_PARAMS;	\
+}
+
+#define UPDATE_SPACE(str, count, total)		\
+{											\
+	if((count) == -1)					 		\
+		return PVRSRV_ERROR_INVALID_PARAMS;	\
+	else									\
+	{										\
+		(str) += (count);						\
+		(total) -= (count);						\
+	}										\
+}
+
+
+IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails);
+
+
+PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena,
+							IMG_CHAR **ppszStr, 
+							IMG_UINT32 *pui32StrLen);
+
+PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena,
+								IMG_CHAR **ppszStr, 
+								IMG_UINT32 *pui32StrLen);
+
+#endif 
+
+#endif
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/resman.h b/drivers/staging/cdv/pvr/services4/srvkm/include/resman.h
new file mode 100644
index 0000000..648e490
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/resman.h
@@ -0,0 +1,118 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __RESMAN_H__
+#define __RESMAN_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+enum {
+	
+	RESMAN_TYPE_SHARED_PB_DESC = 1,					
+	RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,				
+	RESMAN_TYPE_HW_RENDER_CONTEXT,					
+	RESMAN_TYPE_HW_TRANSFER_CONTEXT,				
+	RESMAN_TYPE_HW_2D_CONTEXT,						
+	RESMAN_TYPE_TRANSFER_CONTEXT,					
+
+	
+	RESMAN_TYPE_DMA_CLIENT_FIFO_DATA,				
+
+	
+	
+	
+	
+	RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,			
+	RESMAN_TYPE_DISPLAYCLASS_DEVICE,				
+
+	
+	RESMAN_TYPE_BUFFERCLASS_DEVICE,					
+	
+	
+	RESMAN_TYPE_OS_USERMODE_MAPPING,				
+	
+	
+	RESMAN_TYPE_DEVICEMEM_CONTEXT,					
+	RESMAN_TYPE_DEVICECLASSMEM_MAPPING,				
+	RESMAN_TYPE_DEVICEMEM_MAPPING,					
+	RESMAN_TYPE_DEVICEMEM_WRAP,						
+	RESMAN_TYPE_DEVICEMEM_ALLOCATION,				
+	RESMAN_TYPE_EVENT_OBJECT,						
+    RESMAN_TYPE_SHARED_MEM_INFO,                    
+    RESMAN_TYPE_MODIFY_SYNC_OPS,					
+    RESMAN_TYPE_SYNC_INFO,					        
+	
+	
+	RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION			
+};
+
+#define RESMAN_CRITERIA_ALL				0x00000000	
+#define RESMAN_CRITERIA_RESTYPE			0x00000001	
+#define RESMAN_CRITERIA_PVOID_PARAM		0x00000002	
+#define RESMAN_CRITERIA_UI32_PARAM		0x00000004	
+
+typedef PVRSRV_ERROR (*RESMAN_FREE_FN)(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bForceCleanup); 
+
+typedef struct _RESMAN_ITEM_ *PRESMAN_ITEM;
+typedef struct _RESMAN_CONTEXT_ *PRESMAN_CONTEXT;
+
+PVRSRV_ERROR ResManInit(IMG_VOID);
+IMG_VOID ResManDeInit(IMG_VOID);
+
+PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT	hResManContext,
+							   IMG_UINT32		ui32ResType, 
+							   IMG_PVOID		pvParam, 
+							   IMG_UINT32		ui32Param, 
+							   RESMAN_FREE_FN	pfnFreeResource);
+
+PVRSRV_ERROR ResManFreeResByPtr(PRESMAN_ITEM	psResItem,
+								IMG_BOOL		bForceCleanup);
+
+PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT	hResManContext,
+									 IMG_UINT32			ui32SearchCriteria, 
+									 IMG_UINT32			ui32ResType, 
+									 IMG_PVOID			pvParam, 
+									 IMG_UINT32			ui32Param);
+
+PVRSRV_ERROR ResManDissociateRes(PRESMAN_ITEM		psResItem,
+							 PRESMAN_CONTEXT	psNewResManContext);
+
+PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT	hResManContext,
+									 PRESMAN_ITEM		psItem);
+
+PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE			hPerProc,
+								 PRESMAN_CONTEXT	*phResManContext);
+IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT hResManContext,
+								IMG_BOOL		bKernelContext);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/services_headers.h b/drivers/staging/cdv/pvr/services4/srvkm/include/services_headers.h
new file mode 100644
index 0000000..2b5f197
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/services_headers.h
@@ -0,0 +1,49 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef SERVICES_HEADERS_H
+#define SERVICES_HEADERS_H
+
+#ifdef DEBUG_RELEASE_BUILD
+#pragma optimize( "", off )
+#define DEBUG		1
+#endif
+
+#include "img_defs.h"
+#include "services.h"
+#include "servicesint.h"
+#include "power.h"
+#include "resman.h"
+#include "queue.h"
+#include "srvkm.h"
+#include "kerneldisplay.h"
+#include "syscommon.h"
+#include "pvr_debug.h"
+#include "metrics.h"
+#include "osfunc.h"
+
+#endif 
+
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/srvkm.h b/drivers/staging/cdv/pvr/services4/srvkm/include/srvkm.h
new file mode 100644
index 0000000..474a1ee
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/srvkm.h
@@ -0,0 +1,78 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef SRVKM_H
+#define SRVKM_H
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+	
+	#ifdef PVR_DISABLE_LOGGING
+	#define PVR_LOG(X)
+	#else
+	 
+	#define PVR_LOG(X)			PVRSRVReleasePrintf X;
+	#endif
+
+	IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+
+	IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32	ui32PID, IMG_UINT32 ui32Flags);
+	IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32	ui32PID);
+
+	IMG_IMPORT IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID);
+
+	IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State);
+
+	PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave);
+
+	IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+ 
+#define LOOP_UNTIL_TIMEOUT(TIMEOUT) \
+{\
+	IMG_UINT32 uiOffset, uiStart, uiCurrent; \
+	IMG_INT32 iNotLastLoop;					 \
+	for(uiOffset = 0, uiStart = OSClockus(), uiCurrent = uiStart + 1, iNotLastLoop = 1;\
+		((uiCurrent - uiStart + uiOffset) < (TIMEOUT)) || iNotLastLoop--;				\
+		uiCurrent = OSClockus(),													\
+		uiOffset = uiCurrent < uiStart ? IMG_UINT32_MAX - uiStart : uiOffset,		\
+		uiStart = uiCurrent < uiStart ? 0 : uiStart)
+
+#define END_LOOP_UNTIL_TIMEOUT() \
+}
+
+IMG_IMPORT
+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError);
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/ttrace.h b/drivers/staging/cdv/pvr/services4/srvkm/include/ttrace.h
new file mode 100755
index 0000000..9e04b88
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/ttrace.h
@@ -0,0 +1,184 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "ttrace_common.h"
+#include "ttrace_tokens.h"
+
+#ifndef __TTRACE_H__
+#define __TTRACE_H__
+
+#if defined(TTRACE)
+
+	#define PVR_TTRACE(group, class, token) \
+			PVRSRVTimeTrace(group, class, token)
+	#define PVR_TTRACE_UI8(group, class, token, val) \
+			PVRSRVTimeTraceUI8(group, class, token, val)
+	#define PVR_TTRACE_UI16(group, class, token, val) \
+			PVRSRVTimeTraceUI16(group, class, token, val)
+	#define PVR_TTRACE_UI32(group, class, token, val) \
+			PVRSRVTimeTraceUI32(group, class, token, val)
+	#define PVR_TTRACE_UI64(group, class, token, val) \
+			PVRSRVTimeTraceUI64(group, class, token, val)
+	#define PVR_TTRACE_DEV_VIRTADDR(group, class, token, val) \
+			PVRSRVTimeTraceDevVirtAddr(group, class, token, val)
+	#define PVR_TTRACE_CPU_PHYADDR(group, class, token, val) \
+			PVRSRVTimeTraceCpuPhyAddr(group, class, token, val)
+	#define PVR_TTRACE_DEV_PHYADDR(group, class, token, val) \
+			PVRSRVTimeTraceDevPhysAddr(group, class, token, val)
+	#define PVR_TTRACE_SYS_PHYADDR(group, class, token, val) \
+			PVRSRVTimeTraceSysPhysAddr(group, class, token, val)
+	#define PVR_TTRACE_SYNC_OBJECT(group, token, syncobj, op) \
+			PVRSRVTimeTraceSyncObject(group, token, syncobj, op)
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTimeTraceArray(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+							IMG_UINT32 ui32Token, IMG_UINT32 ui32TypeSize,
+							IMG_UINT32 ui32Count, IMG_UINT8 *ui8Data);
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTrace)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTrace(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+						IMG_UINT32 ui32Token)
+{
+	PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, 0, 0, NULL);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI8)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI8(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+						IMG_UINT32 ui32Token, IMG_UINT8 ui8Value)
+{
+	PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI8,
+				1, &ui8Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI16)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI16(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+						IMG_UINT32 ui32Token, IMG_UINT16 ui16Value)
+{
+	PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI16,
+				1, (IMG_UINT8 *) &ui16Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI32)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI32(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+						IMG_UINT32 ui32Token, IMG_UINT32 ui32Value)
+{
+	PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+				1, (IMG_UINT8 *) &ui32Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI64)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI64(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+						IMG_UINT32 ui32Token, IMG_UINT64 ui64Value)
+{
+	PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI64,
+				1, (IMG_UINT8 *) &ui64Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceDevVirtAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceDevVirtAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+						IMG_UINT32 ui32Token, IMG_DEV_VIRTADDR psVAddr)
+{
+	PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+				1, (IMG_UINT8 *) &psVAddr.uiAddr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceCpuPhyAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceCpuPhyAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+						IMG_UINT32 ui32Token, IMG_CPU_PHYADDR psPAddr)
+{
+	PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+				1, (IMG_UINT8 *) &psPAddr.uiAddr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceDevPhysAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceDevPhysAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+						IMG_UINT32 ui32Token, IMG_DEV_PHYADDR psPAddr)
+{
+	PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+				1, (IMG_UINT8 *) &psPAddr.uiAddr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceSysPhysAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceSysPhysAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+						IMG_UINT32 ui32Token, IMG_SYS_PHYADDR psPAddr)
+{
+	PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, sizeof(psPAddr.uiAddr),
+				1, (IMG_UINT8 *) &psPAddr.uiAddr);
+}
+
+#else 
+
+	#define PVR_TTRACE(group, class, token) \
+			((void) 0)
+	#define PVR_TTRACE_UI8(group, class, token, val) \
+			((void) 0)
+	#define PVR_TTRACE_UI16(group, class, token, val) \
+			((void) 0)
+	#define PVR_TTRACE_UI32(group, class, token, val) \
+			((void) 0)
+	#define PVR_TTRACE_UI64(group, class, token, val) \
+			((void) 0)
+	#define PVR_TTRACE_DEV_VIRTADDR(group, class, token, val) \
+			((void) 0)
+	#define PVR_TTRACE_CPU_PHYADDR(group, class, token, val) \
+			((void) 0)
+	#define PVR_TTRACE_DEV_PHYADDR(group, class, token, val) \
+			((void) 0)
+	#define PVR_TTRACE_SYS_PHYADDR(group, class, token, val) \
+			((void) 0)
+	#define PVR_TTRACE_SYNC_OBJECT(group, token, syncobj, op) \
+			((void) 0)
+
+#endif 
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceInit(IMG_VOID);
+IMG_IMPORT IMG_VOID PVRSRVTimeTraceDeinit(IMG_VOID);
+
+IMG_IMPORT IMG_VOID PVRSRVTimeTraceSyncObject(IMG_UINT32 ui32Group, IMG_UINT32 ui32Token,
+					      PVRSRV_KERNEL_SYNC_INFO *psSync, IMG_UINT8 ui8SyncOp);
+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceBufferCreate(IMG_UINT32 ui32PID);
+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceBufferDestroy(IMG_UINT32 ui32PID);
+
+IMG_IMPORT IMG_VOID PVRSRVDumpTimeTraceBuffers(IMG_VOID);
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/ttrace_common.h b/drivers/staging/cdv/pvr/services4/srvkm/include/ttrace_common.h
new file mode 100755
index 0000000..5895b6c
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/ttrace_common.h
@@ -0,0 +1,81 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "img_types.h"
+
+#ifndef __TTRACE_COMMON_H__
+#define __TTRACE_COMMON_H__
+
+#define PVRSRV_TRACE_HEADER		0
+#define PVRSRV_TRACE_TIMESTAMP		1
+#define PVRSRV_TRACE_HOSTUID		2
+#define PVRSRV_TRACE_DATA_HEADER	3
+#define PVRSRV_TRACE_DATA_PAYLOAD	4
+
+#define PVRSRV_TRACE_ITEM_SIZE		16
+
+#define PVRSRV_TRACE_GROUP_MASK		0xff
+#define PVRSRV_TRACE_CLASS_MASK		0xff
+#define PVRSRV_TRACE_TOKEN_MASK		0xffff
+
+#define PVRSRV_TRACE_GROUP_SHIFT	24
+#define PVRSRV_TRACE_CLASS_SHIFT	16
+#define PVRSRV_TRACE_TOKEN_SHIFT	0
+
+#define PVRSRV_TRACE_SIZE_MASK		0xffff
+#define PVRSRV_TRACE_TYPE_MASK		0xf
+#define PVRSRV_TRACE_COUNT_MASK		0xfff
+
+#define PVRSRV_TRACE_SIZE_SHIFT		16
+#define PVRSRV_TRACE_TYPE_SHIFT		12
+#define PVRSRV_TRACE_COUNT_SHIFT	0
+
+
+#define WRITE_HEADER(n,m) \
+	((m & PVRSRV_TRACE_##n##_MASK) << PVRSRV_TRACE_##n##_SHIFT)
+
+#define READ_HEADER(n,m) \
+	((m & (PVRSRV_TRACE_##n##_MASK << PVRSRV_TRACE_##n##_SHIFT)) >> PVRSRV_TRACE_##n##_SHIFT)
+
+#define TIME_TRACE_BUFFER_SIZE		4096
+
+#define PVRSRV_TRACE_TYPE_UI8		0
+#define PVRSRV_TRACE_TYPE_UI16		1
+#define PVRSRV_TRACE_TYPE_UI32		2
+#define PVRSRV_TRACE_TYPE_UI64		3
+
+#define PVRSRV_TRACE_TYPE_SYNC		15
+ #define PVRSRV_TRACE_SYNC_UID		0
+ #define PVRSRV_TRACE_SYNC_WOP		1
+ #define PVRSRV_TRACE_SYNC_WOC		2
+ #define PVRSRV_TRACE_SYNC_ROP		3
+ #define PVRSRV_TRACE_SYNC_ROC		4
+ #define PVRSRV_TRACE_SYNC_WO_DEV_VADDR	5
+ #define PVRSRV_TRACE_SYNC_RO_DEV_VADDR	6
+ #define PVRSRV_TRACE_SYNC_OP		7
+#define PVRSRV_TRACE_TYPE_SYNC_SIZE	((PVRSRV_TRACE_SYNC_OP + 1) * sizeof(IMG_UINT32))
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/srvkm/include/ttrace_tokens.h b/drivers/staging/cdv/pvr/services4/srvkm/include/ttrace_tokens.h
new file mode 100755
index 0000000..21ea5fb
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/srvkm/include/ttrace_tokens.h
@@ -0,0 +1,84 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __TTRACE_TOKENS_H__
+#define __TTRACE_TOKENS_H__
+
+#define PVRSRV_TRACE_GROUP_KICK		0
+#define PVRSRV_TRACE_GROUP_TRANSFER	1
+#define PVRSRV_TRACE_GROUP_QUEUE	2
+#define PVRSRV_TRACE_GROUP_POWER	3
+#define PVRSRV_TRACE_GROUP_MKSYNC	4
+
+#define PVRSRV_TRACE_GROUP_PADDING	255
+
+#define PVRSRV_TRACE_CLASS_FUNCTION_ENTER	0
+#define PVRSRV_TRACE_CLASS_FUNCTION_EXIT	1
+#define PVRSRV_TRACE_CLASS_SYNC			2
+#define PVRSRV_TRACE_CLASS_CCB			3
+#define PVRSRV_TRACE_CLASS_CMD_START		4
+#define PVRSRV_TRACE_CLASS_CMD_END		5
+#define PVRSRV_TRACE_CLASS_CMD_COMP_START	6
+#define PVRSRV_TRACE_CLASS_CMD_COMP_END		7
+
+#define PVRSRV_TRACE_CLASS_NONE			255
+
+#define PVRSRV_SYNCOP_SAMPLE		0
+#define PVRSRV_SYNCOP_COMPLETE		1
+#define PVRSRV_SYNCOP_DUMP		2
+
+#define KICK_TOKEN_DOKICK		0
+#define KICK_TOKEN_CCB_OFFSET		1
+#define KICK_TOKEN_TA3D_SYNC		2
+#define KICK_TOKEN_TA_SYNC		3
+#define KICK_TOKEN_3D_SYNC		4
+#define KICK_TOKEN_SRC_SYNC		5
+#define KICK_TOKEN_DST_SYNC		6
+
+#define TRANSFER_TOKEN_SUBMIT		0
+#define TRANSFER_TOKEN_TA_SYNC		1
+#define TRANSFER_TOKEN_3D_SYNC		2
+#define TRANSFER_TOKEN_SRC_SYNC		3
+#define TRANSFER_TOKEN_DST_SYNC		4
+#define TRANSFER_TOKEN_CCB_OFFSET	5
+
+#define QUEUE_TOKEN_GET_SPACE		0
+#define QUEUE_TOKEN_INSERTKM		1
+#define QUEUE_TOKEN_SUBMITKM		2
+#define QUEUE_TOKEN_PROCESS_COMMAND	3
+#define QUEUE_TOKEN_PROCESS_QUEUES	4
+#define QUEUE_TOKEN_COMMAND_COMPLETE	5
+#define QUEUE_TOKEN_UPDATE_DST		6
+#define QUEUE_TOKEN_UPDATE_SRC		7
+#define QUEUE_TOKEN_SRC_SYNC		8
+#define QUEUE_TOKEN_DST_SYNC		9
+#define QUEUE_TOKEN_COMMAND_TYPE	10
+
+#define MKSYNC_TOKEN_KERNEL_CCB_OFFSET	0
+#define MKSYNC_TOKEN_CORE_CLK		1
+#define MKSYNC_TOKEN_UKERNEL_CLK	2
+
+#endif 
diff --git a/drivers/staging/cdv/pvr/services4/system/include/syscommon.h b/drivers/staging/cdv/pvr/services4/system/include/syscommon.h
new file mode 100644
index 0000000..6131e13
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/include/syscommon.h
@@ -0,0 +1,262 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _SYSCOMMON_H
+#define _SYSCOMMON_H
+
+#include "sysconfig.h"      
+#include "sysinfo.h"		
+#include "servicesint.h"
+#include "queue.h"
+#include "power.h"
+#include "resman.h"
+#include "ra.h"
+#include "device.h"
+#include "buffer_manager.h"
+#include "pvr_debug.h"
+#include "services.h"
+
+#if defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__)
+#include <asm/io.h>
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+typedef struct _SYS_DEVICE_ID_TAG
+{
+	IMG_UINT32	uiID;
+	IMG_BOOL	bInUse;
+
+} SYS_DEVICE_ID;
+
+
+#define SYS_MAX_LOCAL_DEVMEM_ARENAS	4
+
+typedef IMG_HANDLE (*PFN_HTIMER_CREATE) (IMG_VOID);
+typedef IMG_UINT32 (*PFN_HTIMER_GETUS) (IMG_HANDLE);
+typedef IMG_VOID (*PFN_HTIMER_DESTROY) (IMG_HANDLE);
+typedef struct _SYS_DATA_TAG_
+{
+    IMG_UINT32                  ui32NumDevices;      	   	
+	SYS_DEVICE_ID				sDeviceID[SYS_DEVICE_COUNT];
+    PVRSRV_DEVICE_NODE			*psDeviceNodeList;			
+    PVRSRV_POWER_DEV			*psPowerDeviceList;			
+	PVRSRV_RESOURCE				sPowerStateChangeResource;	
+   	PVRSRV_SYS_POWER_STATE		eCurrentPowerState;			
+   	PVRSRV_SYS_POWER_STATE		eFailedPowerState;			
+   	IMG_UINT32		 			ui32CurrentOSPowerState;	
+    PVRSRV_QUEUE_INFO           *psQueueList;           	
+   	PVRSRV_KERNEL_SYNC_INFO 	*psSharedSyncInfoList;		
+    IMG_PVOID                   pvEnvSpecificData;      	
+    IMG_PVOID                   pvSysSpecificData;    	  	
+	PVRSRV_RESOURCE				sQProcessResource;			
+	IMG_VOID					*pvSOCRegsBase;				
+    IMG_HANDLE                  hSOCTimerRegisterOSMemHandle; 
+	IMG_UINT32					*pvSOCTimerRegisterKM;		
+	IMG_VOID					*pvSOCClockGateRegsBase;	
+	IMG_UINT32					ui32SOCClockGateRegsSize;
+															
+	struct _DEVICE_COMMAND_DATA_ *apsDeviceCommandData[SYS_DEVICE_COUNT];
+															
+
+	RA_ARENA					*apsLocalDevMemArena[SYS_MAX_LOCAL_DEVMEM_ARENAS]; 
+
+    IMG_CHAR                    *pszVersionString;          
+#if defined (SUPPORT_SID_INTERFACE)
+	PVRSRV_EVENTOBJECT_KM		*psGlobalEventObject;		
+#else
+	PVRSRV_EVENTOBJECT			*psGlobalEventObject;		
+#endif
+
+	PVRSRV_MISC_INFO_CPUCACHEOP_TYPE ePendingCacheOpType;	
+
+	PFN_HTIMER_CREATE	pfnHighResTimerCreate;
+	PFN_HTIMER_GETUS	pfnHighResTimerGetus;
+	PFN_HTIMER_DESTROY	pfnHighResTimerDestroy;
+} SYS_DATA;
+
+
+
+PVRSRV_ERROR SysInitialise(IMG_VOID);
+PVRSRV_ERROR SysFinalise(IMG_VOID);
+
+PVRSRV_ERROR SysDeinitialise(SYS_DATA *psSysData);
+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
+									IMG_VOID **ppvDeviceMap);
+
+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_UINT32 SysGetInterruptSource(SYS_DATA			*psSysData,
+								 PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits);
+
+PVRSRV_ERROR SysResetDevice(IMG_UINT32 ui32DeviceIndex);
+
+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
+									PVRSRV_DEV_POWER_STATE eNewPowerState,
+									PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
+									 PVRSRV_DEV_POWER_STATE eNewPowerState,
+									 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock);
+IMG_VOID SysPowerLockUnwrap(IMG_VOID);
+#endif
+
+PVRSRV_ERROR SysOEMFunction (	IMG_UINT32	ui32ID,
+								IMG_VOID	*pvIn,
+								IMG_UINT32  ulInSize,
+								IMG_VOID	*pvOut,
+								IMG_UINT32	ulOutSize);
+
+
+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR cpu_paddr);
+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr);
+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR SysPAddr);
+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR SysPAddr);
+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr);
+#if defined(PVR_LMA)
+IMG_BOOL SysVerifyCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR CpuPAddr);
+IMG_BOOL SysVerifySysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr);
+#endif
+
+extern SYS_DATA* gpsSysData;
+
+
+#if !defined(USE_CODE)
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysAcquireData)
+#endif
+static INLINE IMG_VOID SysAcquireData(SYS_DATA **ppsSysData)
+{
+	
+	*ppsSysData = gpsSysData;
+
+	
+
+
+
+	PVR_ASSERT (gpsSysData != IMG_NULL);
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysAcquireDataNoCheck)
+#endif
+static INLINE SYS_DATA * SysAcquireDataNoCheck(IMG_VOID)
+{
+	
+	return gpsSysData;
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysInitialiseCommon)
+#endif
+static INLINE PVRSRV_ERROR SysInitialiseCommon(SYS_DATA *psSysData)
+{
+	PVRSRV_ERROR	eError;
+
+	
+	eError = PVRSRVInit(psSysData);
+
+	return eError;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysDeinitialiseCommon)
+#endif
+static INLINE IMG_VOID SysDeinitialiseCommon(SYS_DATA *psSysData)
+{
+	
+	PVRSRVDeInit(psSysData);
+
+	OSDestroyResource(&psSysData->sPowerStateChangeResource);
+}
+#endif 
+
+
+#if !(defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__))
+#define	SysReadHWReg(p, o) OSReadHWReg(p, o)
+#define SysWriteHWReg(p, o, v) OSWriteHWReg(p, o, v)
+#else	
+static inline IMG_UINT32 SysReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
+{
+	return (IMG_UINT32) readl(pvLinRegBaseAddr + ui32Offset);
+}
+
+static inline IMG_VOID SysWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+	writel(ui32Value, pvLinRegBaseAddr + ui32Offset);
+}
+#endif	
+
+#if defined(__cplusplus)
+}
+#endif
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysHighResTimerCreate)
+#endif
+static INLINE IMG_HANDLE SysHighResTimerCreate(IMG_VOID)
+{
+	SYS_DATA *psSysData;
+
+	SysAcquireData(&psSysData);
+	return psSysData->pfnHighResTimerCreate();
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysHighResTimerGetus)
+#endif
+static INLINE IMG_UINT32 SysHighResTimerGetus(IMG_HANDLE hTimer)
+{
+	SYS_DATA *psSysData;
+
+	SysAcquireData(&psSysData);
+	return psSysData->pfnHighResTimerGetus(hTimer);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysHighResTimerDestroy)
+#endif
+static INLINE IMG_VOID SysHighResTimerDestroy(IMG_HANDLE hTimer)
+{
+	SYS_DATA *psSysData;
+
+	SysAcquireData(&psSysData);
+	psSysData->pfnHighResTimerDestroy(hTimer);
+}
+#endif
+
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/extsyscache.h b/drivers/staging/cdv/pvr/services4/system/unified/extsyscache.h
new file mode 100644
index 0000000..c3b9517
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/extsyscache.h
@@ -0,0 +1,44 @@
+#include "sgxdefs.h"
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+/*
+	byte offsets to ext cache control registers from the
+	base of the external register bank
+	- TO BE SPECIFIED IN SYSTEM PORT!
+*/
+/* global invalidate */
+/* This address must be the physical address of the cache controller rounded
+   down to the nearest page*/
+#define SYS_EXT_SYS_CACHE_GBL_INV_REG_OFFSET	0x80000000
+
+
+/* per address invalidate (data written in the address) */
+/* This is the offset within the page to the cache controller which we want
+   to write */
+#define SYS_EXT_SYS_CACHE_ADDR_INV_REG_OFFSET	0x0
+
+/*
+	FIXME: these two defines should really live in sgxconfig.h as a heap define
+	not possible right now due to .h include issues
+*/
+
+/* This address must not live within the same virtal address as
+   any of the heaps, but must be within a shared heap */
+
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 32
+#define SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE			(0xF8FFE000)
+#endif
+
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 28
+#define SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE			(0x0F3FE000)
+#endif
+
+/* assume 4k is enough range to cover all control registers */
+#define SGX_EXT_SYSTEM_CACHE_REGS_SIZE					 0x00001000
+
+#define INVALIDATE_EXT_SYSTEM_CACHE_INLINE(RegA)									\
+	mov		RegA, HSH(SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE);						\
+	stad.bpcache	[RegA, HSH(SYS_EXT_SYS_CACHE_ADDR_INV_REG_OFFSET>>2)], HSH(0);	\
+	idf		drc0, st;																\
+	wdf		drc0;
+#endif /* SUPPORT_EXTERNAL_SYSTEM_CACHE */
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/oemfuncs.h b/drivers/staging/cdv/pvr/services4/system/unified/oemfuncs.h
new file mode 100644
index 0000000..0d3b6d7
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/oemfuncs.h
@@ -0,0 +1,72 @@
+/**********************************************************************
+ *
+ * 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(__OEMFUNCS_H__)
+#define __OEMFUNCS_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define OEM_EXCHANGE_POWER_STATE	(1<<0)
+#define OEM_DEVICE_MEMORY_POWER		(1<<1)
+#define OEM_DISPLAY_POWER			(1<<2)
+#define OEM_GET_EXT_FUNCS			(1<<3)
+
+typedef struct OEM_ACCESS_INFO_TAG
+{
+	IMG_UINT32		ui32Size;
+	IMG_UINT32  	ui32FBPhysBaseAddress;
+	IMG_UINT32		ui32FBMemAvailable;		
+	IMG_UINT32  	ui32SysPhysBaseAddress;
+	IMG_UINT32		ui32SysSize;
+	IMG_UINT32		ui32DevIRQ;
+} OEM_ACCESS_INFO, *POEM_ACCESS_INFO; 
+ 
+typedef IMG_UINT32   (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32  Ioctl,
+												IMG_BYTE   *pInBuf,
+												IMG_UINT32  InBufLen, 
+											    IMG_BYTE   *pOutBuf,
+												IMG_UINT32  OutBufLen,
+												IMG_UINT32 *pdwBytesTransferred);
+
+
+typedef PVRSRV_ERROR (*PFN_SRV_READREGSTRING)(PPVRSRV_REGISTRY_INFO psRegInfo);
+
+
+typedef struct PVRSRV_DC_OEM_JTABLE_TAG
+{
+	PFN_SRV_BRIDGEDISPATCH			pfnOEMBridgeDispatch;
+	PFN_SRV_READREGSTRING			pfnOEMReadRegistryString;
+	PFN_SRV_READREGSTRING			pfnOEMWriteRegistryString;
+
+} PVRSRV_DC_OEM_JTABLE;
+#if defined(__cplusplus)
+}
+#endif
+
+#endif	
+
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/sys_pvr_drm_export.c b/drivers/staging/cdv/pvr/services4/system/unified/sys_pvr_drm_export.c
new file mode 100644
index 0000000..c3ba410
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/sys_pvr_drm_export.c
@@ -0,0 +1,202 @@
+/**********************************************************************
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm.h>
+
+#include "pvr_drm_shared.h"
+
+#include "services_headers.h"
+#include "private_data.h"
+#include "pvr_drm.h"
+
+#include "pvr_bridge.h"
+#include "mutex.h"
+#include "lock.h"
+#include "linkage.h"
+#include "mmap.h"
+
+#if defined(PDUMP)
+#include "linuxsrv.h"
+#endif
+
+#include "sys_pvr_drm_import.h"
+
+#include "sys_pvr_drm_export.h"
+
+int
+SYSPVRInit(void)
+{
+	PVRDPFInit();
+
+	return 0;
+}
+
+int
+SYSPVRLoad(struct drm_device *dev, unsigned long flags)
+{
+	return PVRSRVDrmLoad(dev, flags);
+}
+
+int
+SYSPVROpen(struct drm_device *dev, struct drm_file *pFile)
+{
+	return PVRSRVDrmOpen(dev, pFile);
+}
+
+int
+SYSPVRUnload(struct drm_device *dev)
+{
+	return PVRSRVDrmUnload(dev);
+}
+
+void
+SYSPVRPostClose(struct drm_device *dev, struct drm_file *file)
+{
+	return PVRSRVDrmPostClose(dev, file);
+}
+
+int
+SYSPVRBridgeDispatch(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+{
+	return PVRSRV_BridgeDispatchKM(dev, arg, pFile);
+}
+
+int
+SYSPVRDCDriverIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+{
+	return PVRDRM_Dummy_ioctl(dev, arg, pFile);
+
+}
+
+int
+SYSPVRBCDriverIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+{
+	return PVRDRM_Dummy_ioctl(dev, arg, pFile);
+
+}
+
+int
+SYSPVRIsMaster(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+{
+	return PVRDRMIsMaster(dev, arg, pFile);
+}
+
+int
+SYSPVRUnprivCmd(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+{
+	return PVRDRMUnprivCmd(dev, arg, pFile);
+}
+
+int
+SYSPVRMMap(struct file* pFile, struct vm_area_struct* ps_vma)
+{
+	int ret;
+
+	ret = PVRMMap(pFile, ps_vma);
+	if (ret == -ENOENT)
+	{
+		ret = drm_mmap(pFile, ps_vma);
+	}
+
+	return ret;
+}
+
+int
+SYSPVRDBGDrivIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+{
+#if defined(PDUMP)
+	return dbgdrv_ioctl(dev, arg, pFile);
+#else
+	PVR_UNREFERENCED_PARAMETER(dev);
+	PVR_UNREFERENCED_PARAMETER(arg);
+	PVR_UNREFERENCED_PARAMETER(pFile);
+
+	return -EINVAL;
+#endif
+}
+
+void
+SYSPVRSuspendLock(struct drm_device *dev)
+{
+	PVR_UNREFERENCED_PARAMETER(dev);
+
+	LinuxLockMutex(&gPVRSRVLock);
+}
+
+void
+SYSPVRSuspendUnlock(struct drm_device *dev)
+{
+	PVR_UNREFERENCED_PARAMETER(dev);
+
+	LinuxUnLockMutex(&gPVRSRVLock);
+}
+
+int
+SYSPVRPreSuspend(struct drm_device *dev)
+{
+	if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
+	{
+		return -EBUSY;
+	}
+
+#if defined(DISPLAY_CONTROLLER)
+        if (PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Suspend)(dev) != 0)
+        {
+		(void)PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0);
+                return -EBUSY;
+        }
+#else
+	PVR_UNREFERENCED_PARAMETER(dev);
+#endif
+
+	return 0;
+}
+
+int
+SYSPVRPostSuspend(struct drm_device *dev)
+{
+	if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
+	{
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+int
+SYSPVRResume(struct drm_device *dev)
+{
+#if defined(DISPLAY_CONTROLLER)
+        if (PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Resume)(dev) != 0)
+        {
+                return -EINVAL;
+        }
+#else
+	PVR_UNREFERENCED_PARAMETER(dev);
+#endif
+	return 0;
+}
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/sys_pvr_drm_export.h b/drivers/staging/cdv/pvr/services4/system/unified/sys_pvr_drm_export.h
new file mode 100644
index 0000000..f2fc6bf
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/sys_pvr_drm_export.h
@@ -0,0 +1,97 @@
+/**********************************************************************
+ *
+ * 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(__SYS_PVR_DRM_EXPORT_H__)
+#define __SYS_PVR_DRM_EXPORT_H__
+
+#include "pvr_drm_shared.h"
+
+#if defined(__KERNEL__)
+
+#include "services_headers.h"
+#include "private_data.h"
+#include "pvr_drm.h"
+
+#include "pvr_bridge.h"
+
+#if defined(PDUMP)
+#include "linuxsrv.h"
+#endif
+
+#define PVR_DRM_SRVKM_IOCTL \
+	DRM_IOW(DRM_COMMAND_BASE + PVR_DRM_SRVKM_CMD, PVRSRV_BRIDGE_PACKAGE)
+
+#define PVR_DRM_DISP_IOCTL \
+	DRM_IO(DRM_COMMAND_BASE + PVR_DRM_DISP_CMD)
+
+#define PVR_DRM_BC_IOCTL \
+	DRM_IO(DRM_COMMAND_BASE + PVR_DRM_BC_CMD)
+
+#define	PVR_DRM_IS_MASTER_IOCTL \
+	DRM_IO(DRM_COMMAND_BASE + PVR_DRM_IS_MASTER_CMD)
+
+#define	PVR_DRM_UNPRIV_IOCTL \
+	DRM_IOWR(DRM_COMMAND_BASE + PVR_DRM_UNPRIV_CMD, IMG_UINT32)
+
+#if defined(PDUMP)
+#define	PVR_DRM_DBGDRV_IOCTL \
+	DRM_IOW(DRM_COMMAND_BASE + PVR_DRM_DBGDRV_CMD, IOCTL_PACKAGE)
+#else
+#define	PVR_DRM_DBGDRV_IOCTL \
+	DRM_IO(DRM_COMMAND_BASE + PVR_DRM_DBGDRV_CMD)
+#endif
+
+int SYSPVRInit(void);
+int SYSPVRLoad(struct drm_device *dev, unsigned long flags);
+int SYSPVROpen(struct drm_device *dev, struct drm_file *pFile);
+int SYSPVRUnload(struct drm_device *dev);
+void SYSPVRPostClose(struct drm_device *dev, struct drm_file *file);
+int SYSPVRBridgeDispatch(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+int SYSPVRDCDriverIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+int SYSPVRBCDriverIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+int SYSPVRIsMaster(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+int SYSPVRUnprivCmd(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+
+int SYSPVRMMap(struct file* pFile, struct vm_area_struct* ps_vma);
+
+int SYSPVRDBGDrivIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
+
+int SYSPVRServiceSGXInterrupt(struct drm_device *dev);
+
+void SYSPVRSuspendLock(struct drm_device *dev);
+void SYSPVRSuspendUnlock(struct drm_device *dev);
+int SYSPVRPreSuspend(struct drm_device *dev);
+int SYSPVRPostSuspend(struct drm_device *dev);
+int SYSPVRResume(struct drm_device *dev);
+
+int BC_Video_ModInit(void);
+int BC_Video_ModCleanup(void);
+int BC_Video_Bridge(struct drm_device *dev, IMG_VOID *arg, struct drm_file *file_priv);
+
+#endif	
+
+#endif	
+
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/sys_pvr_drm_import.h b/drivers/staging/cdv/pvr/services4/system/unified/sys_pvr_drm_import.h
new file mode 100644
index 0000000..635d903
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/sys_pvr_drm_import.h
@@ -0,0 +1,46 @@
+/**********************************************************************
+ *
+ * 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(__SYS_PVR_DRM_IMPORT_H__)
+#define __SYS_PVR_DRM_IMPORT_H__
+
+#if defined(__KERNEL__)
+#include "psb_drm.h"
+#endif
+
+#define DRM_PSB_PLACEMENT_OFFSET   0x13
+
+#if 0
+#define DRM_PVR_RESERVED1	0x0D
+#define DRM_PVR_RESERVED2	0x0E
+#define DRM_PVR_RESERVED3	0x0F
+#define DRM_PVR_RESERVED4	0x10
+#define DRM_PVR_RESERVED5	0x11
+#define DRM_PVR_RESERVED6	0x12
+#endif
+
+
+#endif	
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/sysconfig.c b/drivers/staging/cdv/pvr/services4/system/unified/sysconfig.c
new file mode 100644
index 0000000..bcf8bbc
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/sysconfig.c
@@ -0,0 +1,1038 @@
+/**********************************************************************
+ *
+ * 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 "linux/pci.h"
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "kerneldisplay.h"
+#include "oemfuncs.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+#include "pdump_km.h"
+#include "syslocal.h"
+#include "env_data.h"
+#include "psb_drv.h"
+#include "psb_powermgmt.h"
+#include "sys_pvr_drm_export.h"
+#include "msvdx_power.h"
+
+
+/* Graphics MSI address and data region in PCIx */
+#define MRST_PCIx_MSI_ADDR_LOC		0x94
+#define MRST_PCIx_MSI_DATA_LOC		0x98
+
+#define SYS_SGX_CLOCK_SPEED			(400000000)
+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ		(100)
+#define SYS_SGX_PDS_TIMER_FREQ			(1000)
+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS		(5)
+
+#define	DRI_DRM_STATIC
+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL;
+SYS_DATA  gsSysData;
+
+static SYS_SPECIFIC_DATA gsSysSpecificData;
+
+IMG_UINT32 gui32SGXDeviceID;
+extern IMG_UINT32 	gui32MRSTDisplayDeviceID;
+IMG_UINT32		gui32MRSTMSVDXDeviceID;
+IMG_UINT32		gui32MRSTTOPAZDeviceID;
+
+static SGX_DEVICE_MAP	gsSGXDeviceMap;
+extern struct drm_device *gpDrmDevice;
+
+static PVRSRV_DEVICE_NODE *gpsSGXDevNode;
+
+IMG_CPU_VIRTADDR gsPoulsboRegsCPUVaddr;
+
+IMG_CPU_VIRTADDR gsPoulsboDisplayRegsCPUVaddr;
+
+extern struct pci_dev *gpsPVRLDMDev;
+
+bool need_sample_cache_workaround;
+
+#define	POULSBO_ADDR_RANGE_INDEX	(MMADR_INDEX - 4)
+#define	POULSBO_HP_ADDR_RANGE_INDEX	(GMADR_INDEX - 4)
+static PVRSRV_ERROR PCIInitDev(SYS_DATA *psSysData)
+{
+	SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+	IMG_UINT32 ui32MaxOffset = POULSBO_MAX_OFFSET;
+	struct pci_dev *mch_dev;
+
+	if (!IS_CDV(gpDrmDevice))
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device not supported"));
+		return PVRSRV_ERROR_NOT_SUPPORTED;
+	}
+
+	mch_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+	if (!mch_dev)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Failed to get (0,0,0) device"));
+		return PVRSRV_ERROR_NOT_SUPPORTED;
+	}
+	if (mch_dev->revision < 4) {
+		need_sample_cache_workaround = true;
+		printk(KERN_INFO "Cedartrail: apply sample cache workaround\n");
+	} else
+		need_sample_cache_workaround = false;
+
+	pci_dev_put(mch_dev);
+
+	psSysSpecData->hSGXPCI = OSPCISetDev((IMG_VOID *)psSysSpecData->psPCIDev, 0);
+	ui32MaxOffset = PSB_POULSBO_MAX_OFFSET;
+
+	if (!psSysSpecData->hSGXPCI)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Failed to acquire PCI device"));
+		return PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND;
+	}
+
+	 SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_PCI_ACQUIRE_DEV);
+
+	PVR_TRACE(("PCI memory region: %x to %x", OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX), OSPCIAddrRangeEnd(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX)));
+#if defined(SGX_FEATURE_HOST_PORT)
+	PVR_TRACE(("Host Port region: %x to %x", OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX), OSPCIAddrRangeEnd(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX)));
+#endif
+
+	if (OSPCIAddrRangeLen(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX) < ui32MaxOffset)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region isn't big enough"));
+		return PVRSRV_ERROR_PCI_REGION_TOO_SMALL;
+	}
+
+
+	if (OSPCIRequestAddrRange(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available"));
+		return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE;
+
+	}
+	 SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_SGX_ADDR_RANGE);
+
+#if defined(SGX_FEATURE_HOST_PORT)
+
+	if (OSPCIRequestAddrRange(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Host Port region not available"));
+		return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE;
+	}
+	 SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_HOST_PORT_RANGE);
+#endif
+	return PVRSRV_OK;
+}
+
+static IMG_VOID PCIDeInitDev(SYS_DATA *psSysData)
+{
+	SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+	if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_SGX_ADDR_RANGE))
+	{
+		OSPCIReleaseAddrRange(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX);
+	}
+#if defined(SGX_FEATURE_HOST_PORT)
+	if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_HOST_PORT_RANGE))
+	{
+		OSPCIReleaseAddrRange(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX);
+	}
+#endif
+	if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_PCI_ACQUIRE_DEV))
+	{
+		OSPCIReleaseDev(psSysSpecData->hSGXPCI);
+	}
+}
+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
+{
+	IMG_UINT32 ui32BaseAddr = 0;
+	IMG_UINT32 ui32IRQ = 0;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+	IMG_UINT32 ui32HostPortAddr = 0;
+#endif
+	SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+   struct drm_psb_private *dev_priv = (struct drm_psb_private *) gpDrmDevice->dev_private;
+#endif
+
+	ui32BaseAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX);
+#if defined(SGX_FEATURE_HOST_PORT)
+	ui32HostPortAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX);
+#endif
+	if (OSPCIIRQ(psSysSpecData->hSGXPCI, &ui32IRQ) != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Couldn't get IRQ"));
+		return PVRSRV_ERROR_INVALID_DEVICE;
+	}
+
+	PVR_TRACE(("ui32BaseAddr: %08X", ui32BaseAddr));
+#if defined(SGX_FEATURE_HOST_PORT)
+	PVR_TRACE(("ui32HostPortAddr: %08X", ui32HostPortAddr));
+#endif
+	PVR_TRACE(("IRQ: %d", ui32IRQ));
+
+
+	gsSGXDeviceMap.ui32Flags = 0x0;
+	gsSGXDeviceMap.ui32IRQ = ui32IRQ;
+
+
+	gsSGXDeviceMap.sRegsSysPBase.uiAddr = ui32BaseAddr + (IS_CDV(gpDrmDevice) ? SGX_REGS_OFFSET : PSB_SGX_REGS_OFFSET);
+	gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
+	gsSGXDeviceMap.ui32RegsSize = SGX_REG_SIZE;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+
+	gsSGXDeviceMap.ui32Flags = SGX_HOSTPORT_PRESENT;
+	gsSGXDeviceMap.sHPSysPBase.uiAddr = ui32HostPortAddr;
+	gsSGXDeviceMap.sHPCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sHPSysPBase);
+	if (IS_CDV(gpDrmDevice) )
+		gsSGXDeviceMap.ui32HPSize = SYS_SGX_HP_SIZE;
+	else
+		gsSGXDeviceMap.ui32HPSize = PSB_SYS_SGX_HP_SIZE;
+#endif
+
+#if defined(MRST_SLAVEPORT)
+
+	gsSGXDeviceMap.sSPSysPBase.uiAddr = ui32BaseAddr + MRST_SGX_SP_OFFSET;
+	gsSGXDeviceMap.sSPCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sSPSysPBase);
+	gsSGXDeviceMap.ui32SPSize = SGX_SP_SIZE;
+#endif
+
+
+
+	gsSGXDeviceMap.sLocalMemSysPBase.uiAddr = 0;
+	gsSGXDeviceMap.sLocalMemDevPBase.uiAddr = 0;
+	gsSGXDeviceMap.sLocalMemCpuPBase.uiAddr = 0;
+	gsSGXDeviceMap.ui32LocalMemSize = 0;
+
+
+	{
+		IMG_SYS_PHYADDR sPoulsboRegsCpuPBase;
+		sPoulsboRegsCpuPBase.uiAddr = ui32BaseAddr + POULSBO_REGS_OFFSET;
+		gsPoulsboRegsCPUVaddr = OSMapPhysToLin(SysSysPAddrToCpuPAddr(sPoulsboRegsCpuPBase),
+												 POULSBO_REG_SIZE,
+												 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+												 IMG_NULL);
+
+		sPoulsboRegsCpuPBase.uiAddr = ui32BaseAddr + POULSBO_DISPLAY_REGS_OFFSET;
+		gsPoulsboDisplayRegsCPUVaddr = OSMapPhysToLin(SysSysPAddrToCpuPAddr(sPoulsboRegsCpuPBase),
+												 POULSBO_DISPLAY_REG_SIZE,
+												 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+												 IMG_NULL);
+	}
+
+#if defined(PDUMP)
+	{
+
+		static IMG_CHAR pszPDumpDevName[] = "SGXMEM";
+		gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName;
+	}
+#endif
+
+	return PVRSRV_OK;
+}
+
+
+#define VERSION_STR_MAX_LEN_TEMPLATE "SGX revision = 000.000.000"
+static PVRSRV_ERROR SysCreateVersionString(SYS_DATA *psSysData)
+{
+    IMG_UINT32 ui32MaxStrLen;
+    PVRSRV_ERROR eError;
+    IMG_INT32 i32Count;
+    IMG_CHAR *pszVersionString;
+    IMG_UINT32 ui32SGXRevision = 0;
+	IMG_VOID *pvSGXRegs;
+
+	pvSGXRegs = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
+											 gsSGXDeviceMap.ui32RegsSize,
+											 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+											 IMG_NULL);
+
+	if (pvSGXRegs != IMG_NULL)
+	{
+            ui32SGXRevision = OSReadHWReg(pvSGXRegs, EUR_CR_CORE_REVISION);
+	     OSUnMapPhysToLin(pvSGXRegs,
+												gsSGXDeviceMap.ui32RegsSize,
+												PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+												IMG_NULL);
+	}
+	else
+	{
+	     PVR_DPF((PVR_DBG_ERROR,"SysCreateVersionString: Couldn't map SGX registers"));
+	}
+
+    ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE);
+    eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+                          ui32MaxStrLen + 1,
+                          (IMG_PVOID *)&pszVersionString,
+                          IMG_NULL,
+			  "Version String");
+    if(eError != PVRSRV_OK)
+    {
+		return eError;
+    }
+
+    i32Count = OSSNPrintf(pszVersionString, ui32MaxStrLen + 1,
+                           "SGX revision = %u.%u.%u",
+                           (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK)
+                            >> EUR_CR_CORE_REVISION_MAJOR_SHIFT),
+                           (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK)
+                            >> EUR_CR_CORE_REVISION_MINOR_SHIFT),
+                           (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK)
+                            >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)
+                           );
+    if(i32Count == -1)
+    {
+        ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE);
+        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+                    ui32MaxStrLen + 1,
+                    pszVersionString,
+                    IMG_NULL);
+
+		return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+    psSysData->pszVersionString = pszVersionString;
+
+    return PVRSRV_OK;
+}
+
+static IMG_VOID SysFreeVersionString(SYS_DATA *psSysData)
+{
+    if(psSysData->pszVersionString)
+    {
+        IMG_UINT32 ui32MaxStrLen;
+        ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE);
+        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+                    ui32MaxStrLen+1,
+                    psSysData->pszVersionString,
+                    IMG_NULL);
+		psSysData->pszVersionString = IMG_NULL;
+    }
+}
+
+PVRSRV_ERROR SysInitialise(IMG_VOID)
+{
+	IMG_UINT32			i			  = 0;
+	PVRSRV_ERROR 		eError;
+	PVRSRV_DEVICE_NODE	*psDeviceNode;
+	SGX_TIMING_INFORMATION*	psTimingInfo;
+
+	gpsSysData = &gsSysData;
+	OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));
+
+	gpsSysData->pvSysSpecificData = &gsSysSpecificData;
+	gsSysSpecificData.ui32SysSpecificData = 0;
+
+	PVR_ASSERT(gpsPVRLDMDev != IMG_NULL);
+	gsSysSpecificData.psPCIDev = gpsPVRLDMDev;
+
+	eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure"));
+		SysDeinitialise(gpsSysData);
+		gpsSysData = IMG_NULL;
+		return eError;
+	}
+
+
+	psTimingInfo = &gsSGXDeviceMap.sTimingInfo;
+	psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED;
+	psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ;
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+	psTimingInfo->bEnableActivePM = (drm_psb_ospm != 0);
+	/*printk(KERN_ERR "SGX APM is %s\n", (drm_psb_ospm != 0)? "enabled":"disabled"); */
+#else
+	psTimingInfo->bEnableActivePM = IMG_FALSE;
+#endif
+	psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;
+	psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ;
+
+	eError = PCIInitDev(gpsSysData);
+	if (eError != PVRSRV_OK)
+	{
+		SysDeinitialise(gpsSysData);
+		gpsSysData = IMG_NULL;
+		return eError;
+	}
+
+	gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;
+
+
+	for(i=0; i<SYS_DEVICE_COUNT; i++)
+	{
+		gpsSysData->sDeviceID[i].uiID = i;
+		gpsSysData->sDeviceID[i].bInUse = IMG_FALSE;
+	}
+
+	gpsSysData->psDeviceNodeList = IMG_NULL;
+	gpsSysData->psQueueList = IMG_NULL;
+
+	eError = SysInitialiseCommon(gpsSysData);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon"));
+		SysDeinitialise(gpsSysData);
+		gpsSysData = IMG_NULL;
+		return eError;
+	}
+
+
+
+
+
+	eError = SysLocateDevices(gpsSysData);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices"));
+		SysDeinitialise(gpsSysData);
+		gpsSysData = IMG_NULL;
+		return eError;
+	}
+
+
+
+
+	eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,
+								  DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!"));
+		SysDeinitialise(gpsSysData);
+		gpsSysData = IMG_NULL;
+		return eError;
+	}
+
+
+	/* register MSVDX, with 0 interrupt bit, no interrupt will be served */
+	eError = PVRSRVRegisterDevice(gpsSysData, MSVDXRegisterDevice,
+				      DEVICE_MSVDX_INTERRUPT, &gui32MRSTMSVDXDeviceID);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register MSVDXdevice!"));
+		SysDeinitialise(gpsSysData);
+		gpsSysData = IMG_NULL;
+		return eError;
+	}
+
+	psDeviceNode = gpsSysData->psDeviceNodeList;
+
+	while(psDeviceNode)
+	{
+
+		switch(psDeviceNode->sDevId.eDeviceType)
+		{
+			case PVRSRV_DEVICE_TYPE_SGX:
+			{
+				DEVICE_MEMORY_INFO *psDevMemoryInfo;
+				DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+
+
+				psDeviceNode->psLocalDevMemArena = IMG_NULL;
+
+
+				psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+				psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+
+
+				for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++)
+				{
+					psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG;
+#ifdef OEM_CUSTOMISE
+
+#endif
+				}
+
+				gpsSGXDevNode = psDeviceNode;
+				break;
+			}
+			case PVRSRV_DEVICE_TYPE_MSVDX:
+			/* nothing need to do here */
+			break;
+			case PVRSRV_DEVICE_TYPE_TOPAZ:
+			break;
+			default:
+			{
+				PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!"));
+				return PVRSRV_ERROR_INIT_FAILURE;
+			}
+		}
+
+
+		psDeviceNode = psDeviceNode->psNext;
+	}
+
+	PDUMPINIT();
+	SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PDUMP_INIT);
+
+
+	eError = PVRSRVInitialiseDevice (gui32SGXDeviceID);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
+		SysDeinitialise(gpsSysData);
+		gpsSysData = IMG_NULL;
+		return eError;
+	}
+	SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_SGX_INITIALISED);
+
+	eError = PVRSRVInitialiseDevice (gui32MRSTMSVDXDeviceID);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
+		SysDeinitialise(gpsSysData);
+		gpsSysData = IMG_NULL;
+		return eError;
+	}
+
+	if (0)
+	{
+		eError = PVRSRVInitialiseDevice (gui32MRSTTOPAZDeviceID);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
+			SysDeinitialise(gpsSysData);
+			gpsSysData = IMG_NULL;
+			return eError;
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SysFinalise(IMG_VOID)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	eError = OSInstallMISR(gpsSysData);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysFinalise: OSInstallMISR failed"));
+		return eError;
+	}
+	SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_MISR_INSTALLED);
+
+	eError = SysCreateVersionString(gpsSysData);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to create a system version string"));
+	}
+	else
+	{
+	    PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString));
+	}
+
+	return eError;
+}
+
+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)
+{
+	PVRSRV_ERROR eError;
+
+	SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+	if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_MISR_INSTALLED))
+	{
+		eError = OSUninstallMISR(psSysData);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed"));
+			return eError;
+		}
+	}
+
+	if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_SGX_INITIALISED))
+	{
+
+		eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device"));
+			return eError;
+		}
+	}
+
+	SysFreeVersionString(psSysData);
+
+	PCIDeInitDev(psSysData);
+
+	eError = OSDeInitEnvData(psSysData->pvEnvSpecificData);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure"));
+		return eError;
+	}
+
+	SysDeinitialiseCommon(gpsSysData);
+
+
+	OSUnMapPhysToLin(gsPoulsboRegsCPUVaddr,
+											 POULSBO_REG_SIZE,
+											 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+											 IMG_NULL);
+
+	OSUnMapPhysToLin(gsPoulsboDisplayRegsCPUVaddr,
+											 POULSBO_DISPLAY_REG_SIZE,
+											 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+											 IMG_NULL);
+
+	if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_PDUMP_INIT))
+	{
+		PDUMPDEINIT();
+	}
+
+	gpsSysData = IMG_NULL;
+
+	return PVRSRV_OK;
+}
+
+IMG_UINT32 SysGetInterruptSource(SYS_DATA* psSysData,
+		PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVR_UNREFERENCED_PARAMETER(psSysData);
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+
+	return 0;
+}
+
+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)
+{
+	PVR_UNREFERENCED_PARAMETER(psSysData);
+	PVR_UNREFERENCED_PARAMETER(ui32ClearBits);
+}
+
+
+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
+									IMG_VOID **ppvDeviceMap)
+{
+	switch(eDeviceType)
+	{
+		case PVRSRV_DEVICE_TYPE_SGX:
+		{
+
+			*ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap;
+			break;
+		}
+		default:
+		{
+			PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type"));
+		}
+	}
+	return PVRSRV_OK;
+}
+
+
+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType,
+										IMG_CPU_PHYADDR CpuPAddr)
+{
+	IMG_DEV_PHYADDR DevPAddr;
+
+	PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+
+	DevPAddr.uiAddr = CpuPAddr.uiAddr;
+
+	return DevPAddr;
+}
+
+
+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr)
+{
+	IMG_CPU_PHYADDR cpu_paddr;
+
+
+	cpu_paddr.uiAddr = sys_paddr.uiAddr;
+	return cpu_paddr;
+}
+
+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr)
+{
+	IMG_SYS_PHYADDR sys_paddr;
+
+
+	sys_paddr.uiAddr = cpu_paddr.uiAddr;
+	return sys_paddr;
+}
+
+
+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr)
+{
+    IMG_DEV_PHYADDR DevPAddr;
+
+	PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+
+    DevPAddr.uiAddr = SysPAddr.uiAddr;
+
+    return DevPAddr;
+}
+
+
+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr)
+{
+    IMG_SYS_PHYADDR SysPAddr;
+
+	PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+
+    SysPAddr.uiAddr = DevPAddr.uiAddr;
+
+    return SysPAddr;
+}
+
+
+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+
+  psDeviceNode->ui32SOCInterruptBit = DEVICE_DISP_INTERRUPT;
+}
+
+
+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+}
+
+PVRSRV_ERROR SysOEMFunction (	IMG_UINT32	ui32ID,
+								IMG_VOID	*pvIn,
+								IMG_UINT32  ulInSize,
+								IMG_VOID	*pvOut,
+								IMG_UINT32	ulOutSize)
+{
+	PVR_UNREFERENCED_PARAMETER(ulInSize);
+	PVR_UNREFERENCED_PARAMETER(pvIn);
+
+	return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+
+static PVRSRV_ERROR SysMapInRegisters(IMG_VOID)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNodeList;
+
+	psDeviceNodeList = gpsSysData->psDeviceNodeList;
+
+	while (psDeviceNodeList)
+	{
+		switch(psDeviceNodeList->sDevId.eDeviceType)
+		{
+		case PVRSRV_DEVICE_TYPE_SGX:
+		{
+			PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNodeList->pvDevice;
+
+			if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS))
+			{
+				psDevInfo->pvRegsBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
+									 gsSGXDeviceMap.ui32RegsSize,
+									 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+									 IMG_NULL);
+
+				if (!psDevInfo->pvRegsBaseKM)
+				{
+					PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in SGX registers\n"));
+					return PVRSRV_ERROR_BAD_MAPPING;
+				}
+				SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS);
+			}
+			psDevInfo->ui32RegSize   = gsSGXDeviceMap.ui32RegsSize;
+			psDevInfo->sRegsPhysBase = gsSGXDeviceMap.sRegsSysPBase;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+			if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT)
+			{
+				if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP))
+				{
+
+					psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sHPCpuPBase,
+														     gsSGXDeviceMap.ui32HPSize,
+														     PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+														     IMG_NULL);
+					if (!psDevInfo->pvHostPortBaseKM)
+					{
+						PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in host port\n"));
+						return PVRSRV_ERROR_BAD_MAPPING;
+					}
+					SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP);
+				}
+				psDevInfo->ui32HPSize  = gsSGXDeviceMap.ui32HPSize;
+				psDevInfo->sHPSysPAddr = gsSGXDeviceMap.sHPSysPBase;
+			}
+#endif
+			break;
+		}
+		default:
+			break;
+		}
+		psDeviceNodeList = psDeviceNodeList->psNext;
+	}
+
+	return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR SysUnmapRegisters(IMG_VOID)
+{
+	PVRSRV_DEVICE_NODE *psDeviceNodeList;
+
+	psDeviceNodeList = gpsSysData->psDeviceNodeList;
+
+	while (psDeviceNodeList)
+	{
+		switch (psDeviceNodeList->sDevId.eDeviceType)
+		{
+		case PVRSRV_DEVICE_TYPE_SGX:
+		{
+			PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNodeList->pvDevice;
+
+			if (psDevInfo->pvRegsBaseKM)
+			{
+				OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,
+				                 gsSGXDeviceMap.ui32RegsSize,
+				                 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+				                 IMG_NULL);
+
+				SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS);
+			}
+
+			psDevInfo->pvRegsBaseKM = IMG_NULL;
+			psDevInfo->ui32RegSize          = 0;
+			psDevInfo->sRegsPhysBase.uiAddr = 0;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+			if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT)
+			{
+
+				if (psDevInfo->pvHostPortBaseKM)
+				{
+					OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM,
+					                 gsSGXDeviceMap.ui32HPSize,
+					                 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+					                 IMG_NULL);
+
+					SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP);
+
+					psDevInfo->pvHostPortBaseKM = IMG_NULL;
+				}
+
+				psDevInfo->ui32HPSize  = 0;
+				psDevInfo->sHPSysPAddr.uiAddr = 0;
+			}
+#endif
+			break;
+		}
+		default:
+			break;
+		}
+		psDeviceNodeList = psDeviceNodeList->psNext;
+	}
+
+	OSUnMapPhysToLin(gsPoulsboRegsCPUVaddr,
+				POULSBO_REG_SIZE,
+				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+				IMG_NULL);
+
+
+	OSUnMapPhysToLin(gsPoulsboDisplayRegsCPUVaddr,
+				POULSBO_DISPLAY_REG_SIZE,
+				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+				IMG_NULL);
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
+{
+	PVRSRV_ERROR eError= PVRSRV_OK;
+	PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)(gsSysSpecificData.hSGXPCI);
+
+	if (eNewPowerState != gpsSysData->eCurrentPowerState)
+	{
+		if ((eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) &&
+			(gpsSysData->eCurrentPowerState < PVRSRV_SYS_POWER_STATE_D3))
+		{
+			SysUnmapRegisters();
+
+			//Save some pci state that won't get saved properly by pci_save_state()
+			pci_read_config_dword(psPVRPCI->psPCIDev, 0x5C, &gsSysSpecificData.saveBSM);
+			pci_read_config_dword(psPVRPCI->psPCIDev, 0xFC, &gsSysSpecificData.saveVBT);
+			pci_read_config_dword(psPVRPCI->psPCIDev, MRST_PCIx_MSI_ADDR_LOC, &gsSysSpecificData.msi_addr);
+			pci_read_config_dword(psPVRPCI->psPCIDev, MRST_PCIx_MSI_DATA_LOC, &gsSysSpecificData.msi_data);
+		}
+	}
+
+	return eError;
+}
+
+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)(gsSysSpecificData.hSGXPCI);
+
+	if (eNewPowerState != gpsSysData->eCurrentPowerState)
+	{
+		if ((gpsSysData->eCurrentPowerState == PVRSRV_SYS_POWER_STATE_D3) &&
+			(eNewPowerState < PVRSRV_SYS_POWER_STATE_D3))
+		{
+			//Restore some pci state that will not have gotten restored properly by pci_restore_state()
+			pci_write_config_dword(psPVRPCI->psPCIDev, 0x5c, gsSysSpecificData.saveBSM);
+			pci_write_config_dword(psPVRPCI->psPCIDev, 0xFC, gsSysSpecificData.saveVBT);
+			pci_write_config_dword(psPVRPCI->psPCIDev, MRST_PCIx_MSI_ADDR_LOC, gsSysSpecificData.msi_addr);
+			pci_write_config_dword(psPVRPCI->psPCIDev, MRST_PCIx_MSI_DATA_LOC, gsSysSpecificData.msi_data);
+
+			eError = SysLocateDevices(gpsSysData);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: Failed to locate devices"));
+				return eError;
+			}
+
+			eError = SysMapInRegisters();
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: Failed to map in registers"));
+				return eError;
+			}
+		}
+	}
+	return eError;
+}
+
+
+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32			ui32DeviceIndex,
+									PVRSRV_DEV_POWER_STATE	eNewPowerState,
+									PVRSRV_DEV_POWER_STATE	eCurrentPowerState)
+{
+	if ((eNewPowerState != eCurrentPowerState) &&
+	    (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF))
+	{
+		if (ui32DeviceIndex == gui32SGXDeviceID)
+		{
+			PVR_DPF((PVR_DBG_MESSAGE,"SysDevicePrePowerState: Remove SGX power"));
+			psb_irq_uninstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
+			/* XXX don't power off SGX on Cedartrail, windows driver guy said don't
+ 			 * need that. -- zhenyu */
+			/* ospm_power_island_down(OSPM_GRAPHICS_ISLAND); */
+		}
+		else if (ui32DeviceIndex == gui32MRSTMSVDXDeviceID)
+		{
+			/* XXX don't power off MSVDX on Cedartrail, windows driver guy said don't
+ 			 * need that. -- zhenyu */
+			/* ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND); */
+#if 0
+			ospm_power_using_hw_end(OSPM_VIDEO_DEC_ISLAND);
+			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+#endif
+		}
+		else if (ui32DeviceIndex == gui32MRSTTOPAZDeviceID)
+		{
+			ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
+		}
+#if 0
+			ospm_power_using_hw_end(OSPM_VIDEO_ENC_ISLAND);
+			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+#endif
+	}
+
+	return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32			ui32DeviceIndex,
+									 PVRSRV_DEV_POWER_STATE	eNewPowerState,
+									 PVRSRV_DEV_POWER_STATE	eCurrentPowerState)
+{
+	if ((eNewPowerState != eCurrentPowerState) &&
+	    (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF))
+	{
+		if (ui32DeviceIndex == gui32SGXDeviceID)
+		{
+			PVR_DPF((PVR_DBG_MESSAGE,"SysDevicePrePowerState: Restore SGX power"));
+			/* XXX we don't power off SGX on Cedartrail */
+			/* ospm_power_island_up(OSPM_GRAPHICS_ISLAND); */
+		}
+		else if (ui32DeviceIndex == gui32MRSTMSVDXDeviceID)
+		{
+			PVR_DPF((PVR_DBG_MESSAGE,"SysDevicePrePowerState: Restore MSVDX power"));
+			/* XXX we don't power off MSVDX on Cedartrail */
+			/* ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND); */
+#if 0
+			if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true))
+			{
+				return PVRSRV_ERROR_GENERIC;
+			}
+
+			if (!ospm_power_using_hw_begin(OSPM_VIDEO_DEC_ISLAND, true))
+			{
+				ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+
+				return PVRSRV_ERROR_GENERIC;
+			}
+#endif
+		}
+		else if (ui32DeviceIndex == gui32MRSTTOPAZDeviceID)
+		{
+			PVR_DPF((PVR_DBG_MESSAGE,"SysDevicePrePowerState: Restore TOPAZ power"));
+
+			ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
+#if 0
+			if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true))
+			{
+				return PVRSRV_ERROR_GENERIC;
+			}
+
+			if (!ospm_power_using_hw_begin(OSPM_VIDEO_ENC_ISLAND, true))
+			{
+				ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+
+				return PVRSRV_ERROR_GENERIC;
+			}
+#endif
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+int SYSPVRServiceSGXInterrupt(struct drm_device *dev)
+{
+	IMG_BOOL bStatus = IMG_FALSE;
+
+	PVR_UNREFERENCED_PARAMETER(dev);
+
+	if (gpsSGXDevNode != IMG_NULL)
+	{
+		bStatus = (*gpsSGXDevNode->pfnDeviceISR)(gpsSGXDevNode->pvISRData);
+		if (bStatus)
+		{
+			OSScheduleMISR((IMG_VOID *)gpsSGXDevNode->psSysData);
+		}
+	}
+
+	return bStatus ? 1 : 0;
+}
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/sysconfig.h b/drivers/staging/cdv/pvr/services4/system/unified/sysconfig.h
new file mode 100644
index 0000000..a89ef8a
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/sysconfig.h
@@ -0,0 +1,133 @@
+/**********************************************************************
+ *
+ * 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(__SOCCONFIG_H__)
+#define __SOCCONFIG_H__
+#include "syscommon.h"
+#include "extsyscache.h"
+
+#define VS_PRODUCT_NAME	"SGX Cedarview"
+
+#define SYS_NO_POWER_LOCK_TIMEOUT
+
+/*#define SGX_FEATURE_HOST_PORT */
+
+#define SYS_SGX_USSE_COUNT					(2)
+
+#define POULSBO_REGS_OFFSET	0x00000
+#define POULSBO_REG_SIZE	0x2100	
+
+#define SGX_REGS_OFFSET		0x80000
+#define PSB_SGX_REGS_OFFSET	0x40000
+#define SGX_REG_SIZE 		0x4000
+#define MSVDX_REGS_OFFSET	0x90000
+
+#ifdef SUPPORT_MSVDX
+#define	POULSBO_MAX_OFFSET	(MSVDX_REGS_OFFSET + MSVDX_REG_SIZE)
+#else
+#define	POULSBO_MAX_OFFSET	(SGX_REGS_OFFSET + SGX_REG_SIZE)
+#define	PSB_POULSBO_MAX_OFFSET	(PSB_SGX_REGS_OFFSET + SGX_REG_SIZE)
+#endif
+
+#define SYS_SGX_DEV_VENDOR_ID		0x8086
+#define PSB_SYS_SGX_DEV_DEVICE_ID_1	0x8108
+#define PSB_SYS_SGX_DEV_DEVICE_ID_2	0x8109
+
+#define SYS_SGX_DEV_DEVICE_ID		0x4102
+
+#define MMADR_INDEX			4
+#define IOPORT_INDEX		5
+#define GMADR_INDEX			6
+#define MMUADR_INDEX		7
+#define FBADR_INDEX			23
+#define FBSIZE_INDEX		24
+
+#define DISPLAY_SURFACE_SIZE        (4 * 1024 * 1024)
+
+#define DEVICE_SGX_INTERRUPT		(1<<0)
+#define DEVICE_MSVDX_INTERRUPT		(1<<1)
+#define DEVICE_DISP_INTERRUPT		(1<<2)
+#define DEVICE_TOPAZ_INTERRUPT		(1<<3)
+
+#define POULSBO_INTERRUPT_ENABLE_REG		0x20A0
+#define POULSBO_INTERRUPT_IDENTITY_REG		0x20A4
+#define POULSBO_INTERRUPT_MASK_REG			0x20A8
+#define POULSBO_INTERRUPT_STATUS_REG		0x20AC
+
+#define POULSBO_DISP_MASK					(1<<17)
+#define POULSBO_THALIA_MASK					(1<<18)
+#define POULSBO_MSVDX_MASK					(1<<19)
+#define POULSBO_VSYNC_PIPEA_VBLANK_MASK		(1<<7)
+#define POULSBO_VSYNC_PIPEA_EVENT_MASK		(1<<6)
+#define POULSBO_VSYNC_PIPEB_VBLANK_MASK		(1<<5)
+#define POULSBO_VSYNC_PIPEB_EVENT_MASK		(1<<4)
+
+#define POULSBO_DISPLAY_REGS_OFFSET			0x70000
+#define POULSBO_DISPLAY_REG_SIZE			0x2000		
+
+#define POULSBO_DISPLAY_A_CONFIG			0x00008
+#define POULSBO_DISPLAY_A_STATUS_SELECT		0x00024
+#define POULSBO_DISPLAY_B_CONFIG			0x01008
+#define POULSBO_DISPLAY_B_STATUS_SELECT		0x01024
+
+#define POULSBO_DISPLAY_PIPE_ENABLE			(1<<31)
+#define POULSBO_DISPLAY_VSYNC_STS_EN		(1<<25)
+#define POULSBO_DISPLAY_VSYNC_STS			(1<<9)
+
+#if defined(SGX_FEATURE_HOST_PORT)
+	#define SYS_SGX_HP_SIZE		0x8000000
+	#define PSB_SYS_SGX_HP_SIZE	0x4000000
+	
+	#define SYS_SGX_HOSTPORT_BASE_DEVVADDR 0xD0000000
+	#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030)
+		
+
+
+		#define SYS_SGX_HOSTPORT_BRN23030_OFFSET 0x7C00000
+	#endif
+#endif
+
+ 
+typedef struct
+{
+	union
+	{
+		IMG_UINT8	aui8PCISpace[256];
+		IMG_UINT16	aui16PCISpace[128];
+		IMG_UINT32	aui32PCISpace[64];
+		struct  
+		{
+			IMG_UINT16	ui16VenID;
+			IMG_UINT16	ui16DevID;
+			IMG_UINT16	ui16PCICmd;
+			IMG_UINT16	ui16PCIStatus;
+		}s;
+	}u;
+} PCICONFIG_SPACE, *PPCICONFIG_SPACE;
+
+extern bool need_sample_cache_workaround;
+
+#endif	
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/sysinfo.h b/drivers/staging/cdv/pvr/services4/system/unified/sysinfo.h
new file mode 100644
index 0000000..6e113c9
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/sysinfo.h
@@ -0,0 +1,43 @@
+/**********************************************************************
+ *
+ * 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(__SYSINFO_H__)
+#define __SYSINFO_H__
+
+#define MAX_HW_TIME_US				(500000)
+#define WAIT_TRY_COUNT				(10000)
+
+typedef enum _SYS_DEVICE_TYPE_
+{
+	SYS_DEVICE_SGX						= 0,
+
+	SYS_DEVICE_FORCE_I16 				= 0x7fff
+
+} SYS_DEVICE_TYPE;
+
+#define SYS_DEVICE_COUNT 10
+
+#endif	
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/sysirq.h b/drivers/staging/cdv/pvr/services4/system/unified/sysirq.h
new file mode 100644
index 0000000..c5efc4a
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/sysirq.h
@@ -0,0 +1,49 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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 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.
+ *
+ * Authors:
+ *    Benjamin Defnet <benjamin.r.defnet@intel.com>
+ *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
+ *
+ **************************************************************************/
+
+#ifndef _SYSIRQ_H_
+#define _SYSIRQ_H_
+
+#include <drm/drmP.h>
+
+bool sysirq_init(struct drm_device *dev);
+void sysirq_uninit(struct drm_device *dev);
+
+void psb_irq_preinstall(struct drm_device *dev);
+int  psb_irq_postinstall(struct drm_device *dev);
+void psb_irq_uninstall(struct drm_device *dev);
+irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
+
+void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands);
+int  psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands);
+void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
+
+int psb_irq_enable_dpst(struct drm_device *dev);
+int psb_irq_disable_dpst(struct drm_device *dev);
+void sysirq_turn_on_dpst(struct drm_device *dev);
+void sysirq_turn_off_dpst(struct drm_device *dev);
+int  psb_enable_vblank(struct drm_device *dev, int pipe);
+void psb_disable_vblank(struct drm_device *dev, int pipe);
+u32  psb_get_vblank_counter(struct drm_device *dev, int pipe);
+
+#endif //_SYSIRQ_H_
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/syslocal.h b/drivers/staging/cdv/pvr/services4/system/unified/syslocal.h
new file mode 100644
index 0000000..c36b9c1
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/syslocal.h
@@ -0,0 +1,75 @@
+/**********************************************************************
+ *
+ * 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(__SYSLOCAL_H__)
+#define __SYSLOCAL_H__
+
+#define SYS_SPECIFIC_DATA_PCI_ACQUIRE_DEV		0x00000001
+#define SYS_SPECIFIC_DATA_PCI_REQUEST_SGX_ADDR_RANGE	0x00000002
+#define SYS_SPECIFIC_DATA_PCI_REQUEST_HOST_PORT_RANGE	0x00000004
+#define	SYS_SPECIFIC_DATA_SGX_INITIALISED		0x00000040
+#if defined(SUPPORT_MSVDX)
+#define	SYS_SPECIFIC_DATA_MSVDX_INITIALISED		0x00000080
+#endif	
+#define	SYS_SPECIFIC_DATA_MISR_INSTALLED		0x00000100
+#define	SYS_SPECIFIC_DATA_LISR_INSTALLED		0x00000200
+#define	SYS_SPECIFIC_DATA_PDUMP_INIT			0x00000400
+#define	SYS_SPECIFIC_DATA_IRQ_ENABLED			0x00000800
+
+#define	SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS		0x00001000
+#define	SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP		0x00004000
+#define	SYS_SPECIFIC_DATA_PM_UNMAP_MSVDX_REGS		0x00008000
+#define	SYS_SPECIFIC_DATA_PM_IRQ_DISABLE		0x00010000
+#define	SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR		0x00020000
+
+#define	SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag)))
+
+#define	SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag)))
+
+#define	SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0)
+ 
+ 
+typedef struct _SYS_SPECIFIC_DATA_TAG_
+{
+	
+	IMG_UINT32 ui32SysSpecificData;
+#ifdef	__linux__
+	PVRSRV_PCI_DEV_HANDLE hSGXPCI;
+#endif
+	struct pci_dev *psPCIDev;
+
+	/* MSI reg save */
+	uint32_t msi_addr;
+	uint32_t msi_data;
+
+	uint32_t saveBSM;
+	uint32_t saveVBT;
+} SYS_SPECIFIC_DATA;
+
+ 
+#endif	
+
+
diff --git a/drivers/staging/cdv/pvr/services4/system/unified/sysutils.c b/drivers/staging/cdv/pvr/services4/system/unified/sysutils.c
new file mode 100644
index 0000000..b89a1da
--- /dev/null
+++ b/drivers/staging/cdv/pvr/services4/system/unified/sysutils.c
@@ -0,0 +1,30 @@
+/**********************************************************************
+ *
+ * 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 "services_headers.h"
+#include "sysinfo.h"
+#include "syslocal.h"
+
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/client/linuxsrv.h b/drivers/staging/cdv/pvr/tools/intern/debug/client/linuxsrv.h
new file mode 100644
index 0000000..f1cb02a
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/client/linuxsrv.h
@@ -0,0 +1,48 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ **************************************************************************/
+
+#ifndef _LINUXSRV_H__
+#define _LINUXSRV_H__
+
+typedef struct tagIOCTL_PACKAGE
+{
+	IMG_UINT32 ui32Cmd;              // ioctl command
+	IMG_UINT32 ui32Size;			   // needs to be correctly set
+	IMG_VOID 	*pInBuffer;          // input data buffer
+	IMG_UINT32  ui32InBufferSize;     // size of input data buffer
+	IMG_VOID    *pOutBuffer;         // output data buffer
+	IMG_UINT32  ui32OutBufferSize;    // size of output data buffer
+} IOCTL_PACKAGE;
+
+IMG_UINT32 DeviceIoControl(IMG_UINT32 hDevice,		
+						IMG_UINT32 ui32ControlCode, 
+						IMG_VOID *pInBuffer,		
+						IMG_UINT32 ui32InBufferSize,
+						IMG_VOID *pOutBuffer,		
+						IMG_UINT32 ui32OutBufferSize,  
+						IMG_UINT32 *pui32BytesReturned); 
+
+#endif /* _LINUXSRV_H__*/
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.c b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.c
new file mode 100644
index 0000000..4bf93d0
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.c
@@ -0,0 +1,2357 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+#ifdef LINUX
+#include <linux/string.h>
+#endif
+#ifdef __QNXNTO__
+#include <string.h>
+#endif
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hotkey.h"
+#include "hostfunc.h"
+#include "pvr_debug.h"
+
+
+
+
+#define LAST_FRAME_BUF_SIZE	1024
+
+typedef struct _DBG_LASTFRAME_BUFFER_
+{
+	PDBG_STREAM	psStream;
+	IMG_UINT8 ui8Buffer[LAST_FRAME_BUF_SIZE];
+	IMG_UINT32		ui32BufLen;
+	struct _DBG_LASTFRAME_BUFFER_	*psNext;
+} *PDBG_LASTFRAME_BUFFER;
+
+
+static PDBG_STREAM	g_psStreamList = 0;
+static PDBG_LASTFRAME_BUFFER	g_psLFBufferList;
+
+static IMG_UINT32		g_ui32LOff = 0;
+static IMG_UINT32		g_ui32Line = 0;
+static IMG_UINT32		g_ui32MonoLines = 25;
+
+static IMG_BOOL			g_bHotkeyMiddump = IMG_FALSE;
+static IMG_UINT32		g_ui32HotkeyMiddumpStart = 0xffffffff;
+static IMG_UINT32		g_ui32HotkeyMiddumpEnd = 0xffffffff;
+
+IMG_VOID *				g_pvAPIMutex=IMG_NULL;
+
+extern IMG_UINT32		g_ui32HotKeyFrame;
+extern IMG_BOOL			g_bHotKeyPressed;
+extern IMG_BOOL			g_bHotKeyRegistered;
+
+IMG_BOOL				gbDumpThisFrame = IMG_FALSE;
+
+
+IMG_UINT32 SpaceInStream(PDBG_STREAM psStream);
+IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize);
+PDBG_LASTFRAME_BUFFER FindLFBuf(PDBG_STREAM psStream);
+
+DBGKM_SERVICE_TABLE g_sDBGKMServices =
+{
+	sizeof (DBGKM_SERVICE_TABLE),
+	ExtDBGDrivCreateStream,
+	ExtDBGDrivDestroyStream,
+	ExtDBGDrivFindStream,
+	ExtDBGDrivWriteString,
+	ExtDBGDrivReadString,
+	ExtDBGDrivWrite,
+	ExtDBGDrivRead,
+	ExtDBGDrivSetCaptureMode,
+	ExtDBGDrivSetOutputMode,
+	ExtDBGDrivSetDebugLevel,
+	ExtDBGDrivSetFrame,
+	ExtDBGDrivGetFrame,
+	ExtDBGDrivOverrideMode,
+	ExtDBGDrivDefaultMode,
+	ExtDBGDrivWrite2,
+	ExtDBGDrivWriteStringCM,
+	ExtDBGDrivWriteCM,
+	ExtDBGDrivSetMarker,
+	ExtDBGDrivGetMarker,
+	ExtDBGDrivStartInitPhase,
+	ExtDBGDrivStopInitPhase,
+	ExtDBGDrivIsCaptureFrame,
+	ExtDBGDrivWriteLF,
+	ExtDBGDrivReadLF,
+	ExtDBGDrivGetStreamOffset,
+	ExtDBGDrivSetStreamOffset,
+	ExtDBGDrivIsLastCaptureFrame,
+	ExtDBGDrivWaitForEvent,
+	ExtDBGDrivSetConnectNotifier,
+	ExtDBGDrivWritePersist
+};
+
+
+static IMG_UINT32 DBGDrivWritePersist(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+static IMG_VOID InvalidateAllStreams(IMG_VOID);
+
+
+
+
+DBGKM_CONNECT_NOTIFIER g_fnDBGKMNotifier;
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetConnectNotifier(DBGKM_CONNECT_NOTIFIER fn_notifier)
+{
+	
+	g_fnDBGKMNotifier = fn_notifier;
+}
+
+IMG_VOID * IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR *	pszName, IMG_UINT32 ui32CapMode, IMG_UINT32	ui32OutMode, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size)
+{
+	IMG_VOID *	pvRet;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	pvRet=DBGDrivCreateStream(pszName, ui32CapMode, ui32OutMode, ui32Flags, ui32Size);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return pvRet;
+}
+
+void IMG_CALLCONV ExtDBGDrivDestroyStream(PDBG_STREAM psStream)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivDestroyStream(psStream);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream)
+{
+	IMG_VOID *	pvRet;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	pvRet=DBGDrivFindStream(pszName, bResetStream);
+	if(g_fnDBGKMNotifier.pfnConnectNotifier)
+	{
+		g_fnDBGKMNotifier.pfnConnectNotifier();
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR, "pfnConnectNotifier not initialised.\n"));
+	}		
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return pvRet;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+	IMG_UINT32	ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret=DBGDrivWriteString(psStream, pszString, ui32Level);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit)
+{
+	IMG_UINT32 ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret=DBGDrivReadString(psStream, pszString, ui32Limit);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+	IMG_UINT32	ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret=DBGDrivWrite(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
+{
+	IMG_UINT32 ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret=DBGDrivRead(psStream, bReadInitBuffer, ui32OutBuffSize, pui8OutBuf);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivSetCaptureMode(psStream, ui32Mode, ui32Start, ui32End, ui32SampleRate);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivSetOutputMode(psStream, ui32OutMode);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivSetDebugLevel(psStream, ui32DebugLevel);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivSetFrame(psStream, ui32Frame);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(PDBG_STREAM psStream)
+{
+	IMG_UINT32	ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret=DBGDrivGetFrame(psStream);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+IMG_BOOL IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream)
+{
+	IMG_BOOL	bRet;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	bRet = DBGDrivIsLastCaptureFrame(psStream);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return bRet;
+}
+
+IMG_BOOL IMG_CALLCONV ExtDBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame)
+{
+	IMG_BOOL	bRet;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	bRet = DBGDrivIsCaptureFrame(psStream, bCheckPreviousFrame);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return bRet;
+}
+
+void IMG_CALLCONV ExtDBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivOverrideMode(psStream, ui32Mode);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+void IMG_CALLCONV ExtDBGDrivDefaultMode(PDBG_STREAM psStream)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivDefaultMode(psStream);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+	IMG_UINT32	ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret=DBGDrivWrite2(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWritePersist(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+	IMG_UINT32	ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret=DBGDrivWritePersist(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+	if(ui32Ret==0xFFFFFFFFU)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "An error occurred in DBGDrivWritePersist."));
+	}
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+	IMG_UINT32	ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret=DBGDrivWriteStringCM(psStream, pszString, ui32Level);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+	IMG_UINT32	ui32Ret;
+	
+	
+	HostAquireMutex(g_pvAPIMutex);
+	
+	ui32Ret=DBGDrivWriteCM(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+	
+	
+	HostReleaseMutex(g_pvAPIMutex);
+	
+	return ui32Ret;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivSetMarker(psStream, ui32Marker);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream)
+{
+	IMG_UINT32	ui32Marker;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Marker = DBGDrivGetMarker(psStream);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Marker;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags)
+{
+	IMG_UINT32	ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret = DBGDrivWriteLF(psStream, pui8InBuf, ui32InBuffSize, ui32Level, ui32Flags);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf)
+{
+	IMG_UINT32 ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret = DBGDrivReadLF(psStream, ui32OutBuffSize, pui8OutBuf);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivStartInitPhase(PDBG_STREAM psStream)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivStartInitPhase(psStream);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivStopInitPhase(PDBG_STREAM psStream)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivStopInitPhase(psStream);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetStreamOffset(PDBG_STREAM psStream)
+{
+	IMG_UINT32 ui32Ret;
+
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	ui32Ret = DBGDrivGetStreamOffset(psStream);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+
+	return ui32Ret;
+}
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset)
+{
+	
+	HostAquireMutex(g_pvAPIMutex);
+
+	DBGDrivSetStreamOffset(psStream, ui32StreamOffset);
+
+	
+	HostReleaseMutex(g_pvAPIMutex);
+}
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent)
+{
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+	DBGDrivWaitForEvent(eEvent);
+#else	
+	PVR_UNREFERENCED_PARAMETER(eEvent);				
+#endif	
+}
+
+IMG_UINT32 AtoI(IMG_CHAR *szIn)
+{
+	IMG_INT		iLen = 0;
+	IMG_UINT32	ui32Value = 0;
+	IMG_UINT32	ui32Digit=1;
+	IMG_UINT32	ui32Base=10;
+	IMG_INT		iPos;
+	IMG_CHAR	bc;
+
+	
+	while (szIn[iLen] > 0)
+	{
+		iLen ++;
+	}
+
+	
+	if (iLen == 0)
+	{
+		return (0);
+	}
+
+	
+	iPos=0;
+	while (szIn[iPos] == '0')
+	{
+		iPos++;
+	}
+	if (szIn[iPos] == '\0')
+	{
+		return 0;
+	}
+	if (szIn[iPos] == 'x' || szIn[iPos] == 'X')
+	{
+		ui32Base=16;
+		szIn[iPos]='0';
+	}
+
+	
+	for (iPos = iLen - 1; iPos >= 0; iPos --)
+	{
+		bc = szIn[iPos];
+
+		if ( (bc >= 'a') && (bc <= 'f') && ui32Base == 16)			
+		{
+			bc -= 'a' - 0xa;
+		}
+		else
+		if ( (bc >= 'A') && (bc <= 'F') && ui32Base == 16)			
+		{
+			bc -= 'A' - 0xa;
+		}
+		else
+		if ((bc >= '0') && (bc <= '9'))				
+		{
+			bc -= '0';
+		}
+		else
+			return (0);
+
+		ui32Value += (IMG_UINT32)bc  * ui32Digit;
+
+		ui32Digit = ui32Digit * ui32Base;
+	}
+	return (ui32Value);
+}
+
+
+static IMG_BOOL StreamValid(PDBG_STREAM psStream)
+{
+	PDBG_STREAM	psThis;
+
+	psThis = g_psStreamList;
+
+	while (psThis)
+	{
+		if (psStream && (psThis == psStream) )
+		{
+			return(IMG_TRUE);
+		}
+		else
+		{
+			psThis = psThis->psNext;
+		}
+	}
+
+	return(IMG_FALSE);
+}
+
+
+static IMG_BOOL StreamValidForRead(PDBG_STREAM psStream)
+{
+	if( StreamValid(psStream) &&
+		((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_WRITEONLY) == 0) )
+	{
+		return(IMG_TRUE);
+	}
+
+	return(IMG_FALSE);
+}
+
+static IMG_BOOL StreamValidForWrite(PDBG_STREAM psStream)
+{
+	if( StreamValid(psStream) &&
+		((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) == 0) )
+	{
+		return(IMG_TRUE);
+	}
+
+	return(IMG_FALSE);
+}
+
+
+static void Write(PDBG_STREAM psStream,IMG_PUINT8 pui8Data,IMG_UINT32 ui32InBuffSize)
+{
+	
+
+	if (!psStream->bCircularAllowed)
+	{
+		
+	}
+
+	if ((psStream->ui32WPtr + ui32InBuffSize) > psStream->ui32Size)
+	{
+		
+		IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32WPtr;
+		IMG_UINT32 ui32B2 = ui32InBuffSize - ui32B1;
+
+		
+		HostMemCopy((IMG_PVOID)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32WPtr),
+				(IMG_PVOID) pui8Data,
+				ui32B1);
+
+		
+		HostMemCopy(psStream->pvBase,
+				(IMG_PVOID)(pui8Data + ui32B1),
+				ui32B2);
+
+		
+		psStream->ui32WPtr = ui32B2;
+	}
+	else
+	{	
+		HostMemCopy((IMG_PVOID)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32WPtr),
+				(IMG_PVOID) pui8Data,
+				ui32InBuffSize);
+
+		psStream->ui32WPtr += ui32InBuffSize;
+
+		if (psStream->ui32WPtr == psStream->ui32Size)
+		{
+			psStream->ui32WPtr = 0;
+		}
+	}
+	psStream->ui32DataWritten += ui32InBuffSize;
+}
+
+
+void MonoOut(IMG_CHAR * pszString,IMG_BOOL bNewLine)
+{
+#if defined (_WIN64)
+	PVR_UNREFERENCED_PARAMETER(pszString);
+	PVR_UNREFERENCED_PARAMETER(bNewLine);
+
+#else
+	IMG_UINT32 	i;
+	IMG_CHAR *	pScreen;
+
+	pScreen = (IMG_CHAR *) DBGDRIV_MONOBASE;
+
+	pScreen += g_ui32Line * 160;
+
+	
+
+	i=0;
+	do
+	{
+		pScreen[g_ui32LOff + (i*2)] = pszString[i];
+		pScreen[g_ui32LOff + (i*2)+1] = 127;
+		i++;
+	}
+	while ((pszString[i] != 0) && (i < 4096));
+
+	g_ui32LOff += i * 2;
+
+	if (bNewLine)
+	{
+		g_ui32LOff = 0;
+		g_ui32Line++;
+	}
+
+	
+
+	if (g_ui32Line == g_ui32MonoLines)
+	{
+		g_ui32Line = g_ui32MonoLines - 1;
+
+		HostMemCopy((IMG_VOID *)DBGDRIV_MONOBASE,(IMG_VOID *)(DBGDRIV_MONOBASE + 160),160 * (g_ui32MonoLines - 1));
+
+		HostMemSet((IMG_VOID *)(DBGDRIV_MONOBASE + (160 * (g_ui32MonoLines - 1))),0,160);
+	}
+#endif	
+}
+
+static IMG_UINT32 WriteExpandingBuffer(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize)
+{
+	IMG_UINT ui32Space;
+
+	
+
+	ui32Space = SpaceInStream(psStream);
+
+	
+
+	if ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) == 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: buffer %x is disabled", (IMG_UINTPTR_T) psStream));
+		return(0);
+	}
+
+	
+
+	if (psStream->psCtrl->ui32Flags & DEBUG_FLAGS_NO_BUF_EXPANDSION)
+	{
+		
+
+
+		if (ui32Space < 32)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: buffer %x is full and isn't expandable", (IMG_UINTPTR_T) psStream));
+			return(0);
+		}
+	}
+	else
+	{
+		if ((ui32Space < 32) || (ui32Space <= (ui32InBuffSize + 4)))
+		{
+			IMG_UINT32	ui32NewBufSize;
+
+			
+
+			ui32NewBufSize = 2 * psStream->ui32Size;
+
+			PVR_DPF((PVR_DBGDRIV_MESSAGE, "Expanding buffer size = %x, new size = %x",
+					psStream->ui32Size, ui32NewBufSize));
+
+			if (ui32InBuffSize > psStream->ui32Size)
+			{
+				ui32NewBufSize += ui32InBuffSize;
+			}
+
+			
+
+			if (!ExpandStreamBuffer(psStream,ui32NewBufSize))
+			{
+				if (ui32Space < 32)
+				{
+					if(psStream->bCircularAllowed)
+					{
+						return(0);
+					}
+					else
+					{
+						
+						PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: Unable to expand %x. Out of memory.", (IMG_UINTPTR_T) psStream));
+						InvalidateAllStreams();
+						return (0xFFFFFFFFUL);
+					}
+				}
+			}
+
+			
+
+			ui32Space = SpaceInStream(psStream);
+			PVR_DPF((PVR_DBGDRIV_MESSAGE, "Expanded buffer, free space = %x",
+					ui32Space));
+		}
+	}
+
+	
+
+	if (ui32Space <= (ui32InBuffSize + 4))
+	{
+		ui32InBuffSize = ui32Space - 4;
+	}
+
+	
+
+	Write(psStream,pui8InBuf,ui32InBuffSize);
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+	if (ui32InBuffSize)
+	{
+		HostSignalEvent(DBG_EVENT_STREAM_DATA);
+	}
+#endif
+	return(ui32InBuffSize);
+}
+
+IMG_VOID * IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR *		pszName,
+								   IMG_UINT32 	ui32CapMode,
+								   IMG_UINT32 	ui32OutMode,
+								   IMG_UINT32	ui32Flags,
+								   IMG_UINT32 	ui32Size)
+{
+	PDBG_STREAM psStream;
+	PDBG_STREAM	psInitStream;
+	PDBG_LASTFRAME_BUFFER	psLFBuffer;
+	PDBG_STREAM_CONTROL psCtrl;
+	IMG_UINT32		ui32Off;
+	IMG_VOID *		pvBase;	
+	static IMG_CHAR pszNameInitSuffix[] = "_Init";
+	IMG_UINT32		ui32OffSuffix;
+
+	
+
+
+	psStream = (PDBG_STREAM) DBGDrivFindStream(pszName, IMG_FALSE);
+
+	if (psStream)
+	{
+		return ((IMG_VOID *) psStream);
+	}
+
+	
+
+	psStream = HostNonPageablePageAlloc(1);
+	psInitStream = HostNonPageablePageAlloc(1);
+	psLFBuffer = HostNonPageablePageAlloc(1);
+	psCtrl = HostNonPageablePageAlloc(1);
+	if	(
+			(!psStream) ||
+			(!psInitStream) ||
+			(!psLFBuffer) ||
+			(!psCtrl)
+		)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc control structs\n\r"));
+		return((IMG_VOID *) 0);
+	}
+
+	
+	if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+	{
+		pvBase = HostNonPageablePageAlloc(ui32Size);
+	}
+	else
+	{
+		pvBase = HostPageablePageAlloc(ui32Size);
+	}
+
+	if (!pvBase)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc Stream buffer\n\r"));
+		HostNonPageablePageFree(psStream);
+		return((IMG_VOID *) 0);
+	}
+
+	
+	psCtrl->ui32Flags = ui32Flags;
+	psCtrl->ui32CapMode = ui32CapMode;
+	psCtrl->ui32OutMode = ui32OutMode;
+	psCtrl->ui32DebugLevel = DEBUG_LEVEL_0;
+	psCtrl->ui32DefaultMode = ui32CapMode;
+	psCtrl->ui32Start = 0;
+	psCtrl->ui32End = 0;
+	psCtrl->ui32Current = 0;
+	psCtrl->ui32SampleRate = 1;
+	psCtrl->bInitPhaseComplete = IMG_FALSE;
+
+	
+
+	psStream->psNext = 0;
+	psStream->pvBase = pvBase;
+	psStream->psCtrl = psCtrl;
+	psStream->ui32Size = ui32Size * 4096UL;
+	psStream->ui32RPtr = 0;
+	psStream->ui32WPtr = 0;
+	psStream->ui32DataWritten = 0;
+	psStream->ui32Marker = 0;
+	psStream->bCircularAllowed = IMG_TRUE;
+	psStream->ui32InitPhaseWOff = 0;
+	
+
+
+	
+	if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+	{
+		pvBase = HostNonPageablePageAlloc(ui32Size);
+	}
+	else
+	{
+		pvBase = HostPageablePageAlloc(ui32Size);
+	}
+
+	if (!pvBase)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc InitStream buffer\n\r"));
+		
+		if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+		{
+			HostNonPageablePageFree(psStream->pvBase);
+		}
+		else
+		{
+			HostPageablePageFree(psStream->pvBase);
+		}
+		HostNonPageablePageFree(psStream);
+		return((IMG_VOID *) 0);
+	}
+
+	
+	psInitStream->psNext = 0;
+	psInitStream->pvBase = pvBase;
+	psInitStream->psCtrl = psCtrl;
+	psInitStream->ui32Size = ui32Size * 4096UL;
+	psInitStream->ui32RPtr = 0;
+	psInitStream->ui32WPtr = 0;
+	psInitStream->ui32DataWritten = 0;
+	psInitStream->ui32Marker = 0;
+	psInitStream->bCircularAllowed = IMG_FALSE;
+	psInitStream->ui32InitPhaseWOff = 0;
+	
+
+
+	psStream->psInitStream = psInitStream;
+
+	
+	psLFBuffer->psStream = psStream;
+	psLFBuffer->ui32BufLen = 0UL;
+
+	g_bHotkeyMiddump = IMG_FALSE;
+	g_ui32HotkeyMiddumpStart = 0xffffffffUL;
+	g_ui32HotkeyMiddumpEnd = 0xffffffffUL;
+
+	
+
+	ui32Off = 0;
+
+	do
+	{
+		psStream->szName[ui32Off] = pszName[ui32Off];
+		psInitStream->szName[ui32Off] = pszName[ui32Off];
+		ui32Off++;
+	}
+	while ((pszName[ui32Off] != 0) && (ui32Off < (4096UL - sizeof(DBG_STREAM))));
+	psStream->szName[ui32Off] = pszName[ui32Off];	
+
+	
+
+	ui32OffSuffix = 0;
+	do
+	{
+		psInitStream->szName[ui32Off] = pszNameInitSuffix[ui32OffSuffix];
+		ui32Off++;
+		ui32OffSuffix++;
+	}
+	while (	(pszNameInitSuffix[ui32OffSuffix] != 0) &&
+			(ui32Off < (4096UL - sizeof(DBG_STREAM))));
+	psInitStream->szName[ui32Off] = pszNameInitSuffix[ui32OffSuffix];	
+
+	
+
+	psStream->psNext = g_psStreamList;
+	g_psStreamList = psStream;
+
+	psLFBuffer->psNext = g_psLFBufferList;
+	g_psLFBufferList = psLFBuffer;
+
+	AddSIDEntry(psStream);
+	
+	return((IMG_VOID *) psStream);
+}
+
+void IMG_CALLCONV DBGDrivDestroyStream(PDBG_STREAM psStream)
+{
+	PDBG_STREAM	psStreamThis;
+	PDBG_STREAM	psStreamPrev;
+	PDBG_LASTFRAME_BUFFER	psLFBuffer;
+	PDBG_LASTFRAME_BUFFER	psLFThis;
+	PDBG_LASTFRAME_BUFFER	psLFPrev;
+
+	PVR_DPF((PVR_DBG_MESSAGE, "DBGDriv: Destroying stream %s\r\n", psStream->szName ));
+
+	
+
+	if (!StreamValid(psStream))
+	{
+		return;
+	}
+
+	RemoveSIDEntry(psStream);
+	
+	psLFBuffer = FindLFBuf(psStream);
+
+	
+
+	psStreamThis = g_psStreamList;
+	psStreamPrev = 0;
+
+	while (psStreamThis)
+	{
+		if (psStreamThis == psStream)
+		{
+			if (psStreamPrev)
+			{
+				psStreamPrev->psNext = psStreamThis->psNext;
+			}
+			else
+			{
+				g_psStreamList = psStreamThis->psNext;
+			}
+
+			psStreamThis = 0;
+		}
+		else
+		{
+			psStreamPrev = psStreamThis;
+			psStreamThis = psStreamThis->psNext;
+		}
+	}
+
+	psLFThis = g_psLFBufferList;
+	psLFPrev = 0;
+
+	while (psLFThis)
+	{
+		if (psLFThis == psLFBuffer)
+		{
+			if (psLFPrev)
+			{
+				psLFPrev->psNext = psLFThis->psNext;
+			}
+			else
+			{
+				g_psLFBufferList = psLFThis->psNext;
+			}
+
+			psLFThis = 0;
+		}
+		else
+		{
+			psLFPrev = psLFThis;
+			psLFThis = psLFThis->psNext;
+		}
+	}
+	
+
+	if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
+	{
+		DeactivateHotKeys();
+	}
+
+	
+
+	if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+	{
+		HostNonPageablePageFree(psStream->psCtrl);
+		HostNonPageablePageFree(psStream->pvBase);
+		HostNonPageablePageFree(psStream->psInitStream->pvBase);
+	}
+	else
+	{
+		HostNonPageablePageFree(psStream->psCtrl);
+		HostPageablePageFree(psStream->pvBase);
+		HostPageablePageFree(psStream->psInitStream->pvBase);
+	}
+	
+	HostNonPageablePageFree(psStream->psInitStream);
+	HostNonPageablePageFree(psStream);
+	HostNonPageablePageFree(psLFBuffer);
+
+	if (g_psStreamList == 0)
+	{
+		PVR_DPF((PVR_DBG_MESSAGE,"DBGDriv: Stream list now empty" ));
+	}
+
+	return;
+}
+
+IMG_VOID * IMG_CALLCONV DBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream)
+{
+	PDBG_STREAM	psStream;
+	PDBG_STREAM	psThis;
+	IMG_UINT32	ui32Off;
+	IMG_BOOL	bAreSame;
+
+	psStream = 0;
+
+	PVR_DPF((PVR_DBGDRIV_MESSAGE, "PDump client connecting to %s %s",
+			pszName,
+			(bResetStream == IMG_TRUE) ? "with reset" : "no reset"));
+
+	
+
+	for (psThis = g_psStreamList; psThis != IMG_NULL; psThis = psThis->psNext)
+	{
+		bAreSame = IMG_TRUE;
+		ui32Off = 0;
+
+		if (strlen(psThis->szName) == strlen(pszName))
+		{
+			while ((psThis->szName[ui32Off] != 0) && (pszName[ui32Off] != 0) && (ui32Off < 128) && bAreSame)
+			{
+				if (psThis->szName[ui32Off] != pszName[ui32Off])
+				{
+					bAreSame = IMG_FALSE;
+				}
+
+				ui32Off++;
+			}
+		}
+		else
+		{
+			bAreSame = IMG_FALSE;
+		}
+
+		if (bAreSame)
+		{
+			psStream = psThis;
+			break;
+		}
+	}
+
+	if(bResetStream && psStream)
+	{
+		static IMG_CHAR szComment[] = "-- Init phase terminated\r\n";
+		psStream->psInitStream->ui32RPtr = 0;
+		psStream->ui32RPtr = 0;
+		psStream->ui32WPtr = 0;
+		psStream->ui32DataWritten = psStream->psInitStream->ui32DataWritten;
+		if (psStream->psCtrl->bInitPhaseComplete == IMG_FALSE)
+		{
+			if (psStream->psCtrl->ui32Flags & DEBUG_FLAGS_TEXTSTREAM)
+			{
+				DBGDrivWrite2(psStream, (IMG_UINT8 *)szComment, sizeof(szComment) - 1, 0x01);
+			}
+			psStream->psCtrl->bInitPhaseComplete = IMG_TRUE;
+		}
+
+		{
+			
+			
+			psStream->psInitStream->ui32InitPhaseWOff = psStream->psInitStream->ui32WPtr;
+			PVR_DPF((PVR_DBGDRIV_MESSAGE, "Set %s client marker bo %x, total bw %x",
+					psStream->szName,
+					psStream->psInitStream->ui32InitPhaseWOff,
+					psStream->psInitStream->ui32DataWritten ));
+		}
+	}
+
+	return((IMG_VOID *) psStream);
+}
+
+static void IMG_CALLCONV DBGDrivInvalidateStream(PDBG_STREAM psStream)
+{
+	IMG_CHAR pszErrorMsg[] = "**OUTOFMEM\n";
+	IMG_UINT32 ui32Space;
+	IMG_UINT32 ui32Off = 0;
+	IMG_UINT32 ui32WPtr = psStream->ui32WPtr;
+	IMG_PUINT8 pui8Buffer = (IMG_UINT8 *) psStream->pvBase;
+	
+	PVR_DPF((PVR_DBG_ERROR, "DBGDrivInvalidateStream: An error occurred for stream %s\r\n", psStream->szName ));
+
+	
+
+	
+
+
+
+
+	
+	ui32Space = SpaceInStream(psStream);
+
+	
+	if(ui32Space > 0)
+	{
+		ui32Space--;
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR, "DBGDrivInvalidateStream: Buffer full."));
+	}
+
+	while((pszErrorMsg[ui32Off] != 0) && (ui32Off < ui32Space))
+	{
+		pui8Buffer[ui32WPtr] = (IMG_UINT8)pszErrorMsg[ui32Off];
+		ui32Off++;
+		ui32WPtr++;
+	}
+	pui8Buffer[ui32WPtr++] = '\0';
+	psStream->ui32WPtr = ui32WPtr;
+
+	
+	psStream->psCtrl->ui32Flags |= DEBUG_FLAGS_READONLY;
+}
+
+static IMG_VOID InvalidateAllStreams(IMG_VOID)
+{
+	PDBG_STREAM psStream = g_psStreamList;
+	while (psStream != IMG_NULL)
+	{
+		DBGDrivInvalidateStream(psStream);
+		psStream = psStream->psNext;
+	}
+	return;
+}
+
+
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+	
+
+	if (!StreamValidForWrite(psStream))
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+	if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+	{
+		if	((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+		{
+			return(0);
+		}
+	}
+	else
+	{
+		if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+		{
+			if ((psStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+			{
+				return(0);
+			}
+		}
+	}
+
+	return(DBGDrivWriteString(psStream,pszString,ui32Level));
+
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+	IMG_UINT32	ui32Len;
+	IMG_UINT32	ui32Space;
+	IMG_UINT32	ui32WPtr;
+	IMG_UINT8 *	pui8Buffer;
+
+	
+
+	if (!StreamValidForWrite(psStream))
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+	if ((psStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+
+	if ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_ASYNC) == 0)
+	{
+		if (psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STANDARDDBG)
+		{
+			PVR_DPF((PVR_DBG_MESSAGE,"%s: %s\r\n",psStream->szName, pszString));
+		}
+
+		
+
+		if (psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_MONO)
+		{
+			MonoOut(psStream->szName,IMG_FALSE);
+			MonoOut(": ",IMG_FALSE);
+			MonoOut(pszString,IMG_TRUE);
+		}
+	}
+
+	
+
+	if	(
+			!(
+				((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) != 0) ||
+				((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_ASYNC) != 0)
+			)
+		)
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+	ui32Space=SpaceInStream(psStream);
+
+	
+	if(ui32Space > 0)
+	{
+		ui32Space--;
+	}
+
+	ui32Len		= 0;
+	ui32WPtr	= psStream->ui32WPtr;
+	pui8Buffer	= (IMG_UINT8 *) psStream->pvBase;
+
+	while((pszString[ui32Len] != 0) && (ui32Len < ui32Space))
+	{
+		pui8Buffer[ui32WPtr] = (IMG_UINT8)pszString[ui32Len];
+		ui32Len++;
+		ui32WPtr++;
+		if (ui32WPtr == psStream->ui32Size)
+		{
+			ui32WPtr = 0;
+		}
+	}
+
+	if (ui32Len < ui32Space)
+	{
+		
+		pui8Buffer[ui32WPtr] = (IMG_UINT8)pszString[ui32Len];
+		ui32Len++;
+		ui32WPtr++;
+		if (ui32WPtr == psStream->ui32Size)
+		{
+			ui32WPtr = 0;
+		}
+
+		
+		psStream->ui32WPtr = ui32WPtr;
+		psStream->ui32DataWritten+= ui32Len;
+	} else
+	{
+		ui32Len = 0;
+	}
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+	if (ui32Len)
+	{
+		HostSignalEvent(DBG_EVENT_STREAM_DATA);
+	}
+#endif
+
+	return(ui32Len);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit)
+{
+	IMG_UINT32				ui32OutLen;
+	IMG_UINT32				ui32Len;
+	IMG_UINT32				ui32Offset;
+	IMG_UINT8				*pui8Buff;
+
+	
+
+	if (!StreamValidForRead(psStream))
+	{
+		return(0);
+	}
+
+	
+
+	pui8Buff = (IMG_UINT8 *)psStream->pvBase;
+	ui32Offset = psStream->ui32RPtr;
+
+	if (psStream->ui32RPtr == psStream->ui32WPtr)
+	{
+		return(0);
+	}
+
+	
+
+	ui32Len = 0;
+	while((pui8Buff[ui32Offset] != 0) && (ui32Offset != psStream->ui32WPtr))
+	{
+		ui32Offset++;
+		ui32Len++;
+
+		
+
+		if (ui32Offset == psStream->ui32Size)
+		{
+			ui32Offset = 0;
+		}
+	}
+
+	ui32OutLen = ui32Len + 1;
+
+	
+
+	if (ui32Len > ui32Limit)
+	{
+		return(0);
+	}
+
+	
+
+	ui32Offset = psStream->ui32RPtr;
+	ui32Len = 0;
+
+	while ((pui8Buff[ui32Offset] != 0) && (ui32Len < ui32Limit))
+	{
+		pszString[ui32Len] = (IMG_CHAR)pui8Buff[ui32Offset];
+		ui32Offset++;
+		ui32Len++;
+
+		
+
+		if (ui32Offset == psStream->ui32Size)
+		{
+			ui32Offset = 0;
+		}
+	}
+
+	pszString[ui32Len] = (IMG_CHAR)pui8Buff[ui32Offset];
+
+	psStream->ui32RPtr = ui32Offset + 1;
+
+	if (psStream->ui32RPtr == psStream->ui32Size)
+	{
+		psStream->ui32RPtr = 0;
+	}
+
+	return(ui32OutLen);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+	IMG_UINT32				ui32Space;
+	DBG_STREAM *psStream;
+
+	
+
+	if (!StreamValidForWrite(psMainStream))
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+	if ((psMainStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+	if (psMainStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+	{
+		if	((psMainStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+		{
+			
+			return(ui32InBuffSize);
+		}
+	}
+	else if (psMainStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+	{
+		if ((psMainStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+		{
+			
+			return(ui32InBuffSize);
+		}
+	}
+
+	if(psMainStream->psCtrl->bInitPhaseComplete)
+	{
+		psStream = psMainStream;
+	}
+	else
+	{
+		psStream = psMainStream->psInitStream;
+	}
+
+	
+
+	ui32Space=SpaceInStream(psStream);
+
+	PVR_DPF((PVR_DBGDRIV_MESSAGE, "Recv %d b for %s: Roff = %x, WOff = %x",
+			ui32InBuffSize,
+			psStream->szName,
+			psStream->ui32RPtr,
+			psStream->ui32WPtr));
+
+	
+
+	if ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) == 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite: buffer %x is disabled", (IMG_UINTPTR_T) psStream));
+		return(0);
+	}
+
+	if (ui32Space < 8)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite: buffer %x is full", (IMG_UINTPTR_T) psStream));
+		return(0);
+	}
+
+	
+
+	if (ui32Space <= (ui32InBuffSize + 4))
+	{
+		ui32InBuffSize = ui32Space - 8;
+	}
+
+	
+
+	Write(psStream,(IMG_UINT8 *) &ui32InBuffSize,4);
+	Write(psStream,pui8InBuf,ui32InBuffSize);
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+	if (ui32InBuffSize)
+	{
+		HostSignalEvent(DBG_EVENT_STREAM_DATA);
+	}
+#endif
+	return(ui32InBuffSize);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+	
+
+	if (!StreamValidForWrite(psStream))
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+	if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+	{
+		if	((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+		{
+			
+			return(ui32InBuffSize);
+		}
+	}
+	else
+	{
+		if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+		{
+			if ((psStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+			{
+				
+				return(ui32InBuffSize);
+			}
+		}
+	}
+
+	return(DBGDrivWrite2(psStream,pui8InBuf,ui32InBuffSize,ui32Level));
+}
+
+
+static IMG_UINT32 DBGDrivWritePersist(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+	DBG_STREAM	*psStream;
+	PVR_UNREFERENCED_PARAMETER(ui32Level);
+
+	
+
+	if (!StreamValidForWrite(psMainStream))
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+	psStream = psMainStream->psInitStream;
+	if(psStream->bCircularAllowed == IMG_TRUE)
+	{
+		PVR_DPF((PVR_DBG_WARNING, "DBGDrivWritePersist: Init phase is a circular buffer, some data may be lost"));
+	}
+
+	PVR_DPF((PVR_DBGDRIV_MESSAGE, "Append %x b to %s: Roff = %x, WOff = %x [bw = %x]",
+			ui32InBuffSize,
+			psStream->szName,
+			psStream->ui32RPtr,
+			psStream->ui32WPtr,
+			psStream->ui32DataWritten));
+
+	return( WriteExpandingBuffer(psStream, pui8InBuf, ui32InBuffSize) );
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+	DBG_STREAM	*psStream;
+
+	
+
+	if (!StreamValidForWrite(psMainStream))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite2: stream not valid"));
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+	if ((psMainStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+	{
+		return(0);
+	}
+
+	if(psMainStream->psCtrl->bInitPhaseComplete)
+	{
+		psStream = psMainStream;
+	}
+	else
+	{
+		psStream = psMainStream->psInitStream;
+	}
+
+	PVR_DPF((PVR_DBGDRIV_MESSAGE, "Recv(exp) %d b for %s: Roff = %x, WOff = %x",
+			ui32InBuffSize,
+			psStream->szName,
+			psStream->ui32RPtr,
+			psStream->ui32WPtr));
+
+	return( WriteExpandingBuffer(psStream, pui8InBuf, ui32InBuffSize) );
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psMainStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
+{
+	IMG_UINT32 ui32Data;
+	DBG_STREAM *psStream;
+
+	
+
+	if (!StreamValidForRead(psMainStream))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "DBGDrivRead: buffer %x is invalid", (IMG_UINTPTR_T) psMainStream));
+		return(0);
+	}
+
+	if(bReadInitBuffer)
+	{
+		psStream = psMainStream->psInitStream;
+	}
+	else
+	{
+		psStream = psMainStream;
+	}
+
+	
+	if (psStream->ui32RPtr == psStream->ui32WPtr ||
+		((psStream->ui32InitPhaseWOff > 0) &&
+		 (psStream->ui32RPtr >= psStream->ui32InitPhaseWOff)) )
+	{
+		return(0);
+	}
+
+	
+
+	if (psStream->ui32RPtr <= psStream->ui32WPtr)
+	{
+		ui32Data = psStream->ui32WPtr - psStream->ui32RPtr;
+	}
+	else
+	{
+		ui32Data = psStream->ui32WPtr + (psStream->ui32Size - psStream->ui32RPtr);
+	}
+
+	
+
+	if ((psStream->ui32InitPhaseWOff > 0) &&
+		(psStream->ui32InitPhaseWOff < psStream->ui32WPtr))
+	{
+		ui32Data = psStream->ui32InitPhaseWOff - psStream->ui32RPtr;
+	}
+
+	
+
+	if (ui32Data > ui32OutBuffSize)
+	{
+		ui32Data = ui32OutBuffSize;
+	}
+
+	PVR_DPF((PVR_DBGDRIV_MESSAGE, "Send %x b from %s: Roff = %x, WOff = %x",
+			ui32Data,
+			psStream->szName,
+			psStream->ui32RPtr,
+			psStream->ui32WPtr));
+
+	
+
+	if ((psStream->ui32RPtr + ui32Data) > psStream->ui32Size)
+	{	
+		IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32RPtr;
+		IMG_UINT32 ui32B2 = ui32Data - ui32B1;
+
+		
+		HostMemCopy((IMG_VOID *) pui8OutBuf,
+				(IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+				ui32B1);
+
+		
+		HostMemCopy((IMG_VOID *)(pui8OutBuf + ui32B1),
+				psStream->pvBase,
+				ui32B2);
+
+		
+		psStream->ui32RPtr = ui32B2;
+	}
+	else
+	{	
+		HostMemCopy((IMG_VOID *) pui8OutBuf,
+				(IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+				ui32Data);
+
+		
+		psStream->ui32RPtr += ui32Data;
+
+		
+		if (psStream->ui32RPtr == psStream->ui32Size)
+		{
+			psStream->ui32RPtr = 0;
+		}
+	}
+
+	return(ui32Data);
+}
+
+void IMG_CALLCONV DBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return;
+	}
+
+	psStream->psCtrl->ui32CapMode = ui32Mode;
+	psStream->psCtrl->ui32DefaultMode = ui32Mode;
+	psStream->psCtrl->ui32Start = ui32Start;
+	psStream->psCtrl->ui32End = ui32End;
+	psStream->psCtrl->ui32SampleRate = ui32SampleRate;
+
+	
+
+	if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
+	{
+		ActivateHotKeys(psStream);
+	}
+}
+
+void IMG_CALLCONV DBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return;
+	}
+
+	psStream->psCtrl->ui32OutMode = ui32OutMode;
+}
+
+void IMG_CALLCONV DBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return;
+	}
+
+	psStream->psCtrl->ui32DebugLevel = ui32DebugLevel;
+}
+
+void IMG_CALLCONV DBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return;
+	}
+
+	psStream->psCtrl->ui32Current = ui32Frame;
+
+	if ((ui32Frame >= psStream->psCtrl->ui32Start) &&
+		(ui32Frame <= psStream->psCtrl->ui32End) &&
+		(((ui32Frame - psStream->psCtrl->ui32Start) % psStream->psCtrl->ui32SampleRate) == 0))
+	{
+		psStream->psCtrl->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
+	}
+	else
+	{
+		psStream->psCtrl->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
+	}
+
+	if (g_bHotkeyMiddump)
+	{
+		if ((ui32Frame >= g_ui32HotkeyMiddumpStart) &&
+			(ui32Frame <= g_ui32HotkeyMiddumpEnd) &&
+			(((ui32Frame - g_ui32HotkeyMiddumpStart) % psStream->psCtrl->ui32SampleRate) == 0))
+		{
+			psStream->psCtrl->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
+		}
+		else
+		{
+			psStream->psCtrl->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
+			if (psStream->psCtrl->ui32Current > g_ui32HotkeyMiddumpEnd)
+			{
+				g_bHotkeyMiddump = IMG_FALSE;
+			}
+		}
+	}
+
+	
+	if (g_bHotKeyRegistered)
+	{
+		g_bHotKeyRegistered = IMG_FALSE;
+
+		PVR_DPF((PVR_DBG_MESSAGE,"Hotkey pressed (%p)!\n",psStream));
+
+		if (!g_bHotKeyPressed)
+		{
+			
+
+			g_ui32HotKeyFrame = psStream->psCtrl->ui32Current + 2;
+
+			
+
+			g_bHotKeyPressed = IMG_TRUE;
+		}
+
+		
+
+		if (((psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) && 
+			((psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_HOTKEY) != 0))
+		{
+			if (!g_bHotkeyMiddump)
+			{
+				
+				g_ui32HotkeyMiddumpStart = g_ui32HotKeyFrame + 1;
+				g_ui32HotkeyMiddumpEnd = 0xffffffff;
+				g_bHotkeyMiddump = IMG_TRUE;
+				PVR_DPF((PVR_DBG_MESSAGE,"Sampling every %d frame(s)\n", psStream->psCtrl->ui32SampleRate));
+			}
+			else
+			{
+				
+				g_ui32HotkeyMiddumpEnd = g_ui32HotKeyFrame;
+				PVR_DPF((PVR_DBG_MESSAGE,"Turning off sampling\n"));
+			}
+		}
+
+	}
+
+	
+
+	if (psStream->psCtrl->ui32Current > g_ui32HotKeyFrame)
+	{
+		g_bHotKeyPressed = IMG_FALSE;
+	}
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(PDBG_STREAM psStream)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return(0);
+	}
+
+	return(psStream->psCtrl->ui32Current);
+}
+
+IMG_BOOL IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream)
+{
+	IMG_UINT32	ui32NextFrame;
+
+	
+
+	if (!StreamValid(psStream))
+	{
+		return IMG_FALSE;
+	}
+
+	if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+	{
+		ui32NextFrame = psStream->psCtrl->ui32Current + psStream->psCtrl->ui32SampleRate;
+		if (ui32NextFrame > psStream->psCtrl->ui32End)
+		{
+			return IMG_TRUE;
+		}
+	}
+	return IMG_FALSE;
+}
+
+IMG_BOOL IMG_CALLCONV DBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame)
+{
+	IMG_UINT32 ui32FrameShift = bCheckPreviousFrame ? 1UL : 0UL;
+
+	
+
+	if (!StreamValid(psStream))
+	{
+		return IMG_FALSE;
+	}
+
+	if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+	{
+		
+		if (g_bHotkeyMiddump)
+		{
+			if ((psStream->psCtrl->ui32Current >= (g_ui32HotkeyMiddumpStart - ui32FrameShift)) &&
+				(psStream->psCtrl->ui32Current <= (g_ui32HotkeyMiddumpEnd - ui32FrameShift)) &&
+				((((psStream->psCtrl->ui32Current + ui32FrameShift) - g_ui32HotkeyMiddumpStart) % psStream->psCtrl->ui32SampleRate) == 0))
+			{
+				return IMG_TRUE;
+			}
+		}
+		else
+		{
+			if ((psStream->psCtrl->ui32Current >= (psStream->psCtrl->ui32Start - ui32FrameShift)) &&
+				(psStream->psCtrl->ui32Current <= (psStream->psCtrl->ui32End - ui32FrameShift)) &&
+				((((psStream->psCtrl->ui32Current + ui32FrameShift) - psStream->psCtrl->ui32Start) % psStream->psCtrl->ui32SampleRate) == 0))
+			{
+				return IMG_TRUE;
+			}
+		}
+	}
+	else if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+	{
+		if ((psStream->psCtrl->ui32Current == (g_ui32HotKeyFrame-ui32FrameShift)) && (g_bHotKeyPressed))
+		{
+			return IMG_TRUE;
+		}
+	}
+	return IMG_FALSE;
+}
+
+void IMG_CALLCONV DBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return;
+	}
+
+	psStream->psCtrl->ui32CapMode = ui32Mode;
+}
+
+void IMG_CALLCONV DBGDrivDefaultMode(PDBG_STREAM psStream)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return;
+	}
+
+	psStream->psCtrl->ui32CapMode = psStream->psCtrl->ui32DefaultMode;
+}
+
+IMG_VOID IMG_CALLCONV DBGDrivSetClientMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return;
+	}
+
+	psStream->ui32InitPhaseWOff = ui32Marker;
+}
+
+void IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return;
+	}
+
+	psStream->ui32Marker = ui32Marker;
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream)
+{
+	
+
+	if (!StreamValid(psStream))
+	{
+		return 0;
+	}
+
+	return psStream->ui32Marker;
+}
+
+
+IMG_UINT32 IMG_CALLCONV DBGDrivGetStreamOffset(PDBG_STREAM psMainStream)
+{
+	PDBG_STREAM psStream;
+
+	
+
+	if (!StreamValid(psMainStream))
+	{
+		return 0;
+	}
+
+	if(psMainStream->psCtrl->bInitPhaseComplete)
+	{
+		psStream = psMainStream;
+	}
+	else
+	{
+		psStream = psMainStream->psInitStream;
+	}
+
+	return psStream->ui32DataWritten;
+}
+
+IMG_VOID IMG_CALLCONV DBGDrivSetStreamOffset(PDBG_STREAM psMainStream, IMG_UINT32 ui32StreamOffset)
+{
+	PDBG_STREAM psStream;
+
+	
+
+	if (!StreamValid(psMainStream))
+	{
+		return;
+	}
+
+	if(psMainStream->psCtrl->bInitPhaseComplete)
+	{
+		psStream = psMainStream;
+	}
+	else
+	{
+		psStream = psMainStream->psInitStream;
+	}
+
+	PVR_DPF((PVR_DBGDRIV_MESSAGE, "DBGDrivSetStreamOffset: %s set to %x b",
+			psStream->szName,
+			ui32StreamOffset));
+	psStream->ui32DataWritten = ui32StreamOffset;
+}
+
+IMG_PVOID IMG_CALLCONV DBGDrivGetServiceTable(IMG_VOID)
+{
+	return((IMG_PVOID)&g_sDBGKMServices);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags)
+{
+	PDBG_LASTFRAME_BUFFER	psLFBuffer;
+
+	
+
+	if (!StreamValidForWrite(psStream))
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+	if ((psStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+	{
+		return(0xFFFFFFFFUL);
+	}
+
+	
+
+	if ((psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0)
+	{
+		if	((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+		{
+			
+			return(ui32InBuffSize);
+		}
+	}
+	else if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+	{
+		if ((psStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+		{
+			
+			return(ui32InBuffSize);
+		}
+	}
+
+	psLFBuffer = FindLFBuf(psStream);
+
+	if (ui32Flags & WRITELF_FLAGS_RESETBUF)
+	{
+		
+
+		ui32InBuffSize = (ui32InBuffSize > LAST_FRAME_BUF_SIZE) ? LAST_FRAME_BUF_SIZE : ui32InBuffSize;
+		HostMemCopy((IMG_VOID *)psLFBuffer->ui8Buffer, (IMG_VOID *)pui8InBuf, ui32InBuffSize);
+		psLFBuffer->ui32BufLen = ui32InBuffSize;
+	}
+	else
+	{
+		
+
+		ui32InBuffSize = ((psLFBuffer->ui32BufLen + ui32InBuffSize) > LAST_FRAME_BUF_SIZE) ? (LAST_FRAME_BUF_SIZE - psLFBuffer->ui32BufLen) : ui32InBuffSize;
+		HostMemCopy((IMG_VOID *)(&psLFBuffer->ui8Buffer[psLFBuffer->ui32BufLen]), (IMG_VOID *)pui8InBuf, ui32InBuffSize);
+		psLFBuffer->ui32BufLen += ui32InBuffSize;
+	}
+
+	return(ui32InBuffSize);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf)
+{
+	PDBG_LASTFRAME_BUFFER	psLFBuffer;
+	IMG_UINT32	ui32Data;
+
+	
+
+	if (!StreamValidForRead(psStream))
+	{
+		return(0);
+	}
+
+	psLFBuffer = FindLFBuf(psStream);
+
+	
+
+	ui32Data = (ui32OutBuffSize < psLFBuffer->ui32BufLen) ? ui32OutBuffSize : psLFBuffer->ui32BufLen;
+
+	
+
+	HostMemCopy((IMG_VOID *)pui8OutBuf, (IMG_VOID *)psLFBuffer->ui8Buffer, ui32Data);
+
+	return ui32Data;
+}
+
+IMG_VOID IMG_CALLCONV DBGDrivStartInitPhase(PDBG_STREAM psStream)
+{
+	psStream->psCtrl->bInitPhaseComplete = IMG_FALSE;
+}
+
+IMG_VOID IMG_CALLCONV DBGDrivStopInitPhase(PDBG_STREAM psStream)
+{
+	psStream->psCtrl->bInitPhaseComplete = IMG_TRUE;
+}
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+IMG_VOID IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent)
+{
+	HostWaitForEvent(eEvent);
+}
+#endif
+
+IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize)
+{
+	IMG_VOID *	pvNewBuf;
+	IMG_UINT32	ui32NewSizeInPages;
+	IMG_UINT32	ui32NewWOffset;
+	IMG_UINT32	ui32NewROffset;
+	IMG_UINT32	ui32SpaceInOldBuf;
+
+	
+
+	if (psStream->ui32Size >= ui32NewSize)
+	{
+		return IMG_FALSE;
+	}
+
+	
+
+	ui32SpaceInOldBuf = SpaceInStream(psStream);
+
+	
+
+	ui32NewSizeInPages = ((ui32NewSize + 0xfffUL) & ~0xfffUL) / 4096UL;
+
+	if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+	{
+		pvNewBuf = HostNonPageablePageAlloc(ui32NewSizeInPages);
+	}
+	else
+	{
+		pvNewBuf = HostPageablePageAlloc(ui32NewSizeInPages);
+	}
+
+	if (pvNewBuf == IMG_NULL)
+	{
+		return IMG_FALSE;
+	}
+
+	if(psStream->bCircularAllowed)
+	{
+		
+
+
+		if (psStream->ui32RPtr <= psStream->ui32WPtr)
+		{
+			
+
+		HostMemCopy(pvNewBuf,
+					(IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+					psStream->ui32WPtr - psStream->ui32RPtr);
+		}
+		else
+		{
+			IMG_UINT32	ui32FirstCopySize;
+	
+			
+
+			ui32FirstCopySize = psStream->ui32Size - psStream->ui32RPtr;
+	
+			HostMemCopy(pvNewBuf,
+					(IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+					ui32FirstCopySize);
+	
+			
+
+			HostMemCopy((IMG_VOID *)((IMG_UINTPTR_T)pvNewBuf + ui32FirstCopySize),
+					(IMG_VOID *)(IMG_PBYTE)psStream->pvBase,
+					psStream->ui32WPtr);
+		}
+		ui32NewROffset = 0;
+	}
+	else
+	{
+		
+		HostMemCopy(pvNewBuf, psStream->pvBase,	psStream->ui32WPtr);
+		ui32NewROffset = psStream->ui32RPtr;
+	}
+
+	
+
+                                                        
+	ui32NewWOffset = psStream->ui32Size - ui32SpaceInOldBuf;
+
+	
+
+	if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+	{
+		HostNonPageablePageFree(psStream->pvBase);
+	}
+	else
+	{
+		HostPageablePageFree(psStream->pvBase);
+	}
+
+	
+
+	psStream->pvBase = pvNewBuf;
+	psStream->ui32RPtr = ui32NewROffset;
+	psStream->ui32WPtr = ui32NewWOffset;
+	psStream->ui32Size = ui32NewSizeInPages * 4096;
+
+	return IMG_TRUE;
+}
+
+IMG_UINT32 SpaceInStream(PDBG_STREAM psStream)
+{
+	IMG_UINT32	ui32Space;
+
+	if (psStream->bCircularAllowed)
+	{
+		
+	if (psStream->ui32RPtr > psStream->ui32WPtr)
+	{
+		ui32Space = psStream->ui32RPtr - psStream->ui32WPtr;
+	}
+	else
+	{
+		ui32Space = psStream->ui32RPtr + (psStream->ui32Size - psStream->ui32WPtr);
+	}
+	}
+	else
+	{
+		
+		ui32Space = psStream->ui32Size - psStream->ui32WPtr;
+	}
+
+	return ui32Space;
+}
+
+
+void DestroyAllStreams(void)
+{
+	while (g_psStreamList != IMG_NULL)
+	{
+		DBGDrivDestroyStream(g_psStreamList);
+	}
+	return;
+}
+
+PDBG_LASTFRAME_BUFFER FindLFBuf(PDBG_STREAM psStream)
+{
+	PDBG_LASTFRAME_BUFFER	psLFBuffer;
+
+	psLFBuffer = g_psLFBufferList;
+
+	while (psLFBuffer)
+	{
+		if (psLFBuffer->psStream == psStream)
+		{
+			break;
+		}
+
+		psLFBuffer = psLFBuffer->psNext;
+	}
+
+	return psLFBuffer;
+}
+
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.h b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.h
new file mode 100644
index 0000000..2db4843
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.h
@@ -0,0 +1,122 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _DBGDRIV_
+#define _DBGDRIV_
+
+#define BUFFER_SIZE 64*PAGESIZE
+
+#define DBGDRIV_VERSION 	0x100
+#define MAX_PROCESSES 		2
+#define BLOCK_USED			0x01
+#define BLOCK_LOCKED		0x02
+#define DBGDRIV_MONOBASE	0x000B0000
+
+
+extern IMG_VOID *	g_pvAPIMutex;
+
+IMG_VOID * IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR *		pszName,
+								   IMG_UINT32 	ui32CapMode,
+								   IMG_UINT32 	ui32OutMode,
+								   IMG_UINT32	ui32Flags,
+								   IMG_UINT32 	ui32Pages);
+IMG_VOID   IMG_CALLCONV DBGDrivDestroyStream(PDBG_STREAM psStream);
+IMG_VOID * IMG_CALLCONV DBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream);
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV DBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit);
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBufferSize,IMG_UINT8 *pui8OutBuf);
+IMG_VOID   IMG_CALLCONV DBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32Stop,IMG_UINT32 ui32SampleRate);
+IMG_VOID   IMG_CALLCONV DBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode);
+IMG_VOID   IMG_CALLCONV DBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel);
+IMG_VOID   IMG_CALLCONV DBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(PDBG_STREAM psStream);
+IMG_VOID   IMG_CALLCONV DBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode);
+IMG_VOID   IMG_CALLCONV DBGDrivDefaultMode(PDBG_STREAM psStream);
+IMG_PVOID  IMG_CALLCONV DBGDrivGetServiceTable(IMG_VOID);
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_VOID   IMG_CALLCONV DBGDrivSetClientMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_VOID   IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream);
+IMG_BOOL   IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream);
+IMG_BOOL   IMG_CALLCONV DBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame);
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags);
+IMG_UINT32 IMG_CALLCONV DBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf);
+IMG_VOID   IMG_CALLCONV DBGDrivStartInitPhase(PDBG_STREAM psStream);
+IMG_VOID   IMG_CALLCONV DBGDrivStopInitPhase(PDBG_STREAM psStream);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetStreamOffset(PDBG_STREAM psStream);
+IMG_VOID   IMG_CALLCONV DBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset);
+IMG_VOID   IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent);
+
+IMG_VOID DestroyAllStreams(IMG_VOID);
+
+IMG_UINT32 AtoI(IMG_CHAR *szIn);
+
+IMG_VOID HostMemSet(IMG_VOID *pvDest,IMG_UINT8 ui8Value,IMG_UINT32 ui32Size);
+IMG_VOID HostMemCopy(IMG_VOID *pvDest,IMG_VOID *pvSrc,IMG_UINT32 ui32Size);
+IMG_VOID MonoOut(IMG_CHAR * pszString,IMG_BOOL bNewLine);
+
+IMG_SID PStream2SID(PDBG_STREAM psStream);
+PDBG_STREAM SID2PStream(IMG_SID hStream); 
+IMG_BOOL AddSIDEntry(PDBG_STREAM psStream);
+IMG_BOOL RemoveSIDEntry(PDBG_STREAM psStream);
+
+IMG_VOID * IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR *	pszName, IMG_UINT32 ui32CapMode, IMG_UINT32	ui32OutMode, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivDestroyStream(PDBG_STREAM psStream);
+IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 *pui8OutBuf);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(PDBG_STREAM psStream);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivDefaultMode(PDBG_STREAM psStream);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivStartInitPhase(PDBG_STREAM psStream);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivStopInitPhase(PDBG_STREAM psStream);
+IMG_BOOL   IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream);
+IMG_BOOL   IMG_CALLCONV ExtDBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetStreamOffset(PDBG_STREAM psStream);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivSetConnectNotifier(DBGKM_CONNECT_NOTIFIER fn_notifier);
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWritePersist(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+
+#endif
+
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/dbgdriv_ioctl.h b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/dbgdriv_ioctl.h
new file mode 100644
index 0000000..130c146
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/dbgdriv_ioctl.h
@@ -0,0 +1,35 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _IOCTL_
+#define _IOCTL_
+
+#define MAX_DBGVXD_W32_API 25
+
+extern IMG_UINT32 (*g_DBGDrivProc[MAX_DBGVXD_W32_API])(IMG_VOID *, IMG_VOID *);
+
+#endif
+
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/handle.c b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/handle.c
new file mode 100644
index 0000000..ddffb3f
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/handle.c
@@ -0,0 +1,121 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "img_defs.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+
+#define MAX_SID_ENTRIES		8
+
+typedef struct _SID_INFO
+{
+	PDBG_STREAM	psStream;
+} SID_INFO, *PSID_INFO;
+
+static SID_INFO gaSID_Xlat_Table[MAX_SID_ENTRIES];
+
+IMG_SID PStream2SID(PDBG_STREAM psStream)
+{
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		IMG_INT32 iIdx;
+
+		for (iIdx = 0; iIdx < MAX_SID_ENTRIES; iIdx++)
+		{
+			if (psStream == gaSID_Xlat_Table[iIdx].psStream)
+			{
+				
+				return (IMG_SID)iIdx+1;
+			}
+		}
+	}
+
+	return (IMG_SID)0;
+}
+
+
+PDBG_STREAM SID2PStream(IMG_SID hStream)
+{
+	
+	IMG_INT32 iIdx = (IMG_INT32)hStream-1;
+
+	if (iIdx >= 0 && iIdx < MAX_SID_ENTRIES)
+	{
+		return gaSID_Xlat_Table[iIdx].psStream;
+	}
+	else
+	{
+    	return (PDBG_STREAM)IMG_NULL;
+    }
+}
+
+
+IMG_BOOL AddSIDEntry(PDBG_STREAM psStream)
+{
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		IMG_INT32 iIdx;
+
+		for (iIdx = 0; iIdx < MAX_SID_ENTRIES; iIdx++)
+		{
+			if (psStream == gaSID_Xlat_Table[iIdx].psStream)
+			{
+				
+				return IMG_TRUE;
+			}
+
+			if (gaSID_Xlat_Table[iIdx].psStream == (PDBG_STREAM)IMG_NULL)
+			{
+				
+				gaSID_Xlat_Table[iIdx].psStream = psStream;
+				return IMG_TRUE;
+			}
+		}
+	}
+
+	return IMG_FALSE;
+}
+
+IMG_BOOL RemoveSIDEntry(PDBG_STREAM psStream)
+{
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		IMG_INT32 iIdx;
+
+		for (iIdx = 0; iIdx < MAX_SID_ENTRIES; iIdx++)
+		{
+			if (psStream == gaSID_Xlat_Table[iIdx].psStream)
+			{
+				gaSID_Xlat_Table[iIdx].psStream = (PDBG_STREAM)IMG_NULL;
+				return IMG_TRUE;
+			}
+		}
+	}
+
+	return IMG_FALSE;
+}
+
+
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/hostfunc.h b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/hostfunc.h
new file mode 100644
index 0000000..70192fb
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/hostfunc.h
@@ -0,0 +1,58 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _HOSTFUNC_
+#define _HOSTFUNC_
+
+#define HOST_PAGESIZE			(4096)
+#define DBG_MEMORY_INITIALIZER	(0xe2)
+
+IMG_UINT32 HostReadRegistryDWORDFromString(IMG_CHAR *pcKey, IMG_CHAR *pcValueName, IMG_UINT32 *pui32Data);
+
+IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages);
+IMG_VOID HostPageablePageFree(IMG_VOID * pvBase);
+IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages);
+IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase);
+
+IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID * *ppvMdl);
+IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess);
+
+IMG_VOID HostCreateRegDeclStreams(IMG_VOID);
+
+IMG_VOID * HostCreateMutex(IMG_VOID);
+IMG_VOID HostAquireMutex(IMG_VOID * pvMutex);
+IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex);
+IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex);
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+IMG_INT32 HostCreateEventObjects(IMG_VOID);
+IMG_VOID HostWaitForEvent(DBG_EVENT eEvent);
+IMG_VOID HostSignalEvent(DBG_EVENT eEvent);
+IMG_VOID HostDestroyEventObjects(IMG_VOID);
+#endif	
+
+#endif
+
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/hotkey.c b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/hotkey.c
new file mode 100644
index 0000000..62c89e3
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/hotkey.c
@@ -0,0 +1,135 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+#if (!defined(LINUX) && !defined(__QNXNTO__))
+#include <ntddk.h>
+#include <windef.h>
+#endif
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hotkey.h"
+#include "hostfunc.h"
+
+
+
+
+
+IMG_UINT32	g_ui32HotKeyFrame = 0xFFFFFFFF;
+IMG_BOOL	g_bHotKeyPressed = IMG_FALSE;
+IMG_BOOL	g_bHotKeyRegistered = IMG_FALSE;
+
+PRIVATEHOTKEYDATA    g_PrivateHotKeyData;
+
+
+IMG_VOID ReadInHotKeys(IMG_VOID)
+{
+	g_PrivateHotKeyData.ui32ScanCode = 0x58;	
+	g_PrivateHotKeyData.ui32ShiftState = 0x0;
+
+	
+
+#if 0
+	if (_RegOpenKey(HKEY_LOCAL_MACHINE,pszRegPath,&hKey) == ERROR_SUCCESS)
+	{
+		
+
+		QueryReg(hKey,"ui32ScanCode",&g_PrivateHotKeyData.ui32ScanCode);
+		QueryReg(hKey,"ui32ShiftState",&g_PrivateHotKeyData.ui32ShiftState);
+	}
+#else
+	HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ScanCode"  , &g_PrivateHotKeyData.ui32ScanCode);
+	HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ShiftState", &g_PrivateHotKeyData.ui32ShiftState);
+#endif
+}
+
+IMG_VOID RegisterKeyPressed(IMG_UINT32 dwui32ScanCode, PHOTKEYINFO pInfo)
+{
+	PDBG_STREAM	psStream;
+
+	PVR_UNREFERENCED_PARAMETER(pInfo);
+
+	if (dwui32ScanCode == g_PrivateHotKeyData.ui32ScanCode)
+	{
+		PVR_DPF((PVR_DBG_MESSAGE,"PDUMP Hotkey pressed !\n"));
+
+		psStream = (PDBG_STREAM) g_PrivateHotKeyData.sHotKeyInfo.pvStream;
+
+		if (!g_bHotKeyPressed)
+		{
+			
+
+			g_ui32HotKeyFrame = psStream->psCtrl->ui32Current + 2;
+
+			
+
+			g_bHotKeyPressed = IMG_TRUE;
+		}
+	}
+}
+
+IMG_VOID ActivateHotKeys(PDBG_STREAM psStream)
+{
+	
+
+	ReadInHotKeys();
+
+	
+
+	if (!g_PrivateHotKeyData.sHotKeyInfo.hHotKey)
+	{
+		if (g_PrivateHotKeyData.ui32ScanCode != 0)
+		{
+			PVR_DPF((PVR_DBG_MESSAGE,"Activate HotKey for PDUMP.\n"));
+
+			
+
+			g_PrivateHotKeyData.sHotKeyInfo.pvStream = psStream;
+
+			DefineHotKey(g_PrivateHotKeyData.ui32ScanCode, g_PrivateHotKeyData.ui32ShiftState, &g_PrivateHotKeyData.sHotKeyInfo);
+		}
+		else
+		{
+			g_PrivateHotKeyData.sHotKeyInfo.hHotKey = 0;
+		}
+	}
+}
+
+IMG_VOID DeactivateHotKeys(IMG_VOID)
+{
+	if (g_PrivateHotKeyData.sHotKeyInfo.hHotKey != 0)
+	{
+		PVR_DPF((PVR_DBG_MESSAGE,"Deactivate HotKey.\n"));
+
+		RemoveHotKey(g_PrivateHotKeyData.sHotKeyInfo.hHotKey);
+		g_PrivateHotKeyData.sHotKeyInfo.hHotKey = 0;
+	}
+}
+
+
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/hotkey.h b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/hotkey.h
new file mode 100644
index 0000000..c5d84bb
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/hotkey.h
@@ -0,0 +1,60 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _HOTKEY_
+#define _HOTKEY_
+
+
+typedef struct _hotkeyinfo
+{
+	IMG_UINT8 ui8ScanCode;
+	IMG_UINT8 ui8Type;
+	IMG_UINT8 ui8Flag;
+	IMG_UINT8 ui8Filler1;
+	IMG_UINT32 ui32ShiftState;
+	IMG_UINT32 ui32HotKeyProc;
+	IMG_VOID *pvStream;
+	IMG_UINT32 hHotKey;			
+} HOTKEYINFO, *PHOTKEYINFO;
+
+typedef struct _privatehotkeydata
+{
+	IMG_UINT32		ui32ScanCode;
+	IMG_UINT32		ui32ShiftState;
+	HOTKEYINFO	sHotKeyInfo;
+} PRIVATEHOTKEYDATA, *PPRIVATEHOTKEYDATA;
+
+
+IMG_VOID ReadInHotKeys (IMG_VOID);
+IMG_VOID ActivateHotKeys(PDBG_STREAM psStream);
+IMG_VOID DeactivateHotKeys(IMG_VOID);
+
+IMG_VOID RemoveHotKey (IMG_UINT32 hHotKey);
+IMG_VOID DefineHotKey (IMG_UINT32 ui32ScanCode, IMG_UINT32 ui32ShiftState, PHOTKEYINFO psInfo);
+IMG_VOID RegisterKeyPressed (IMG_UINT32 ui32ScanCode, PHOTKEYINFO psInfo);
+
+#endif
+
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/ioctl.c b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/ioctl.c
new file mode 100644
index 0000000..a8b8b6e
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/common/ioctl.c
@@ -0,0 +1,586 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+
+#ifdef LINUX
+#include <asm/uaccess.h>
+#endif 
+
+#include "img_types.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hotkey.h"
+#include "dbgdriv_ioctl.h"
+
+
+static IMG_UINT32 DBGDIOCDrivCreateStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_CREATESTREAM psIn;
+	IMG_VOID * *ppvOut;
+	#ifdef LINUX
+	static IMG_CHAR name[32];
+	#endif
+
+	psIn = (PDBG_IN_CREATESTREAM) pvInBuffer;
+	ppvOut = (IMG_VOID * *) pvOutBuffer;
+
+	#ifdef LINUX
+
+	if (copy_from_user(name, psIn->u.pszName, 32) != 0)
+	{
+		return IMG_FALSE;
+	}
+
+	*ppvOut = ExtDBGDrivCreateStream(name, psIn->ui32CapMode, psIn->ui32OutMode, 0, psIn->ui32Pages);
+
+	#else
+	*ppvOut = ExtDBGDrivCreateStream(psIn->u.pszName, psIn->ui32CapMode, psIn->ui32OutMode, DEBUG_FLAGS_NO_BUF_EXPANDSION, psIn->ui32Pages);
+	#endif
+
+
+	return(IMG_TRUE);
+}
+
+static IMG_UINT32 DBGDIOCDrivDestroyStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_STREAM *ppsStream;
+	PDBG_STREAM  psStream;
+
+	ppsStream = (PDBG_STREAM *) pvInBuffer;
+	psStream  = (PDBG_STREAM) *ppsStream;
+
+	PVR_UNREFERENCED_PARAMETER(	pvOutBuffer);
+
+	ExtDBGDrivDestroyStream(psStream);
+
+	return(IMG_TRUE);
+}
+
+static IMG_UINT32 DBGDIOCDrivGetStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_FINDSTREAM psParams;
+	IMG_SID *	phStream;
+
+	psParams	= (PDBG_IN_FINDSTREAM)pvInBuffer;
+	phStream	= (IMG_SID *)pvOutBuffer;
+
+	*phStream = PStream2SID(ExtDBGDrivFindStream(psParams->u.pszName, psParams->bResetStream));
+
+	return(IMG_TRUE);
+}
+
+static IMG_UINT32 DBGDIOCDrivWriteString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_WRITESTRING psParams;
+	IMG_UINT32 *pui32OutLen;
+	PDBG_STREAM psStream;
+
+	psParams = (PDBG_IN_WRITESTRING) pvInBuffer;
+	pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32OutLen = ExtDBGDrivWriteString(psStream,psParams->u.pszString,psParams->ui32Level);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32OutLen = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivWriteStringCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_WRITESTRING psParams;
+	IMG_UINT32 *pui32OutLen;
+	PDBG_STREAM psStream;
+
+	psParams = (PDBG_IN_WRITESTRING) pvInBuffer;
+	pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32OutLen = ExtDBGDrivWriteStringCM(psStream,psParams->u.pszString,psParams->ui32Level);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32OutLen = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivReadString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	IMG_UINT32 * pui32OutLen;
+	PDBG_IN_READSTRING	psParams;
+	PDBG_STREAM  psStream;
+
+	psParams = (PDBG_IN_READSTRING) pvInBuffer;
+	pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32OutLen = ExtDBGDrivReadString(psStream,
+											psParams->u.pszString,psParams->ui32StringLen);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32OutLen = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivWrite(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	IMG_UINT32 *	pui32BytesCopied;
+	PDBG_IN_WRITE	psInParams;
+	PDBG_STREAM		psStream;
+
+	psInParams = (PDBG_IN_WRITE) pvInBuffer;
+	pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psInParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32BytesCopied = ExtDBGDrivWrite(psStream,
+										psInParams->u.pui8InBuffer,
+										psInParams->ui32TransferSize,
+										psInParams->ui32Level);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32BytesCopied = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivWrite2(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	IMG_UINT32 *	pui32BytesCopied;
+	PDBG_IN_WRITE	psInParams;
+	PDBG_STREAM 	psStream;
+
+	psInParams = (PDBG_IN_WRITE) pvInBuffer;
+	pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psInParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32BytesCopied = ExtDBGDrivWrite2(psStream,
+										 psInParams->u.pui8InBuffer,
+										 psInParams->ui32TransferSize,
+										 psInParams->ui32Level);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32BytesCopied = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivWriteCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	IMG_UINT32 *	pui32BytesCopied;
+	PDBG_IN_WRITE	psInParams;
+	PDBG_STREAM		psStream;
+
+	psInParams = (PDBG_IN_WRITE) pvInBuffer;
+	pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psInParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32BytesCopied = ExtDBGDrivWriteCM(psStream,
+										  psInParams->u.pui8InBuffer,
+										  psInParams->ui32TransferSize,
+										  psInParams->ui32Level);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32BytesCopied = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivRead(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	IMG_UINT32 *	pui32BytesCopied;
+	PDBG_IN_READ	psInParams;
+	PDBG_STREAM		psStream;
+
+	psInParams = (PDBG_IN_READ) pvInBuffer;
+	pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psInParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32BytesCopied = ExtDBGDrivRead(psStream,
+									   psInParams->bReadInitBuffer,
+									   psInParams->ui32OutBufferSize,
+									   psInParams->u.pui8OutBuffer);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32BytesCopied = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivSetCaptureMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_SETDEBUGMODE	psParams;
+	PDBG_STREAM				psStream;
+
+	psParams = (PDBG_IN_SETDEBUGMODE) pvInBuffer;
+	PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		ExtDBGDrivSetCaptureMode(psStream,
+							 psParams->ui32Mode,
+							 psParams->ui32Start,
+							 psParams->ui32End,
+							 psParams->ui32SampleRate);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivSetOutMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_SETDEBUGOUTMODE psParams;
+	PDBG_STREAM				psStream;
+
+	psParams = (PDBG_IN_SETDEBUGOUTMODE) pvInBuffer;
+	PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		ExtDBGDrivSetOutputMode(psStream,psParams->ui32Mode);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivSetDebugLevel(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_SETDEBUGLEVEL psParams;
+	PDBG_STREAM           psStream;
+
+	psParams = (PDBG_IN_SETDEBUGLEVEL) pvInBuffer;
+	PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		ExtDBGDrivSetDebugLevel(psStream,psParams->ui32Level);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivSetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_SETFRAME	psParams;
+	PDBG_STREAM			psStream;
+
+	psParams = (PDBG_IN_SETFRAME) pvInBuffer;
+	PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		ExtDBGDrivSetFrame(psStream,psParams->ui32Frame);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivGetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_STREAM  psStream;
+	IMG_UINT32  *pui32Current;
+
+	pui32Current = (IMG_UINT32 *) pvOutBuffer;
+	psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+	
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32Current = ExtDBGDrivGetFrame(psStream);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32Current = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivIsCaptureFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_ISCAPTUREFRAME psParams;
+	IMG_UINT32 *			pui32Current;
+	PDBG_STREAM				psStream;
+
+	psParams = (PDBG_IN_ISCAPTUREFRAME) pvInBuffer;
+	pui32Current = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32Current = ExtDBGDrivIsCaptureFrame(psStream,
+											 psParams->bCheckPreviousFrame);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32Current = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivOverrideMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_OVERRIDEMODE	psParams;
+	PDBG_STREAM				psStream;
+
+	psParams = (PDBG_IN_OVERRIDEMODE) pvInBuffer;
+	PVR_UNREFERENCED_PARAMETER(	pvOutBuffer);
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		ExtDBGDrivOverrideMode(psStream,psParams->ui32Mode);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivDefaultMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_STREAM  psStream;
+
+	PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+	psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		ExtDBGDrivDefaultMode(psStream);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivSetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_SETMARKER	psParams;
+	PDBG_STREAM			psStream;
+
+	psParams = (PDBG_IN_SETMARKER) pvInBuffer;
+	PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+	psStream = SID2PStream(psParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		ExtDBGDrivSetMarker(psStream, psParams->ui32Marker);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivGetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_STREAM  psStream;
+	IMG_UINT32  *pui32Current;
+
+	pui32Current = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32Current = ExtDBGDrivGetMarker(psStream);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32Current = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivGetServiceTable(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	IMG_PVOID *	ppvOut;
+
+	PVR_UNREFERENCED_PARAMETER(pvInBuffer);
+	ppvOut = (IMG_PVOID *) pvOutBuffer;
+
+	*ppvOut = DBGDrivGetServiceTable();
+
+    return(IMG_TRUE);
+}
+
+static IMG_UINT32 DBGDIOCDrivWriteLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	PDBG_IN_WRITE_LF psInParams;
+	IMG_UINT32      *pui32BytesCopied;
+	PDBG_STREAM      psStream;
+
+	psInParams = (PDBG_IN_WRITE_LF) pvInBuffer;
+	pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psInParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32BytesCopied = ExtDBGDrivWriteLF(psStream,
+										  psInParams->u.pui8InBuffer,
+										  psInParams->ui32BufferSize,
+										  psInParams->ui32Level,
+										  psInParams->ui32Flags);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivReadLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	IMG_UINT32 *	pui32BytesCopied;
+	PDBG_IN_READ	psInParams;
+	PDBG_STREAM		psStream;
+
+	psInParams = (PDBG_IN_READ) pvInBuffer;
+	pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+	psStream = SID2PStream(psInParams->hStream);
+	if (psStream != (PDBG_STREAM)IMG_NULL)
+	{
+		*pui32BytesCopied = ExtDBGDrivReadLF(psStream,
+										 psInParams->ui32OutBufferSize,
+										 psInParams->u.pui8OutBuffer);
+		return(IMG_TRUE);
+	}
+	else
+	{
+		
+		*pui32BytesCopied = 0;
+		return(IMG_FALSE);
+	}
+}
+
+static IMG_UINT32 DBGDIOCDrivWaitForEvent(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+	DBG_EVENT eEvent = (DBG_EVENT)(*(IMG_UINT32 *)pvInBuffer);
+
+	PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+	ExtDBGDrivWaitForEvent(eEvent);
+
+	return(IMG_TRUE);
+}
+
+IMG_UINT32 (*g_DBGDrivProc[25])(IMG_VOID *, IMG_VOID *) =
+{
+	DBGDIOCDrivCreateStream,
+	DBGDIOCDrivDestroyStream,
+	DBGDIOCDrivGetStream,
+	DBGDIOCDrivWriteString,
+	DBGDIOCDrivReadString,
+	DBGDIOCDrivWrite,
+	DBGDIOCDrivRead,
+	DBGDIOCDrivSetCaptureMode,
+	DBGDIOCDrivSetOutMode,
+	DBGDIOCDrivSetDebugLevel,
+	DBGDIOCDrivSetFrame,
+	DBGDIOCDrivGetFrame,
+	DBGDIOCDrivOverrideMode,
+	DBGDIOCDrivDefaultMode,
+	DBGDIOCDrivGetServiceTable,
+	DBGDIOCDrivWrite2,
+	DBGDIOCDrivWriteStringCM,
+	DBGDIOCDrivWriteCM,
+	DBGDIOCDrivSetMarker,
+	DBGDIOCDrivGetMarker,
+	DBGDIOCDrivIsCaptureFrame,
+	DBGDIOCDrivWriteLF,
+	DBGDIOCDrivReadLF,
+	DBGDIOCDrivWaitForEvent
+};
+
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/hostfunc.c b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/hostfunc.c
new file mode 100644
index 0000000..66d328d
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/hostfunc.c
@@ -0,0 +1,324 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <asm/page.h>
+#include <linux/vmalloc.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#include <linux/mutex.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#include <linux/hardirq.h>
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#endif	
+
+#include "img_types.h"
+#include "pvr_debug.h"
+
+#include "dbgdrvif.h"
+#include "hostfunc.h"
+#include "dbgdriv.h"
+
+#if defined(MODULE) && defined(DEBUG) && !defined(SUPPORT_DRI_DRM)
+IMG_UINT32	gPVRDebugLevel = (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
+
+#define PVR_STRING_TERMINATOR		'\0'
+#define PVR_IS_FILE_SEPARATOR(character) ( ((character) == '\\') || ((character) == '/') )
+
+void PVRSRVDebugPrintf	(
+						IMG_UINT32	ui32DebugLevel,
+						const IMG_CHAR*	pszFileName,
+						IMG_UINT32	ui32Line,
+						const IMG_CHAR*	pszFormat,
+						...
+					)
+{
+	IMG_BOOL bTrace;
+#if !defined(__sh__)
+	IMG_CHAR *pszLeafName;
+
+	pszLeafName = (char *)strrchr (pszFileName, '\\');
+
+	if (pszLeafName)
+	{
+		pszFileName = pszLeafName;
+	}
+#endif 
+
+	bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
+
+	if (gPVRDebugLevel & ui32DebugLevel)
+	{
+		va_list vaArgs;
+		char szBuffer[256];
+		char *szBufferEnd = szBuffer;
+		char *szBufferLimit = szBuffer + sizeof(szBuffer) - 1;
+
+		
+		*szBufferLimit = '\0';
+
+		snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "PVR_K:");
+		szBufferEnd += strlen(szBufferEnd);
+
+		
+		if (bTrace == IMG_FALSE)
+		{
+			switch(ui32DebugLevel)
+			{
+				case DBGPRIV_FATAL:
+				{
+					snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Fatal):");
+					break;
+				}
+				case DBGPRIV_ERROR:
+				{
+					snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Error):");
+					break;
+				}
+				case DBGPRIV_WARNING:
+				{
+					snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Warning):");
+					break;
+				}
+				case DBGPRIV_MESSAGE:
+				{
+					snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Message):");
+					break;
+				}
+				case DBGPRIV_VERBOSE:
+				{
+					snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Verbose):");
+					break;
+				}
+				default:
+				{
+					snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Unknown message level)");
+					break;
+				}
+			}
+			szBufferEnd += strlen(szBufferEnd);
+		}
+		snprintf(szBufferEnd, szBufferLimit - szBufferEnd, " ");
+		szBufferEnd += strlen(szBufferEnd);
+
+		va_start (vaArgs, pszFormat);
+		vsnprintf(szBufferEnd, szBufferLimit - szBufferEnd, pszFormat, vaArgs);
+		va_end (vaArgs);
+		szBufferEnd += strlen(szBufferEnd);
+
+ 		
+ 		if (bTrace == IMG_FALSE)
+		{
+			snprintf(szBufferEnd, szBufferLimit - szBufferEnd, 
+			         " [%d, %s]", (int)ui32Line, pszFileName);
+			szBufferEnd += strlen(szBufferEnd);
+		}
+
+		printk(KERN_INFO "%s\r\n", szBuffer);
+	}
+}
+#endif	
+
+IMG_VOID HostMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
+{
+	memset(pvDest, (int) ui8Value, (size_t) ui32Size);
+}
+
+IMG_VOID HostMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
+{
+#if defined(USE_UNOPTIMISED_MEMCPY)
+    unsigned char *src,*dst;
+    int i;
+
+    src=(unsigned char *)pvSrc;
+    dst=(unsigned char *)pvDst;
+    for(i=0;i<ui32Size;i++)
+    {
+        dst[i]=src[i];
+    }
+#else
+    memcpy(pvDst, pvSrc, ui32Size);
+#endif
+}
+
+IMG_UINT32 HostReadRegistryDWORDFromString(char *pcKey, char *pcValueName, IMG_UINT32 *pui32Data)
+{
+    
+	return 0;
+}
+
+IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+    return (void*)vmalloc(ui32Pages * PAGE_SIZE);
+}
+
+IMG_VOID HostPageablePageFree(IMG_VOID * pvBase)
+{
+    vfree(pvBase);
+}
+
+IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+    return (void*)vmalloc(ui32Pages * PAGE_SIZE);
+}
+
+IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase)
+{
+    vfree(pvBase);
+}
+
+IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID **ppvMdl)
+{
+    
+	return IMG_NULL;
+}
+
+IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess)
+{
+    
+}
+
+IMG_VOID HostCreateRegDeclStreams(IMG_VOID)
+{
+    
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+typedef	struct mutex		MUTEX;
+#define	INIT_MUTEX(m)		mutex_init(m)
+#define	DOWN_TRYLOCK(m)		(!mutex_trylock(m))
+#define	DOWN(m)			mutex_lock(m)
+#define UP(m)			mutex_unlock(m)
+#else
+typedef	struct semaphore	MUTEX;
+#define	INIT_MUTEX(m)		init_MUTEX(m)
+#define	DOWN_TRYLOCK(m)		down_trylock(m)
+#define	DOWN(m)			down(m)
+#define UP(m)			up(m)
+#endif
+
+IMG_VOID * HostCreateMutex(IMG_VOID)
+{
+	MUTEX *psMutex;
+
+	psMutex = kmalloc(sizeof(*psMutex), GFP_KERNEL);
+	if (psMutex)
+	{
+		INIT_MUTEX(psMutex);
+	}
+
+	return psMutex;
+}
+
+IMG_VOID HostAquireMutex(IMG_VOID * pvMutex)
+{
+	BUG_ON(in_interrupt());
+
+#if defined(PVR_DEBUG_DBGDRV_DETECT_HOST_MUTEX_COLLISIONS)
+	if (DOWN_TRYLOCK((MUTEX *)pvMutex))
+	{
+		printk(KERN_INFO "HostAquireMutex: Waiting for mutex\n");
+		DOWN((MUTEX *)pvMutex);
+	}
+#else
+	DOWN((MUTEX *)pvMutex);
+#endif
+}
+
+IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex)
+{
+	UP((MUTEX *)pvMutex);
+}
+
+IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex)
+{
+	if (pvMutex)
+	{
+		kfree(pvMutex);
+	}
+}
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+
+#define	EVENT_WAIT_TIMEOUT_MS	500
+#define	EVENT_WAIT_TIMEOUT_JIFFIES	(EVENT_WAIT_TIMEOUT_MS * HZ / 1000)
+
+static int iStreamData;
+static wait_queue_head_t sStreamDataEvent;
+
+IMG_INT32 HostCreateEventObjects(IMG_VOID)
+{
+	init_waitqueue_head(&sStreamDataEvent);
+
+	return 0;
+}
+
+IMG_VOID HostWaitForEvent(DBG_EVENT eEvent)
+{
+	switch(eEvent)
+	{
+		case DBG_EVENT_STREAM_DATA:
+			
+			wait_event_interruptible_timeout(sStreamDataEvent, iStreamData != 0, EVENT_WAIT_TIMEOUT_JIFFIES);
+			iStreamData = 0;
+			break;
+		default:
+			
+			msleep_interruptible(EVENT_WAIT_TIMEOUT_MS);
+			break;
+	}
+}
+
+IMG_VOID HostSignalEvent(DBG_EVENT eEvent)
+{
+	switch(eEvent)
+	{
+		case DBG_EVENT_STREAM_DATA:
+			iStreamData = 1;
+			wake_up_interruptible(&sStreamDataEvent);
+			break;
+		default:
+			break;
+	}
+}
+
+IMG_VOID HostDestroyEventObjects(IMG_VOID)
+{
+}
+#endif	
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/kbuild/Makefile b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/kbuild/Makefile
new file mode 100644
index 0000000..00db6ef
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/kbuild/Makefile
@@ -0,0 +1,35 @@
+#
+# 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		= dbgdrv
+
+INCLUDES = -I$(EURASIAROOT)/services4/srvkm/env/linux
+
+SOURCES	=
+				
+include $(EURASIAROOT)/tools/intern/debug/dbgdriv/linux/makefile.linux.common
+
+include $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/main.c b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/main.c
new file mode 100644
index 0000000..b577a2f
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/main.c
@@ -0,0 +1,315 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope it will be useful but, except 
+ * as otherwise stated in writing, without any warranty; without even the 
+ * implied warranty of merchantability or fitness for a particular purpose. 
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/version.h>
+
+#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRI_DRM)
+#include <linux/platform_device.h>
+#endif
+
+#if defined(LDM_PCI) && !defined(SUPPORT_DRI_DRM)
+#include <linux/pci.h>
+#endif
+
+#include <asm/uaccess.h>
+
+#if defined(SUPPORT_DRI_DRM)
+#include "drmP.h"
+#include "drm.h"
+#endif
+
+#include "img_types.h"
+#include "linuxsrv.h"
+#include "dbgdriv_ioctl.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hostfunc.h"
+#include "hotkey.h"
+#include "pvr_debug.h"
+#include "pvrmodule.h"
+
+#if defined(SUPPORT_DRI_DRM)
+
+#include "pvr_drm_shared.h"
+#include "pvr_drm.h"
+
+#else 
+
+#define DRVNAME "dbgdrv"
+MODULE_SUPPORTED_DEVICE(DRVNAME);
+
+#if (defined(LDM_PLATFORM) || defined(LDM_PCI)) && !defined(SUPPORT_DRI_DRM)
+static struct class *psDbgDrvClass;
+#endif
+
+static int AssignedMajorNumber = 0;
+
+long dbgdrv_ioctl(struct file *, unsigned int, unsigned long);
+
+static int dbgdrv_open(struct inode unref__ * pInode, struct file unref__ * pFile)
+{
+	return 0;
+}
+
+static int dbgdrv_release(struct inode unref__ * pInode, struct file unref__ * pFile)
+{
+	return 0;
+}
+
+static int dbgdrv_mmap(struct file* pFile, struct vm_area_struct* ps_vma)
+{
+	return 0;
+}
+
+static struct file_operations dbgdrv_fops = {
+	.owner          = THIS_MODULE,
+	.unlocked_ioctl = dbgdrv_ioctl,
+	.open           = dbgdrv_open,
+	.release        = dbgdrv_release,
+	.mmap           = dbgdrv_mmap,
+};
+
+#endif  
+
+IMG_VOID DBGDrvGetServiceTable(IMG_VOID **fn_table);
+
+IMG_VOID DBGDrvGetServiceTable(IMG_VOID **fn_table)
+{
+	extern DBGKM_SERVICE_TABLE g_sDBGKMServices;
+
+	*fn_table = &g_sDBGKMServices;
+}
+
+#if defined(SUPPORT_DRI_DRM)
+void dbgdrv_cleanup(void)
+#else
+static void __exit dbgdrv_cleanup(void)
+#endif
+{
+#if !defined(SUPPORT_DRI_DRM)
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+	device_destroy(psDbgDrvClass, MKDEV(AssignedMajorNumber, 0));
+	class_destroy(psDbgDrvClass);
+#endif
+	unregister_chrdev(AssignedMajorNumber, DRVNAME);
+#endif 
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+	HostDestroyEventObjects();
+#endif
+	HostDestroyMutex(g_pvAPIMutex);
+	return;
+}
+
+#if defined(SUPPORT_DRI_DRM)
+IMG_INT dbgdrv_init(void)
+#else
+static int __init dbgdrv_init(void)
+#endif
+{
+#if (defined(LDM_PLATFORM) || defined(LDM_PCI)) && !defined(SUPPORT_DRI_DRM)
+	struct device *psDev;
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+	int err = -EBUSY;
+#endif
+
+	
+	if ((g_pvAPIMutex=HostCreateMutex()) == IMG_NULL)
+	{
+		return -ENOMEM;
+	}
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+	
+	(void) HostCreateEventObjects();
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+	AssignedMajorNumber =
+	register_chrdev(AssignedMajorNumber, DRVNAME, &dbgdrv_fops);
+
+	if (AssignedMajorNumber <= 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR," unable to get major\n"));
+		goto ErrDestroyEventObjects;
+	}
+
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+	
+	psDbgDrvClass = class_create(THIS_MODULE, DRVNAME);
+	if (IS_ERR(psDbgDrvClass))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: unable to create class (%ld)",
+				 __func__, PTR_ERR(psDbgDrvClass)));
+		goto ErrUnregisterCharDev;
+	}
+
+	psDev = device_create(psDbgDrvClass, NULL, MKDEV(AssignedMajorNumber, 0),
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+						  NULL,
+#endif
+						  DRVNAME);
+	if (IS_ERR(psDev))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: unable to create device (%ld)",
+								__func__, PTR_ERR(psDev)));
+		goto ErrDestroyClass;
+	}
+#endif 
+#endif 
+
+	return 0;
+
+#if !defined(SUPPORT_DRI_DRM)
+ErrDestroyEventObjects:
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+	HostDestroyEventObjects();
+#endif
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ErrUnregisterCharDev:
+	unregister_chrdev(AssignedMajorNumber, DRVNAME);
+ErrDestroyClass:
+	class_destroy(psDbgDrvClass);
+#endif
+	return err;
+#endif 
+}
+
+#if defined(SUPPORT_DRI_DRM)
+int dbgdrv_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+#else
+long dbgdrv_ioctl(struct file *file, unsigned int ioctlCmd, unsigned long arg)
+#endif
+{
+	IOCTL_PACKAGE *pIP = (IOCTL_PACKAGE *) arg;
+	char *buffer, *in, *out;
+	unsigned int cmd;
+
+	if((pIP->ui32InBufferSize > (PAGE_SIZE >> 1) ) || (pIP->ui32OutBufferSize > (PAGE_SIZE >> 1)))
+	{
+		PVR_DPF((PVR_DBG_ERROR,"Sizes of the buffers are too large, cannot do ioctl\n"));
+		return -1;
+	}
+
+	buffer = (char *) HostPageablePageAlloc(1);
+	if(!buffer)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"Failed to allocate buffer, cannot do ioctl\n"));
+		return -EFAULT;
+	}
+
+	in = buffer;
+	out = buffer + (PAGE_SIZE >>1);
+
+	if (copy_from_user(in, pIP->pInBuffer, pIP->ui32InBufferSize) != 0)
+	{
+		goto init_failed;
+	}
+
+	cmd = MAKEIOCTLINDEX(pIP->ui32Cmd) - DEBUG_SERVICE_IOCTL_BASE - 1;
+
+	if(pIP->ui32Cmd == DEBUG_SERVICE_READ)
+	{
+		IMG_UINT32 *pui32BytesCopied = (IMG_UINT32 *)out;
+		DBG_IN_READ *psReadInParams = (DBG_IN_READ *)in;
+		DBG_STREAM *psStream;
+		IMG_CHAR *ui8Tmp;
+
+		ui8Tmp = vmalloc(psReadInParams->ui32OutBufferSize);
+
+		if(!ui8Tmp)
+		{
+			goto init_failed;
+		}
+
+		psStream = SID2PStream(psReadInParams->hStream);
+		if(!psStream)
+		{
+			goto init_failed;
+		}
+
+		*pui32BytesCopied = ExtDBGDrivRead(psStream,
+										   psReadInParams->bReadInitBuffer,
+										   psReadInParams->ui32OutBufferSize,
+										   ui8Tmp);
+
+		if (copy_to_user(psReadInParams->u.pui8OutBuffer,
+						ui8Tmp,
+						*pui32BytesCopied) != 0)
+		{
+			vfree(ui8Tmp);
+			goto init_failed;
+		}
+
+		vfree(ui8Tmp);
+	}
+	else
+	{
+		(g_DBGDrivProc[cmd])(in, out);
+	}
+
+	if(copy_to_user(pIP->pOutBuffer, out, pIP->ui32OutBufferSize) != 0)
+	{
+		goto init_failed;
+	}
+
+	HostPageablePageFree((IMG_VOID *)buffer);
+	return 0;
+
+init_failed:
+	HostPageablePageFree((IMG_VOID *)buffer);
+	return -EFAULT;
+}
+
+
+IMG_VOID RemoveHotKey (IMG_UINT32 hHotKey)
+{
+	PVR_UNREFERENCED_PARAMETER(hHotKey);
+}
+
+IMG_VOID DefineHotKey (IMG_UINT32 ui32ScanCode, IMG_UINT32 ui32ShiftState, PHOTKEYINFO psInfo)
+{
+	PVR_UNREFERENCED_PARAMETER(ui32ScanCode);
+	PVR_UNREFERENCED_PARAMETER(ui32ShiftState);
+	PVR_UNREFERENCED_PARAMETER(psInfo);
+}
+
+EXPORT_SYMBOL(DBGDrvGetServiceTable);
+
+#if !defined(SUPPORT_DRI_DRM)
+subsys_initcall(dbgdrv_init);
+module_exit(dbgdrv_cleanup);
+#endif
diff --git a/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/makefile.linux.common b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/makefile.linux.common
new file mode 100644
index 0000000..a995a15
--- /dev/null
+++ b/drivers/staging/cdv/pvr/tools/intern/debug/dbgdriv/linux/makefile.linux.common
@@ -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
+#
+#
+#
+
+DBGDRV_SOURCES_ROOT = $(KBUILDROOT)/../tools/intern/debug/dbgdriv
+
+INCLUDES += 	-I$(EURASIAROOT)/include4 \
+			-I$(EURASIAROOT)/tools/intern/debug \
+			-I$(EURASIAROOT)/tools/intern/debug/dbgdriv/common \
+			-I$(EURASIAROOT)/tools/intern/debug/client
+
+SOURCES	+=	$(DBGDRV_SOURCES_ROOT)/linux/main.c \
+				$(DBGDRV_SOURCES_ROOT)/common/dbgdriv.c \
+				$(DBGDRV_SOURCES_ROOT)/common/ioctl.c \
+				$(DBGDRV_SOURCES_ROOT)/common/handle.c \
+				$(DBGDRV_SOURCES_ROOT)/linux/hostfunc.c \
+				$(DBGDRV_SOURCES_ROOT)/common/hotkey.c
